Annotation of GNUtools/emacs/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:   long i;
                     64:   
                     65:   /* For the greatest flexibility, should create a temporary file in
                     66:      the same directory as the new file.  When everything is complete,
                     67:      rename the temp file to the new name.
                     68:      This way, a program could update its own a.out file even while
                     69:      it is still executing.  If problems occur, everything is still
                     70:      intact.  NOT implemented.  */
                     71:   
                     72:   /* Open the input and output a.out files */
                     73:   old = open(old_name, O_RDONLY);
                     74:   if (old < 0)
                     75:     { perror(old_name); exit(1); }
                     76:   new = open(new_name, O_CREAT|O_RDWR|O_TRUNC, 0777);
                     77:   if (new < 0)
                     78:     { perror(new_name); exit(1); }
                     79:   
                     80:   /* Read the old headers */
                     81:   read_header(old, &hdr, &auxhdr);
                     82:   
                     83:   /* Decide how large the new and old data areas are */
                     84:   old_size = auxhdr.exec_dsize;
                     85:   /* I suspect these two statements are separate
                     86:      to avoid a compiler bug in hpux version 8.  */
                     87:   i = sbrk (0);
                     88:   new_size = i - auxhdr.exec_dmem;
                     89:   
                     90:   /* Copy the old file to the new, up to the data space */
                     91:   lseek(old, 0, 0);
                     92:   copy_file(old, new, auxhdr.exec_dfile);
                     93:   
                     94:   /* Skip the old data segment and write a new one */
                     95:   lseek(old, old_size, 1);
                     96:   save_data_space(new, &hdr, &auxhdr, new_size);
                     97:   
                     98:   /* Copy the rest of the file */
                     99:   copy_rest(old, new);
                    100:   
                    101:   /* Update file pointers since we probably changed size of data area */
                    102:   update_file_ptrs(new, &hdr, &auxhdr, auxhdr.exec_dfile, new_size-old_size);
                    103:   
                    104:   /* Save the modified header */
                    105:   write_header(new, &hdr, &auxhdr);
                    106:   
                    107:   /* Close the binary file */
                    108:   close(old);
                    109:   close(new);
                    110:   exit(0);
                    111: }
                    112: 
                    113: /* Save current data space in the file, update header.  */
                    114: 
                    115: save_data_space(file, hdr, auxhdr, size)
                    116:      int file;
                    117:      struct header *hdr;
                    118:      struct som_exec_auxhdr *auxhdr;
                    119:      int size;
                    120: {
                    121:   /* Write the entire data space out to the file */
                    122:   if (write(file, auxhdr->exec_dmem, size) != size)
                    123:     { perror("Can't save new data space"); exit(1); }
                    124:   
                    125:   /* Update the header to reflect the new data size */
                    126:   auxhdr->exec_dsize = size;
                    127:   auxhdr->exec_bsize = 0;
                    128: }
                    129: 
                    130: /* Update the values of file pointers when something is inserted.  */
                    131: 
                    132: update_file_ptrs(file, hdr, auxhdr, location, offset)
                    133:      int file;
                    134:      struct header *hdr;
                    135:      struct som_exec_auxhdr *auxhdr;
                    136:      unsigned int location;
                    137:      int offset;
                    138: {
                    139:   struct subspace_dictionary_record subspace;
                    140:   int i;
                    141:   
                    142:   /* Increase the overall size of the module */
                    143:   hdr->som_length += offset;
                    144:   
                    145:   /* Update the various file pointers in the header */
                    146: #define update(ptr) if (ptr > location) ptr = ptr + offset
                    147:   update(hdr->aux_header_location);
                    148:   update(hdr->space_strings_location);
                    149:   update(hdr->init_array_location);
                    150:   update(hdr->compiler_location);
                    151:   update(hdr->symbol_location);
                    152:   update(hdr->fixup_request_location);
                    153:   update(hdr->symbol_strings_location);
                    154:   update(hdr->unloadable_sp_location);
                    155:   update(auxhdr->exec_tfile);
                    156:   update(auxhdr->exec_dfile);
                    157:   
                    158:   /* Do for each subspace dictionary entry */
                    159:   lseek(file, hdr->subspace_location, 0);
                    160:   for (i = 0; i < hdr->subspace_total; i++)
                    161:     {
                    162:       if (read(file, &subspace, sizeof(subspace)) != sizeof(subspace))
                    163:        { perror("Can't read subspace record"); exit(1); }
                    164:       
                    165:       /* If subspace has a file location, update it */
                    166:       if (subspace.initialization_length > 0 
                    167:          && subspace.file_loc_init_value > location)
                    168:        {
                    169:          subspace.file_loc_init_value += offset;
                    170:          lseek(file, -sizeof(subspace), 1);
                    171:          if (write(file, &subspace, sizeof(subspace)) != sizeof(subspace))
                    172:            { perror("Can't update subspace record"); exit(1); }
                    173:        }
                    174:     } 
                    175:   
                    176:   /* Do for each initialization pointer record */
                    177:   /* (I don't think it applies to executable files, only relocatables) */
                    178: #undef update
                    179: }
                    180: 
                    181: /* Read in the header records from an a.out file.  */
                    182: 
                    183: read_header(file, hdr, auxhdr)
                    184:      int file;
                    185:      struct header *hdr;
                    186:      struct som_exec_auxhdr *auxhdr;
                    187: {
                    188:   
                    189:   /* Read the header in */
                    190:   lseek(file, 0, 0);
                    191:   if (read(file, hdr, sizeof(*hdr)) != sizeof(*hdr))
                    192:     { perror("Couldn't read header from a.out file"); exit(1); }
                    193:   
                    194:   if (hdr->a_magic != EXEC_MAGIC && hdr->a_magic != SHARE_MAGIC
                    195:       &&  hdr->a_magic != DEMAND_MAGIC)
                    196:     {
                    197:       fprintf(stderr, "a.out file doesn't have legal magic number\n"); 
                    198:       exit(1);  
                    199:     }
                    200:   
                    201:   lseek(file, hdr->aux_header_location, 0);
                    202:   if (read(file, auxhdr, sizeof(*auxhdr)) != sizeof(*auxhdr))
                    203:     {
                    204:       perror("Couldn't read auxiliary header from a.out file");
                    205:       exit(1);
                    206:     }  
                    207: }
                    208: 
                    209: /* Write out the header records into an a.out file.  */
                    210: 
                    211: write_header(file, hdr, auxhdr)
                    212:      int file;
                    213:      struct header *hdr;
                    214:      struct som_exec_auxhdr *auxhdr;
                    215: {
                    216:   /* Update the checksum */
                    217:   hdr->checksum = calculate_checksum(hdr);
                    218:   
                    219:   /* Write the header back into the a.out file */
                    220:   lseek(file, 0, 0);
                    221:   if (write(file, hdr, sizeof(*hdr)) != sizeof(*hdr))
                    222:     { perror("Couldn't write header to a.out file"); exit(1); }
                    223:   lseek(file, hdr->aux_header_location, 0);
                    224:   if (write(file, auxhdr, sizeof(*auxhdr)) != sizeof(*auxhdr))
                    225:     { perror("Couldn't write auxiliary header to a.out file"); exit(1); }
                    226: }
                    227: 
                    228: /* Calculate the checksum of a SOM header record. */
                    229: 
                    230: calculate_checksum(hdr)
                    231:      struct header *hdr;
                    232: {
                    233:   int checksum, i, *ptr;
                    234:   
                    235:   checksum = 0;  ptr = (int *) hdr;
                    236:   
                    237:   for (i=0; i<sizeof(*hdr)/sizeof(int)-1; i++)
                    238:     checksum ^= ptr[i];
                    239:   
                    240:   return(checksum);
                    241: }
                    242: 
                    243: /* Copy size bytes from the old file to the new one.  */
                    244: 
                    245: copy_file(old, new, size)
                    246:      int new, old;
                    247:      int size;
                    248: {
                    249:   int len;
                    250:   int buffer[8196];  /* word aligned will be faster */
                    251:   
                    252:   for (; size > 0; size -= len)
                    253:     {
                    254:       len = min(size, sizeof(buffer));
                    255:       if (read(old, buffer, len) != len)
                    256:        { perror("Read failure on a.out file"); exit(1); }
                    257:       if (write(new, buffer, len) != len)
                    258:        { perror("Write failure in a.out file"); exit(1); }
                    259:     }
                    260: }
                    261: 
                    262: /* Copy the rest of the file, up to EOF.  */
                    263: 
                    264: copy_rest(old, new)
                    265:      int new, old;
                    266: {
                    267:   int buffer[4096];
                    268:   int len;
                    269:   
                    270:   /* Copy bytes until end of file or error */
                    271:   while ( (len = read(old, buffer, sizeof(buffer))) > 0)
                    272:     if (write(new, buffer, len) != len) break;
                    273:   
                    274:   if (len != 0)
                    275:     { perror("Unable to copy the rest of the file"); exit(1); }
                    276: }
                    277: 
                    278: #ifdef DEBUG
                    279: display_header(hdr, auxhdr)
                    280:      struct header *hdr;
                    281:      struct som_exec_auxhdr *auxhdr;
                    282: {
                    283:   /* Display the header information (debug) */
                    284:   printf("\n\nFILE HEADER\n");
                    285:   printf("magic number %d \n", hdr->a_magic); 
                    286:   printf("text loc %.8x   size %d \n", auxhdr->exec_tmem, auxhdr->exec_tsize);
                    287:   printf("data loc %.8x   size %d \n", auxhdr->exec_dmem, auxhdr->exec_dsize);
                    288:   printf("entry     %x \n",   auxhdr->exec_entry);
                    289:   printf("Bss  segment size %u\n", auxhdr->exec_bsize);
                    290:   printf("\n");
                    291:   printf("data file loc %d    size %d\n",
                    292:         auxhdr->exec_dfile, auxhdr->exec_dsize);
                    293:   printf("som_length %d\n", hdr->som_length);
                    294:   printf("unloadable sploc %d    size %d\n",
                    295:         hdr->unloadable_sp_location, hdr->unloadable_sp_size);
                    296: }
                    297: #endif /* DEBUG */

unix.superglobalmegacorp.com

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