Annotation of 43BSDReno/contrib/emacs-18.55/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:   
        !            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.