Annotation of GNUtools/emacs/src/unexhp9k800.c, revision 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.