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

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