Annotation of 43BSD/contrib/emacs/src/unexec.c, revision 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.