Annotation of 43BSDReno/contrib/emacs-18.55/src/unexhp9k800.c, revision 1.1.1.1

1.1       root        1: /* Unexec for HP 9000 Series 800 machines.
                      2:    Bob Desinger <[email protected]>
                      3: 
                      4:    Note that the GNU project considers support for HP operation a
                      5:    peripheral activity which should not be allowed to divert effort
                      6:    from development of the GNU system.  Changes in this code will be
                      7:    installed when users send them in, but aside from that we don't
                      8:    plan to think about it, or about whether other Emacs maintenance
                      9:    might break it.
                     10: 
                     11: 
                     12:   Unexec creates a copy of the old a.out file, and replaces the old data
                     13:   area with the current data area.  When the new file is executed, the
                     14:   process will see the same data structures and data values that the
                     15:   original process had when unexec was called.
                     16:   
                     17:   Unlike other versions of unexec, this one copies symbol table and
                     18:   debug information to the new a.out file.  Thus, the new a.out file
                     19:   may be debugged with symbolic debuggers.
                     20:   
                     21:   If you fix any bugs in this, I'd like to incorporate your fixes.
                     22:   Send them to uunet!hpda!hpsemc!jmorris or jmorris%[email protected].
                     23:   
                     24:   CAVEATS:
                     25:   This routine saves the current value of all static and external
                     26:   variables.  This means that any data structure that needs to be
                     27:   initialized must be explicitly reset.  Variables will not have their
                     28:   expected default values.
                     29:   
                     30:   Unfortunately, the HP-UX signal handler has internal initialization
                     31:   flags which are not explicitly reset.  Thus, for signals to work in
                     32:   conjunction with this routine, the following code must executed when
                     33:   the new process starts up.
                     34:   
                     35:   void _sigreturn();
                     36:   ...
                     37:   sigsetreturn(_sigreturn);
                     38: */
                     39: 
                     40: #include <stdio.h>
                     41: #include <fcntl.h>
                     42: #include <errno.h>
                     43: 
                     44: #include <a.out.h>
                     45: 
                     46: #define NBPG 2048
                     47: #define roundup(x,n) ( ( (x)+(n-1) ) & ~(n-1) )  /* n is power of 2 */
                     48: #define min(x,y)  ( ((x)<(y))?(x):(y) )
                     49: 
                     50: 
                     51: /* Create a new a.out file, same as old but with current data space */
                     52: 
                     53: unexec(new_name, old_name, new_end_of_text, dummy1, dummy2)
                     54:      char new_name[];          /* name of the new a.out file to be created */
                     55:      char old_name[];          /* name of the old a.out file */
                     56:      char *new_end_of_text;    /* ptr to new edata/etext; NOT USED YET */
                     57:      int dummy1, dummy2;       /* not used by emacs */
                     58: {
                     59:   int old, new;
                     60:   int old_size, new_size;
                     61:   struct header hdr;
                     62:   struct som_exec_auxhdr auxhdr;
                     63:   
                     64:   /* For the greatest flexibility, should create a temporary file in
                     65:      the same directory as the new file.  When everything is complete,
                     66:      rename the temp file to the new name.
                     67:      This way, a program could update its own a.out file even while
                     68:      it is still executing.  If problems occur, everything is still
                     69:      intact.  NOT implemented.  */
                     70:   
                     71:   /* Open the input and output a.out files */
                     72:   old = open(old_name, O_RDONLY);
                     73:   if (old < 0)
                     74:     { perror(old_name); exit(1); }
                     75:   new = open(new_name, O_CREAT|O_RDWR|O_TRUNC, 0777);
                     76:   if (new < 0)
                     77:     { perror(new_name); exit(1); }
                     78:   
                     79:   /* Read the old headers */
                     80:   read_header(old, &hdr, &auxhdr);
                     81:   
                     82:   /* Decide how large the new and old data areas are */
                     83:   old_size = auxhdr.exec_dsize;
                     84:   new_size = sbrk(0) - auxhdr.exec_dmem;
                     85:   
                     86:   /* Copy the old file to the new, up to the data space */
                     87:   lseek(old, 0, 0);
                     88:   copy_file(old, new, auxhdr.exec_dfile);
                     89:   
                     90:   /* Skip the old data segment and write a new one */
                     91:   lseek(old, old_size, 1);
                     92:   save_data_space(new, &hdr, &auxhdr, new_size);
                     93:   
                     94:   /* Copy the rest of the file */
                     95:   copy_rest(old, new);
                     96:   
                     97:   /* Update file pointers since we probably changed size of data area */
                     98:   update_file_ptrs(new, &hdr, &auxhdr, auxhdr.exec_dfile, new_size-old_size);
                     99:   
                    100:   /* Save the modified header */
                    101:   write_header(new, &hdr, &auxhdr);
                    102:   
                    103:   /* Close the binary file */
                    104:   close(old);
                    105:   close(new);
                    106:   exit(0);
                    107: }
                    108: 
                    109: /* Save current data space in the file, update header.  */
                    110: 
                    111: save_data_space(file, hdr, auxhdr, size)
                    112:      int file;
                    113:      struct header *hdr;
                    114:      struct som_exec_auxhdr *auxhdr;
                    115:      int size;
                    116: {
                    117:   /* Write the entire data space out to the file */
                    118:   if (write(file, auxhdr->exec_dmem, size) != size)
                    119:     { perror("Can't save new data space"); exit(1); }
                    120:   
                    121:   /* Update the header to reflect the new data size */
                    122:   auxhdr->exec_dsize = size;
                    123:   auxhdr->exec_bsize = 0;
                    124: }
                    125: 
                    126: /* Update the values of file pointers when something is inserted.  */
                    127: 
                    128: update_file_ptrs(file, hdr, auxhdr, location, offset)
                    129:      int file;
                    130:      struct header *hdr;
                    131:      struct som_exec_auxhdr *auxhdr;
                    132:      unsigned int location;
                    133:      int offset;
                    134: {
                    135:   struct subspace_dictionary_record subspace;
                    136:   int i;
                    137:   
                    138:   /* Increase the overall size of the module */
                    139:   hdr->som_length += offset;
                    140:   
                    141:   /* Update the various file pointers in the header */
                    142: #define update(ptr) if (ptr > location) ptr = ptr + offset
                    143:   update(hdr->aux_header_location);
                    144:   update(hdr->space_strings_location);
                    145:   update(hdr->init_array_location);
                    146:   update(hdr->compiler_location);
                    147:   update(hdr->symbol_location);
                    148:   update(hdr->fixup_request_location);
                    149:   update(hdr->symbol_strings_location);
                    150:   update(hdr->unloadable_sp_location);
                    151:   update(auxhdr->exec_tfile);
                    152:   update(auxhdr->exec_dfile);
                    153:   
                    154:   /* Do for each subspace dictionary entry */
                    155:   lseek(file, hdr->subspace_location, 0);
                    156:   for (i = 0; i < hdr->subspace_total; i++)
                    157:     {
                    158:       if (read(file, &subspace, sizeof(subspace)) != sizeof(subspace))
                    159:        { perror("Can't read subspace record"); exit(1); }
                    160:       
                    161:       /* If subspace has a file location, update it */
                    162:       if (subspace.initialization_length > 0 
                    163:          && subspace.file_loc_init_value > location)
                    164:        {
                    165:          subspace.file_loc_init_value += offset;
                    166:          lseek(file, -sizeof(subspace), 1);
                    167:          if (write(file, &subspace, sizeof(subspace)) != sizeof(subspace))
                    168:            { perror("Can't update subspace record"); exit(1); }
                    169:        }
                    170:     } 
                    171:   
                    172:   /* Do for each initialization pointer record */
                    173:   /* (I don't think it applies to executable files, only relocatables) */
                    174: #undef update
                    175: }
                    176: 
                    177: /* Read in the header records from an a.out file.  */
                    178: 
                    179: read_header(file, hdr, auxhdr)
                    180:      int file;
                    181:      struct header *hdr;
                    182:      struct som_exec_auxhdr *auxhdr;
                    183: {
                    184:   
                    185:   /* Read the header in */
                    186:   lseek(file, 0, 0);
                    187:   if (read(file, hdr, sizeof(*hdr)) != sizeof(*hdr))
                    188:     { perror("Couldn't read header from a.out file"); exit(1); }
                    189:   
                    190:   if (hdr->a_magic != EXEC_MAGIC && hdr->a_magic != SHARE_MAGIC
                    191:       &&  hdr->a_magic != DEMAND_MAGIC)
                    192:     {
                    193:       fprintf(stderr, "a.out file doesn't have legal magic number\n"); 
                    194:       exit(1);  
                    195:     }
                    196:   
                    197:   lseek(file, hdr->aux_header_location, 0);
                    198:   if (read(file, auxhdr, sizeof(*auxhdr)) != sizeof(*auxhdr))
                    199:     {
                    200:       perror("Couldn't read auxiliary header from a.out file");
                    201:       exit(1);
                    202:     }  
                    203: }
                    204: 
                    205: /* Write out the header records into an a.out file.  */
                    206: 
                    207: write_header(file, hdr, auxhdr)
                    208:      int file;
                    209:      struct header *hdr;
                    210:      struct som_exec_auxhdr *auxhdr;
                    211: {
                    212:   /* Update the checksum */
                    213:   hdr->checksum = calculate_checksum(hdr);
                    214:   
                    215:   /* Write the header back into the a.out file */
                    216:   lseek(file, 0, 0);
                    217:   if (write(file, hdr, sizeof(*hdr)) != sizeof(*hdr))
                    218:     { perror("Couldn't write header to a.out file"); exit(1); }
                    219:   lseek(file, hdr->aux_header_location, 0);
                    220:   if (write(file, auxhdr, sizeof(*auxhdr)) != sizeof(*auxhdr))
                    221:     { perror("Couldn't write auxiliary header to a.out file"); exit(1); }
                    222: }
                    223: 
                    224: /* Calculate the checksum of a SOM header record. */
                    225: 
                    226: calculate_checksum(hdr)
                    227:      struct header *hdr;
                    228: {
                    229:   int checksum, i, *ptr;
                    230:   
                    231:   checksum = 0;  ptr = (int *) hdr;
                    232:   
                    233:   for (i=0; i<sizeof(*hdr)/sizeof(int)-1; i++)
                    234:     checksum ^= ptr[i];
                    235:   
                    236:   return(checksum);
                    237: }
                    238: 
                    239: /* Copy size bytes from the old file to the new one.  */
                    240: 
                    241: copy_file(old, new, size)
                    242:      int new, old;
                    243:      int size;
                    244: {
                    245:   int len;
                    246:   int buffer[8196];  /* word aligned will be faster */
                    247:   
                    248:   for (; size > 0; size -= len)
                    249:     {
                    250:       len = min(size, sizeof(buffer));
                    251:       if (read(old, buffer, len) != len)
                    252:        { perror("Read failure on a.out file"); exit(1); }
                    253:       if (write(new, buffer, len) != len)
                    254:        { perror("Write failure in a.out file"); exit(1); }
                    255:     }
                    256: }
                    257: 
                    258: /* Copy the rest of the file, up to EOF.  */
                    259: 
                    260: copy_rest(old, new)
                    261:      int new, old;
                    262: {
                    263:   int buffer[4096];
                    264:   int len;
                    265:   
                    266:   /* Copy bytes until end of file or error */
                    267:   while ( (len = read(old, buffer, sizeof(buffer))) > 0)
                    268:     if (write(new, buffer, len) != len) break;
                    269:   
                    270:   if (len != 0)
                    271:     { perror("Unable to copy the rest of the file"); exit(1); }
                    272: }
                    273: 
                    274: #ifdef DEBUG
                    275: display_header(hdr, auxhdr)
                    276:      struct header *hdr;
                    277:      struct som_exec_auxhdr *auxhdr;
                    278: {
                    279:   /* Display the header information (debug) */
                    280:   printf("\n\nFILE HEADER\n");
                    281:   printf("magic number %d \n", hdr->a_magic); 
                    282:   printf("text loc %.8x   size %d \n", auxhdr->exec_tmem, auxhdr->exec_tsize);
                    283:   printf("data loc %.8x   size %d \n", auxhdr->exec_dmem, auxhdr->exec_dsize);
                    284:   printf("entry     %x \n",   auxhdr->exec_entry);
                    285:   printf("Bss  segment size %u\n", auxhdr->exec_bsize);
                    286:   printf("\n");
                    287:   printf("data file loc %d    size %d\n",
                    288:         auxhdr->exec_dfile, auxhdr->exec_dsize);
                    289:   printf("som_length %d\n", hdr->som_length);
                    290:   printf("unloadable sploc %d    size %d\n",
                    291:         hdr->unloadable_sp_location, hdr->unloadable_sp_size);
                    292: }
                    293: #endif /* DEBUG */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.