Annotation of 43BSDReno/contrib/emacs-18.55/src/unexec.c, revision 1.1.1.1

1.1       root        1: /* Copyright (C) 1985, 1986, 1987, 1988 Free Software Foundation, Inc.
                      2: 
                      3:                       NO WARRANTY
                      4: 
                      5:   BECAUSE THIS PROGRAM IS LICENSED FREE OF CHARGE, WE PROVIDE ABSOLUTELY
                      6: NO WARRANTY, TO THE EXTENT PERMITTED BY APPLICABLE STATE LAW.  EXCEPT
                      7: WHEN OTHERWISE STATED IN WRITING, FREE SOFTWARE FOUNDATION, INC,
                      8: RICHARD M. STALLMAN AND/OR OTHER PARTIES PROVIDE THIS PROGRAM "AS IS"
                      9: WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
                     10: BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
                     11: FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY
                     12: AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE PROGRAM PROVE
                     13: DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR
                     14: CORRECTION.
                     15: 
                     16:  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW WILL RICHARD M.
                     17: STALLMAN, THE FREE SOFTWARE FOUNDATION, INC., AND/OR ANY OTHER PARTY
                     18: WHO MAY MODIFY AND REDISTRIBUTE THIS PROGRAM AS PERMITTED BELOW, BE
                     19: LIABLE TO YOU FOR DAMAGES, INCLUDING ANY LOST PROFITS, LOST MONIES, OR
                     20: OTHER SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
                     21: USE OR INABILITY TO USE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR
                     22: DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY THIRD PARTIES OR
                     23: A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS) THIS
                     24: PROGRAM, EVEN IF YOU HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH
                     25: DAMAGES, OR FOR ANY CLAIM BY ANY OTHER PARTY.
                     26: 
                     27:                GENERAL PUBLIC LICENSE TO COPY
                     28: 
                     29:   1. You may copy and distribute verbatim copies of this source file
                     30: as you receive it, in any medium, provided that you conspicuously and
                     31: appropriately publish on each copy a valid copyright notice "Copyright
                     32: (C) 1987 Free Software Foundation, Inc."; and include following the
                     33: copyright notice a verbatim copy of the above disclaimer of warranty
                     34: and of this License.  You may charge a distribution fee for the
                     35: physical act of transferring a copy.
                     36: 
                     37:   2. You may modify your copy or copies of this source file or
                     38: any portion of it, and copy and distribute such modifications under
                     39: the terms of Paragraph 1 above, provided that you also do the following:
                     40: 
                     41:     a) cause the modified files to carry prominent notices stating
                     42:     that you changed the files and the date of any change; and
                     43: 
                     44:     b) cause the whole of any work that you distribute or publish,
                     45:     that in whole or in part contains or is a derivative of this
                     46:     program or any part thereof, to be licensed at no charge to all
                     47:     third parties on terms identical to those contained in this
                     48:     License Agreement (except that you may choose to grant more extensive
                     49:     warranty protection to some or all third parties, at your option).
                     50: 
                     51:     c) You may charge a distribution fee for the physical act of
                     52:     transferring a copy, and you may at your option offer warranty
                     53:     protection in exchange for a fee.
                     54: 
                     55: Mere aggregation of another unrelated program with this program (or its
                     56: derivative) on a volume of a storage or distribution medium does not bring
                     57: the other program under the scope of these terms.
                     58: 
                     59:   3. You may copy and distribute this program (or a portion or derivative
                     60: of it, under Paragraph 2) in object code or executable form under the terms
                     61: of Paragraphs 1 and 2 above provided that you also do one of the following:
                     62: 
                     63:     a) accompany it with the complete corresponding machine-readable
                     64:     source code, which must be distributed under the terms of
                     65:     Paragraphs 1 and 2 above; or,
                     66: 
                     67:     b) accompany it with a written offer, valid for at least three
                     68:     years, to give any third party free (except for a nominal
                     69:     shipping charge) a complete machine-readable copy of the
                     70:     corresponding source code, to be distributed under the terms of
                     71:     Paragraphs 1 and 2 above; or,
                     72: 
                     73:     c) accompany it with the information you received as to where the
                     74:     corresponding source code may be obtained.  (This alternative is
                     75:     allowed only for noncommercial distribution and only if you
                     76:     received the program in object code or executable form alone.)
                     77: 
                     78: For an executable file, complete source code means all the source code for
                     79: all modules it contains; but, as a special exception, it need not include
                     80: source code for modules which are standard libraries that accompany the
                     81: operating system on which the executable file runs.
                     82: 
                     83:   4. You may not copy, sublicense, distribute or transfer this program
                     84: except as expressly provided under this License Agreement.  Any attempt
                     85: otherwise to copy, sublicense, distribute or transfer this program is void and
                     86: your rights to use the program under this License agreement shall be
                     87: automatically terminated.  However, parties who have received computer
                     88: software programs from you with this License Agreement will not have
                     89: their licenses terminated so long as such parties remain in full compliance.
                     90: 
                     91:   5. If you wish to incorporate parts of this program into other free
                     92: programs whose distribution conditions are different, write to the Free
                     93: Software Foundation at 675 Mass Ave, Cambridge, MA 02139.  We have not yet
                     94: worked out a simple rule that can be stated here, but we will often permit
                     95: this.  We will be guided by the two goals of preserving the free status of
                     96: all derivatives of our free software and of promoting the sharing and reuse of
                     97: software.
                     98: 
                     99: 
                    100: In other words, you are welcome to use, share and improve this program.
                    101: You are forbidden to forbid anyone else to use, share and improve
                    102: what you give them.   Help stamp out software-hoarding!  */
                    103: 
                    104: 
                    105: /*
                    106:  * unexec.c - Convert a running program into an a.out file.
                    107:  *
                    108:  * Author:     Spencer W. Thomas
                    109:  *             Computer Science Dept.
                    110:  *             University of Utah
                    111:  * Date:       Tue Mar  2 1982
                    112:  * Modified heavily since then.
                    113:  *
                    114:  * Synopsis:
                    115:  *     unexec (new_name, a_name, data_start, bss_start, entry_address)
                    116:  *     char *new_name, *a_name;
                    117:  *     unsigned data_start, bss_start, entry_address;
                    118:  *
                    119:  * Takes a snapshot of the program and makes an a.out format file in the
                    120:  * file named by the string argument new_name.
                    121:  * If a_name is non-NULL, the symbol table will be taken from the given file.
                    122:  * On some machines, an existing a_name file is required.
                    123:  *
                    124:  * The boundaries within the a.out file may be adjusted with the data_start
                    125:  * and bss_start arguments.  Either or both may be given as 0 for defaults.
                    126:  *
                    127:  * Data_start gives the boundary between the text segment and the data
                    128:  * segment of the program.  The text segment can contain shared, read-only
                    129:  * program code and literal data, while the data segment is always unshared
                    130:  * and unprotected.  Data_start gives the lowest unprotected address.
                    131:  * The value you specify may be rounded down to a suitable boundary
                    132:  * as required by the machine you are using.
                    133:  *
                    134:  * Specifying zero for data_start means the boundary between text and data
                    135:  * should not be the same as when the program was loaded.
                    136:  * If NO_REMAP is defined, the argument data_start is ignored and the
                    137:  * segment boundaries are never changed.
                    138:  *
                    139:  * Bss_start indicates how much of the data segment is to be saved in the
                    140:  * a.out file and restored when the program is executed.  It gives the lowest
                    141:  * unsaved address, and is rounded up to a page boundary.  The default when 0
                    142:  * is given assumes that the entire data segment is to be stored, including
                    143:  * the previous data and bss as well as any additional storage allocated with
                    144:  * break (2).
                    145:  *
                    146:  * The new file is set up to start at entry_address.
                    147:  *
                    148:  * If you make improvements I'd like to get them too.
                    149:  * harpo!utah-cs!thomas, thomas@Utah-20
                    150:  *
                    151:  */
                    152: 
                    153: /* There are several compilation parameters affecting unexec:
                    154: 
                    155: * COFF
                    156: 
                    157: Define this if your system uses COFF for executables.
                    158: Otherwise we assume you use Berkeley format.
                    159: 
                    160: * NO_REMAP
                    161: 
                    162: Define this if you do not want to try to save Emacs's pure data areas
                    163: as part of the text segment.
                    164: 
                    165: Saving them as text is good because it allows users to share more.
                    166: 
                    167: However, on machines that locate the text area far from the data area,
                    168: the boundary cannot feasibly be moved.  Such machines require
                    169: NO_REMAP.
                    170: 
                    171: Also, remapping can cause trouble with the built-in startup routine
                    172: /lib/crt0.o, which defines `environ' as an initialized variable.
                    173: Dumping `environ' as pure does not work!  So, to use remapping,
                    174: you must write a startup routine for your machine in Emacs's crt0.c.
                    175: If NO_REMAP is defined, Emacs uses the system's crt0.o.
                    176: 
                    177: * SECTION_ALIGNMENT
                    178: 
                    179: Some machines that use COFF executables require that each section
                    180: start on a certain boundary *in the COFF file*.  Such machines should
                    181: define SECTION_ALIGNMENT to a mask of the low-order bits that must be
                    182: zero on such a boundary.  This mask is used to control padding between
                    183: segments in the COFF file.
                    184: 
                    185: If SECTION_ALIGNMENT is not defined, the segments are written
                    186: consecutively with no attempt at alignment.  This is right for
                    187: unmodified system V.
                    188: 
                    189: * SEGMENT_MASK
                    190: 
                    191: Some machines require that the beginnings and ends of segments
                    192: *in core* be on certain boundaries.  For most machines, a page
                    193: boundary is sufficient.  That is the default.  When a larger
                    194: boundary is needed, define SEGMENT_MASK to a mask of
                    195: the bits that must be zero on such a boundary.
                    196: 
                    197: * A_TEXT_OFFSET(HDR)
                    198: 
                    199: Some machines count the a.out header as part of the size of the text
                    200: segment (a_text); they may actually load the header into core as the
                    201: first data in the text segment.  Some have additional padding between
                    202: the header and the real text of the program that is counted in a_text.
                    203: 
                    204: For these machines, define A_TEXT_OFFSET(HDR) to examine the header
                    205: structure HDR and return the number of bytes to add to `a_text'
                    206: before writing it (above and beyond the number of bytes of actual
                    207: program text).  HDR's standard fields are already correct, except that
                    208: this adjustment to the `a_text' field has not yet been made;
                    209: thus, the amount of offset can depend on the data in the file.
                    210:   
                    211: * A_TEXT_SEEK(HDR)
                    212: 
                    213: If defined, this macro specifies the number of bytes to seek into the
                    214: a.out file before starting to write the text segment.a
                    215: 
                    216: * EXEC_MAGIC
                    217: 
                    218: For machines using COFF, this macro, if defined, is a value stored
                    219: into the magic number field of the output file.
                    220: 
                    221: * ADJUST_EXEC_HEADER
                    222: 
                    223: This macro can be used to generate statements to adjust or
                    224: initialize nonstandard fields in the file header
                    225: 
                    226: * ADDR_CORRECT(ADDR)
                    227: 
                    228: Macro to correct an int which is the bit pattern of a pointer to a byte
                    229: into an int which is the number of a byte.
                    230: 
                    231: This macro has a default definition which is usually right.
                    232: This default definition is a no-op on most machines (where a
                    233: pointer looks like an int) but not on all machines.
                    234: 
                    235: */
                    236: 
                    237: #ifndef emacs
                    238: #define PERROR(arg) perror (arg); return -1
                    239: #else
                    240: #include "config.h"
                    241: #define PERROR(file) report_error (file, new)
                    242: #endif
                    243: 
                    244: #ifndef CANNOT_DUMP  /* all rest of file!  */
                    245: 
                    246: #ifndef CANNOT_UNEXEC /* most of rest of file */
                    247: 
                    248: #include <a.out.h>
                    249: /* Define getpagesize () if the system does not.
                    250:    Note that this may depend on symbols defined in a.out.h
                    251:  */
                    252: #include "getpagesize.h"
                    253: 
                    254: #ifndef makedev                        /* Try to detect types.h already loaded */
                    255: #include <sys/types.h>
                    256: #endif
                    257: #include <stdio.h>
                    258: #include <sys/stat.h>
                    259: #include <errno.h>
                    260: 
                    261: extern char *start_of_text ();         /* Start of text */
                    262: extern char *start_of_data ();         /* Start of initialized data */
                    263: 
                    264: #ifdef COFF
                    265: #ifndef USG
                    266: #ifndef STRIDE
                    267: #ifndef UMAX
                    268: #ifndef sun386
                    269: /* I have a suspicion that these are turned off on all systems
                    270:    and can be deleted.  Try it in version 19.  */
                    271: #include <filehdr.h>
                    272: #include <aouthdr.h>
                    273: #include <scnhdr.h>
                    274: #include <syms.h>
                    275: #endif /* not sun386 */
                    276: #endif /* not UMAX */
                    277: #endif /* Not STRIDE */
                    278: #endif /* not USG */
                    279: static long block_copy_start;          /* Old executable start point */
                    280: static struct filehdr f_hdr;           /* File header */
                    281: static struct aouthdr f_ohdr;          /* Optional file header (a.out) */
                    282: long bias;                     /* Bias to add for growth */
                    283: long lnnoptr;                  /* Pointer to line-number info within file */
                    284: #define SYMS_START block_copy_start
                    285: 
                    286: static long text_scnptr;
                    287: static long data_scnptr;
                    288: 
                    289: #else /* not COFF */
                    290: 
                    291: extern char *sbrk ();
                    292: 
                    293: #define SYMS_START ((long) N_SYMOFF (ohdr))
                    294: 
                    295: /* Some machines override the structure name for an a.out header.  */
                    296: #ifndef EXEC_HDR_TYPE
                    297: #define EXEC_HDR_TYPE struct exec
                    298: #endif
                    299: 
                    300: #ifdef HPUX
                    301: #ifdef HP9000S200_ID
                    302: #define MY_ID HP9000S200_ID
                    303: #else
                    304: #include <model.h>
                    305: #define MY_ID MYSYS
                    306: #endif /* no HP9000S200_ID */
                    307: static MAGIC OLDMAGIC = {MY_ID, SHARE_MAGIC};
                    308: static MAGIC NEWMAGIC = {MY_ID, DEMAND_MAGIC};
                    309: #define N_TXTOFF(x) TEXT_OFFSET(x)
                    310: #define N_SYMOFF(x) LESYM_OFFSET(x)
                    311: static EXEC_HDR_TYPE hdr, ohdr;
                    312: 
                    313: #else /* not HPUX */
                    314: 
                    315: #if defined (USG) && !defined (IBMRTAIX) && !defined (IRIS)
                    316: static struct bhdr hdr, ohdr;
                    317: #define a_magic fmagic
                    318: #define a_text tsize
                    319: #define a_data dsize
                    320: #define a_bss bsize
                    321: #define a_syms ssize
                    322: #define a_trsize rtsize
                    323: #define a_drsize rdsize
                    324: #define a_entry entry
                    325: #define        N_BADMAG(x) \
                    326:     (((x).fmagic)!=OMAGIC && ((x).fmagic)!=NMAGIC &&\
                    327:      ((x).fmagic)!=FMAGIC && ((x).fmagic)!=IMAGIC)
                    328: #define NEWMAGIC FMAGIC
                    329: #else /* IRIS or IBMRTAIX or not USG */
                    330: static EXEC_HDR_TYPE hdr, ohdr;
                    331: #define NEWMAGIC ZMAGIC
                    332: #endif /* IRIS or IBMRTAIX not USG */
                    333: #endif /* not HPUX */
                    334: 
                    335: static int unexec_text_start;
                    336: static int unexec_data_start;
                    337: 
                    338: #endif /* not COFF */
                    339: 
                    340: static int pagemask;
                    341: 
                    342: /* Correct an int which is the bit pattern of a pointer to a byte
                    343:    into an int which is the number of a byte.
                    344:    This is a no-op on ordinary machines, but not on all.  */
                    345: 
                    346: #ifndef ADDR_CORRECT   /* Let m-*.h files override this definition */
                    347: #define ADDR_CORRECT(x) ((char *)(x) - (char*)0)
                    348: #endif
                    349: 
                    350: #ifdef emacs
                    351: 
                    352: static
                    353: report_error (file, fd)
                    354:      char *file;
                    355:      int fd;
                    356: {
                    357:   if (fd)
                    358:     close (fd);
                    359:   error ("Failure operating on %s", file);
                    360: }
                    361: #endif /* emacs */
                    362: 
                    363: #define ERROR0(msg) report_error_1 (new, msg, 0, 0); return -1
                    364: #define ERROR1(msg,x) report_error_1 (new, msg, x, 0); return -1
                    365: #define ERROR2(msg,x,y) report_error_1 (new, msg, x, y); return -1
                    366: 
                    367: static
                    368: report_error_1 (fd, msg, a1, a2)
                    369:      int fd;
                    370:      char *msg;
                    371:      int a1, a2;
                    372: {
                    373:   close (fd);
                    374: #ifdef emacs
                    375:   error (msg, a1, a2);
                    376: #else
                    377:   fprintf (stderr, msg, a1, a2);
                    378:   fprintf (stderr, "\n");
                    379: #endif
                    380: }
                    381: 
                    382: /* ****************************************************************
                    383:  * unexec
                    384:  *
                    385:  * driving logic.
                    386:  */
                    387: unexec (new_name, a_name, data_start, bss_start, entry_address)
                    388:      char *new_name, *a_name;
                    389:      unsigned data_start, bss_start, entry_address;
                    390: {
                    391:   int new, a_out = -1;
                    392: 
                    393:   if (a_name && (a_out = open (a_name, 0)) < 0)
                    394:     {
                    395:       PERROR (a_name);
                    396:     }
                    397:   if ((new = creat (new_name, 0666)) < 0)
                    398:     {
                    399:       PERROR (new_name);
                    400:     }
                    401: 
                    402:   if (make_hdr (new, a_out, data_start, bss_start, entry_address, a_name, new_name) < 0
                    403:       || copy_text_and_data (new) < 0
                    404:       || copy_sym (new, a_out, a_name, new_name) < 0
                    405: #ifdef COFF
                    406:       || adjust_lnnoptrs (new, a_out, new_name) < 0
                    407: #endif
                    408:       )
                    409:     {
                    410:       close (new);
                    411:       /* unlink (new_name);            /* Failed, unlink new a.out */
                    412:       return -1;       
                    413:     }
                    414: 
                    415:   close (new);
                    416:   if (a_out >= 0)
                    417:     close (a_out);
                    418:   mark_x (new_name);
                    419:   return 0;
                    420: }
                    421: 
                    422: /* ****************************************************************
                    423:  * make_hdr
                    424:  *
                    425:  * Make the header in the new a.out from the header in core.
                    426:  * Modify the text and data sizes.
                    427:  */
                    428: static int
                    429: make_hdr (new, a_out, data_start, bss_start, entry_address, a_name, new_name)
                    430:      int new, a_out;
                    431:      unsigned data_start, bss_start, entry_address;
                    432:      char *a_name;
                    433:      char *new_name;
                    434: {
                    435:   int tem;
                    436: #ifdef COFF
                    437:   auto struct scnhdr f_thdr;           /* Text section header */
                    438:   auto struct scnhdr f_dhdr;           /* Data section header */
                    439:   auto struct scnhdr f_bhdr;           /* Bss section header */
                    440:   auto struct scnhdr scntemp;          /* Temporary section header */
                    441:   register int scns;
                    442: #endif /* COFF */
                    443:   unsigned int bss_end;
                    444: 
                    445:   pagemask = getpagesize () - 1;
                    446: 
                    447:   /* Adjust text/data boundary. */
                    448: #ifdef NO_REMAP
                    449:   data_start = (int) start_of_data ();
                    450: #else /* not NO_REMAP */
                    451:   if (!data_start)
                    452:     data_start = (int) start_of_data ();
                    453: #endif /* not NO_REMAP */
                    454:   data_start = ADDR_CORRECT (data_start);
                    455: 
                    456: #ifdef SEGMENT_MASK
                    457:   data_start = data_start & ~SEGMENT_MASK; /* (Down) to segment boundary. */
                    458: #else
                    459:   data_start = data_start & ~pagemask; /* (Down) to page boundary. */
                    460: #endif
                    461: 
                    462:   bss_end = ADDR_CORRECT (sbrk (0)) + pagemask;
                    463:   bss_end &= ~ pagemask;
                    464: 
                    465:   /* Adjust data/bss boundary. */
                    466:   if (bss_start != 0)
                    467:     {
                    468:       bss_start = (ADDR_CORRECT (bss_start) + pagemask);
                    469:       /* (Up) to page bdry. */
                    470:       bss_start &= ~ pagemask;
                    471:       if (bss_start > bss_end)
                    472:        {
                    473:          ERROR1 ("unexec: Specified bss_start (%u) is past end of program",
                    474:                  bss_start);
                    475:        }
                    476:     }
                    477:   else
                    478:     bss_start = bss_end;
                    479: 
                    480:   if (data_start > bss_start)  /* Can't have negative data size. */
                    481:     {
                    482:       ERROR2 ("unexec: data_start (%u) can't be greater than bss_start (%u)",
                    483:              data_start, bss_start);
                    484:     }
                    485: 
                    486: #ifdef COFF
                    487:   /* Salvage as much info from the existing file as possible */
                    488:   if (a_out >= 0)
                    489:     {
                    490:       if (read (a_out, &f_hdr, sizeof (f_hdr)) != sizeof (f_hdr))
                    491:        {
                    492:          PERROR (a_name);
                    493:        }
                    494:       block_copy_start += sizeof (f_hdr);
                    495:       if (f_hdr.f_opthdr > 0)
                    496:        {
                    497:          if (read (a_out, &f_ohdr, sizeof (f_ohdr)) != sizeof (f_ohdr))
                    498:            {
                    499:              PERROR (a_name);
                    500:            }
                    501:          block_copy_start += sizeof (f_ohdr);
                    502:        }
                    503:       /* Loop through section headers, copying them in */
                    504:       for (scns = f_hdr.f_nscns; scns > 0; scns--) {
                    505:        if (read (a_out, &scntemp, sizeof (scntemp)) != sizeof (scntemp))
                    506:          {
                    507:            PERROR (a_name);
                    508:          }
                    509:        if (scntemp.s_scnptr > 0L)
                    510:          {
                    511:             if (block_copy_start < scntemp.s_scnptr + scntemp.s_size)
                    512:              block_copy_start = scntemp.s_scnptr + scntemp.s_size;
                    513:          }
                    514:        if (strcmp (scntemp.s_name, ".text") == 0)
                    515:          {
                    516:            f_thdr = scntemp;
                    517:          }
                    518:        else if (strcmp (scntemp.s_name, ".data") == 0)
                    519:          {
                    520:            f_dhdr = scntemp;
                    521:          }
                    522:        else if (strcmp (scntemp.s_name, ".bss") == 0)
                    523:          {
                    524:            f_bhdr = scntemp;
                    525:          }
                    526:       }
                    527:     }
                    528:   else
                    529:     {
                    530:       ERROR0 ("can't build a COFF file from scratch yet");
                    531:     }
                    532: 
                    533:   /* Now we alter the contents of all the f_*hdr variables
                    534:      to correspond to what we want to dump.  */
                    535: 
                    536:   f_hdr.f_flags |= (F_RELFLG | F_EXEC);
                    537: #ifdef EXEC_MAGIC
                    538:   f_ohdr.magic = EXEC_MAGIC;
                    539: #endif
                    540: #ifndef NO_REMAP
                    541:   f_ohdr.text_start = (long) start_of_text ();
                    542:   f_ohdr.tsize = data_start - f_ohdr.text_start;
                    543:   f_ohdr.data_start = data_start;
                    544: #endif /* NO_REMAP */
                    545:   f_ohdr.dsize = bss_start - f_ohdr.data_start;
                    546:   f_ohdr.bsize = bss_end - bss_start;
                    547:   f_thdr.s_size = f_ohdr.tsize;
                    548:   f_thdr.s_scnptr = sizeof (f_hdr) + sizeof (f_ohdr);
                    549:   f_thdr.s_scnptr += (f_hdr.f_nscns) * (sizeof (f_thdr));
                    550:   lnnoptr = f_thdr.s_lnnoptr;
                    551: #ifdef SECTION_ALIGNMENT
                    552:   /* Some systems require special alignment
                    553:      of the sections in the file itself.  */
                    554:   f_thdr.s_scnptr
                    555:     = (f_thdr.s_scnptr + SECTION_ALIGNMENT) & ~SECTION_ALIGNMENT;
                    556: #endif /* SECTION_ALIGNMENT */
                    557:   text_scnptr = f_thdr.s_scnptr;
                    558:   f_dhdr.s_paddr = f_ohdr.data_start;
                    559:   f_dhdr.s_vaddr = f_ohdr.data_start;
                    560:   f_dhdr.s_size = f_ohdr.dsize;
                    561:   f_dhdr.s_scnptr = f_thdr.s_scnptr + f_thdr.s_size;
                    562: #ifdef SECTION_ALIGNMENT
                    563:   /* Some systems require special alignment
                    564:      of the sections in the file itself.  */
                    565:   f_dhdr.s_scnptr
                    566:     = (f_dhdr.s_scnptr + SECTION_ALIGNMENT) & ~SECTION_ALIGNMENT;
                    567: #endif /* SECTION_ALIGNMENT */
                    568: #ifdef DATA_SECTION_ALIGNMENT
                    569:   /* Some systems require special alignment
                    570:      of the data section only.  */
                    571:   f_dhdr.s_scnptr
                    572:     = (f_dhdr.s_scnptr + DATA_SECTION_ALIGNMENT) & ~DATA_SECTION_ALIGNMENT;
                    573: #endif /* DATA_SECTION_ALIGNMENT */
                    574:   data_scnptr = f_dhdr.s_scnptr;
                    575:   f_bhdr.s_paddr = f_ohdr.data_start + f_ohdr.dsize;
                    576:   f_bhdr.s_vaddr = f_ohdr.data_start + f_ohdr.dsize;
                    577:   f_bhdr.s_size = f_ohdr.bsize;
                    578:   f_bhdr.s_scnptr = 0L;
                    579:   bias = f_dhdr.s_scnptr + f_dhdr.s_size - block_copy_start;
                    580: 
                    581:   if (f_hdr.f_symptr > 0L)
                    582:     {
                    583:       f_hdr.f_symptr += bias;
                    584:     }
                    585: 
                    586:   if (f_thdr.s_lnnoptr > 0L)
                    587:     {
                    588:       f_thdr.s_lnnoptr += bias;
                    589:     }
                    590: 
                    591: #ifdef ADJUST_EXEC_HEADER
                    592:   ADJUST_EXEC_HEADER
                    593: #endif /* ADJUST_EXEC_HEADER */
                    594: 
                    595:   if (write (new, &f_hdr, sizeof (f_hdr)) != sizeof (f_hdr))
                    596:     {
                    597:       PERROR (new_name);
                    598:     }
                    599: 
                    600:   if (write (new, &f_ohdr, sizeof (f_ohdr)) != sizeof (f_ohdr))
                    601:     {
                    602:       PERROR (new_name);
                    603:     }
                    604: 
                    605:   if (write (new, &f_thdr, sizeof (f_thdr)) != sizeof (f_thdr))
                    606:     {
                    607:       PERROR (new_name);
                    608:     }
                    609: 
                    610:   if (write (new, &f_dhdr, sizeof (f_dhdr)) != sizeof (f_dhdr))
                    611:     {
                    612:       PERROR (new_name);
                    613:     }
                    614: 
                    615:   if (write (new, &f_bhdr, sizeof (f_bhdr)) != sizeof (f_bhdr))
                    616:     {
                    617:       PERROR (new_name);
                    618:     }
                    619:   return (0);
                    620: 
                    621: #else /* if not COFF */
                    622: 
                    623:   /* Get symbol table info from header of a.out file if given one. */
                    624:   if (a_out >= 0)
                    625:     {
                    626:       if (read (a_out, &ohdr, sizeof hdr) != sizeof hdr)
                    627:        {
                    628:          PERROR (a_name);
                    629:        }
                    630: 
                    631:       if (N_BADMAG (ohdr))
                    632:        {
                    633:          ERROR1 ("invalid magic number in %s", a_name);
                    634:        }
                    635:       hdr = ohdr;
                    636:     }
                    637:   else
                    638:     {
                    639:       bzero (hdr, sizeof hdr);
                    640:     }
                    641: 
                    642:   unexec_text_start = (long) start_of_text ();
                    643:   unexec_data_start = data_start;
                    644: 
                    645:   /* Machine-dependent fixup for header, or maybe for unexec_text_start */
                    646: #ifdef ADJUST_EXEC_HEADER
                    647:   ADJUST_EXEC_HEADER;
                    648: #endif /* ADJUST_EXEC_HEADER */
                    649: 
                    650:   hdr.a_trsize = 0;
                    651:   hdr.a_drsize = 0;
                    652:   if (entry_address != 0)
                    653:     hdr.a_entry = entry_address;
                    654: 
                    655:   hdr.a_bss = bss_end - bss_start;
                    656:   hdr.a_data = bss_start - data_start;
                    657: #ifdef NO_REMAP
                    658:   hdr.a_text = ohdr.a_text;
                    659: #else /* not NO_REMAP */
                    660:   hdr.a_text = data_start - unexec_text_start;
                    661: 
                    662: #ifdef A_TEXT_OFFSET
                    663:   hdr.a_text += A_TEXT_OFFSET (ohdr);
                    664: #endif
                    665: 
                    666: #endif /* not NO_REMAP */
                    667: 
                    668:   if (write (new, &hdr, sizeof hdr) != sizeof hdr)
                    669:     {
                    670:       PERROR (new_name);
                    671:     }
                    672: 
                    673: #ifdef A_TEXT_OFFSET
                    674:   hdr.a_text -= A_TEXT_OFFSET (ohdr);
                    675: #endif
                    676: 
                    677:   return 0;
                    678: 
                    679: #endif /* not COFF */
                    680: }
                    681: 
                    682: /* ****************************************************************
                    683:  * copy_text_and_data
                    684:  *
                    685:  * Copy the text and data segments from memory to the new a.out
                    686:  */
                    687: static int
                    688: copy_text_and_data (new)
                    689:      int new;
                    690: {
                    691:   register char *end;
                    692:   register char *ptr;
                    693: 
                    694: #ifdef COFF
                    695:   lseek (new, (long) text_scnptr, 0);
                    696:   ptr = (char *) f_ohdr.text_start;
                    697:   end = ptr + f_ohdr.tsize;
                    698:   write_segment (new, ptr, end);
                    699: 
                    700:   lseek (new, (long) data_scnptr, 0);
                    701:   ptr = (char *) f_ohdr.data_start;
                    702:   end = ptr + f_ohdr.dsize;
                    703:   write_segment (new, ptr, end);
                    704: 
                    705: #else /* if not COFF */
                    706: 
                    707: /* Some machines count the header as part of the text segment.
                    708:    That is to say, the header appears in core
                    709:    just before the address that start_of_text () returns.
                    710:    For them, N_TXTOFF is the place where the header goes.
                    711:    We must adjust the seek to the place after the header.
                    712:    Note that at this point hdr.a_text does *not* count
                    713:    the extra A_TEXT_OFFSET bytes, only the actual bytes of code.  */
                    714: 
                    715: #ifdef A_TEXT_SEEK
                    716:   lseek (new, (long) A_TEXT_SEEK (hdr), 0);
                    717: #else
                    718: #ifdef A_TEXT_OFFSET
                    719:   /* Note that on the Sequent machine A_TEXT_OFFSET != sizeof (hdr)
                    720:      and sizeof (hdr) is the correct amount to add here.  */
                    721:   /* In version 19, eliminate this case and use A_TEXT_SEEK whenever
                    722:      N_TXTOFF is not right.  */
                    723:   lseek (new, (long) N_TXTOFF (hdr) + sizeof (hdr), 0);
                    724: #else
                    725:   lseek (new, (long) N_TXTOFF (hdr), 0);
                    726: #endif /* no A_TEXT_OFFSET */
                    727: #endif /* no A_TEXT_SEEK */
                    728: 
                    729:   ptr = (char *) unexec_text_start;
                    730:   end = ptr + hdr.a_text;
                    731:   write_segment (new, ptr, end);
                    732: 
                    733:   ptr = (char *) unexec_data_start;
                    734:   end = ptr + hdr.a_data;
                    735: /*  This lseek is certainly incorrect when A_TEXT_OFFSET
                    736:     and I believe it is a no-op otherwise.
                    737:     Let's see if its absence ever fails.  */
                    738: /*  lseek (new, (long) N_TXTOFF (hdr) + hdr.a_text, 0); */
                    739:   write_segment (new, ptr, end);
                    740: 
                    741: #endif /* not COFF */
                    742: 
                    743:   return 0;
                    744: }
                    745: 
                    746: write_segment (new, ptr, end)
                    747:      int new;
                    748:      register char *ptr, *end;
                    749: {
                    750:   register int i, nwrite, ret;
                    751:   char buf[80];
                    752:   extern int errno;
                    753:   char zeros[128];
                    754: 
                    755:   bzero (zeros, sizeof zeros);
                    756: 
                    757:   for (i = 0; ptr < end;)
                    758:     {
                    759:       /* distance to next multiple of 128.  */
                    760:       nwrite = (((int) ptr + 128) & -128) - (int) ptr;
                    761:       /* But not beyond specified end.  */
                    762:       if (nwrite > end - ptr) nwrite = end - ptr;
                    763:       ret = write (new, ptr, nwrite);
                    764:       /* If write gets a page fault, it means we reached
                    765:         a gap between the old text segment and the old data segment.
                    766:         This gap has probably been remapped into part of the text segment.
                    767:         So write zeros for it.  */
                    768:       if (ret == -1 && errno == EFAULT)
                    769:        write (new, zeros, nwrite);
                    770:       else if (nwrite != ret)
                    771:        {
                    772:          sprintf (buf,
                    773:                   "unexec write failure: addr 0x%x, fileno %d, size 0x%x, wrote 0x%x, errno %d",
                    774:                   ptr, new, nwrite, ret, errno);
                    775:          PERROR (buf);
                    776:        }
                    777:       i += nwrite;
                    778:       ptr += nwrite;
                    779:     }
                    780: }
                    781: 
                    782: /* ****************************************************************
                    783:  * copy_sym
                    784:  *
                    785:  * Copy the relocation information and symbol table from the a.out to the new
                    786:  */
                    787: static int
                    788: copy_sym (new, a_out, a_name, new_name)
                    789:      int new, a_out;
                    790:      char *a_name, *new_name;
                    791: {
                    792:   char page[1024];
                    793:   int n;
                    794: 
                    795:   if (a_out < 0)
                    796:     return 0;
                    797: 
                    798: #ifdef COFF
                    799:   if (SYMS_START == 0L)
                    800:     return 0;
                    801: #endif  /* COFF */
                    802: 
                    803: #ifdef COFF
                    804:   if (lnnoptr)                 /* if there is line number info */
                    805:     lseek (a_out, lnnoptr, 0); /* start copying from there */
                    806:   else
                    807: #endif /* COFF */
                    808:     lseek (a_out, SYMS_START, 0);      /* Position a.out to symtab. */
                    809: 
                    810:   while ((n = read (a_out, page, sizeof page)) > 0)
                    811:     {
                    812:       if (write (new, page, n) != n)
                    813:        {
                    814:          PERROR (new_name);
                    815:        }
                    816:     }
                    817:   if (n < 0)
                    818:     {
                    819:       PERROR (a_name);
                    820:     }
                    821:   return 0;
                    822: }
                    823: 
                    824: /* ****************************************************************
                    825:  * mark_x
                    826:  *
                    827:  * After succesfully building the new a.out, mark it executable
                    828:  */
                    829: static
                    830: mark_x (name)
                    831:      char *name;
                    832: {
                    833:   struct stat sbuf;
                    834:   int um;
                    835:   int new = 0;  /* for PERROR */
                    836: 
                    837:   um = umask (777);
                    838:   umask (um);
                    839:   if (stat (name, &sbuf) == -1)
                    840:     {
                    841:       PERROR (name);
                    842:     }
                    843:   sbuf.st_mode |= 0111 & ~um;
                    844:   if (chmod (name, sbuf.st_mode) == -1)
                    845:     PERROR (name);
                    846: }
                    847: 
                    848: /*
                    849:  *     If the COFF file contains a symbol table and a line number section,
                    850:  *     then any auxiliary entries that have values for x_lnnoptr must
                    851:  *     be adjusted by the amount that the line number section has moved
                    852:  *     in the file (bias computed in make_hdr).  The #@$%&* designers of
                    853:  *     the auxiliary entry structures used the absolute file offsets for
                    854:  *     the line number entry rather than an offset from the start of the
                    855:  *     line number section!
                    856:  *
                    857:  *     When I figure out how to scan through the symbol table and pick out
                    858:  *     the auxiliary entries that need adjustment, this routine will
                    859:  *     be fixed.  As it is now, all such entries are wrong and sdb
                    860:  *     will complain.   Fred Fish, UniSoft Systems Inc.
                    861:  */
                    862: 
                    863: #ifdef COFF
                    864: 
                    865: /* This function is probably very slow.  Instead of reopening the new
                    866:    file for input and output it should copy from the old to the new
                    867:    using the two descriptors already open (WRITEDESC and READDESC).
                    868:    Instead of reading one small structure at a time it should use
                    869:    a reasonable size buffer.  But I don't have time to work on such
                    870:    things, so I am installing it as submitted to me.  -- RMS.  */
                    871: 
                    872: adjust_lnnoptrs (writedesc, readdesc, new_name)
                    873:      int writedesc;
                    874:      int readdesc;
                    875:      char *new_name;
                    876: {
                    877:   register int nsyms;
                    878:   register int new;
                    879: #ifdef amdahl_uts
                    880:   SYMENT symentry;
                    881:   AUXENT auxentry;
                    882: #else
                    883:   struct syment symentry;
                    884:   union auxent auxentry;
                    885: #endif
                    886: 
                    887:   if (!lnnoptr || !f_hdr.f_symptr)
                    888:     return 0;
                    889: 
                    890:   if ((new = open (new_name, 2)) < 0)
                    891:     {
                    892:       PERROR (new_name);
                    893:       return -1;
                    894:     }
                    895: 
                    896:   lseek (new, f_hdr.f_symptr, 0);
                    897:   for (nsyms = 0; nsyms < f_hdr.f_nsyms; nsyms++)
                    898:     {
                    899:       read (new, &symentry, SYMESZ);
                    900:       if (symentry.n_numaux)
                    901:        {
                    902:          read (new, &auxentry, AUXESZ);
                    903:          nsyms++;
                    904:          if (ISFCN (symentry.n_type)) {
                    905:            auxentry.x_sym.x_fcnary.x_fcn.x_lnnoptr += bias;
                    906:            lseek (new, -AUXESZ, 1);
                    907:            write (new, &auxentry, AUXESZ);
                    908:          }
                    909:        }
                    910:     }
                    911:   close (new);
                    912: }
                    913: 
                    914: #endif /* COFF */
                    915: 
                    916: #endif /* not CANNOT_UNEXEC */
                    917: 
                    918: #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.