Annotation of 43BSD/contrib/emacs/src/unexec.c, revision 1.1.1.1

1.1       root        1: /* Copyright (C) 1985 Free Software Foundation, Inc.
                      2: 
                      3: This file is part of GNU Emacs.
                      4: 
                      5: GNU Emacs is distributed in the hope that it will be useful,
                      6: but WITHOUT ANY WARRANTY.  No author or distributor
                      7: accepts responsibility to anyone for the consequences of using it
                      8: or for whether it serves any particular purpose or works at all,
                      9: unless he says so in writing.  Refer to the GNU Emacs General Public
                     10: License for full details.
                     11: 
                     12: Everyone is granted permission to copy, modify and redistribute
                     13: GNU Emacs, but only under the conditions described in the
                     14: GNU Emacs General Public License.   A copy of this license is
                     15: supposed to have been given to you along with GNU Emacs so you
                     16: can know your rights and responsibilities.  It should be in a
                     17: file named COPYING.  Among other things, the copyright notice
                     18: and this notice must be preserved on all copies.  */
                     19: 
                     20: 
                     21: /* 
                     22:  * unexec.c - Convert a running program into an a.out file.
                     23:  * 
                     24:  * Author:     Spencer W. Thomas
                     25:  *             Computer Science Dept.
                     26:  *             University of Utah
                     27:  * Date:       Tue Mar  2 1982
                     28:  * Modified heavily since then.
                     29:  *
                     30:  * Synopsis:
                     31:  *     unexec (new_name, a_name, data_start, bss_start, entry_address)
                     32:  *     char *new_name, *a_name;
                     33:  *     unsigned data_start, bss_start, entry_address;
                     34:  *
                     35:  * Takes a snapshot of the program and makes an a.out format file in the
                     36:  * file named by the string argument new_name.
                     37:  * If a_name is non-NULL, the symbol table will be taken from the given file.
                     38:  * 
                     39:  * The boundaries within the a.out file may be adjusted with the data_start 
                     40:  * and bss_start arguments.  Either or both may be given as 0 for defaults.
                     41:  * 
                     42:  * Data_start gives the boundary between the text segment and the data
                     43:  * segment of the program.  The text segment can contain shared, read-only
                     44:  * program code and literal data, while the data segment is always unshared
                     45:  * and unprotected.  Data_start gives the lowest unprotected address.  Since
                     46:  * the granularity of write-protection is on 1k page boundaries on the VAX, a
                     47:  * given data_start value which is not on a page boundary is rounded down to
                     48:  * the beginning of the page it is on.  The default when 0 is given leaves the
                     49:  * number of protected pages the same as it was before.
                     50:  * 
                     51:  * Bss_start indicates how much of the data segment is to be saved in the
                     52:  * a.out file and restored when the program is executed.  It gives the lowest
                     53:  * unsaved address, and is rounded up to a page boundary.  The default when 0
                     54:  * is given assumes that the entire data segment is to be stored, including
                     55:  * the previous data and bss as well as any additional storage allocated with
                     56:  * break (2).
                     57:  *
                     58:  * The new file is set up to start at entry_address.
                     59:  *
                     60:  * If you make improvements I'd like to get them too.
                     61:  * harpo!utah-cs!thomas, thomas@Utah-20
                     62:  *
                     63:  */
                     64: 
                     65: #ifndef emacs
                     66: #define PERROR(arg) perror (arg); return -1
                     67: #else
                     68: #include "config.h"
                     69: #define PERROR(file) report_error (file, new)
                     70: #endif
                     71: 
                     72: #ifndef CANNOT_DUMP  /* all rest of file!  */
                     73: 
                     74: #include <sys/param.h>
                     75: #ifndef makedev                        /* Try to detect types.h already loaded */
                     76: #include <sys/types.h>
                     77: #endif
                     78: #include <stdio.h>
                     79: #include <sys/stat.h>
                     80: #include <errno.h>
                     81:   
                     82: extern char *start_of_text ();         /* Start of text */
                     83: extern char *start_of_data ();         /* Start of initialized data */
                     84:   
                     85: #ifdef COFF
                     86: #include <filehdr.h>
                     87: #include <aouthdr.h>
                     88: #include <scnhdr.h>
                     89: #include <syms.h>
                     90: static long block_copy_start;          /* Old executable start point */
                     91: static struct filehdr f_hdr;           /* File header */
                     92: static struct aouthdr f_ohdr;          /* Optional file header (a.out) */
                     93: long bias;                     /* Bias to add for growth */
                     94: long lnnoptr;                  /* Pointer to line-number info within file */
                     95: #define SYMS_START block_copy_start
                     96: 
                     97: static int text_scnptr;
                     98: 
                     99: #else /* not COFF */
                    100: 
                    101: extern char *sbrk ();
                    102: 
                    103: #include <a.out.h>
                    104: #define SYMS_START ((long) N_SYMOFF (ohdr))
                    105: 
                    106: #ifdef HPUX
                    107: #ifdef hp9000s200
                    108: #define MY_ID HP9000S200_ID
                    109: #else
                    110: #include <model.h>
                    111: #define MY_ID MYSYS
                    112: #endif /* not hp9000s200 */
                    113: static MAGIC OLDMAGIC = {MY_ID, SHARE_MAGIC};
                    114: static MAGIC NEWMAGIC = {MY_ID, DEMAND_MAGIC};
                    115: #define N_TXTOFF(x) TEXT_OFFSET(x)
                    116: #define N_SYMOFF(x) LESYM_OFFSET(x)
                    117: static struct exec hdr, ohdr;
                    118: 
                    119: #else /* not HPUX */
                    120: 
                    121: #ifdef USG
                    122: static struct bhdr hdr, ohdr;
                    123: #define a_magic fmagic
                    124: #define a_text tsize
                    125: #define a_data dsize
                    126: #define a_bss bsize
                    127: #define a_syms ssize
                    128: #define a_trsize rtsize
                    129: #define a_drsize rdsize
                    130: #define a_entry entry
                    131: #define        N_BADMAG(x) \
                    132:     (((x).fmagic)!=OMAGIC && ((x).fmagic)!=NMAGIC &&\
                    133:      ((x).fmagic)!=FMAGIC && ((x).fmagic)!=IMAGIC)
                    134: #define NEWMAGIC FMAGIC
                    135: #else /* not USG */
                    136: static struct exec hdr, ohdr;
                    137: #define NEWMAGIC ZMAGIC
                    138: #endif /* not USG */
                    139: #endif /* not HPUX */
                    140: 
                    141: #endif /* not COFF */
                    142: 
                    143: static int pagemask;
                    144: 
                    145: #if defined (BSD4_1) || defined (USG)
                    146: #ifdef EXEC_PAGESIZE
                    147: #define getpagesize() EXEC_PAGESIZE
                    148: #else
                    149: #ifdef NBPG
                    150: #define getpagesize() NBPG * CLSIZE
                    151: #ifndef CLSIZE
                    152: #define CLSIZE 1
                    153: #endif /* no CLSIZE */
                    154: #else /* no NBPG */
                    155: #define getpagesize() NBPC
                    156: #endif /* no NBPG */
                    157: #endif /* no EXEC_PAGESIZE */
                    158: #endif /* BSD4_1 or USG */
                    159: 
                    160: /* Correct an int which is the bit pattern of a pointer to a byte
                    161:    into an int which is the number of a byte.
                    162:    This is a no-op on ordinary machines, but not on all.  */
                    163: 
                    164: #ifndef ADDR_CORRECT   /* Let m-*.h files override this definition */
                    165: #define ADDR_CORRECT(x) ((char *)(x) - (char*)0)
                    166: #endif
                    167: 
                    168: #ifdef emacs
                    169: 
                    170: static
                    171: report_error (file, fd)
                    172:      char *file;
                    173:      int fd;
                    174: {
                    175:   if (fd)
                    176:     close (fd);
                    177:   error ("Failure operating on %s", file);
                    178: }
                    179: #endif /* emacs */
                    180: 
                    181: #define ERROR0(msg) report_error_1 (new, msg, 0, 0); return -1
                    182: #define ERROR1(msg,x) report_error_1 (new, msg, x, 0); return -1
                    183: #define ERROR2(msg,x,y) report_error_1 (new, msg, x, y); return -1
                    184: 
                    185: static
                    186: report_error_1 (fd, msg, a1, a2)
                    187:      int fd;
                    188:      char *msg;
                    189:      int a1, a2;
                    190: {
                    191:   close (fd);
                    192: #ifdef emacs
                    193:   error (msg, a1, a2);
                    194: #else
                    195:   fprintf (stderr, msg, a1, a2);
                    196:   fprintf (stderr, "\n");
                    197: #endif
                    198: }
                    199: 
                    200: /* ****************************************************************
                    201:  * unexec
                    202:  *
                    203:  * driving logic.
                    204:  */
                    205: unexec (new_name, a_name, data_start, bss_start, entry_address)
                    206:      char *new_name, *a_name;
                    207:      unsigned data_start, bss_start, entry_address;
                    208: {
                    209:   int new, a_out = -1;
                    210: 
                    211:   if (a_name && (a_out = open (a_name, 0)) < 0)
                    212:     {
                    213:       PERROR (a_name);
                    214:     }
                    215:   if ((new = creat (new_name, 0666)) < 0)
                    216:     {
                    217:       PERROR (new_name);
                    218:     }
                    219:   if (make_hdr (new, a_out, data_start, bss_start, entry_address, a_name, new_name) < 0
                    220:       || copy_text_and_data (new) < 0
                    221:       || copy_sym (new, a_out, a_name, new_name) < 0
                    222: #ifdef COFF
                    223:       || adjust_lnnoptrs (new, a_out, new_name) < 0
                    224: #endif
                    225:       )
                    226:     {
                    227:       close (new);
                    228:       /* unlink (new_name);            /* Failed, unlink new a.out */
                    229:       return -1;       
                    230:     }
                    231: 
                    232:   close (new);
                    233:   if (a_out >= 0)
                    234:     close (a_out);
                    235:   mark_x (new_name);
                    236:   return 0;
                    237: }
                    238: 
                    239: /* ****************************************************************
                    240:  * make_hdr
                    241:  *
                    242:  * Make the header in the new a.out from the header in core.
                    243:  * Modify the text and data sizes.
                    244:  */
                    245: static int
                    246: make_hdr (new, a_out, data_start, bss_start, entry_address, a_name, new_name)
                    247:      int new, a_out;
                    248:      unsigned data_start, bss_start, entry_address;
                    249:      char *a_name;
                    250:      char *new_name;
                    251: {
                    252:   int tem;
                    253: #ifdef COFF
                    254:   auto struct scnhdr f_thdr;           /* Text section header */
                    255:   auto struct scnhdr f_dhdr;           /* Data section header */
                    256:   auto struct scnhdr f_bhdr;           /* Bss section header */
                    257:   auto struct scnhdr scntemp;          /* Temporary section header */
                    258:   register int scns;
                    259: 
                    260:   /* Salvage as much info from the existing file as possible */
                    261:   if (a_out >= 0)
                    262:     {
                    263:       if (read (a_out, &f_hdr, sizeof (f_hdr)) != sizeof (f_hdr))
                    264:        {
                    265:          PERROR (a_name);
                    266:        }
                    267:       block_copy_start += sizeof (f_hdr);
                    268:       if (f_hdr.f_opthdr > 0)
                    269:        {
                    270:          if (read (a_out, &f_ohdr, sizeof (f_ohdr)) != sizeof (f_ohdr))
                    271:            {
                    272:              PERROR (a_name);
                    273:            }
                    274:          block_copy_start += sizeof (f_ohdr);
                    275:        }           
                    276:       /* Loop through section headers, copying them in */
                    277:       for (scns = f_hdr.f_nscns; scns > 0; scns--) {
                    278:        if (read (a_out, &scntemp, sizeof (scntemp)) != sizeof (scntemp))
                    279:          {
                    280:            PERROR (a_name);
                    281:          }
                    282:        block_copy_start += sizeof (scntemp);
                    283:        if (scntemp.s_scnptr > 0L)
                    284:          {
                    285:            block_copy_start += scntemp.s_size;
                    286:          }
                    287:        if (strcmp (scntemp.s_name, ".text") == 0)
                    288:          {
                    289:            f_thdr = scntemp;
                    290:          }
                    291:        else if (strcmp (scntemp.s_name, ".data") == 0)
                    292:          {
                    293:            f_dhdr = scntemp;
                    294:          }
                    295:        else if (strcmp (scntemp.s_name, ".bss") == 0)
                    296:          {
                    297:            f_bhdr = scntemp;
                    298:          }
                    299:       }            
                    300:     }
                    301:   else
                    302:     {
                    303:       ERROR0 ("can't build a COFF file from scratch yet");
                    304:     }
                    305: 
                    306:   pagemask = getpagesize () - 1;
                    307: 
                    308: #ifdef NO_REMAP
                    309:   data_start = (int) start_of_data ();
                    310: #else /* not NO_REMAP */
                    311:   if (!data_start)
                    312:     data_start = (int) start_of_data ();
                    313: #endif /* not NO_REMAP */
                    314:   data_start = ADDR_CORRECT (data_start);
                    315:   data_start = data_start & ~pagemask; /* down to a page boundary */
                    316: 
                    317:   f_hdr.f_flags |= (F_RELFLG | F_EXEC);
                    318: #ifdef EXEC_MAGIC
                    319:   f_ohdr.magic = EXEC_MAGIC;
                    320: #endif
                    321:   f_ohdr.text_start = (long) start_of_text ();
                    322:   f_ohdr.tsize = data_start - f_ohdr.text_start;
                    323:   f_ohdr.data_start = data_start;
                    324:   f_ohdr.dsize = (long) sbrk (0) - f_ohdr.data_start;
                    325:   f_ohdr.bsize = 0;
                    326:   f_thdr.s_size = f_ohdr.tsize;
                    327:   f_thdr.s_scnptr = sizeof (f_hdr) + sizeof (f_ohdr);
                    328:   f_thdr.s_scnptr += (f_hdr.f_nscns) * (sizeof (f_thdr));
                    329:   lnnoptr = f_thdr.s_lnnoptr;
                    330: #ifdef UMAX
                    331:   /* Umax is bsd using coff; it has restrictions on alignment
                    332:      of the sections in the file itself.  */
                    333:   f_thdr.s_scnptr = (f_thdr.s_scnptr + pagemask) & ~pagemask;  /* round up */
                    334: #endif /* UMAX */
                    335:   text_scnptr = f_thdr.s_scnptr;
                    336:   f_dhdr.s_paddr = f_ohdr.data_start;
                    337:   f_dhdr.s_vaddr = f_ohdr.data_start;
                    338:   f_dhdr.s_size = f_ohdr.dsize;
                    339:   f_dhdr.s_scnptr = f_thdr.s_scnptr + f_thdr.s_size;
                    340: #ifdef UMAX
                    341:   f_dhdr.s_scnptr &= ~pagemask; /* round down to page boundary */
                    342: #endif /* UMAX */
                    343:   f_bhdr.s_paddr = f_ohdr.data_start + f_ohdr.dsize;
                    344:   f_bhdr.s_vaddr = f_ohdr.data_start + f_ohdr.dsize;
                    345:   f_bhdr.s_size = f_ohdr.bsize;
                    346:   f_bhdr.s_scnptr = 0L;
                    347:   bias = f_dhdr.s_scnptr + f_dhdr.s_size - block_copy_start;
                    348: 
                    349:   if (f_hdr.f_symptr > 0L)
                    350:     {
                    351:       f_hdr.f_symptr += bias;
                    352:     }
                    353: 
                    354:   if (f_thdr.s_lnnoptr > 0L) 
                    355:     {
                    356:       f_thdr.s_lnnoptr += bias;
                    357:     }
                    358: 
                    359:   if (write (new, &f_hdr, sizeof (f_hdr)) != sizeof (f_hdr))
                    360:     {
                    361:       PERROR (new_name);
                    362:     }
                    363: 
                    364:   if (write (new, &f_ohdr, sizeof (f_ohdr)) != sizeof (f_ohdr))
                    365:     {
                    366:       PERROR (new_name);
                    367:     }
                    368: 
                    369:   if (write (new, &f_thdr, sizeof (f_thdr)) != sizeof (f_thdr))
                    370:     {
                    371:       PERROR (new_name);
                    372:     }
                    373: 
                    374:   if (write (new, &f_dhdr, sizeof (f_dhdr)) != sizeof (f_dhdr))
                    375:     {
                    376:       PERROR (new_name);
                    377:     }
                    378: 
                    379:   if (write (new, &f_bhdr, sizeof (f_bhdr)) != sizeof (f_bhdr))
                    380:     {
                    381:       PERROR (new_name);
                    382:     }
                    383:   return (0);
                    384:     
                    385: #else /* if not COFF */
                    386: 
                    387:   /* Get symbol table info from header of a.out file if given one. */
                    388:   if (a_out >= 0)
                    389:     {
                    390:       if (read (a_out, &ohdr, sizeof hdr) != sizeof hdr)
                    391:        {
                    392:          PERROR (a_name);
                    393:        }
                    394: 
                    395:       if N_BADMAG (ohdr)
                    396:        {
                    397:          ERROR1 ("invalid magic number in %s", a_name);
                    398:        }
                    399: #ifdef celerity
                    400:       hdr.a_scovrfl = ohdr.a_scovrfl;
                    401: #endif
                    402: #ifdef HPUX
                    403:       hdr.a_lesyms = ohdr.a_lesyms;
                    404:       hdr.a_sltsize = ohdr.a_sltsize;
                    405:       hdr.a_dnttsize = ohdr.a_dnttsize;
                    406:       hdr.a_vtsize = ohdr.a_vtsize;
                    407: #else /* not HPUX */
                    408:       hdr.a_syms = ohdr.a_syms;
                    409: #endif /* not HPUX */
                    410:     }
                    411:   else
                    412:     {
                    413: #ifdef celerity
                    414:       hdr.a_scovrfl = 0;
                    415: #endif
                    416: #ifdef HPUX
                    417:       hdr.a_lesyms = 0;
                    418:       hdr.a_sltsize = 0;
                    419:       hdr.a_dnttsize = 0;
                    420:       hdr.a_vtsize = 0;
                    421: #else /* not HPUX */
                    422:       hdr.a_syms = 0;                  /* No a.out, so no symbol info. */
                    423: #endif /* not HPUX */
                    424:     }
                    425: 
                    426:   /* Construct header from user structure. */
                    427: #ifdef HPUX
                    428:   /* (((MAGIC) ohdr.a_magic) == ((MAGIC) OLDMAGIC)) This does not work */
                    429:   hdr.a_magic = ((ohdr.a_magic.file_type == OLDMAGIC.file_type) ?
                    430:                 NEWMAGIC : ohdr.a_magic);
                    431: #else /* not HPUX */
                    432: /* hdr.a_magic = NEWMAGIC; */
                    433:   hdr.a_magic = ohdr.a_magic;
                    434: #endif /* not HPUX */
                    435: 
                    436: #ifdef sun3
                    437:   hdr.a_machtype = ohdr.a_machtype;
                    438: #endif /* sun3 */
                    439:   hdr.a_trsize = 0;
                    440:   hdr.a_drsize = 0;
                    441:   hdr.a_entry = entry_address;
                    442: 
                    443:   pagemask = getpagesize () - 1;
                    444: 
                    445:   /* Adjust data/bss boundary. */
                    446:   if (bss_start != 0)
                    447:     {
                    448:       bss_start = (ADDR_CORRECT (bss_start) + pagemask) & ~pagemask;         /* (Up) to page bdry. */
                    449:       if (bss_start > ADDR_CORRECT (sbrk (0)))
                    450:        {
                    451:          ERROR1 ("unexec: Specified bss_start (%u) is past end of program",
                    452:                  bss_start);
                    453:        }
                    454:     }
                    455:   else
                    456:     {
                    457:       bss_start = ADDR_CORRECT (sbrk (0));
                    458:       bss_start = (bss_start + pagemask) & ~pagemask;
                    459:     }
                    460: 
                    461:   /* Adjust text/data boundary. */
                    462: #ifdef NO_REMAP
                    463:   data_start = (int) start_of_data ();
                    464: #else /* not NO_REMAP */
                    465:   if (!data_start)
                    466:     data_start = (int) start_of_data ();
                    467: #endif /* not NO_REMAP */
                    468:   data_start = ADDR_CORRECT (data_start);
                    469: 
                    470: #ifdef sun
                    471:   data_start = data_start & ~(SEGSIZ - 1); /* (Down) to segment boundary. */
                    472: #else
                    473:   data_start = data_start & ~pagemask; /* (Down) to page boundary. */
                    474: #endif
                    475: 
                    476:   if (data_start > bss_start)  /* Can't have negative data size. */
                    477:     {
                    478:       ERROR2 ("unexec: data_start (%u) can't be greater than bss_start (%u)",
                    479:              data_start, bss_start);
                    480:     }
                    481: 
                    482:   tem = ADDR_CORRECT (sbrk (0));
                    483:   hdr.a_bss = tem - bss_start;
                    484:   if (tem < bss_start)         /* Note a_bss is unsigned on some systems */
                    485:     hdr.a_bss = 0;
                    486:   hdr.a_data = bss_start - data_start;
                    487: #if defined(sequent)
                    488:   hdr.a_text = data_start - (long) start_of_text () + sizeof(hdr) + N_ADDRADJ(ohdr);
                    489: #else
                    490:   hdr.a_text = data_start - (long) start_of_text ();
                    491: #endif /* not sequent */
                    492: 
                    493:   if (write (new, &hdr, sizeof hdr) != sizeof hdr)
                    494:     {
                    495:       PERROR (new_name);
                    496:     }
                    497:   return 0;
                    498: 
                    499: #endif /* not COFF */
                    500: }
                    501: 
                    502: /* ****************************************************************
                    503:  * copy_text_and_data
                    504:  *
                    505:  * Copy the text and data segments from memory to the new a.out
                    506:  */
                    507: static int
                    508: copy_text_and_data (new)
                    509:      int new;
                    510: {
                    511:   register int nwrite, ret;
                    512:   register char *end;
                    513:   int i;
                    514:   register char *ptr;
                    515:   char buf[80];
                    516:   extern int errno;
                    517:   
                    518: #ifdef COFF
                    519:   lseek (new, (long) text_scnptr, 0);
                    520:   ptr = (char *) f_ohdr.text_start;
                    521:   end = ptr + f_ohdr.tsize + f_ohdr.dsize;
                    522:   while (ptr < end)
                    523:     {
                    524:       nwrite = 128;
                    525:       if (nwrite > end - ptr) nwrite = end - ptr;
                    526:       ret = write (new, ptr, nwrite);
                    527:       if (nwrite != ret)
                    528:        {
                    529:          sprintf (buf,
                    530:                   "unexec write failure: addr 0x%x, fileno %d, size 0x%x, wrote 0x%x, errno %d",
                    531:                   ptr, new, nwrite, ret, errno);
                    532:          PERROR (buf);
                    533:        }
                    534:       ptr += nwrite;
                    535:     }
                    536:   return (0);
                    537: 
                    538: #else /* if not COFF */
                    539: 
                    540: #if defined(sun3) || defined(sequent)
                    541:   lseek (new, (long) (N_TXTOFF (hdr) + sizeof (hdr)), 0);
                    542: #else
                    543:   lseek (new, (long) N_TXTOFF (hdr), 0);
                    544: #endif
                    545: 
                    546:   ptr = start_of_text ();
                    547:   end = ptr + hdr.a_text + hdr.a_data;
                    548: #if defined(sequent)
                    549:   end -= (sizeof(hdr) + N_ADDRADJ(hdr));
                    550: #endif
                    551:   for (i = 0; ptr < end;)
                    552:     {
                    553:       nwrite = 128;
                    554:       if (nwrite > end - ptr) nwrite = end - ptr;
                    555:       ret = write (new, ptr, nwrite);
                    556:       if (ret == -1 && errno == EFAULT)
                    557:        {
                    558:           /* BZS - again, see above about N_TXTOFF on a SUN */
                    559: #if defined(sun3) || defined(sequent)
                    560:          lseek (new, (long) (N_TXTOFF (hdr) + i + nwrite + sizeof (hdr)), 0);
                    561: #else
                    562:          lseek (new, (long) (N_TXTOFF (hdr) + i + nwrite), 0);
                    563: #endif
                    564:        }
                    565:       else if (nwrite != ret)
                    566:        {
                    567:          sprintf (buf,
                    568:                   "unexec write failure: addr 0x%x, fileno %d, size 0x%x, wrote 0x%x, errno %d",
                    569:                   ptr, new, nwrite, ret, errno);
                    570:          PERROR (buf);
                    571:        }
                    572:       i += nwrite;
                    573:       ptr += nwrite;
                    574:     }
                    575: 
                    576:   return 0;
                    577: #endif /* not COFF */
                    578: }
                    579: 
                    580: /* ****************************************************************
                    581:  * copy_sym
                    582:  *
                    583:  * Copy the relocation information and symbol table from the a.out to the new
                    584:  */
                    585: static int
                    586: copy_sym (new, a_out, a_name, new_name)
                    587:      int new, a_out;
                    588:      char *a_name, *new_name;
                    589: {
                    590:   char page[1024];
                    591:   int n;
                    592: 
                    593:   if (a_out < 0)
                    594:     return 0;
                    595: 
                    596: #ifdef COFF
                    597:   if (SYMS_START == 0L)
                    598:     return 0;
                    599: #endif  /* COFF */
                    600: 
                    601: #ifdef sun3
                    602:   /* BZS - I might be covering a sin with this */
                    603:   lseek (new, N_SYMOFF (hdr), 0);
                    604: #else
                    605: #ifdef COFF
                    606:   if (lnnoptr)                 /* if there is line number info */
                    607:     lseek (a_out, lnnoptr, 0); /* start copying from there */
                    608:   else
                    609: #endif /* COFF */
                    610:     lseek (a_out, SYMS_START, 0);      /* Position a.out to symtab. */
                    611: #endif
                    612:   while ((n = read (a_out, page, sizeof page)) > 0)
                    613:     {
                    614:       if (write (new, page, n) != n)
                    615:        {
                    616:          PERROR (new_name);
                    617:        }
                    618:     }
                    619:   if (n < 0)
                    620:     {
                    621:       PERROR (a_name);
                    622:     }
                    623:   return 0;
                    624: }
                    625: 
                    626: /* ****************************************************************
                    627:  * mark_x
                    628:  *
                    629:  * After succesfully building the new a.out, mark it executable
                    630:  */
                    631: static
                    632: mark_x (name)
                    633:      char *name;
                    634: {
                    635:   struct stat sbuf;
                    636:   int um;
                    637:   int new = 0;  /* for PERROR */
                    638: 
                    639:   um = umask (777);
                    640:   umask (um);
                    641:   if (stat (name, &sbuf) == -1)
                    642:     {
                    643:       PERROR (name);
                    644:     }
                    645:   sbuf.st_mode |= 0111 & ~um;
                    646:   if (chmod (name, sbuf.st_mode) == -1)
                    647:     PERROR (name);
                    648: }
                    649: 
                    650: /*
                    651:  *     If the COFF file contains a symbol table and a line number section,
                    652:  *     then any auxiliary entries that have values for x_lnnoptr must
                    653:  *     be adjusted by the amount that the line number section has moved
                    654:  *     in the file (bias computed in make_hdr).  The #@$%&* designers of
                    655:  *     the auxiliary entry structures used the absolute file offsets for
                    656:  *     the line number entry rather than an offset from the start of the
                    657:  *     line number section!
                    658:  *
                    659:  *     When I figure out how to scan through the symbol table and pick out
                    660:  *     the auxiliary entries that need adjustment, this routine will
                    661:  *     be fixed.  As it is now, all such entries are wrong and sdb
                    662:  *     will complain.   Fred Fish, UniSoft Systems Inc.
                    663:  */
                    664: 
                    665: #ifdef COFF
                    666: 
                    667: /* This function is probably very slow.  Instead of reopening the new
                    668:    file for input and output it should copy from the old to the new
                    669:    using the two descriptors already open (WRITEDESC and READDESC).
                    670:    Instead of reading one small structure at a time it should use
                    671:    a reasonable size buffer.  But I don't have time to work on such
                    672:    things, so I am installing it as submitted to me.  -- RMS.  */
                    673: 
                    674: adjust_lnnoptrs (writedesc, readdesc, new_name)
                    675:      int writedesc;
                    676:      int readdesc;
                    677:      char *new_name;
                    678: {
                    679:   register int nsyms;
                    680:   register int new;
                    681:   struct syment symentry;
                    682:   struct auxent auxentry;
                    683: 
                    684:   if (!lnnoptr || !f_hdr.f_symptr)
                    685:     return 0;
                    686: 
                    687:   if ((new = open (new_name, 2)) < 0)
                    688:     {
                    689:       PERROR (new_name);
                    690:       return -1;
                    691:     }
                    692: 
                    693:   lseek (new, f_hdr.f_symptr, 0);
                    694:   for (nsyms = 0; nsyms < f_hdr.f_nsyms; nsyms++)
                    695:     {
                    696:       read (new, &symentry, SYMESZ);
                    697:       if (symentry.n_numaux)
                    698:        {
                    699:          read (new, &auxentry, AUXESZ);
                    700:          nsyms++;
                    701:          if (ISFCN (symentry.n_type)) {
                    702:            auxentry.x_sym.x_fcnary.x_fcn.x_lnnoptr += bias;
                    703:            lseek (new, -AUXESZ, 1);
                    704:            write (new, &auxentry, AUXESZ);
                    705:          }
                    706:        }
                    707:     }
                    708:   close (new);
                    709: }
                    710: 
                    711: #endif /* COFF */
                    712: 
                    713: #endif /* not CANNOT_DUMP */

unix.superglobalmegacorp.com

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