Annotation of binutils/ld.c, revision 1.1.1.3

1.1       root        1: /* Linker `ld' for GNU
                      2:    Copyright (C) 1988 Free Software Foundation, Inc.
                      3: 
                      4:                       NO WARRANTY
                      5: 
                      6:   BECAUSE THIS PROGRAM IS LICENSED FREE OF CHARGE, WE PROVIDE ABSOLUTELY
                      7: NO WARRANTY, TO THE EXTENT PERMITTED BY APPLICABLE STATE LAW.  EXCEPT
                      8: WHEN OTHERWISE STATED IN WRITING, FREE SOFTWARE FOUNDATION, INC,
                      9: RICHARD M. STALLMAN AND/OR OTHER PARTIES PROVIDE THIS PROGRAM "AS IS"
                     10: WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
                     11: BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
                     12: FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY
                     13: AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE PROGRAM PROVE
                     14: DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR
                     15: CORRECTION.
                     16: 
                     17:  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW WILL RICHARD M.
                     18: STALLMAN, THE FREE SOFTWARE FOUNDATION, INC., AND/OR ANY OTHER PARTY
                     19: WHO MAY MODIFY AND REDISTRIBUTE THIS PROGRAM AS PERMITTED BELOW, BE
                     20: LIABLE TO YOU FOR DAMAGES, INCLUDING ANY LOST PROFITS, LOST MONIES, OR
                     21: OTHER SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
                     22: USE OR INABILITY TO USE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR
                     23: DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY THIRD PARTIES OR
                     24: A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS) THIS
                     25: PROGRAM, EVEN IF YOU HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH
                     26: DAMAGES, OR FOR ANY CLAIM BY ANY OTHER PARTY.
                     27: 
                     28:                GENERAL PUBLIC LICENSE TO COPY
                     29: 
                     30:   1. You may copy and distribute verbatim copies of this source file
                     31: as you receive it, in any medium, provided that you conspicuously
                     32: and appropriately publish on each copy a valid copyright notice
                     33: "Copyright (C) 1988 Free Software Foundation, Inc.", and include
                     34: following the copyright notice a verbatim copy of the above disclaimer
                     35: of warranty and of this License.
                     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:  In other words, you are welcome to use, share and improve this program.
                    100:  You are forbidden to forbid anyone else to use, share and improve
                    101:  what you give them.   Help stamp out software-hoarding!  */
                    102: 
1.1.1.2   root      103: /* Written by Richard Stallman with some help from Eric Albert.
                    104:    Set and indirect features added by Randy Smith.  */
1.1       root      105: 
                    106: #include <ar.h>
                    107: #include <stdio.h>
                    108: #include <sys/types.h>
                    109: #include <sys/stat.h>
                    110: #include <sys/file.h>
1.1.1.3 ! root      111: #include <fcntl.h>
        !           112: 
        !           113: #ifdef COFF_ENCAPSULATE
        !           114: #include "a.out.encap.h"
        !           115: #else
        !           116: #include <a.out.h>
        !           117: #endif
        !           118: 
        !           119: /* If compiled with GNU C, use the built-in alloca */
        !           120: #ifdef __GNUC__
        !           121: #define alloca __builtin_alloca
        !           122: #endif
        !           123: 
        !           124: /* Always use the GNU version of debugging symbol type codes, if possible.  */
        !           125: 
        !           126: #include "stab.h"
        !           127: #define CORE_ADDR unsigned long        /* For symseg.h */
        !           128: #include "symseg.h"
        !           129: 
        !           130: #ifdef USG
        !           131: #include <string.h>
        !           132: #else
        !           133: #include <strings.h>
        !           134: #endif
        !           135: 
        !           136: /* Determine whether we should attempt to handle (minimally)
        !           137:    N_BINCL and N_EINCL.  */
        !           138: 
        !           139: #if defined (__GNU_STAB__) || defined (N_BINCL)
        !           140: #define HAVE_SUN_STABS
        !           141: #endif
1.1       root      142: 
                    143: #define min(a,b) ((a) < (b) ? (a) : (b))
                    144: 
1.1.1.2   root      145: /* Macro to control the number of undefined references printed */
                    146: #define MAX_UREFS_PRINTED      10
                    147: 
1.1       root      148: /* Size of a page; obtained from the operating system.  */
                    149: 
                    150: int page_size;
1.1.1.3 ! root      151: 
        !           152: /* Name this program was invoked by.  */
        !           153: 
        !           154: char *progname;
1.1       root      155: 
                    156: /* System dependencies */
                    157: 
                    158: /* Define this if names etext, edata and end should not start with `_'.  */
                    159: /* #define nounderscore 1 */
                    160: 
                    161: /* Define NON_NATIVE if using BSD or pseudo-BSD file format on a system
                    162:    whose native format is different.  */
                    163: /* #define NON_NATIVE */
                    164: 
                    165: /* Define this to specify the default executable format.  */
                    166: 
                    167: #ifdef hpux
                    168: #define DEFAULT_MAGIC NMAGIC  /* hpux bugs screw ZMAGIC */
                    169: #endif
                    170: 
                    171: #ifndef DEFAULT_MAGIC
                    172: #define DEFAULT_MAGIC ZMAGIC
                    173: #endif
                    174: 
                    175: /* Ordinary 4.3bsd lacks these macros in a.out.h.  */
                    176: 
                    177: #ifndef N_TXTADDR
                    178: #ifdef vax
                    179: #define N_TXTADDR(X) 0
                    180: #endif
1.1.1.3 ! root      181: #ifdef is68k
        !           182: #define N_TXTADDR(x)  (sizeof (struct exec))
        !           183: #endif
1.1       root      184: #endif
                    185: 
                    186: #ifndef N_DATADDR
                    187: #ifdef vax
                    188: #define N_DATADDR(x) \
                    189:        (((x).a_magic==OMAGIC)? (N_TXTADDR(x)+(x).a_text) \
                    190:        : (page_size+((N_TXTADDR(x)+(x).a_text-1) & ~(page_size-1))))
                    191: #endif
1.1.1.3 ! root      192: #ifdef is68k
        !           193: #define SEGMENT_SIZE 0x20000
        !           194: #define N_DATADDR(x) \
        !           195:     (((x).a_magic==Omagic)? (N_TXTADDR(x)+(x).a_text) \
        !           196:      : (SEGMENT_SIZE + ((N_TXTADDR(x)+(x).a_text-1) & ~(SEGMENT_SIZE-1))))
        !           197: #endif
1.1       root      198: #endif
                    199: 
                    200: #ifdef hpux
                    201: #define getpagesize() EXEC_PAGESIZE
                    202: #endif
                    203: 
                    204: /* Define how to initialize system-dependent header fields.  */
                    205: #ifdef sun
1.1.1.3 ! root      206: #ifdef sparc
        !           207: #define INITIALIZE_HEADER \
        !           208:   {outheader.a_machtype = M_SPARC; outheader.a_toolversion = 1;}
        !           209: #endif
        !           210: #if defined(mc68010) || defined(m68010) || (TARGET == SUN2)
        !           211: #define INITIALIZE_HEADER outheader.a_machtype = M_68010
        !           212: #endif
        !           213: #ifndef INITIALIZE_HEADER
1.1       root      214: #define INITIALIZE_HEADER outheader.a_machtype = M_68020
                    215: #endif
1.1.1.3 ! root      216: #endif
        !           217: #ifdef is68k
        !           218: #ifdef M_68020
        !           219: /* ISI rel 4.0D doesn't use it, and rel 3.05 doesn't have an
        !           220:    a_machtype field and so won't recognize the magic number.  To keep
        !           221:    binary compatibility for now, just ignore it */
        !           222: #define INITIALIZE_HEADER outheader.a_machtype = 0;
        !           223: #endif
        !           224: #endif
1.1       root      225: #ifdef hpux
                    226: #define INITIALIZE_HEADER outheader.a_machtype = HP9000S200_ID
                    227: #endif
1.1.1.3 ! root      228: #ifdef i386
        !           229: #define INITIALIZE_HEADER outheader.a_machtype = M_386
        !           230: #endif
        !           231: 
        !           232: #ifdef is68k
        !           233: /* This enables code to take care of an ugly hack in the ISI OS.
        !           234:    If a symbol beings with _$, then the object file is included only
        !           235:    if the rest of the symbol name has been referenced. */
        !           236: #define DOLLAR_KLUDGE
        !           237: #endif
        !           238: 
        !           239: /*
        !           240:  * Alloca include.
        !           241:  */
        !           242: #if defined(sun) && defined(sparc)
        !           243: #include "alloca.h"
        !           244: #endif
        !           245: 
        !           246: #ifndef L_SET
        !           247: #define L_SET 0
        !           248: #endif
        !           249: 
        !           250: /*
        !           251:  * Ok.  Following are the relocation information macros.  If your
        !           252:  * system should not be able to use the default set (below), you must
        !           253:  * define the following:
        !           254: 
        !           255:  *   relocation_info: This must be typedef'd (or #define'd to the type
        !           256:  * of structure that is stored in the relocation info section of your
        !           257:  * a.out files.  Often this is defined in the a.out.h for your system.
        !           258:  *
        !           259:  *   RELOC_ADDRESS (rval): Offset into the current section of the
        !           260:  * <whatever> to be relocated.  *Must be an lvalue*.
        !           261:  *
        !           262:  *   RELOC_EXTERN_P (rval):  Is this relocation entry based on an
        !           263:  * external symbol (1), or was it fully resolved upon entering the
        !           264:  * loader (0) in which case some combination of the value in memory
        !           265:  * (if RELOC_MEMORY_ADD_P) and the extra (if RELOC_ADD_EXTRA) contains
        !           266:  * what the value of the relocation actually was.  *Must be an lvalue*.
        !           267:  *
        !           268:  *   RELOC_TYPE (rval): If this entry was fully resolved upon
        !           269:  * entering the loader, what type should it be relocated as?
        !           270:  *
        !           271:  *   RELOC_SYMBOL (rval): If this entry was not fully resolved upon
        !           272:  * entering the loader, what is the index of it's symbol in the symbol
        !           273:  * table?  *Must be a lvalue*.
        !           274:  *
        !           275:  *   RELOC_MEMORY_ADD_P (rval): This should return true if the final
        !           276:  * relocation value output here should be added to memory, or if the
        !           277:  * section of memory described should simply be set to the relocation
        !           278:  * value.
        !           279:  *
        !           280:  *   RELOC_ADD_EXTRA (rval): (Optional) This macro, if defined, gives
        !           281:  * an extra value to be added to the relocation value based on the
        !           282:  * individual relocation entry.
        !           283:  *
        !           284:  *   RELOC_PCREL_P (rval): True if the relocation value described is
        !           285:  * pc relative.
        !           286:  *
        !           287:  *   RELOC_VALUE_RIGHTSHIFT (rval): Number of bits right to shift the
        !           288:  * final relocation value before putting it where it belongs.
        !           289:  *
        !           290:  *   RELOC_TARGET_SIZE (rval): log to the base 2 of the number of
        !           291:  * bytes of size this relocation entry describes; 1 byte == 0; 2 bytes
        !           292:  * == 1; 4 bytes == 2, and etc.  This is somewhat redundant (we could
        !           293:  * do everything in terms of the bit operators below), but having this
        !           294:  * macro could end up producing better code on machines without fancy
        !           295:  * bit twiddling.  Also, it's easier to understand/code big/little
        !           296:  * endian distinctions with this macro.
        !           297:  *
        !           298:  *   RELOC_TARGET_BITPOS (rval): The starting bit position within the
        !           299:  * object described in RELOC_TARGET_SIZE in which the relocation value
        !           300:  * will go.
        !           301:  *
        !           302:  *   RELOC_TARGET_BITSIZE (rval): How many bits are to be replaced
        !           303:  * with the bits of the relocation value.  It may be assumed by the
        !           304:  * code that the relocation value will fit into this many bits.  This
        !           305:  * may be larger than RELOC_TARGET_SIZE if such be useful.
        !           306:  *
        !           307:  *
        !           308:  *             Things I haven't implemented
        !           309:  *             ----------------------------
        !           310:  *
        !           311:  *    Values for RELOC_TARGET_SIZE other than 0, 1, or 2.
        !           312:  *
        !           313:  *    Pc relative relocation for External references.
        !           314:  *
        !           315:  *
        !           316:  */
        !           317: 
        !           318: #if defined(sun) && defined(sparc)
        !           319: /* Sparc (Sun 4) macros */
        !           320: #undef relocation_info
        !           321: #define relocation_info                        reloc_info_sparc
        !           322: #define RELOC_ADDRESS(r)               ((r)->r_address)                 
        !           323: #define RELOC_EXTERN_P(r)               ((r)->r_extern)      
        !           324: #define RELOC_TYPE(r)                   ((r)->r_index)  
        !           325: #define RELOC_SYMBOL(r)                 ((r)->r_index)   
        !           326: #define RELOC_MEMORY_ADD_P(r)           0                          
        !           327: #define RELOC_ADD_EXTRA(r)              ((r)->r_addend)       
        !           328: #define RELOC_PCREL_P(r)             \
        !           329:         ((r)->r_type >= RELOC_DISP8 && (r)->r_type <= RELOC_WDISP22)
        !           330: #define RELOC_VALUE_RIGHTSHIFT(r)       (reloc_target_rightshift[(r)->r_type])
        !           331: #define RELOC_TARGET_SIZE(r)            (reloc_target_size[(r)->r_type])
        !           332: #define RELOC_TARGET_BITPOS(r)          0
        !           333: #define RELOC_TARGET_BITSIZE(r)         (reloc_target_bitsize[(r)->r_type])
        !           334: 
        !           335: /* Note that these are very dependent on the order of the enums in
        !           336:    enum reloc_type (in a.out.h); if they change the following must be
        !           337:    changed */
        !           338: /* Also note that the last few may be incorrect; I have no information */
        !           339: static int reloc_target_rightshift[] = {
        !           340:   0, 0, 0, 0, 0, 0, 2, 2, 10, 0, 0, 0, 0, 0, 0,
        !           341: };
        !           342: static int reloc_target_size[] = {
        !           343:   0, 1, 2, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
        !           344: };
        !           345: static int reloc_target_bitsize[] = {
        !           346:   8, 16, 32, 8, 16, 32, 30, 22, 22, 22, 13, 10, 32, 32, 16,
        !           347: };
        !           348: #endif
        !           349: 
        !           350: /* Default macros */
        !           351: #ifndef RELOC_ADDRESS
        !           352: #define RELOC_ADDRESS(r)               ((r)->r_address)
        !           353: #define RELOC_EXTERN_P(r)              ((r)->r_extern)
        !           354: #define RELOC_TYPE(r)          ((r)->r_symbolnum)
        !           355: #define RELOC_SYMBOL(r)                ((r)->r_symbolnum)
        !           356: #define RELOC_MEMORY_ADD_P(r)  1
        !           357: /* #define RELOC_ADD_EXTRA(r)          0       /* Don't need to define */
        !           358: #define RELOC_PCREL_P(r)               ((r)->r_pcrel)
        !           359: #define RELOC_VALUE_RIGHTSHIFT(r)      0
        !           360: #define RELOC_TARGET_SIZE(r)           ((r)->r_length)
        !           361: #define RELOC_TARGET_BITPOS(r) 0
        !           362: #define RELOC_TARGET_BITSIZE(r)        32
        !           363: #endif
1.1       root      364: 
1.1.1.2   root      365: /* Special global symbol types understood by GNU LD.  */
                    366: 
                    367: /* The following type indicates the definition of a symbol as being
                    368:    an indirect reference to another symbol.  The other symbol
                    369:    appears as an undefined reference, immediately following this symbol.
                    370: 
                    371:    Indirection is asymmetrical.  The other symbol's value will be used
                    372:    to satisfy requests for the indirect symbol, but not vice versa.
                    373:    If the other symbol does not have a definition, libraries will
                    374:    be searched to find a definition.  */
                    375: #ifndef N_INDR
                    376: #define N_INDR 0xa
                    377: #endif
                    378: 
                    379: /* The following symbols refer to set elements.
                    380:    All the N_SET[ATDB] symbols with the same name form one set.
                    381:    Space is allocated for the set in the text section, and each set
                    382:    element's value is stored into one word of the space.
                    383:    The first word of the space is the length of the set (number of elements).
                    384: 
                    385:    The address of the set is made into an N_SETV symbol
                    386:    whose name is the same as the name of the set.
                    387:    This symbol acts like a N_TEXT global symbol
                    388:    in that it can satisfy undefined external references.  */
                    389: 
                    390: #ifndef N_SETA
                    391: #define        N_SETA  0x14            /* Absolute set element symbol */
                    392: #endif                         /* This is input to LD, in a .o file.  */
                    393: 
                    394: #ifndef N_SETT
                    395: #define        N_SETT  0x16            /* Text set element symbol */
                    396: #endif                         /* This is input to LD, in a .o file.  */
                    397: 
                    398: #ifndef N_SETD
                    399: #define        N_SETD  0x18            /* Data set element symbol */
                    400: #endif                         /* This is input to LD, in a .o file.  */
                    401: 
                    402: #ifndef N_SETB
                    403: #define        N_SETB  0x1A            /* Bss set element symbol */
                    404: #endif                         /* This is input to LD, in a .o file.  */
                    405: 
                    406: /* Macros dealing with the set element symbols defined in a.out.h */
                    407: #define        SET_ELEMENT_P(x)        ((x)>=N_SETA&&(x)<=(N_SETB|N_EXT))
                    408: #define TYPE_OF_SET_ELEMENT(x) ((x)-N_SETA+N_ABS)
                    409: 
                    410: #ifndef N_SETV
                    411: #define N_SETV 0x1C            /* Pointer to set vector in text area.  */
                    412: #endif                         /* This is output from LD.  */
1.1.1.3 ! root      413: 
        !           414: #ifndef N_WARNING
        !           415: #define N_WARNING 0x1E         /* Warning message to print if file included */
        !           416: #endif                         /* This is input to ld */
        !           417: 
        !           418: #ifndef __GNU_STAB__
        !           419: 
        !           420: /* Line number for the data section.  This is to be used to describe
        !           421:    the source location of a variable declaration.  */
        !           422: #ifndef N_DSLINE
        !           423: #define N_DSLINE (N_SLINE+N_DATA-N_TEXT)
        !           424: #endif
        !           425: 
        !           426: /* Line number for the bss section.  This is to be used to describe
        !           427:    the source location of a variable declaration.  */
        !           428: #ifndef N_BSLINE
        !           429: #define N_BSLINE (N_SLINE+N_BSS-N_TEXT)
        !           430: #endif
        !           431: 
        !           432: #endif /* not __GNU_STAB__ */
1.1.1.2   root      433: 
1.1       root      434: /* Symbol table */
                    435: 
                    436: /* Global symbol data is recorded in these structures,
                    437:    one for each global symbol.
                    438:    They are found via hashing in 'symtab', which points to a vector of buckets.
                    439:    Each bucket is a chain of these structures through the link field.  */
                    440: 
                    441: typedef
                    442:   struct glosym
                    443:     {
                    444:       /* Pointer to next symbol in this symbol's hash bucket.  */
                    445:       struct glosym *link;
                    446:       /* Name of this symbol.  */
                    447:       char *name;
                    448:       /* Value of this symbol as a global symbol.  */
                    449:       long value;
1.1.1.3 ! root      450:       /* Chain of external 'nlist's in files for this symbol, both defs
        !           451:         and refs.  */
1.1       root      452:       struct nlist *refs;
1.1.1.3 ! root      453:       /* Any warning message that might be associated with this symbol
        !           454:          from an N_WARNING symbol encountered. */
        !           455:       char *warning;
1.1       root      456:       /* Nonzero means definitions of this symbol as common have been seen,
                    457:         and the value here is the largest size specified by any of them.  */
                    458:       int max_common_size;
                    459:       /* For relocatable_output, records the index of this global sym in the
1.1.1.3 ! root      460:         symbol table to be written, with the first global sym given index 0.*/
1.1       root      461:       int def_count;
                    462:       /* Nonzero means a definition of this global symbol is known to exist.
                    463:         Library members should not be loaded on its account.  */
                    464:       char defined;
                    465:       /* Nonzero means a reference to this global symbol has been seen
                    466:         in a file that is surely being loaded.
1.1.1.2   root      467:         A value higher than 1 is the n_type code for the symbol's
                    468:         definition.  */
1.1       root      469:       char referenced;
1.1.1.2   root      470:       /* A count of the number of undefined references printed for a
1.1.1.3 ! root      471:         specific symbol.  If a symbol is unresolved at the end of
        !           472:         digest_symbols (and the loading run is supposed to produce
        !           473:         relocatable output) do_file_warnings keeps track of how many
        !           474:         unresolved reference error messages have been printed for
        !           475:         each symbol here.  When the number hits MAX_UREFS_PRINTED,
        !           476:         messages stop. */
1.1.1.2   root      477:       unsigned char undef_refs;
1.1       root      478:       /* Nonzero means print a message at all refs or defs of this symbol */
                    479:       char trace;
                    480:     }
                    481:   symbol;
                    482: 
                    483: /* Number of buckets in symbol hash table */
                    484: #define        TABSIZE 1009
                    485: 
                    486: /* The symbol hash table: a vector of TABSIZE pointers to struct glosym. */
                    487: symbol *symtab[TABSIZE];
                    488: 
                    489: /* Number of symbols in symbol hash table. */
                    490: int num_hash_tab_syms = 0;
                    491: 
                    492: /* Count the number of nlist entries that are for local symbols.
                    493:    This count and the three following counts
                    494:    are incremented as as symbols are entered in the symbol table.  */
                    495: int local_sym_count;
                    496: 
                    497: /* Count number of nlist entries that are for local symbols
                    498:    whose names don't start with L. */
                    499: int non_L_local_sym_count;
                    500: 
                    501: /* Count the number of nlist entries for debugger info.  */
                    502: int debugger_sym_count;
                    503: 
                    504: /* Count the number of global symbols referenced and not defined.  */
                    505: int undefined_global_sym_count;
                    506: 
                    507: /* Count the number of defined global symbols.
                    508:    Each symbol is counted only once
                    509:    regardless of how many different nlist entries refer to it,
                    510:    since the output file will need only one nlist entry for it.
                    511:    This count is computed by `digest_symbols';
                    512:    it is undefined while symbols are being loaded. */
                    513: int defined_global_sym_count;
                    514: 
1.1.1.2   root      515: /* Count the number of set element type symbols and the number of
                    516:    separate vectors which these symbols will fit into.  See the
                    517:    GNU a.out.h for more info.
                    518:    This count is computed by 'enter_file_symbols' */
                    519: int set_symbol_count;
                    520: int set_vector_count;
                    521: 
                    522: /* Count the number of definitions done indirectly (ie. done relative
                    523:    to the value of some other symbol. */
                    524: int global_indirect_count;
                    525: 
1.1.1.3 ! root      526: /* Count the number of warning symbols encountered. */
        !           527: int warning_count;
        !           528: 
1.1       root      529: /* Total number of symbols to be written in the output file.
                    530:    Computed by digest_symbols from the variables above.  */
                    531: int nsyms;
                    532: 
                    533: 
                    534: /* Nonzero means ptr to symbol entry for symbol to use as start addr.
                    535:    -e sets this.  */
                    536: symbol *entry_symbol;
                    537: 
                    538: symbol *edata_symbol;   /* the symbol _edata */
                    539: symbol *etext_symbol;   /* the symbol _etext */
                    540: symbol *end_symbol;    /* the symbol _end */
                    541: 
                    542: /* Each input file, and each library member ("subfile") being loaded,
                    543:    has a `file_entry' structure for it.
                    544: 
                    545:    For files specified by command args, these are contained in the vector
                    546:    which `file_table' points to.
                    547: 
                    548:    For library members, they are dynamically allocated,
                    549:    and chained through the `chain' field.
                    550:    The chain is found in the `subfiles' field of the `file_entry'.
                    551:    The `file_entry' objects for the members have `superfile' fields pointing
                    552:    to the one for the library.  */
                    553: 
                    554: struct file_entry {
                    555:   /* Name of this file.  */
                    556:   char *filename;
                    557:   /* Name to use for the symbol giving address of text start */
                    558:   /* Usually the same as filename, but for a file spec'd with -l
                    559:      this is the -l switch itself rather than the filename.  */
                    560:   char *local_sym_name;
                    561: 
                    562:   /* Describe the layout of the contents of the file */
                    563: 
                    564:   /* The file's a.out header.  */
                    565:   struct exec header;
                    566:   /* Offset in file of GDB symbol segment, or 0 if there is none.  */
                    567:   int symseg_offset;
                    568: 
                    569:   /* Describe data from the file loaded into core */
                    570: 
                    571:   /* Symbol table of the file.  */
                    572:   struct nlist *symbols;
                    573:   /* Size in bytes of string table.  */
                    574:   int string_size;
                    575:   /* Pointer to the string table.
                    576:      The string table is not kept in core all the time,
                    577:      but when it is in core, its address is here.  */
                    578:   char *strings;
1.1.1.3 ! root      579:   /* Pointer to any warning specified in this file by an N_WARNING
        !           580:      type symbol */
        !           581:   char *warning;
1.1       root      582: 
1.1.1.2   root      583:   /* Next two used only if `relocatable_output' or if needed for */
                    584:   /* output of undefined reference line numbers. */
1.1       root      585: 
                    586:   /* Text reloc info saved by `write_text' for `coptxtrel'.  */
                    587:   struct relocation_info *textrel;
                    588:   /* Data reloc info saved by `write_data' for `copdatrel'.  */
                    589:   struct relocation_info *datarel;
                    590: 
                    591:   /* Relation of this file's segments to the output file */
                    592: 
                    593:   /* Start of this file's text seg in the output file core image.  */
                    594:   int text_start_address;
                    595:   /* Start of this file's data seg in the output file core image.  */
                    596:   int data_start_address;
                    597:   /* Start of this file's bss seg in the output file core image.  */
                    598:   int bss_start_address;
                    599:   /* Offset in bytes in the output file symbol table
                    600:      of the first local symbol for this file.  Set by `write_file_symbols'.  */
1.1.1.3 ! root      601:   int local_syms_offset;
1.1       root      602: 
                    603:   /* For library members only */
                    604: 
                    605:   /* For a library, points to chain of entries for the library members.  */
                    606:   struct file_entry *subfiles;
                    607:   /* For a library member, offset of the member within the archive.
                    608:      Zero for files that are not library members.  */
                    609:   int starting_offset;
                    610:   /* Size of contents of this file, if library member.  */
                    611:   int total_size;
                    612:   /* For library member, points to the library's own entry.  */
                    613:   struct file_entry *superfile;
                    614:   /* For library member, points to next entry for next member.  */
                    615:   struct file_entry *chain;
                    616: 
                    617:   /* 1 if file is a library. */
                    618:   char library_flag;
                    619: 
                    620:   /* 1 if file's header has been read into this structure.  */
                    621:   char header_read_flag;
                    622: 
                    623:   /* 1 means search a set of directories for this file.  */
                    624:   char search_dirs_flag;
                    625: 
                    626:   /* 1 means this is base file of incremental load.
                    627:      Do not load this file's text or data.
                    628:      Also default text_start to after this file's bss. */
                    629:   char just_syms_flag;
                    630: };
                    631: 
                    632: /* Vector of entries for input files specified by arguments.
                    633:    These are all the input files except for members of specified libraries.  */
                    634: struct file_entry *file_table;
                    635: 
                    636: /* Length of that vector.  */
                    637: int number_of_files;
                    638: 
                    639: /* When loading the text and data, we can avoid doing a close
                    640:    and another open between members of the same library.
                    641: 
                    642:    These two variables remember the file that is currently open.
                    643:    Both are zero if no file is open.
                    644: 
                    645:    See `each_file' and `file_close'.  */
                    646: 
                    647: struct file_entry *input_file;
                    648: int input_desc;
                    649: 
                    650: /* The name of the file to write; "a.out" by default.  */
                    651: 
                    652: char *output_filename;
                    653: 
                    654: /* Descriptor for writing that file with `mywrite'.  */
                    655: 
                    656: int outdesc;
                    657: 
                    658: /* Header for that file (filled in by `write_header').  */
                    659: 
                    660: struct exec outheader;
                    661: 
1.1.1.3 ! root      662: #ifdef COFF_ENCAPSULATE
        !           663: struct coffheader coffheader;
        !           664: int need_coff_header;
        !           665: #endif
        !           666: 
1.1       root      667: /* The following are computed by `digest_symbols'.  */
                    668: 
                    669: int text_size;         /* total size of text of all input files.  */
                    670: int data_size;         /* total size of data of all input files.  */
                    671: int bss_size;          /* total size of bss of all input files.  */
                    672: int text_reloc_size;   /* total size of text relocation of all input files.  */
1.1.1.2   root      673: int data_reloc_size;   /* total size of data relocation of all input */
                    674:                        /* files.  */
                    675: 
                    676: /* Specifications of start and length of the area reserved at the end
                    677:    of the text segment for the set vectors.  Computed in 'digest_symbols' */
                    678: int set_sect_start;
                    679: int set_sect_size;
                    680: 
                    681: /* Pointer for in core storage for the above vectors, before they are
                    682:    written. */
                    683: unsigned long *set_vectors;
1.1       root      684: 
                    685: /* Amount of cleared space to leave between the text and data segments.  */
                    686: 
                    687: int text_pad;
                    688: 
                    689: /* Amount of bss segment to include as part of the data segment.  */
                    690: 
                    691: int data_pad;
                    692: 
                    693: /* Format of __.SYMDEF:
                    694:    First, a longword containing the size of the 'symdef' data that follows.
                    695:    Second, zero or more 'symdef' structures.
                    696:    Third, a word containing the length of symbol name strings.
                    697:    Fourth, zero or more symbol name strings (each followed by a zero).  */
                    698: 
                    699: struct symdef {
                    700:   int symbol_name_string_index;
                    701:   int library_member_offset;
                    702: };
                    703: 
                    704: /* Record most of the command options.  */
                    705: 
                    706: /* Address we assume the text section will be loaded at.
                    707:    We relocate symbols and text and data for this, but we do not
                    708:    write any padding in the output file for it.  */
                    709: int text_start;
                    710: 
                    711: /* Offset of default entry-pc within the text section.  */
                    712: int entry_offset;
                    713: 
                    714: /* Address we decide the data section will be loaded at.  */
                    715: int data_start;
                    716: 
                    717: /* `text-start' address is normally this much plus a page boundary.
                    718:    This is not a user option; it is fixed for each system.  */
                    719: int text_start_alignment;
                    720: 
                    721: /* Nonzero if -T was specified in the command line.
                    722:    This prevents text_start from being set later to default values.  */
                    723: int T_flag_specified;
                    724: 
                    725: /* Nonzero if -Tdata was specified in the command line.
                    726:    This prevents data_start from being set later to default values.  */
                    727: int Tdata_flag_specified;
                    728: 
                    729: /* Size to pad data section up to.
                    730:    We simply increase the size of the data section, padding with zeros,
                    731:    and reduce the size of the bss section to match.  */
                    732: int specified_data_size;
                    733: 
                    734: /* Magic number to use for the output file, set by switch.  */
                    735: int magic;
                    736: 
                    737: /* Nonzero means print names of input files as processed.  */
                    738: int trace_files;
                    739: 
                    740: /* Which symbols should be stripped (omitted from the output):
                    741:    none, all, or debugger symbols.  */
                    742: enum { STRIP_NONE, STRIP_ALL, STRIP_DEBUGGER } strip_symbols;
                    743: 
                    744: /* Which local symbols should be omitted:
                    745:    none, all, or those starting with L.
                    746:    This is irrelevant if STRIP_NONE.  */
                    747: enum { DISCARD_NONE, DISCARD_ALL, DISCARD_L } discard_locals;
                    748: 
                    749: /* 1 => write load map.  */
                    750: int write_map;
                    751: 
                    752: /* 1 => write relocation into output file so can re-input it later.  */
                    753: int relocatable_output;
                    754: 
                    755: /* 1 => assign space to common symbols even if `relocatable_output'.  */
                    756: int force_common_definition;
                    757: 
                    758: /* Standard directories to search for files specified by -l.  */
                    759: char *standard_search_dirs[] =
1.1.1.3 ! root      760: #ifdef STANDARD_SEARCH_DIRS
        !           761:   {STANDARD_SEARCH_DIRS};
        !           762: #else
1.1       root      763: #ifdef NON_NATIVE
                    764:   {"/usr/local/lib/gnu"};
                    765: #else
                    766:   {"/lib", "/usr/lib", "/usr/local/lib"};
                    767: #endif
1.1.1.3 ! root      768: #endif
1.1       root      769: 
                    770: /* Actual vector of directories to search;
                    771:    this contains those specified with -L plus the standard ones.  */
                    772: char **search_dirs;
                    773: 
                    774: /* Length of the vector `search_dirs'.  */
                    775: int n_search_dirs;
                    776: 
1.1.1.2   root      777: /* Non zero means to create the output executable. */
1.1       root      778: /* Cleared by nonfatal errors.  */
                    779: int make_executable;
                    780: 
1.1.1.2   root      781: /* Force the executable to be output, even if there are non-fatal
                    782:    errors */
                    783: int force_executable;
                    784: 
1.1.1.3 ! root      785: /* Keep a list of any symbols referenced from the command line (so
        !           786:    that error messages for these guys can be generated). This list is
        !           787:    zero terminated. */
        !           788: struct glosym **cmdline_references;
        !           789: int cl_refs_allocated;
        !           790: 
1.1.1.2   root      791: void bcopy (), bzero ();
1.1.1.3 ! root      792: int malloc (), realloc ();
        !           793: #ifndef alloca
        !           794: int alloca ();
        !           795: #endif
1.1.1.2   root      796: int free ();
                    797: 
                    798: int xmalloc ();
                    799: int xrealloc ();
                    800: void fatal ();
                    801: void fatal_with_file ();
                    802: void perror_name ();
                    803: void perror_file ();
                    804: void error ();
                    805: 
1.1       root      806: void digest_symbols ();
                    807: void print_symbols ();
                    808: void load_symbols ();
                    809: void decode_command ();
                    810: void list_undefined_symbols ();
1.1.1.2   root      811: void list_unresolved_references ();
1.1       root      812: void write_output ();
                    813: void write_header ();
                    814: void write_text ();
1.1.1.2   root      815: void read_file_relocation ();
1.1       root      816: void write_data ();
                    817: void write_rel ();
                    818: void write_syms ();
1.1.1.2   root      819: void write_symsegs ();
                    820: void mywrite ();
                    821: void symtab_init ();
1.1       root      822: void padfile ();
                    823: char *concat ();
1.1.1.2   root      824: char *get_file_name ();
1.1       root      825: symbol *getsym (), *getsym_soft ();
                    826: 
1.1.1.2   root      827: int
1.1       root      828: main (argc, argv)
                    829:      char **argv;
                    830:      int argc;
                    831: {
                    832:   page_size = getpagesize ();
1.1.1.3 ! root      833:   progname = argv[0];
1.1       root      834: 
                    835:   /* Clear the cumulative info on the output file.  */
                    836: 
                    837:   text_size = 0;
                    838:   data_size = 0;
                    839:   bss_size = 0;
                    840:   text_reloc_size = 0;
                    841:   data_reloc_size = 0;
                    842: 
                    843:   data_pad = 0;
                    844:   text_pad = 0;
                    845: 
                    846:   /* Initialize the data about options.  */
                    847: 
                    848:   specified_data_size = 0;
                    849:   strip_symbols = STRIP_NONE;
                    850:   trace_files = 0;
                    851:   discard_locals = DISCARD_NONE;
                    852:   entry_symbol = 0;
                    853:   write_map = 0;
                    854:   relocatable_output = 0;
                    855:   force_common_definition = 0;
                    856:   T_flag_specified = 0;
                    857:   Tdata_flag_specified = 0;
                    858:   magic = DEFAULT_MAGIC;
                    859:   make_executable = 1;
1.1.1.2   root      860:   force_executable = 0;
1.1       root      861: 
                    862:   /* Initialize the cumulative counts of symbols.  */
                    863: 
                    864:   local_sym_count = 0;
                    865:   non_L_local_sym_count = 0;
                    866:   debugger_sym_count = 0;
                    867:   undefined_global_sym_count = 0;
1.1.1.2   root      868:   set_symbol_count = 0;
                    869:   set_vector_count = 0;
                    870:   global_indirect_count = 0;
1.1.1.3 ! root      871:   warning_count = 0;
        !           872: 
        !           873:   /* Keep a list of symbols referenced from the command line */
        !           874:   cl_refs_allocated = 10;
        !           875:   cmdline_references =
        !           876:     (struct glosym **) xmalloc (cl_refs_allocated
        !           877:                                * sizeof(struct glosym *));
1.1       root      878: 
                    879:   /* Completely decode ARGV.  */
                    880: 
                    881:   decode_command (argc, argv);
                    882: 
                    883:   /* Create the symbols `etext', `edata' and `end'.  */
                    884: 
                    885:   if (!relocatable_output)
                    886:     symtab_init ();
                    887: 
                    888:   /* Determine whether to count the header as part of
                    889:      the text size, and initialize the text size accordingly.
                    890:      This depends on the kind of system and on the output format selected.  */
                    891: 
                    892:   outheader.a_magic = magic;
                    893: #ifdef INITIALIZE_HEADER
                    894:   INITIALIZE_HEADER;
                    895: #endif
                    896: 
1.1.1.3 ! root      897:   text_size = sizeof (struct exec);
        !           898: #ifdef COFF_ENCAPSULATE
        !           899:   if (relocatable_output == 0)
        !           900:     {
        !           901:       need_coff_header = 1;
        !           902:       /* set A_ENCAP now, since it will change the values of N_TXTOFF, etc */
        !           903:       outheader.a_flags |= A_ENCAP;
        !           904:       text_size += sizeof (struct coffheader);
        !           905:     }
        !           906: #endif
        !           907: 
        !           908:   text_size -= N_TXTOFF (outheader);
        !           909: 
1.1       root      910:   if (text_size < 0)
                    911:     text_size = 0;
                    912:   entry_offset = text_size;
                    913: 
                    914:   if (!T_flag_specified && !relocatable_output)
                    915:     text_start = N_TXTADDR (outheader);
                    916: 
                    917:   /* The text-start address is normally this far past a page boundary.  */
                    918:   text_start_alignment = text_start % page_size;
                    919: 
                    920:   /* Load symbols of all input files.
                    921:      Also search all libraries and decide which library members to load.  */
                    922: 
                    923:   load_symbols ();
                    924: 
                    925:   /* Compute where each file's sections go, and relocate symbols.  */
                    926: 
                    927:   digest_symbols ();
                    928: 
1.1.1.3 ! root      929:   /* Print error messages for any missing symbols, for any warning
        !           930:      symbols, and possibly multiple definitions */
1.1       root      931: 
1.1.1.3 ! root      932:   do_warnings (stderr);
1.1       root      933: 
                    934:   /* Print a map, if requested.  */
                    935: 
                    936:   if (write_map) print_symbols (stdout);
                    937: 
                    938:   /* Write the output file.  */
                    939: 
1.1.1.2   root      940:   if (make_executable || force_executable)
                    941:     write_output ();
1.1       root      942: 
1.1.1.3 ! root      943:   return ! make_executable;
1.1       root      944: }
                    945: 
                    946: void decode_option ();
                    947: 
                    948: /* Analyze a command line argument.
                    949:    Return 0 if the argument is a filename.
                    950:    Return 1 if the argument is a option complete in itself.
                    951:    Return 2 if the argument is a option which uses an argument.
                    952: 
                    953:    Thus, the value is the number of consecutive arguments
                    954:    that are part of options.  */
                    955: 
                    956: int
                    957: classify_arg (arg)
                    958:      register char *arg;
                    959: {
                    960:   if (*arg != '-') return 0;
                    961:   switch (arg[1])
                    962:     {
                    963:     case 'A':
                    964:     case 'D':
                    965:     case 'e':
                    966:     case 'L':
                    967:     case 'l':
                    968:     case 'o':
                    969:     case 'u':
                    970:     case 'y':
                    971:       if (arg[2])
                    972:        return 1;
                    973:       return 2;
                    974: 
                    975:     case 'T':
                    976:       if (arg[2] == 0)
                    977:        return 2;
                    978:       if (! strcmp (&arg[2], "text"))
                    979:        return 2;
                    980:       if (! strcmp (&arg[2], "data"))
                    981:        return 2;
                    982:       return 1;
                    983:     }
                    984: 
                    985:   return 1;
                    986: }
                    987: 
                    988: /* Process the command arguments,
                    989:    setting up file_table with an entry for each input file,
                    990:    and setting variables according to the options.  */
                    991: 
                    992: void
                    993: decode_command (argc, argv)
                    994:      char **argv;
                    995:      int argc;
                    996: {
                    997:   register int i;
                    998:   register struct file_entry *p;
                    999: 
                   1000:   number_of_files = 0;
                   1001:   output_filename = "a.out";
                   1002: 
                   1003:   n_search_dirs = 0;
                   1004:   search_dirs = (char **) xmalloc (sizeof (char *));
                   1005: 
                   1006:   /* First compute number_of_files so we know how long to make file_table.  */
                   1007:   /* Also process most options completely.  */
                   1008: 
                   1009:   for (i = 1; i < argc; i++)
                   1010:     {
                   1011:       register int code = classify_arg (argv[i]);
                   1012:       if (code)
                   1013:        {
                   1014:          if (i + code > argc)
                   1015:            fatal ("no argument following %s\n", argv[i]);
                   1016: 
                   1017:          decode_option (argv[i], argv[i+1]);
                   1018: 
                   1019:          if (argv[i][1] == 'l' || argv[i][1] == 'A')
                   1020:            number_of_files++;
                   1021: 
                   1022:          i += code - 1;
                   1023:        }
                   1024:       else
                   1025:        number_of_files++;
                   1026:     }
                   1027: 
                   1028:   if (!number_of_files)
                   1029:     fatal ("no input files", 0);
                   1030: 
                   1031:   p = file_table
                   1032:     = (struct file_entry *) xmalloc (number_of_files * sizeof (struct file_entry));
                   1033:   bzero (p, number_of_files * sizeof (struct file_entry));
                   1034: 
                   1035:   /* Now scan again and fill in file_table.  */
                   1036:   /* All options except -A and -l are ignored here.  */
                   1037: 
                   1038:   for (i = 1; i < argc; i++)
                   1039:     {
                   1040:       register int code = classify_arg (argv[i]);
                   1041: 
                   1042:       if (code)
                   1043:        {
                   1044:          char *string;
                   1045:          if (code == 2)
                   1046:            string = argv[i+1];
                   1047:          else
                   1048:            string = &argv[i][2];
                   1049: 
                   1050:          if (argv[i][1] == 'A')
                   1051:            {
                   1052:              if (p != file_table)
                   1053:                fatal ("-A specified before an input file other than the first");
                   1054: 
                   1055:              p->filename = string;
                   1056:              p->local_sym_name = string;
                   1057:              p->just_syms_flag = 1;
                   1058:              p++;
                   1059:            }
                   1060:          if (argv[i][1] == 'l')
                   1061:            {
                   1062:              p->filename = concat ("lib", string, ".a");
                   1063:              p->local_sym_name = concat ("-l", string, "");
                   1064:              p->search_dirs_flag = 1;
                   1065:              p++;
                   1066:            }
                   1067:          i += code - 1;
                   1068:        }
                   1069:       else
                   1070:        {
                   1071:          p->filename = argv[i];
                   1072:          p->local_sym_name = argv[i];
                   1073:          p++;
                   1074:        }
                   1075:     }
                   1076: 
                   1077:   /* Now check some option settings for consistency.  */
                   1078: 
                   1079:   if ((magic == ZMAGIC || magic == NMAGIC)
                   1080:       && (text_start - text_start_alignment) & (page_size - 1))
                   1081:     fatal ("-T argument not multiple of page size, with sharable output", 0);
                   1082: 
                   1083:   /* Append the standard search directories to the user-specified ones.  */
                   1084:   {
                   1085:     int n = sizeof standard_search_dirs / sizeof standard_search_dirs[0];
                   1086:     n_search_dirs += n;
                   1087:     search_dirs
                   1088:       = (char **) xrealloc (search_dirs, n_search_dirs * sizeof (char *));
                   1089:     bcopy (standard_search_dirs, &search_dirs[n_search_dirs - n],
                   1090:           n * sizeof (char *));
                   1091:   }
                   1092: }
                   1093: 
1.1.1.3 ! root     1094: 
        !          1095: void
        !          1096: add_cmdline_ref (sp)
        !          1097:      struct glosym *sp;
        !          1098: {
        !          1099:   struct glosym **ptr;
        !          1100: 
        !          1101:   for (ptr = cmdline_references;
        !          1102:        ptr < cmdline_references + cl_refs_allocated && *ptr;
        !          1103:        ptr++)
        !          1104:     ;
        !          1105: 
        !          1106:   if (ptr == cmdline_references + cl_refs_allocated)
        !          1107:     {
        !          1108:       int diff = ptr - cmdline_references;
        !          1109:       
        !          1110:       cl_refs_allocated *= 2;
        !          1111:       cmdline_references = (struct glosym **)
        !          1112:        xrealloc (cmdline_references,
        !          1113:                 cl_refs_allocated * sizeof (struct glosym *));
        !          1114:       ptr = cmdline_references + diff;
        !          1115:     }
        !          1116:   
        !          1117:   *ptr++ = sp;
        !          1118:   *ptr = (struct glosym *) 0;
        !          1119: }
        !          1120:     
1.1.1.2   root     1121: int parse ();
                   1122: 
1.1       root     1123: /* Record an option and arrange to act on it later.
                   1124:    ARG should be the following command argument,
                   1125:    which may or may not be used by this option.
                   1126: 
                   1127:    The `l' and `A' options are ignored here since they actually
                   1128:    specify input files.  */
                   1129: 
                   1130: void
                   1131: decode_option (swt, arg)
                   1132:      register char *swt, *arg;
                   1133: {
1.1.1.2   root     1134:   if (! strcmp (swt + 1, "Ttext"))
1.1       root     1135:     {
                   1136:       text_start = parse (arg, "%x", "invalid argument to -Ttext");
                   1137:       T_flag_specified = 1;
                   1138:       return;
                   1139:     }
1.1.1.2   root     1140:   if (! strcmp (swt + 1, "Tdata"))
1.1       root     1141:     {
                   1142:       data_start = parse (arg, "%x", "invalid argument to -Tdata");
                   1143:       Tdata_flag_specified = 1;
                   1144:       return;
                   1145:     }
1.1.1.2   root     1146:   if (! strcmp (swt + 1, "noinhibit-exec"))
                   1147:     {
                   1148:       force_executable = 1;
                   1149:       return;
                   1150:     }
1.1       root     1151: 
                   1152:   if (swt[2] != 0)
                   1153:     arg = &swt[2];
                   1154: 
                   1155:   switch (swt[1])
                   1156:     {
                   1157:     case 'A':
                   1158:       return;
                   1159: 
                   1160:     case 'D':
                   1161:       specified_data_size = parse (arg, "%x", "invalid argument to -D");
                   1162:       return;
                   1163: 
                   1164:     case 'd':
                   1165:       force_common_definition = 1;
                   1166:       return;
                   1167: 
                   1168:     case 'e':
                   1169:       entry_symbol = getsym (arg);
                   1170:       if (!entry_symbol->defined && !entry_symbol->referenced)
                   1171:        undefined_global_sym_count++;
                   1172:       entry_symbol->referenced = 1;
1.1.1.3 ! root     1173:       add_cmdline_ref (entry_symbol);
1.1       root     1174:       return;
                   1175: 
                   1176:     case 'l':
                   1177:       return;
                   1178: 
                   1179:     case 'L':
                   1180:       n_search_dirs++;
                   1181:       search_dirs
                   1182:        = (char **) xrealloc (search_dirs, n_search_dirs * sizeof (char *));
                   1183:       search_dirs[n_search_dirs - 1] = arg;
                   1184:       return;
1.1.1.3 ! root     1185: 
1.1       root     1186:     case 'M':
                   1187:       write_map = 1;
                   1188:       return;
                   1189: 
                   1190:     case 'N':
                   1191:       magic = OMAGIC;
                   1192:       return;
                   1193: 
                   1194:     case 'n':
                   1195:       magic = NMAGIC;
                   1196:       return;
                   1197: 
                   1198:     case 'o':
                   1199:       output_filename = arg;
                   1200:       return;
                   1201: 
                   1202:     case 'r':
                   1203:       relocatable_output = 1;
                   1204:       magic = OMAGIC;
                   1205:       text_start = 0;
                   1206:       return;
                   1207: 
                   1208:     case 'S':
                   1209:       strip_symbols = STRIP_DEBUGGER;
                   1210:       return;
                   1211: 
                   1212:     case 's':
                   1213:       strip_symbols = STRIP_ALL;
                   1214:       return;
                   1215: 
                   1216:     case 'T':
                   1217:       text_start = parse (arg, "%x", "invalid argument to -T");
                   1218:       T_flag_specified = 1;
                   1219:       return;
                   1220: 
                   1221:     case 't':
                   1222:       trace_files = 1;
                   1223:       return;
                   1224: 
                   1225:     case 'u':
                   1226:       {
                   1227:        register symbol *sp = getsym (arg);
1.1.1.3 ! root     1228:        if (!sp->defined && !sp->referenced)
        !          1229:          undefined_global_sym_count++;
1.1       root     1230:        sp->referenced = 1;
1.1.1.3 ! root     1231:        add_cmdline_ref (sp);
1.1       root     1232:       }
                   1233:       return;
                   1234: 
                   1235:     case 'X':
                   1236:       discard_locals = DISCARD_L;
                   1237:       return;
                   1238: 
                   1239:     case 'x':
                   1240:       discard_locals = DISCARD_ALL;
                   1241:       return;
                   1242: 
                   1243:     case 'y':
                   1244:       {
                   1245:        register symbol *sp = getsym (&swt[2]);
                   1246:        sp->trace = 1;
                   1247:       }
                   1248:       return;
                   1249: 
                   1250:     case 'z':
                   1251:       magic = ZMAGIC;
                   1252:       return;
                   1253: 
                   1254:     default:
                   1255:       fatal ("invalid command option `%s'", swt);
                   1256:     }
                   1257: }
                   1258: 
1.1.1.2   root     1259: /** Convenient functions for operating on one or all files being */
                   1260:  /** loaded.  */
                   1261: void print_file_name ();
1.1       root     1262: 
                   1263: /* Call FUNCTION on each input file entry.
                   1264:    Do not call for entries for libraries;
                   1265:    instead, call once for each library member that is being loaded.
1.1.1.3 ! root     1266: 
1.1       root     1267:    FUNCTION receives two arguments: the entry, and ARG.  */
                   1268: 
                   1269: void
                   1270: each_file (function, arg)
                   1271:      register void (*function)();
                   1272:      register int arg;
                   1273: {
                   1274:   register int i;
1.1.1.3 ! root     1275: 
1.1       root     1276:   for (i = 0; i < number_of_files; i++)
                   1277:     {
                   1278:       register struct file_entry *entry = &file_table[i];
                   1279:       if (entry->library_flag)
                   1280:         {
                   1281:          register struct file_entry *subentry = entry->subfiles;
                   1282:          for (; subentry; subentry = subentry->chain)
                   1283:            (*function) (subentry, arg);
                   1284:        }
                   1285:       else
                   1286:        (*function) (entry, arg);
                   1287:     }
                   1288: }
                   1289: 
1.1.1.2   root     1290: /* Call FUNCTION on each input file entry until it returns a non-zero
                   1291:    value.  Return this value.
                   1292:    Do not call for entries for libraries;
                   1293:    instead, call once for each library member that is being loaded.
1.1.1.3 ! root     1294: 
1.1.1.2   root     1295:    FUNCTION receives two arguments: the entry, and ARG.  It must be a
                   1296:    function returning unsigned long (though this can probably be fudged). */
                   1297: 
                   1298: unsigned long
                   1299: check_each_file (function, arg)
                   1300:      register unsigned long (*function)();
                   1301:      register int arg;
                   1302: {
                   1303:   register int i;
                   1304:   register unsigned long return_val;
1.1.1.3 ! root     1305: 
1.1.1.2   root     1306:   for (i = 0; i < number_of_files; i++)
                   1307:     {
                   1308:       register struct file_entry *entry = &file_table[i];
                   1309:       if (entry->library_flag)
                   1310:         {
                   1311:          register struct file_entry *subentry = entry->subfiles;
                   1312:          for (; subentry; subentry = subentry->chain)
                   1313:            if (return_val = (*function) (subentry, arg))
                   1314:              return return_val;
                   1315:        }
                   1316:       else
                   1317:        if (return_val = (*function) (entry, arg))
                   1318:          return return_val;
                   1319:     }
                   1320:   return 0;
                   1321: }
                   1322: 
1.1       root     1323: /* Like `each_file' but ignore files that were just for symbol definitions.  */
                   1324: 
                   1325: void
                   1326: each_full_file (function, arg)
                   1327:      register void (*function)();
                   1328:      register int arg;
                   1329: {
                   1330:   register int i;
                   1331: 
                   1332:   for (i = 0; i < number_of_files; i++)
                   1333:     {
                   1334:       register struct file_entry *entry = &file_table[i];
                   1335:       if (entry->just_syms_flag)
                   1336:        continue;
                   1337:       if (entry->library_flag)
                   1338:         {
                   1339:          register struct file_entry *subentry = entry->subfiles;
                   1340:          for (; subentry; subentry = subentry->chain)
                   1341:            (*function) (subentry, arg);
                   1342:        }
                   1343:       else
                   1344:        (*function) (entry, arg);
                   1345:     }
                   1346: }
                   1347: 
                   1348: /* Close the input file that is now open.  */
                   1349: 
                   1350: void
                   1351: file_close ()
                   1352: {
                   1353:   close (input_desc);
                   1354:   input_desc = 0;
                   1355:   input_file = 0;
                   1356: }
                   1357: 
                   1358: /* Open the input file specified by 'entry', and return a descriptor.
                   1359:    The open file is remembered; if the same file is opened twice in a row,
                   1360:    a new open is not actually done.  */
                   1361: 
                   1362: int
                   1363: file_open (entry)
                   1364:      register struct file_entry *entry;
                   1365: {
                   1366:   register int desc;
                   1367: 
                   1368:   if (entry->superfile)
                   1369:     return file_open (entry->superfile);
                   1370: 
                   1371:   if (entry == input_file)
                   1372:     return input_desc;
                   1373: 
                   1374:   if (input_file) file_close ();
                   1375: 
                   1376:   if (entry->search_dirs_flag)
                   1377:     {
                   1378:       register char **p = search_dirs;
                   1379:       int i;
                   1380: 
                   1381:       for (i = 0; i < n_search_dirs; i++)
                   1382:        {
                   1383:          register char *string
                   1384:            = concat (search_dirs[i], "/", entry->filename);
                   1385:          desc = open (string, O_RDONLY, 0);
                   1386:          if (desc > 0)
                   1387:            {
                   1388:              entry->filename = string;
                   1389:              entry->search_dirs_flag = 0;
                   1390:              break;
                   1391:            }
                   1392:          free (string);
                   1393:        }
                   1394:     }
                   1395:   else
                   1396:     desc = open (entry->filename, O_RDONLY, 0);
                   1397: 
                   1398:   if (desc > 0)
                   1399:     {
                   1400:       input_file = entry;
                   1401:       input_desc = desc;
                   1402:       return desc;
                   1403:     }
                   1404: 
                   1405:   perror_file (entry);
1.1.1.2   root     1406:   /* NOTREACHED */
1.1       root     1407: }
                   1408: 
                   1409: /* Print the filename of ENTRY on OUTFILE (a stdio stream),
                   1410:    and then a newline.  */
                   1411: 
1.1.1.2   root     1412: void
1.1       root     1413: prline_file_name (entry, outfile)
                   1414:      struct file_entry *entry;
                   1415:      FILE *outfile;
                   1416: {
                   1417:   print_file_name (entry, outfile);
                   1418:   fprintf (outfile, "\n");
                   1419: }
                   1420: 
                   1421: /* Print the filename of ENTRY on OUTFILE (a stdio stream).  */
                   1422: 
1.1.1.2   root     1423: void
1.1       root     1424: print_file_name (entry, outfile)
                   1425:      struct file_entry *entry;
                   1426:      FILE *outfile;
                   1427: {
                   1428:   if (entry->superfile)
                   1429:     {
                   1430:       print_file_name (entry->superfile, outfile);
                   1431:       fprintf (outfile, "(%s)", entry->filename);
                   1432:     }
                   1433:   else
                   1434:     fprintf (outfile, "%s", entry->filename);
                   1435: }
1.1.1.2   root     1436: 
                   1437: /* Return the filename of entry as a string (malloc'd for the purpose) */
                   1438: 
                   1439: char *
                   1440: get_file_name (entry)
                   1441:      struct file_entry *entry;
                   1442: {
                   1443:   char *result, *supfile;
                   1444:   if (entry->superfile)
                   1445:     {
                   1446:       supfile = get_file_name (entry->superfile);
                   1447:       result = (char *) xmalloc (strlen (supfile)
                   1448:                                 + strlen (entry->filename) + 3);
                   1449:       sprintf (result, "%s(%s)", supfile, entry->filename);
                   1450:       free (supfile);
                   1451:     }
                   1452:   else
                   1453:     {
                   1454:       result = (char *) xmalloc (strlen (entry->filename) + 1);
                   1455:       strcpy (result, entry->filename);
                   1456:     }
                   1457:   return result;
                   1458: }
1.1       root     1459: 
                   1460: /* Medium-level input routines for rel files.  */
                   1461: 
                   1462: /* Read a file's header into the proper place in the file_entry.
                   1463:    DESC is the descriptor on which the file is open.
                   1464:    ENTRY is the file's entry.  */
                   1465: 
                   1466: void
                   1467: read_header (desc, entry)
                   1468:      int desc;
                   1469:      register struct file_entry *entry;
                   1470: {
                   1471:   register int len;
1.1.1.3 ! root     1472:   struct exec *loc = (struct exec *) &entry->header;
1.1       root     1473: 
                   1474:   lseek (desc, entry->starting_offset, 0);
                   1475:   len = read (desc, loc, sizeof (struct exec));
                   1476:   if (len != sizeof (struct exec))
                   1477:     fatal_with_file ("failure reading header of ", entry);
                   1478:   if (N_BADMAG (*loc))
                   1479:     fatal_with_file ("bad magic number in ", entry);
                   1480: 
                   1481:   entry->header_read_flag = 1;
                   1482: }
                   1483: 
                   1484: /* Read the symbols of file ENTRY into core.
                   1485:    Assume it is already open, on descriptor DESC.
                   1486:    Also read the length of the string table, which follows the symbol table,
                   1487:    but don't read the contents of the string table.  */
                   1488: 
                   1489: void
                   1490: read_entry_symbols (desc, entry)
                   1491:      struct file_entry *entry;
                   1492:      int desc;
                   1493: {
                   1494:   int str_size;
                   1495: 
                   1496:   if (!entry->header_read_flag)
                   1497:     read_header (desc, entry);
                   1498: 
                   1499:   entry->symbols = (struct nlist *) xmalloc (entry->header.a_syms);
                   1500: 
                   1501:   lseek (desc, N_SYMOFF (entry->header) + entry->starting_offset, 0);
                   1502:   if (entry->header.a_syms != read (desc, entry->symbols, entry->header.a_syms))
                   1503:     fatal_with_file ("premature end of file in symbols of ", entry);
                   1504: 
                   1505:   lseek (desc, N_STROFF (entry->header) + entry->starting_offset, 0);
                   1506:   if (sizeof str_size != read (desc, &str_size, sizeof str_size))
                   1507:     fatal_with_file ("bad string table size in ", entry);
                   1508: 
                   1509:   entry->string_size = str_size;
                   1510: }
                   1511: 
                   1512: /* Read the string table of file ENTRY into core.
                   1513:    Assume it is already open, on descriptor DESC.
                   1514:    Also record whether a GDB symbol segment follows the string table.  */
                   1515: 
                   1516: void
                   1517: read_entry_strings (desc, entry)
                   1518:      struct file_entry *entry;
                   1519:      int desc;
                   1520: {
                   1521:   int buffer;
                   1522: 
                   1523:   if (!entry->header_read_flag)
                   1524:     read_header (desc, entry);
                   1525: 
                   1526:   lseek (desc, N_STROFF (entry->header) + entry->starting_offset, 0);
                   1527:   if (entry->string_size != read (desc, entry->strings, entry->string_size))
                   1528:     fatal_with_file ("premature end of file in strings of ", entry);
                   1529: 
                   1530:   /* While we are here, see if the file has a symbol segment at the end.
                   1531:      For a separate file, just try reading some more.
                   1532:      For a library member, compare current pos against total size.  */
                   1533:   if (entry->superfile)
                   1534:     {
                   1535:       if (entry->total_size == N_STROFF (entry->header) + entry->string_size)
                   1536:        return;
                   1537:     }
                   1538:   else
                   1539:     {
                   1540:       buffer = read (desc, &buffer, sizeof buffer);
                   1541:       if (buffer == 0)
                   1542:        return;
                   1543:       if (buffer != sizeof buffer)
                   1544:        fatal_with_file ("premature end of file in GDB symbol segment of ", entry);
                   1545:     }
                   1546: 
                   1547:   entry->symseg_offset = N_STROFF (entry->header) + entry->string_size;
                   1548: }
                   1549: 
                   1550: /* Read in the symbols of all input files.  */
                   1551: 
                   1552: void read_file_symbols (), read_entry_symbols (), read_entry_strings ();
                   1553: void enter_file_symbols (), enter_global_ref (), search_library ();
                   1554: 
                   1555: void
                   1556: load_symbols ()
                   1557: {
                   1558:   register int i;
                   1559: 
                   1560:   if (trace_files) fprintf (stderr, "Loading symbols:\n\n");
                   1561: 
                   1562:   for (i = 0; i < number_of_files; i++)
                   1563:     {
                   1564:       register struct file_entry *entry = &file_table[i];
                   1565:       read_file_symbols (entry);
                   1566:     }
                   1567: 
                   1568:   if (trace_files) fprintf (stderr, "\n");
                   1569: }
                   1570: 
                   1571: /* If ENTRY is a rel file, read its symbol and string sections into core.
                   1572:    If it is a library, search it and load the appropriate members
                   1573:    (which means calling this function recursively on those members).  */
                   1574: 
                   1575: void
                   1576: read_file_symbols (entry)
                   1577:      register struct file_entry *entry;
                   1578: {
                   1579:   register int desc;
                   1580:   register int len;
                   1581:   int magicnum;
                   1582: 
                   1583:   desc = file_open (entry);
                   1584: 
                   1585:   len = read (desc, &magicnum, sizeof magicnum);
                   1586:   if (len != sizeof magicnum)
                   1587:     fatal_with_file ("failure reading header of ", entry);
                   1588: 
                   1589:   if (!N_BADMAG (*((struct exec *)&magicnum)))
                   1590:     {
                   1591:       read_entry_symbols (desc, entry);
                   1592:       entry->strings = (char *) alloca (entry->string_size);
                   1593:       read_entry_strings (desc, entry);
                   1594:       enter_file_symbols (entry);
                   1595:       entry->strings = 0;
                   1596:     }
                   1597:   else
                   1598:     {
                   1599:       char armag[SARMAG];
                   1600: 
                   1601:       lseek (desc, 0, 0);
                   1602:       if (SARMAG != read (desc, armag, SARMAG) || strncmp (armag, ARMAG, SARMAG))
                   1603:        fatal_with_file ("malformed input file (not rel or archive) ", entry);
                   1604:       entry->library_flag = 1;
                   1605:       search_library (desc, entry);
                   1606:     }
                   1607: 
                   1608:   file_close ();
                   1609: }
                   1610: 
                   1611: /* Enter the external symbol defs and refs of ENTRY in the hash table.  */
                   1612: 
                   1613: void
                   1614: enter_file_symbols (entry)
                   1615:      struct file_entry *entry;
                   1616: {
1.1.1.3 ! root     1617:    register struct nlist
        !          1618:      *p,
        !          1619:      *end = entry->symbols + entry->header.a_syms / sizeof (struct nlist);
1.1.1.2   root     1620:    int lowest_set_vector = -1;
1.1       root     1621: 
                   1622:   if (trace_files) prline_file_name (entry, stderr);
                   1623: 
                   1624:   for (p = entry->symbols; p < end; p++)
1.1.1.2   root     1625: #if 0
                   1626:     /* Currently N_SETV symbols shouldn't be in input to the loader, */
                   1627:     /* but I'll leave this here in case they ever are */
                   1628:     if ((p->n_type & ~N_EXT) == N_SETV &&
                   1629:        (lowest_set_vector = -1 || lowest_set_vector > p->n_value))
                   1630:       lowest_set_vector = p->n_value;
                   1631:     else
                   1632: #endif
                   1633:     if (SET_ELEMENT_P (p->n_type))
                   1634:       {
                   1635:        set_symbol_count++;
                   1636:        if (!relocatable_output)
                   1637:          enter_global_ref (p, p->n_un.n_strx + entry->strings, entry);
                   1638:       }
1.1.1.3 ! root     1639:     else if (p->n_type == N_WARNING)
        !          1640:       {
        !          1641:        char *name = p->n_un.n_strx + entry->strings;
        !          1642:        
        !          1643:        entry->warning = (char *) xmalloc (strlen(name) + 1);
        !          1644:        strcpy (entry->warning, name);
        !          1645:        warning_count++;
        !          1646:       }
1.1.1.2   root     1647:     else if (p->n_type & N_EXT)
1.1       root     1648:       enter_global_ref (p, p->n_un.n_strx + entry->strings, entry);
                   1649:     else if (p->n_un.n_strx && !(p->n_type & (N_STAB | N_EXT)))
                   1650:       {
                   1651:        if ((p->n_un.n_strx + entry->strings)[0] != 'L')
                   1652:          non_L_local_sym_count++;
                   1653:        local_sym_count++;
                   1654:       }
                   1655:     else debugger_sym_count++;
                   1656: 
1.1.1.3 ! root     1657: #if 0
1.1.1.2   root     1658:   entry->set_vector_offset = lowest_set_vector;
                   1659: #endif
                   1660: 
1.1       root     1661:    /* Count one for the local symbol that we generate,
                   1662:       whose name is the file's name (usually) and whose address
                   1663:       is the start of the file's text.  */
                   1664: 
                   1665:   local_sym_count++;
                   1666:   non_L_local_sym_count++;
                   1667: }
                   1668: 
                   1669: /* Enter one global symbol in the hash table.
                   1670:    NLIST_P points to the `struct nlist' read from the file
                   1671:    that describes the global symbol.  NAME is the symbol's name.
                   1672:    ENTRY is the file entry for the file the symbol comes from.
                   1673: 
                   1674:    The `struct nlist' is modified by placing it on a chain of
                   1675:    all such structs that refer to the same global symbol.
                   1676:    This chain starts in the `refs' field of the symbol table entry
                   1677:    and is chained through the `n_name'.  */
                   1678: 
                   1679: void
                   1680: enter_global_ref (nlist_p, name, entry)
                   1681:      register struct nlist *nlist_p;
                   1682:      char *name;
                   1683:      struct file_entry *entry;
                   1684: {
                   1685:   register symbol *sp = getsym (name);
                   1686:   register int type = nlist_p->n_type;
                   1687:   int oldref = sp->referenced;
                   1688:   int olddef = sp->defined;
                   1689: 
                   1690:   nlist_p->n_un.n_name = (char *) sp->refs;
                   1691:   sp->refs = nlist_p;
                   1692: 
                   1693:   sp->referenced = 1;
                   1694:   if (type != (N_UNDF | N_EXT) || nlist_p->n_value)
                   1695:     {
                   1696:       sp->defined = 1;
1.1.1.3 ! root     1697:       if (oldref && !olddef)
        !          1698:        undefined_global_sym_count--;
1.1       root     1699:       /* If this is a common definition, keep track of largest
                   1700:         common definition seen for this symbol.  */
                   1701:       if (type == (N_UNDF | N_EXT)
                   1702:          && sp->max_common_size < nlist_p->n_value)
                   1703:        sp->max_common_size = nlist_p->n_value;
1.1.1.2   root     1704:       if (SET_ELEMENT_P (type) && !olddef)
                   1705:        set_vector_count++;
                   1706:       /* Indirect symbols value should be modified to point
                   1707:         a symbol being equivalenced to. */
                   1708:       if (type == (N_INDR | N_EXT))
                   1709:        {
                   1710:          nlist_p->n_value =
                   1711:            (unsigned int) getsym ((nlist_p + 1)->n_un.n_strx
                   1712:                                   + entry->strings);
                   1713:          global_indirect_count++;
                   1714:        }
1.1       root     1715:     }
                   1716:   else
1.1.1.3 ! root     1717:     if (!oldref)
        !          1718: #ifndef DOLLAR_KLUDGE
        !          1719:       undefined_global_sym_count++;
        !          1720: #else
        !          1721:       {
        !          1722:        if (entry->superfile && type == (N_UNDF | N_EXT) && name[1] == '$')
        !          1723:          {
        !          1724:            /* This is an (ISI?) $-conditional; skip it */
        !          1725:            sp->referenced = 0;
        !          1726:            if (sp->trace)
        !          1727:              {
        !          1728:                fprintf (stderr, "symbol %s is a $-conditional ignored in ", sp->name);
        !          1729:                print_file_name (entry, stderr);
        !          1730:                fprintf (stderr, "\n");
        !          1731:              }
        !          1732:            return;
        !          1733:          }
        !          1734:        else
        !          1735:          undefined_global_sym_count++;
        !          1736:       }
        !          1737: #endif
1.1       root     1738: 
                   1739:   if (sp == end_symbol && entry->just_syms_flag && !T_flag_specified)
                   1740:     text_start = nlist_p->n_value;
                   1741: 
                   1742:   if (sp->trace)
                   1743:     {
                   1744:       register char *reftype;
                   1745:       switch (type & N_TYPE)
                   1746:        {
                   1747:        case N_UNDF:
                   1748:          if (nlist_p->n_value)
                   1749:            reftype = "defined as common";
                   1750:          else reftype = "referenced";
                   1751:          break;
                   1752: 
                   1753:        case N_ABS:
                   1754:          reftype = "defined as absolute";
                   1755:          break;
                   1756: 
                   1757:        case N_TEXT:
                   1758:          reftype = "defined in text section";
                   1759:          break;
                   1760: 
                   1761:        case N_DATA:
                   1762:          reftype = "defined in data section";
                   1763:          break;
                   1764: 
                   1765:        case N_BSS:
                   1766:          reftype = "defined in BSS section";
                   1767:          break;
1.1.1.2   root     1768: 
                   1769:        case N_SETT:
                   1770:          reftype = "is a text set element";
                   1771:          break;
1.1.1.3 ! root     1772: 
1.1.1.2   root     1773:        case N_SETD:
                   1774:          reftype = "is a data set element";
                   1775:          break;
1.1.1.3 ! root     1776: 
1.1.1.2   root     1777:        case N_SETB:
                   1778:          reftype = "is a BSS set element";
                   1779:          break;
1.1.1.3 ! root     1780: 
1.1.1.2   root     1781:        case N_SETA:
                   1782:          reftype = "is an absolute set element";
                   1783:          break;
                   1784: 
                   1785:        case N_SETV:
                   1786:          reftype = "defined in text section as vector";
                   1787:          break;
1.1.1.3 ! root     1788: 
1.1.1.2   root     1789:        case N_INDR:
                   1790:          reftype = (char *) alloca (23
                   1791:                                     + strlen ((nlist_p + 1)->n_un.n_strx
                   1792:                                               + entry->strings));
                   1793:          sprintf (reftype, "defined equivalent to %s",
                   1794:                   (nlist_p + 1)->n_un.n_strx + entry->strings);
                   1795:          break;
1.1       root     1796:        }
                   1797: 
                   1798:       fprintf (stderr, "symbol %s %s in ", sp->name, reftype);
                   1799:       print_file_name (entry, stderr);
                   1800:       fprintf (stderr, "\n");
                   1801:     }
                   1802: }
1.1.1.2   root     1803: 
                   1804: /* This return 0 if the given file entry's symbol table does *not*
                   1805:    contain the nlist point entry, and it returns the files entry
                   1806:    pointer (cast to unsigned long) if it does. */
                   1807: 
                   1808: unsigned long
                   1809: contains_symbol (entry, n_ptr)
                   1810:      struct file_entry *entry;
                   1811:      register struct nlist *n_ptr;
                   1812: {
                   1813:   if (n_ptr >= entry->symbols &&
                   1814:       n_ptr < (entry->symbols
                   1815:               + (entry->header.a_syms / sizeof (struct nlist))))
                   1816:     return (unsigned long) entry;
                   1817:   return 0;
                   1818: }
                   1819: 
1.1       root     1820: 
                   1821: /* Searching libraries */
                   1822: 
                   1823: struct file_entry *decode_library_subfile ();
                   1824: void linear_library (), symdef_library ();
                   1825: 
                   1826: /* Search the library ENTRY, already open on descriptor DESC.
                   1827:    This means deciding which library members to load,
                   1828:    making a chain of `struct file_entry' for those members,
                   1829:    and entering their global symbols in the hash table.  */
                   1830: 
                   1831: void
                   1832: search_library (desc, entry)
                   1833:      int desc;
                   1834:      struct file_entry *entry;
                   1835: {
                   1836:   int member_length;
                   1837:   register char *name;
                   1838:   register struct file_entry *subentry;
                   1839: 
                   1840:   if (!undefined_global_sym_count) return;
                   1841: 
                   1842:   /* Examine its first member, which starts SARMAG bytes in.  */
                   1843:   subentry = decode_library_subfile (desc, entry, SARMAG, &member_length);
                   1844:   if (!subentry) return;
                   1845: 
                   1846:   name = subentry->filename;
                   1847:   free (subentry);
                   1848: 
                   1849:   /* Search via __.SYMDEF if that exists, else linearly.  */
                   1850: 
                   1851:   if (!strcmp (name, "__.SYMDEF"))
                   1852:     symdef_library (desc, entry, member_length);
                   1853:   else
                   1854:     linear_library (desc, entry);
                   1855: }
                   1856: 
                   1857: /* Construct and return a file_entry for a library member.
                   1858:    The library's file_entry is library_entry, and the library is open on DESC.
                   1859:    SUBFILE_OFFSET is the byte index in the library of this member's header.
                   1860:    We store the length of the member into *LENGTH_LOC.  */
                   1861: 
                   1862: struct file_entry *
                   1863: decode_library_subfile (desc, library_entry, subfile_offset, length_loc)
                   1864:      int desc;
                   1865:      struct file_entry *library_entry;
                   1866:      int subfile_offset;
                   1867:      int *length_loc;
                   1868: {
                   1869:   int bytes_read;
                   1870:   register int namelen;
                   1871:   int member_length;
                   1872:   register char *name;
                   1873:   struct ar_hdr hdr1;
                   1874:   register struct file_entry *subentry;
                   1875: 
                   1876:   lseek (desc, subfile_offset, 0);
                   1877: 
                   1878:   bytes_read = read (desc, &hdr1, sizeof hdr1);
                   1879:   if (!bytes_read)
                   1880:     return 0;          /* end of archive */
                   1881: 
                   1882:   if (sizeof hdr1 != bytes_read)
                   1883:     fatal_with_file ("malformed library archive ", library_entry);
                   1884: 
                   1885:   if (sscanf (hdr1.ar_size, "%d", &member_length) != 1)
                   1886:     fatal_with_file ("malformatted header of archive member in ", library_entry);
                   1887: 
                   1888:   subentry = (struct file_entry *) xmalloc (sizeof (struct file_entry));
                   1889:   bzero (subentry, sizeof (struct file_entry));
                   1890: 
                   1891:   for (namelen = 0;
                   1892:        namelen < sizeof hdr1.ar_name
1.1.1.3 ! root     1893:        && hdr1.ar_name[namelen] != 0 && hdr1.ar_name[namelen] != ' '
        !          1894:        && hdr1.ar_name[namelen] != '/';
1.1       root     1895:        namelen++);
                   1896: 
                   1897:   name = (char *) xmalloc (namelen+1);
                   1898:   strncpy (name, hdr1.ar_name, namelen);
                   1899:   name[namelen] = 0;
                   1900: 
                   1901:   subentry->filename = name;
                   1902:   subentry->local_sym_name = name;
                   1903:   subentry->symbols = 0;
                   1904:   subentry->strings = 0;
                   1905:   subentry->subfiles = 0;
                   1906:   subentry->starting_offset = subfile_offset + sizeof hdr1;
                   1907:   subentry->superfile = library_entry;
                   1908:   subentry->library_flag = 0;
                   1909:   subentry->header_read_flag = 0;
                   1910:   subentry->just_syms_flag = 0;
                   1911:   subentry->chain = 0;
                   1912:   subentry->total_size = member_length;
                   1913: 
                   1914:   (*length_loc) = member_length;
                   1915: 
                   1916:   return subentry;
                   1917: }
                   1918: 
1.1.1.2   root     1919: int subfile_wanted_p ();
                   1920: 
1.1       root     1921: /* Search a library that has a __.SYMDEF member.
                   1922:    DESC is a descriptor on which the library is open.
                   1923:      The file pointer is assumed to point at the __.SYMDEF data.
                   1924:    ENTRY is the library's file_entry.
                   1925:    MEMBER_LENGTH is the length of the __.SYMDEF data.  */
                   1926: 
                   1927: void
                   1928: symdef_library (desc, entry, member_length)
                   1929:      int desc;
                   1930:      struct file_entry *entry;
                   1931:      int member_length;
                   1932: {
                   1933:   int *symdef_data = (int *) xmalloc (member_length);
                   1934:   register struct symdef *symdef_base;
                   1935:   char *sym_name_base;
                   1936:   int number_of_symdefs;
                   1937:   int length_of_strings;
                   1938:   int not_finished;
                   1939:   int bytes_read;
                   1940:   register int i;
                   1941:   struct file_entry *prev = 0;
                   1942:   int prev_offset = 0;
                   1943: 
                   1944:   bytes_read = read (desc, symdef_data, member_length);
                   1945:   if (bytes_read != member_length)
                   1946:     fatal_with_file ("malformatted __.SYMDEF in ", entry);
                   1947: 
                   1948:   number_of_symdefs = *symdef_data / sizeof (struct symdef);
                   1949:   if (number_of_symdefs < 0 ||
                   1950:        number_of_symdefs * sizeof (struct symdef) + 2 * sizeof (int) > member_length)
                   1951:     fatal_with_file ("malformatted __.SYMDEF in ", entry);
                   1952: 
                   1953:   symdef_base = (struct symdef *) (symdef_data + 1);
                   1954:   length_of_strings = *(int *) (symdef_base + number_of_symdefs);
                   1955: 
                   1956:   if (length_of_strings < 0
                   1957:       || number_of_symdefs * sizeof (struct symdef) + length_of_strings
                   1958:          + 2 * sizeof (int) != member_length)
                   1959:     fatal_with_file ("malformatted __.SYMDEF in ", entry);
                   1960: 
                   1961:   sym_name_base = sizeof (int) + (char *) (symdef_base + number_of_symdefs);
                   1962: 
                   1963:   /* Check all the string indexes for validity.  */
                   1964: 
                   1965:   for (i = 0; i < number_of_symdefs; i++)
                   1966:     {
                   1967:       register int index = symdef_base[i].symbol_name_string_index;
                   1968:       if (index < 0 || index >= length_of_strings
                   1969:          || (index && *(sym_name_base + index - 1)))
                   1970:        fatal_with_file ("malformatted __.SYMDEF in ", entry);
                   1971:     }
                   1972: 
                   1973:   /* Search the symdef data for members to load.
                   1974:      Do this until one whole pass finds nothing to load.  */
                   1975: 
                   1976:   not_finished = 1;
                   1977:   while (not_finished)
                   1978:     {
                   1979:       not_finished = 0;
                   1980: 
                   1981:       /* Scan all the symbols mentioned in the symdef for ones that we need.
                   1982:         Load the library members that contain such symbols.  */
                   1983: 
                   1984:       for (i = 0; i < number_of_symdefs && undefined_global_sym_count; i++)
                   1985:        if (symdef_base[i].symbol_name_string_index >= 0)
                   1986:          {
                   1987:            register symbol *sp;
                   1988: 
                   1989:            sp = getsym_soft (sym_name_base
                   1990:                              + symdef_base[i].symbol_name_string_index);
                   1991: 
                   1992:            /* If we find a symbol that appears to be needed, think carefully
                   1993:               about the archive member that the symbol is in.  */
                   1994: 
                   1995:            if (sp && sp->referenced && !sp->defined)
                   1996:              {
                   1997:                int junk;
                   1998:                register int j;
                   1999:                register int offset = symdef_base[i].library_member_offset;
                   2000:                struct file_entry *subentry;
                   2001: 
                   2002:                /* Don't think carefully about any archive member
                   2003:                   more than once in a given pass.  */
                   2004: 
                   2005:                if (prev_offset == offset)
                   2006:                  continue;
                   2007:                prev_offset = offset;
                   2008: 
                   2009:                /* Read the symbol table of the archive member.  */
                   2010: 
                   2011:                subentry = decode_library_subfile (desc, entry, offset, &junk);
                   2012:                read_entry_symbols (desc, subentry);
                   2013:                subentry->strings = (char *) malloc (subentry->string_size);
                   2014:                read_entry_strings (desc, subentry);
                   2015: 
                   2016:                /* Now scan the symbol table and decide whether to load.  */
                   2017: 
                   2018:                if (!subfile_wanted_p (subentry))
                   2019:                  {
                   2020:                    free (subentry->symbols);
                   2021:                    free (subentry);
                   2022:                  }
                   2023:                else
                   2024:                  {
                   2025:                    /* This member is needed; load it.
                   2026:                       Since we are loading something on this pass,
                   2027:                       we must make another pass through the symdef data.  */
                   2028: 
                   2029:                    not_finished = 1;
                   2030: 
                   2031:                    enter_file_symbols (subentry);
                   2032: 
                   2033:                    if (prev)
                   2034:                      prev->chain = subentry;
                   2035:                    else entry->subfiles = subentry;
                   2036:                    prev = subentry;
                   2037: 
                   2038:                    /* Clear out this member's symbols from the symdef data
                   2039:                       so that following passes won't waste time on them.  */
                   2040: 
                   2041:                    for (j = 0; j < number_of_symdefs; j++)
                   2042:                      {
                   2043:                        if (symdef_base[j].library_member_offset == offset)
                   2044:                          symdef_base[j].symbol_name_string_index = -1;
                   2045:                      }
                   2046:                  }
                   2047: 
                   2048:                /* We'll read the strings again if we need them again.  */
                   2049:                free (subentry->strings);
                   2050:              }
                   2051:          }
                   2052:     }
                   2053: 
                   2054:   free (symdef_data);
                   2055: }
                   2056: 
                   2057: /* Search a library that has no __.SYMDEF.
                   2058:    ENTRY is the library's file_entry.
                   2059:    DESC is the descriptor it is open on.  */
                   2060: 
                   2061: void
                   2062: linear_library (desc, entry)
                   2063:      int desc;
                   2064:      struct file_entry *entry;
                   2065: {
                   2066:   register struct file_entry *prev = 0;
                   2067:   register int this_subfile_offset = SARMAG;
                   2068: 
                   2069:   while (undefined_global_sym_count)
                   2070:     {
                   2071:       int member_length;
                   2072:       register struct file_entry *subentry;
                   2073: 
                   2074:       subentry = decode_library_subfile (desc, entry, this_subfile_offset, &member_length);
                   2075: 
                   2076:       if (!subentry) return;
                   2077: 
                   2078:       read_entry_symbols (desc, subentry);
                   2079:       subentry->strings = (char *) alloca (subentry->string_size);
                   2080:       read_entry_strings (desc, subentry);
                   2081: 
                   2082:       if (!subfile_wanted_p (subentry))
                   2083:        {
                   2084:          free (subentry->symbols);
                   2085:          free (subentry);
                   2086:        }
                   2087:       else
                   2088:        {
                   2089:          enter_file_symbols (subentry);
                   2090: 
                   2091:          if (prev)
                   2092:            prev->chain = subentry;
                   2093:          else entry->subfiles = subentry;
                   2094:          prev = subentry;
                   2095:        }
                   2096: 
                   2097:       this_subfile_offset += member_length + sizeof (struct ar_hdr);
                   2098:       if (this_subfile_offset & 1) this_subfile_offset++;
                   2099:     }
                   2100: }
                   2101: 
                   2102: /* ENTRY is an entry for a library member.
                   2103:    Its symbols have been read into core, but not entered.
                   2104:    Return nonzero if we ought to load this member.  */
                   2105: 
                   2106: int
                   2107: subfile_wanted_p (entry)
                   2108:      struct file_entry *entry;
                   2109: {
                   2110:   register struct nlist *p;
                   2111:   register struct nlist *end
                   2112:     = entry->symbols + entry->header.a_syms / sizeof (struct nlist);
1.1.1.3 ! root     2113: #ifdef DOLLAR_KLUDGE
        !          2114:   register int dollar_cond = 0;
        !          2115: #endif
1.1       root     2116: 
                   2117:   for (p = entry->symbols; p < end; p++)
                   2118:     {
                   2119:       register int type = p->n_type;
1.1.1.3 ! root     2120:       register char *name = p->n_un.n_strx + entry->strings;
1.1       root     2121: 
1.1.1.3 ! root     2122:       if (type & N_EXT && (type != (N_UNDF | N_EXT) || p->n_value
        !          2123: #ifdef DOLLAR_KLUDGE
        !          2124:                           || name[1] == '$'
        !          2125: #endif
        !          2126:                           ))
1.1       root     2127:        {
                   2128:          register symbol *sp = getsym_soft (name);
                   2129: 
1.1.1.3 ! root     2130: #ifdef DOLLAR_KLUDGE
        !          2131:          if (name[1] == '$')
        !          2132:            {
        !          2133:              sp = getsym_soft (&name[2]);
        !          2134:              dollar_cond = 1;
        !          2135:              if (!sp) continue;
        !          2136:              if (sp->referenced)
        !          2137:                {
        !          2138:                  if (write_map)
        !          2139:                    {
        !          2140:                      print_file_name (entry, stdout);
        !          2141:                      fprintf (stdout, " needed due to $-conditional %s\n", name);
        !          2142:                    }
        !          2143:                  return 1;
        !          2144:                }
        !          2145:              continue;
        !          2146:            }
        !          2147: #endif
        !          2148: 
1.1       root     2149:          /* If this symbol has not been hashed, we can't be looking for it. */
                   2150: 
                   2151:          if (!sp) continue;
                   2152: 
                   2153:          if (sp->referenced && !sp->defined)
                   2154:            {
                   2155:              /* This is a symbol we are looking for.  */
1.1.1.3 ! root     2156: #ifdef DOLLAR_KLUDGE
        !          2157:              if (dollar_cond) continue;
        !          2158: #endif
1.1       root     2159:              if (type == (N_UNDF | N_EXT))
                   2160:                {
                   2161:                  /* Symbol being defined as common.
                   2162:                     Remember this, but don't load subfile just for this.  */
                   2163: 
                   2164:                  if (sp->max_common_size < p->n_value)
                   2165:                    sp->max_common_size = p->n_value;
                   2166:                  if (!sp->defined)
                   2167:                    undefined_global_sym_count--;
                   2168:                  sp->defined = 1;
                   2169:                  continue;
                   2170:                }
                   2171: 
                   2172:              if (write_map)
                   2173:                {
                   2174:                  print_file_name (entry, stdout);
                   2175:                  fprintf (stdout, " needed due to %s\n", sp->name);
                   2176:                }
                   2177:              return 1;
                   2178:            }
                   2179:        }
                   2180:     }
                   2181: 
                   2182:   return 0;
                   2183: }
                   2184: 
                   2185: void consider_file_section_lengths (), relocate_file_addresses ();
1.1.1.2   root     2186: void print_files_defining_symbol ();
1.1       root     2187: 
                   2188: /* Having entered all the global symbols and found the sizes of sections
                   2189:    of all files to be linked, make all appropriate deductions from this data.
                   2190: 
                   2191:    We propagate global symbol values from definitions to references.
                   2192:    We compute the layout of the output file and where each input file's
                   2193:    contents fit into it.  */
                   2194: 
                   2195: void
                   2196: digest_symbols ()
                   2197: {
                   2198:   register int i;
1.1.1.2   root     2199:   int setv_fill_count;
1.1       root     2200: 
                   2201:   if (trace_files)
                   2202:     fprintf (stderr, "Digesting symbol information:\n\n");
                   2203: 
                   2204:   /* Compute total size of sections */
                   2205: 
                   2206:   each_file (consider_file_section_lengths, 0);
                   2207: 
1.1.1.2   root     2208:   /* Setup the set element vector */
                   2209: 
                   2210:   if (!relocatable_output)
                   2211:     {
                   2212:       set_sect_size =
                   2213:        (set_symbol_count + set_vector_count) * sizeof (unsigned long);
1.1.1.3 ! root     2214:       set_sect_start = text_start + text_size;
1.1.1.2   root     2215:       text_size += set_sect_size;
                   2216:       set_vectors = (unsigned long *) xmalloc (set_sect_size);
                   2217:       setv_fill_count = 0;
                   2218:     }
1.1       root     2219:   /* If necessary, pad text section to full page in the file.
                   2220:      Include the padding in the text segment size.  */
                   2221: 
                   2222:   if (magic == NMAGIC || magic == ZMAGIC)
                   2223:     {
                   2224:       int text_end = text_size + N_TXTOFF (outheader);
                   2225:       text_pad = ((text_end + page_size - 1) & (- page_size)) - text_end;
                   2226:       text_size += text_pad;
                   2227:     }
                   2228: 
                   2229:   outheader.a_text = text_size;
                   2230: 
                   2231:   /* Make the data segment address start in memory on a suitable boundary.  */
                   2232: 
                   2233:   if (! Tdata_flag_specified)
                   2234:     data_start = N_DATADDR (outheader) + text_start - N_TXTADDR (outheader);
                   2235: 
                   2236:   /* Compute start addresses of each file's sections and symbols.  */
                   2237: 
                   2238:   each_full_file (relocate_file_addresses, 0);
                   2239: 
                   2240:   /* Now, for each symbol, verify that it is defined globally at most once.
                   2241:      Put the global value into the symbol entry.
                   2242:      Common symbols are allocated here, in the BSS section.
                   2243:      Each defined symbol is given a '->defined' field
                   2244:       which is the correct N_ code for its definition,
                   2245:       except in the case of common symbols with -r.
                   2246:      Then make all the references point at the symbol entry
                   2247:      instead of being chained together. */
                   2248: 
                   2249:   defined_global_sym_count = 0;
                   2250: 
                   2251:   for (i = 0; i < TABSIZE; i++)
                   2252:     {
                   2253:       register symbol *sp;
                   2254:       for (sp = symtab[i]; sp; sp = sp->link)
                   2255:        {
1.1.1.3 ! root     2256:          /* For each symbol */
1.1       root     2257:          register struct nlist *p, *next;
                   2258:          int defs = 0, com = sp->max_common_size, erred = 0;
1.1.1.2   root     2259:          struct nlist *first_definition;
1.1       root     2260:          for (p = sp->refs; p; p = next)
                   2261:            {
                   2262:              register int type = p->n_type;
1.1.1.2   root     2263: 
                   2264: #if 0
                   2265:              if ((type & ~N_EXT) == N_SETV) continue;
                   2266: #endif
                   2267:              if (SET_ELEMENT_P (type))
                   2268:                {
                   2269:                  if (relocatable_output)
                   2270:                    fatal ("internal: global ref to set element with -r");
                   2271:                  if (!defs++)
                   2272:                    {
                   2273:                      sp->value = set_sect_start
                   2274:                        + setv_fill_count++ * sizeof (unsigned long);
                   2275:                      sp->defined = N_SETV | N_EXT;
                   2276:                      first_definition = p;
                   2277:                    }
                   2278:                  else if ((sp->defined & ~N_EXT) != N_SETV)
                   2279:                    {
                   2280:                      make_executable = 0;
1.1.1.3 ! root     2281:                      error ("text symbol `%s' redefined as set vector.  Files:",
1.1.1.2   root     2282:                             sp->name);
                   2283:                      print_files_defining_symbol (first_definition, p);
                   2284:                    }
                   2285:                  set_vectors[setv_fill_count++] = p->n_value;
                   2286:                }
                   2287:              else if ((type & N_EXT) && type != (N_UNDF | N_EXT))
1.1       root     2288:                {
                   2289:                  /* non-common definition */
                   2290:                  if (defs++ && sp->value != p->n_value)
                   2291:                    if (!erred++)
                   2292:                      {
                   2293:                        make_executable = 0;
1.1.1.3 ! root     2294:                        error ("multiple definitions of symbol `%s'.  Files:",
1.1.1.2   root     2295:                               sp->name);
                   2296:                        print_files_defining_symbol (first_definition, p);
1.1       root     2297:                      }
                   2298:                  sp->value = p->n_value;
                   2299:                  sp->defined = type;
1.1.1.2   root     2300:                  first_definition = p;
1.1       root     2301:                }
                   2302:              next = (struct nlist *) p->n_un.n_name;
                   2303:              p->n_un.n_name = (char *) sp;
                   2304:            }
                   2305:          /* Allocate as common if defined as common and not defined for real */
                   2306:          if (com && !defs)
                   2307:            {
                   2308:              if (!relocatable_output || force_common_definition)
                   2309:                {
                   2310:                  com = (com + sizeof (int) - 1) & (- sizeof (int));
1.1.1.3 ! root     2311: 
1.1       root     2312:                  sp->value = data_start + data_size + bss_size;
                   2313:                  sp->defined = N_BSS | N_EXT;
                   2314:                  bss_size += com;
                   2315:                  if (write_map)
                   2316:                    printf ("Allocating common %s: %x at %x\n",
                   2317:                            sp->name, com, sp->value);
                   2318:                }
1.1.1.2   root     2319:              else
                   2320:                {
                   2321:                  sp->defined = 0;
                   2322:                  undefined_global_sym_count++;
                   2323:                }
1.1       root     2324:            }
1.1.1.2   root     2325:          /* Set length word at front of vector */
                   2326:          if ((sp->defined & ~N_EXT) == N_SETV)
                   2327:            {
                   2328:              unsigned long length_word_index =
                   2329:                (sp->value - set_sect_start) / sizeof (unsigned long);
1.1.1.3 ! root     2330: 
1.1.1.2   root     2331:              set_vectors[length_word_index] = setv_fill_count - 1 - length_word_index;
1.1.1.3 ! root     2332:            }
1.1       root     2333:          if (sp->defined)
                   2334:            defined_global_sym_count++;
                   2335:        }
                   2336:     }
                   2337: 
                   2338:   if (end_symbol)              /* These are null if -r.  */
                   2339:     {
                   2340:       etext_symbol->value = text_size + text_start;
                   2341:       edata_symbol->value = data_start + data_size;
                   2342:       end_symbol->value = data_start + data_size + bss_size;
                   2343:     }
                   2344: 
                   2345:   /* Figure the data_pad now, so that it overlaps with the bss addresses.  */
                   2346: 
                   2347:   if (specified_data_size && specified_data_size > data_size)
                   2348:     data_pad = specified_data_size - data_size;
                   2349: 
                   2350:   if (magic == ZMAGIC)
                   2351:     data_pad = ((data_pad + data_size + page_size - 1) & (- page_size))
                   2352:                - data_size;
                   2353: 
                   2354:   bss_size -= data_pad;
                   2355:   if (bss_size < 0) bss_size = 0;
                   2356: 
                   2357:   data_size += data_pad;
                   2358: }
                   2359: 
                   2360: /* Accumulate the section sizes of input file ENTRY
                   2361:    into the section sizes of the output file.  */
                   2362: 
                   2363: void
                   2364: consider_file_section_lengths (entry)
                   2365:      register struct file_entry *entry;
                   2366: {
                   2367:   if (entry->just_syms_flag)
                   2368:     return;
                   2369: 
                   2370:   entry->text_start_address = text_size;
1.1.1.2   root     2371:   /* If there were any vectors, we need to chop them off */
                   2372: #if 0
                   2373:   /* There should never be set vectors in input to the loader */
                   2374:   if (entry->set_vector_offset == -1)
                   2375: #endif
1.1       root     2376:   text_size += entry->header.a_text;
1.1.1.2   root     2377: #if 0
                   2378:   else
                   2379:     text_size += entry->set_vector_offset - N_TXTOFF (entry->header);
                   2380: #endif
1.1       root     2381:   entry->data_start_address = data_size;
                   2382:   data_size += entry->header.a_data;
                   2383:   entry->bss_start_address = bss_size;
                   2384:   bss_size += entry->header.a_bss;
                   2385: 
                   2386:   text_reloc_size += entry->header.a_trsize;
                   2387:   data_reloc_size += entry->header.a_drsize;
                   2388: }
                   2389: 
                   2390: /* Determine where the sections of ENTRY go into the output file,
                   2391:    whose total section sizes are already known.
                   2392:    Also relocate the addresses of the file's local and debugger symbols.  */
                   2393: 
                   2394: void
                   2395: relocate_file_addresses (entry)
                   2396:      register struct file_entry *entry;
                   2397: {
                   2398:   entry->text_start_address += text_start;
                   2399:   /* Note that `data_start' and `data_size' have not yet been
                   2400:      adjusted for `data_pad'.  If they had been, we would get the wrong
                   2401:      results here.  */
                   2402:   entry->data_start_address += data_start;
                   2403:   entry->bss_start_address += data_start + data_size;
                   2404: 
                   2405:   {
                   2406:     register struct nlist *p;
                   2407:     register struct nlist *end
                   2408:       = entry->symbols + entry->header.a_syms / sizeof (struct nlist);
                   2409: 
                   2410:     for (p = entry->symbols; p < end; p++)
                   2411:       {
                   2412:        /* If this belongs to a section, update it by the section's start address */
                   2413:        register int type = p->n_type & N_TYPE;
                   2414: 
1.1.1.3 ! root     2415:        switch (type)
        !          2416:          {
        !          2417:          case N_TEXT:
        !          2418:          case N_SETV:
        !          2419:          case N_SETT:
        !          2420:            p->n_value += entry->text_start_address;
        !          2421:            break;
        !          2422:          case N_DATA:
        !          2423:          case N_SETD:
        !          2424:            /* A symbol whose value is in the data section
        !          2425:               is present in the input file as if the data section
        !          2426:               started at an address equal to the length of the file's text.  */
        !          2427:            p->n_value += entry->data_start_address - entry->header.a_text;
        !          2428:            break;
        !          2429:          case N_BSS:
        !          2430:          case N_SETB:
        !          2431:            /* likewise for symbols with value in BSS.  */
        !          2432:            p->n_value += entry->bss_start_address
        !          2433:              - entry->header.a_text - entry->header.a_data;
        !          2434:            break;
        !          2435:          }
1.1       root     2436:       }
                   2437:   }
                   2438: }
                   2439: 
                   2440: void describe_file_sections (), list_file_locals ();
                   2441: 
                   2442: /* Print a complete or partial map of the output file.  */
                   2443: 
                   2444: void
                   2445: print_symbols (outfile)
                   2446:      FILE *outfile;
                   2447: {
                   2448:   register int i;
                   2449: 
                   2450:   fprintf (outfile, "\nFiles:\n\n");
                   2451: 
                   2452:   each_file (describe_file_sections, outfile);
                   2453: 
                   2454:   fprintf (outfile, "\nGlobal symbols:\n\n");
                   2455: 
                   2456:   for (i = 0; i < TABSIZE; i++)
                   2457:     {
                   2458:       register symbol *sp;
                   2459:       for (sp = symtab[i]; sp; sp = sp->link)
                   2460:        {
                   2461:          if (sp->defined == 1)
                   2462:            fprintf (outfile, "  %s: common, length 0x%x\n", sp->name, sp->max_common_size);
                   2463:          if (sp->defined)
                   2464:            fprintf (outfile, "  %s: 0x%x\n", sp->name, sp->value);
                   2465:          else if (sp->referenced)
                   2466:            fprintf (outfile, "  %s: undefined\n", sp->name);
                   2467:        }
                   2468:     }
                   2469: 
                   2470:   each_file (list_file_locals, outfile);
                   2471: }
                   2472: 
                   2473: void
                   2474: describe_file_sections (entry, outfile)
                   2475:      struct file_entry *entry;
                   2476:      FILE *outfile;
                   2477: {
                   2478:   fprintf (outfile, "  ");
                   2479:   print_file_name (entry, outfile);
                   2480:   if (entry->just_syms_flag)
                   2481:     fprintf (outfile, " symbols only\n", 0);
                   2482:   else
                   2483:     fprintf (outfile, " text %x(%x), data %x(%x), bss %x(%x) hex\n",
                   2484:             entry->text_start_address, entry->header.a_text,
                   2485:             entry->data_start_address, entry->header.a_data,
                   2486:             entry->bss_start_address, entry->header.a_bss);
                   2487: }
                   2488: 
                   2489: void
                   2490: list_file_locals (entry, outfile)
                   2491:      struct file_entry *entry;
                   2492:      FILE *outfile;
                   2493: {
                   2494:   register struct nlist *p, *end = entry->symbols + entry->header.a_syms / sizeof (struct nlist);
                   2495: 
                   2496:   entry->strings = (char *) alloca (entry->string_size);
                   2497:   read_entry_strings (file_open (entry), entry);
                   2498: 
                   2499:   fprintf (outfile, "\nLocal symbols of ");
                   2500:   print_file_name (entry, outfile);
                   2501:   fprintf (outfile, ":\n\n");
                   2502: 
                   2503:   for (p = entry->symbols; p < end; p++)
1.1.1.3 ! root     2504:     /* If this is a definition,
1.1       root     2505:        update it if necessary by this file's start address.  */
                   2506:     if (!(p->n_type & (N_STAB | N_EXT)))
                   2507:       fprintf (outfile, "  %s: 0x%x\n",
                   2508:               entry->strings + p->n_un.n_strx, p->n_value);
                   2509: }
                   2510: 
1.1.1.3 ! root     2511: 
        !          2512: /* Static vars for do_warnings and subroutines of it */
        !          2513: int list_unresolved_refs;      /* List unresolved refs */
        !          2514: int list_warning_symbols;      /* List warning syms */
        !          2515: int list_multple_defs;         /* List multiple definitions */
1.1       root     2516: 
1.1.1.2   root     2517: /*
1.1.1.3 ! root     2518:  * Structure for communication between do_file_warnings and it's
1.1.1.2   root     2519:  * helper routines.  Will in practice be an array of three of these:
                   2520:  * 0) Current line, 1) Next line, 2) Source file info.
                   2521:  */
1.1.1.3 ! root     2522: struct line_debug_entry
        !          2523: {
1.1.1.2   root     2524:   int line;
                   2525:   char *filename;
                   2526:   struct nlist *sym;
                   2527: };
                   2528: 
                   2529: void qsort ();
                   2530: 
                   2531: struct line_debug_entry *init_debug_scan ();
                   2532: int next_debug_entry ();
                   2533: int address_to_line ();
                   2534: int relocation_entries_relation ();
                   2535: 
1.1.1.3 ! root     2536: /* Print on OUTFILE a list of all warnings generated by references
        !          2537:    and/or definitions in the file ENTRY.  List source file and line
        !          2538:    number if possible, just the .o file if not. */
1.1.1.2   root     2539: 
                   2540: void
1.1.1.3 ! root     2541: do_file_warnings (entry, outfile)
1.1.1.2   root     2542:      struct file_entry *entry;
                   2543:      FILE *outfile;
                   2544: {
                   2545:   struct relocation_info *txt_reloc, *data_reloc;
                   2546:   struct line_debug_entry *state_pointer;
                   2547:   register struct line_debug_entry *current, *next, *source;
1.1.1.3 ! root     2548:   char *errfmt;                                /* Assigned to generally */
        !          2549:                                        /* static values; should not */
        !          2550:                                        /* be written into */
        !          2551:   char *errmsg;                                /* Assigned to malloc'd values */
        !          2552:                                        /* and copied into; should be */
        !          2553:                                        /* freed when done */
        !          2554:   int invalidate_line_number;
1.1.1.2   root     2555: 
                   2556:   /* Read in the files strings if they aren't available */
1.1.1.3 ! root     2557:   if (!entry->strings)
        !          2558:     {
        !          2559:       int desc;
        !          2560: 
        !          2561:       entry->strings = (char *) alloca (entry->string_size);
        !          2562:       desc = file_open (entry);
        !          2563:       read_entry_strings (desc, entry);
        !          2564:     }
1.1.1.2   root     2565: 
                   2566:   state_pointer = init_debug_scan (0, entry);
                   2567:   current = state_pointer;
                   2568:   next = state_pointer + 1;
                   2569:   source = state_pointer + 2;
1.1.1.3 ! root     2570: 
1.1.1.2   root     2571:   read_file_relocation (entry);
                   2572: 
                   2573:   /* We need to sort the relocation info here.  Sheesh, so much effort
                   2574:      for one lousy error optimization. */
                   2575: 
                   2576:   qsort (entry->textrel,
                   2577:         entry->header.a_trsize/sizeof (struct relocation_info),
                   2578:         sizeof (struct relocation_info),
                   2579:         relocation_entries_relation);
                   2580: 
                   2581:   for (txt_reloc = entry->textrel;
                   2582:        txt_reloc < (entry->textrel
                   2583:                    + entry->header.a_trsize/sizeof (struct relocation_info));
                   2584:        txt_reloc++)
1.1       root     2585:     {
1.1.1.2   root     2586:       register struct nlist *s;
                   2587:       register symbol *g;
1.1.1.3 ! root     2588: 
        !          2589:       /* If the relocation isn't resolved through a symbol, continue */
        !          2590:       if (!RELOC_EXTERN_P(txt_reloc))
        !          2591:        continue;
        !          2592: 
        !          2593:       s = &(entry->symbols[RELOC_SYMBOL(txt_reloc)]);
        !          2594: 
        !          2595:       /* Local symbols shouldn't ever be used by relocation info, so
        !          2596:         the next should be safe.
        !          2597:         This is, of course, wrong.  References to local BSS symbols can be
        !          2598:         the targets of relocation info, and they can (must) be
        !          2599:         resolved through symbols.  However, these must be defined properly,
        !          2600:         (the compiler would have caught it otherwise), so we can
        !          2601:         ignore these cases.  */
        !          2602:       if (!(s->n_type & N_EXT))
        !          2603:        continue;
        !          2604: 
1.1.1.2   root     2605:       g = (symbol *) s->n_un.n_name;
1.1.1.3 ! root     2606: 
        !          2607:       if (!g->defined)                      /* Reference */
1.1       root     2608:        {
1.1.1.3 ! root     2609:          if (!list_unresolved_refs ||               /* Don't list any */
        !          2610:              g->undef_refs >= MAX_UREFS_PRINTED)    /* Listed too many */
        !          2611:            continue;
        !          2612: 
        !          2613:          /* Undefined symbol which we should mention */
        !          2614: 
        !          2615:          if (++(g->undef_refs) == MAX_UREFS_PRINTED)
1.1       root     2616:            {
1.1.1.3 ! root     2617:              errfmt = "More undefined symbol %s refs follow";
        !          2618:              invalidate_line_number = 1;
        !          2619:            }
        !          2620:          else
        !          2621:            {
        !          2622:              errfmt = "Undefined symbol %s referenced from text";
        !          2623:              invalidate_line_number = 0;
1.1       root     2624:            }
                   2625:        }
1.1.1.3 ! root     2626:       else                                          /* Defined */
        !          2627:        {
        !          2628:          /* Potential symbol warning here */
        !          2629:          if (!g->warning) continue;
        !          2630: 
        !          2631:          errfmt = g->warning;
        !          2632:          invalidate_line_number = 0;
        !          2633:        }
1.1.1.2   root     2634:       
1.1.1.3 ! root     2635:       errmsg = (char *) xmalloc (strlen (errfmt) + strlen (g->name) + 1);
        !          2636:       sprintf(errmsg, errfmt, g->name);
        !          2637:       address_to_line ( (RELOC_ADDRESS (txt_reloc)
        !          2638:                         + entry->text_start_address),
        !          2639:                       state_pointer);
        !          2640: 
        !          2641:       if (current->line >=0)
        !          2642:        fprintf (outfile, "%s:%d: %s\n", current->filename,
        !          2643:                 invalidate_line_number ? 0 : current->line, errmsg);
        !          2644:       else
        !          2645:        fprintf (outfile, "%s: %s\n", current->filename, errmsg);
        !          2646: 
        !          2647:       free (errmsg);
        !          2648:     }
        !          2649: 
1.1.1.2   root     2650:   free (state_pointer);
                   2651:   state_pointer = init_debug_scan (1, entry);
                   2652:   current = state_pointer;
                   2653:   next = state_pointer + 1;
                   2654:   source = state_pointer + 2;
                   2655: 
                   2656:   /*
                   2657:    * Once again, time to sort the relocation info.
                   2658:    */
                   2659: 
                   2660:   qsort (entry->datarel,
                   2661:         entry->header.a_drsize/sizeof (struct relocation_info),
                   2662:         sizeof (struct relocation_info),
                   2663:         relocation_entries_relation);
                   2664: 
                   2665:   for (data_reloc = entry->datarel;
                   2666:        data_reloc < (entry->datarel
                   2667:                     + entry->header.a_drsize/sizeof (struct relocation_info));
                   2668:        data_reloc++)
                   2669:     {
                   2670:       register struct nlist *s;
                   2671:       register symbol *g;
1.1.1.3 ! root     2672: 
        !          2673:       /* If the relocation isn't resolved through a symbol, continue */
        !          2674:       if (!RELOC_EXTERN_P(data_reloc))
        !          2675:        continue;
        !          2676: 
        !          2677:       s = &(entry->symbols[RELOC_SYMBOL(data_reloc)]);
1.1.1.2   root     2678:       g = (symbol *) s->n_un.n_name;
1.1.1.3 ! root     2679: 
        !          2680:       if (!g->defined)                      /* Reference */
1.1.1.2   root     2681:        {
1.1.1.3 ! root     2682:          if (!list_unresolved_refs ||               /* Don't list any */
        !          2683:              g->undef_refs >= MAX_UREFS_PRINTED)    /* Listed too many */
        !          2684:            continue;
        !          2685: 
        !          2686:          /* Undefined symbol which we should mention */
        !          2687: 
        !          2688:          if (++(g->undef_refs) == MAX_UREFS_PRINTED)
        !          2689:            {
        !          2690:              errfmt = "More undefined symbol %s refs follow";
        !          2691:              invalidate_line_number = 1;
        !          2692:            }
1.1.1.2   root     2693:          else
1.1.1.3 ! root     2694:            {
        !          2695:              errfmt = "Undefined symbol %s referenced from data";
        !          2696:              invalidate_line_number = 0;
        !          2697:            }
        !          2698:        }
        !          2699:       else                                          /* Defined */
        !          2700:        {
        !          2701:          /* Potential symbol warning here */
        !          2702:          if (!g->warning) continue;
        !          2703: 
        !          2704:          errfmt = g->warning;
        !          2705:          invalidate_line_number = 0;
1.1.1.2   root     2706:        }
1.1.1.3 ! root     2707:       
        !          2708:       errmsg = (char *) xmalloc (strlen (errfmt) + strlen (g->name) + 1);
        !          2709:       sprintf(errmsg, errfmt, g->name);
        !          2710:       address_to_line ( (RELOC_ADDRESS (data_reloc)
        !          2711:                         + entry->text_start_address),
        !          2712:                       state_pointer);
        !          2713: 
        !          2714:       if (current->line >=0)
        !          2715:        fprintf (outfile, "%s:%d: %s\n", current->filename,
        !          2716:                 invalidate_line_number ? 0 : current->line, errmsg);
        !          2717:       else
        !          2718:        fprintf (outfile, "%s: %s\n", current->filename, errmsg);
        !          2719: 
        !          2720:       free (errmsg);
1.1.1.2   root     2721:     }
                   2722: }
                   2723: /*
1.1.1.3 ! root     2724:  * Helper routines for do_file_warnings.
1.1.1.2   root     2725:  */
1.1       root     2726: 
1.1.1.2   root     2727: /*
                   2728:  * Return an integer less than, equal to, or greater than 0 as per the
                   2729:  * relation between the two relocation entries.
                   2730:  * Used by qsort.
                   2731:  */
                   2732: int
                   2733: relocation_entries_relation (rel1, rel2)
                   2734:      struct relocation_info *rel1, *rel2;
                   2735: {
1.1.1.3 ! root     2736:   return RELOC_ADDRESS(rel1) - RELOC_ADDRESS(rel2);
1.1       root     2737: }
1.1.1.2   root     2738: 
                   2739: /*
                   2740:  * Takes the values in state_pointer and moves onward to the next
                   2741:  * debug line symbol.  It assumes that state_pointer[1] is valid; ie
                   2742:  * that it.sym points into some entry in the symbol table.  If
                   2743:  * state_pointer[1].sym == 0, this routine should not be called.
                   2744:  */
                   2745: 
                   2746: int
                   2747: next_debug_entry (use_data_symbols, state_pointer)
                   2748:      register int use_data_symbols;
                   2749:      struct line_debug_entry state_pointer[3]; /* Must be passed by reference! */
                   2750: {
                   2751:   register struct line_debug_entry
                   2752:     *current = state_pointer,
                   2753:     *next = state_pointer + 1,
                   2754:     *source = state_pointer + 2; /* Used to store source file */
                   2755:   struct file_entry *entry = (struct file_entry *) source->sym;
                   2756: 
                   2757:   current->sym = next->sym;
                   2758:   current->line = next->line;
1.1.1.3 ! root     2759:   current->filename = next->filename;
1.1.1.2   root     2760: 
                   2761:   while (++(next->sym) < (entry->symbols
                   2762:                          + entry->header.a_syms/sizeof (struct nlist)))
                   2763:     {
1.1.1.3 ! root     2764:       switch (next->sym->n_type)
        !          2765:        {
1.1.1.2   root     2766:        case N_SLINE:
                   2767:          if (use_data_symbols) continue;
                   2768:          next->line = next->sym->n_desc;
                   2769:          return 1;
1.1.1.3 ! root     2770:        case N_DSLINE:
1.1.1.2   root     2771:          if (!use_data_symbols) continue;
                   2772:          next->line = next->sym->n_desc;
                   2773:          return 1;
1.1.1.3 ! root     2774: #ifdef HAVE_SUN_STABS
        !          2775:        case N_EINCL:
        !          2776:          next->filename = source->filename;
        !          2777:          continue;
        !          2778: #endif
        !          2779:        case N_SO:
1.1.1.2   root     2780:          source->filename = next->sym->n_un.n_strx + entry->strings;
                   2781:          source->line++;
1.1.1.3 ! root     2782: #ifdef HAVE_SUN_STABS
        !          2783:        case N_BINCL:
        !          2784: #endif
        !          2785:        case N_SOL:
        !          2786:          next->filename =
1.1.1.2   root     2787:            next->sym->n_un.n_strx + entry->strings;
1.1.1.3 ! root     2788:        default:
        !          2789:          continue;
        !          2790:        }
        !          2791:     }
1.1.1.2   root     2792:   next->sym = (struct nlist *) 0;
                   2793:   return 0;
                   2794: }
1.1.1.3 ! root     2795: 
1.1.1.2   root     2796: int
                   2797: address_to_line (address, state_pointer)
                   2798:      unsigned long address;
                   2799:      struct line_debug_entry state_pointer[3]; /* Must be passed by reference! */
                   2800: {
                   2801:   struct line_debug_entry
                   2802:     *current = state_pointer,
                   2803:     *next = state_pointer + 1;
1.1.1.3 ! root     2804: 
1.1.1.2   root     2805:   int use_data_symbols;
                   2806: 
                   2807:   if (next->sym)
                   2808:     use_data_symbols = (next->sym->n_type & N_TYPE) == N_DATA;
1.1.1.3 ! root     2809: 
1.1.1.2   root     2810:   while (next->sym
                   2811:         && next->sym->n_value < address
                   2812:         && next_debug_entry (use_data_symbols, state_pointer))
                   2813:     ;
                   2814:   return current->line;
                   2815: }
                   2816: 
                   2817: struct line_debug_entry *
                   2818: init_debug_scan (use_data_symbols, entry)
                   2819:      int use_data_symbols;
                   2820:      struct file_entry *entry;
                   2821: {
                   2822:   struct line_debug_entry
                   2823:     *state_pointer =
                   2824:       (struct line_debug_entry *) xmalloc (3 * sizeof (struct line_debug_entry));
                   2825:   register struct line_debug_entry
                   2826:     *current = state_pointer,
                   2827:     *next = state_pointer + 1,
                   2828:     *source = state_pointer + 2; /* Used to store source file */
                   2829: 
                   2830:   struct nlist *tmp;
                   2831: 
                   2832:   for (tmp = entry->symbols;
                   2833:        tmp < (entry->symbols
                   2834:              + entry->header.a_syms/sizeof (struct nlist));
                   2835:        tmp++)
1.1.1.3 ! root     2836:     if (tmp->n_type == (int) N_SO) break;
1.1.1.2   root     2837: 
                   2838:   if (tmp >= (entry->symbols
1.1.1.3 ! root     2839:              + entry->header.a_syms/sizeof (struct nlist)))
        !          2840:     {
        !          2841:       /* I believe this translates to "We lose" */
        !          2842:       current->filename = next->filename = entry->filename;
        !          2843:       current->line = next->line = -1;
        !          2844:       current->sym = next->sym = (struct nlist *) 0;
        !          2845:       return state_pointer;
        !          2846:     }
1.1.1.2   root     2847: 
                   2848:   next->line = source->line = 0;
1.1.1.3 ! root     2849:   next->filename = source->filename
        !          2850:     = (tmp->n_un.n_strx + entry->strings);
1.1.1.2   root     2851:   source->sym = (struct nlist *) entry;
                   2852:   next->sym = tmp;
                   2853: 
                   2854:   next_debug_entry (use_data_symbols, state_pointer); /* To setup next */
                   2855: 
                   2856:   if (!next->sym)              /* No line numbers for this section; */
                   2857:                                /* setup output results as appropriate */
                   2858:     {
                   2859:       if (source->line)
                   2860:        {
                   2861:          current->filename = source->filename = entry->filename;
                   2862:          current->line = -1;   /* Don't print lineno */
                   2863:        }
                   2864:       else
                   2865:        {
                   2866:          current->filename = source->filename;
                   2867:          current->line = 0;
                   2868:        }
                   2869:       return state_pointer;
                   2870:     }
1.1.1.3 ! root     2871: 
        !          2872: 
1.1.1.2   root     2873:   next_debug_entry (use_data_symbols, state_pointer); /* To setup current */
                   2874: 
                   2875:   return state_pointer;
                   2876: }
1.1.1.3 ! root     2877: 
        !          2878: void 
        !          2879: mark_flagged_symbols (entry, outfile)
        !          2880:      struct file_entry *entry;
        !          2881:      FILE *outfile;
        !          2882: {
        !          2883:   struct nlist *p;
1.1.1.2   root     2884:   
1.1.1.3 ! root     2885:   if (!entry->warning) return;
        !          2886: 
        !          2887:   for (p = entry->symbols;
        !          2888:        p < entry->symbols + (entry->header.a_syms / sizeof(struct nlist));
        !          2889:        p++)
        !          2890:     {
        !          2891:       unsigned char type = p->n_type;
        !          2892:       struct glosym *sym;
        !          2893:       
        !          2894:      /* Ignore locals and references */
        !          2895:       if (!(type & N_EXT) || type == N_EXT) continue;
        !          2896: 
        !          2897:       sym = (struct glosym *) p->n_un.n_name;
        !          2898:       if (sym->referenced)
        !          2899:        ((struct glosym *) p->n_un.n_name)->warning = entry->warning;
        !          2900:     }
        !          2901: }
        !          2902: 
        !          2903: do_warnings (outfile)
        !          2904:      FILE *outfile;
        !          2905: {
        !          2906:   struct glosym **clrefs;
        !          2907: 
        !          2908:   list_unresolved_refs = !relocatable_output && undefined_global_sym_count;
        !          2909:   list_warning_symbols = warning_count;
        !          2910:   list_multple_defs = 0;               /* Not currently done here */
        !          2911: 
        !          2912:   if (!(list_unresolved_refs ||
        !          2913:        list_warning_symbols ||
        !          2914:        list_multple_defs      ))
        !          2915:     /* No need to run this routine */
        !          2916:     return;
        !          2917: 
        !          2918:   if (list_warning_symbols)
        !          2919:     each_full_file (mark_flagged_symbols, outfile);
        !          2920: 
        !          2921:   each_full_file (do_file_warnings, outfile);
        !          2922: 
        !          2923:   if (!relocatable_output)
        !          2924:     for (clrefs = cmdline_references;
        !          2925:         clrefs < cmdline_references + cl_refs_allocated && *clrefs;
        !          2926:         clrefs++)
        !          2927:       if ((*clrefs)->referenced && !(*clrefs)->defined)
        !          2928:        fprintf(stderr, "Error: Unresolved reference to symbol %s\n",
        !          2929:                (*clrefs)->name);
        !          2930: 
        !          2931:   fprintf (outfile, "\n");
        !          2932: 
        !          2933:   if (list_unresolved_refs || list_multple_defs)
        !          2934:     make_executable = 0;
        !          2935: }
        !          2936: 
1.1.1.2   root     2937: /* Print the files which have the definitions for a given symbol.
                   2938:    FIRST_DEF is the first nlist entry which defines the symbol, and
                   2939:    REST_OF_REFS is a chain of nlist entries which may or may not be
                   2940:    definitions for this symbol, but which are all references for the
1.1.1.3 ! root     2941:    symbol.
1.1.1.2   root     2942: 
                   2943:    We do the job in this clumsy fashion because of the state our data
                   2944:    structures are in in the middle of digest_symbols (from which this
                   2945:    is called). */
                   2946: 
                   2947: void
                   2948: print_files_defining_symbol (first_def, rest_of_refs)
                   2949:      struct nlist *first_def, *rest_of_refs;
                   2950: {
                   2951:   struct file_entry *holder;
                   2952:   struct nlist *n_ptr;
1.1.1.3 ! root     2953: 
1.1.1.2   root     2954:   if (holder =
                   2955:       (struct file_entry *) check_each_file (contains_symbol, first_def))
                   2956:     {
                   2957:       fprintf (stderr, " ");
                   2958:       prline_file_name (holder, stderr);
                   2959:     }
                   2960:   else
                   2961:     fatal ("internal: file not found containing nlist entry");
                   2962: 
                   2963:   for (n_ptr = rest_of_refs;
                   2964:        n_ptr;
                   2965:        n_ptr = (struct nlist *) n_ptr->n_un.n_name)
                   2966:     if (n_ptr->n_type & ~N_EXT)
                   2967:       if (holder =
                   2968:          (struct file_entry *) check_each_file (contains_symbol, n_ptr))
                   2969:        {
                   2970:          fprintf (stderr, " ");
                   2971:          prline_file_name (holder, stderr);
                   2972:        }
                   2973:       else
                   2974:        fatal ("internal: file not found containing nlist entry");
                   2975: }
                   2976: 
1.1.1.3 ! root     2977: /* Write the output file */
1.1       root     2978: 
                   2979: void
                   2980: write_output ()
                   2981: {
                   2982:   struct stat statbuf;
                   2983:   int filemode;
                   2984: 
                   2985:   outdesc = open (output_filename, O_WRONLY | O_CREAT | O_TRUNC, 0666);
                   2986:   if (outdesc < 0) perror_name (output_filename);
                   2987: 
                   2988:   if (fstat (outdesc, &statbuf) < 0)
                   2989:     perror_name (output_filename);
                   2990: 
                   2991:   filemode = statbuf.st_mode;
                   2992: 
                   2993:   chmod (output_filename, filemode & ~0111);
                   2994: 
                   2995:   /* Output the a.out header.  */
                   2996:   write_header ();
                   2997: 
                   2998:   /* Output the text and data segments, relocating as we go.  */
                   2999:   write_text ();
                   3000:   write_data ();
                   3001: 
                   3002:   /* Output the merged relocation info, if requested with `-r'.  */
                   3003:   if (relocatable_output)
                   3004:     write_rel ();
                   3005: 
                   3006:   /* Output the symbol table (both globals and locals).  */
                   3007:   write_syms ();
                   3008: 
                   3009:   /* Copy any GDB symbol segments from input files.  */
                   3010:   write_symsegs ();
                   3011: 
                   3012:   close (outdesc);
                   3013: 
1.1.1.2   root     3014:   chmod (output_filename, filemode | 0111);
1.1       root     3015: }
                   3016: 
                   3017: void modify_location (), perform_relocation (), copy_text (), copy_data ();
                   3018: 
                   3019: void
                   3020: write_header ()
                   3021: {
                   3022:   outheader.a_magic = magic;
                   3023:   outheader.a_text = text_size;
                   3024:   outheader.a_data = data_size;
                   3025:   outheader.a_bss = bss_size;
                   3026:   outheader.a_entry = (entry_symbol ? entry_symbol->value
                   3027:                       : text_start + entry_offset);
1.1.1.3 ! root     3028: #ifdef COFF_ENCAPSULATE
        !          3029:   if (need_coff_header)
        !          3030:     {
        !          3031:       /* We are encapsulating BSD format within COFF format.  */
        !          3032:       struct coffscn *tp, *dp, *bp;
        !          3033: 
        !          3034:       tp = &coffheader.scns[0];
        !          3035:       dp = &coffheader.scns[1];
        !          3036:       bp = &coffheader.scns[2];
        !          3037: 
        !          3038:       strcpy (tp->s_name, ".text");
        !          3039:       tp->s_paddr = text_start;
        !          3040:       tp->s_vaddr = text_start;
        !          3041:       tp->s_size = text_size;
        !          3042:       tp->s_scnptr = sizeof (struct coffheader) + sizeof (struct exec);
        !          3043:       tp->s_relptr = 0;
        !          3044:       tp->s_lnnoptr = 0;
        !          3045:       tp->s_nreloc = 0;
        !          3046:       tp->s_nlnno = 0;
        !          3047:       tp->s_flags = 0x20;
        !          3048:       strcpy (dp->s_name, ".data");
        !          3049:       dp->s_paddr = data_start;
        !          3050:       dp->s_vaddr = data_start;
        !          3051:       dp->s_size = data_size;
        !          3052:       dp->s_scnptr = tp->s_scnptr + tp->s_size;
        !          3053:       dp->s_relptr = 0;
        !          3054:       dp->s_lnnoptr = 0;
        !          3055:       dp->s_nreloc = 0;
        !          3056:       dp->s_nlnno = 0;
        !          3057:       dp->s_flags = 0x40;
        !          3058:       strcpy (bp->s_name, ".bss");
        !          3059:       bp->s_paddr = dp->s_vaddr + dp->s_size;
        !          3060:       bp->s_vaddr = bp->s_paddr;
        !          3061:       bp->s_size = bss_size;
        !          3062:       bp->s_scnptr = 0;
        !          3063:       bp->s_relptr = 0;
        !          3064:       bp->s_lnnoptr = 0;
        !          3065:       bp->s_nreloc = 0;
        !          3066:       bp->s_nlnno = 0;
        !          3067:       bp->s_flags = 0x80;
        !          3068: 
        !          3069:       coffheader.f_magic = COFF_MAGIC;
        !          3070:       coffheader.f_nscns = 3;
        !          3071:       coffheader.f_timdat = 0;
        !          3072:       coffheader.f_symptr = 0;
        !          3073:       coffheader.f_nsyms = 0;
        !          3074:       coffheader.f_opthdr = 28;
        !          3075:       coffheader.f_flags = 0x103;
        !          3076:       /* aouthdr */
        !          3077:       coffheader.magic = ZMAGIC;
        !          3078:       coffheader.vstamp = 0;
        !          3079:       coffheader.tsize = tp->s_size;
        !          3080:       coffheader.dsize = dp->s_size;
        !          3081:       coffheader.bsize = bp->s_size;
        !          3082:       coffheader.entry = outheader.a_entry;
        !          3083:       coffheader.text_start = tp->s_vaddr;
        !          3084:       coffheader.data_start = dp->s_vaddr;
        !          3085:     }
        !          3086: #endif
        !          3087: 
        !          3088: #ifdef INITIALIZE_HEADER
        !          3089:   INITIALIZE_HEADER;
        !          3090: #endif
1.1       root     3091: 
                   3092:   if (strip_symbols == STRIP_ALL)
                   3093:     nsyms = 0;
                   3094:   else
                   3095:     {
1.1.1.2   root     3096:       nsyms = (defined_global_sym_count
                   3097:               + undefined_global_sym_count);
1.1       root     3098:       if (discard_locals == DISCARD_L)
                   3099:        nsyms += non_L_local_sym_count;
                   3100:       else if (discard_locals == DISCARD_NONE)
                   3101:        nsyms += local_sym_count;
1.1.1.2   root     3102:       /* One extra for following reference on indirects */
                   3103:       if (relocatable_output)
                   3104:        nsyms += set_symbol_count + global_indirect_count;
1.1       root     3105:     }
                   3106: 
                   3107:   if (strip_symbols == STRIP_NONE)
                   3108:     nsyms += debugger_sym_count;
                   3109: 
                   3110:   outheader.a_syms = nsyms * sizeof (struct nlist);
                   3111: 
                   3112:   if (relocatable_output)
                   3113:     {
                   3114:       outheader.a_trsize = text_reloc_size;
                   3115:       outheader.a_drsize = data_reloc_size;
                   3116:     }
                   3117:   else
                   3118:     {
                   3119:       outheader.a_trsize = 0;
                   3120:       outheader.a_drsize = 0;
                   3121:     }
                   3122: 
1.1.1.3 ! root     3123: #ifdef COFF_ENCAPSULATE
        !          3124:   if (need_coff_header)
        !          3125:     mywrite (&coffheader, sizeof coffheader, 1, outdesc);
        !          3126: #endif
1.1       root     3127:   mywrite (&outheader, sizeof (struct exec), 1, outdesc);
                   3128: 
                   3129:   /* Output whatever padding is required in the executable file
                   3130:      between the header and the start of the text.  */
                   3131: 
1.1.1.3 ! root     3132: #ifndef COFF_ENCAPSULATE
1.1       root     3133:   padfile (N_TXTOFF (outheader) - sizeof outheader, outdesc);
1.1.1.3 ! root     3134: #endif
1.1       root     3135: }
                   3136: 
                   3137: /* Relocate the text segment of each input file
                   3138:    and write to the output file.  */
                   3139: 
                   3140: void
                   3141: write_text ()
                   3142: {
                   3143:   if (trace_files)
                   3144:     fprintf (stderr, "Copying and relocating text:\n\n");
                   3145: 
                   3146:   each_full_file (copy_text);
                   3147:   file_close ();
                   3148: 
1.1.1.2   root     3149:   /* Write out the set element vectors */
1.1.1.3 ! root     3150: 
1.1.1.2   root     3151:   if (set_vector_count)
                   3152:     mywrite (set_vectors, set_symbol_count + set_vector_count, sizeof (unsigned long), outdesc);
                   3153: 
1.1       root     3154:   if (trace_files)
                   3155:     fprintf (stderr, "\n");
                   3156: 
                   3157:   padfile (text_pad, outdesc);
                   3158: }
                   3159: 
                   3160: int
                   3161: text_offset (entry)
                   3162:      struct file_entry *entry;
                   3163: {
                   3164:   return entry->starting_offset + N_TXTOFF (entry->header);
                   3165: }
                   3166: 
1.1.1.2   root     3167: /* Read in all of the relocation information */
                   3168: 
                   3169: void
                   3170: read_relocation ()
                   3171: {
                   3172:   each_full_file (read_file_relocation);
                   3173: }
                   3174: 
                   3175: /* Read in the relocation sections of ENTRY if necessary */
                   3176: 
                   3177: void
                   3178: read_file_relocation (entry)
                   3179:      struct file_entry *entry;
                   3180: {
                   3181:   register struct relocation_info *reloc;
                   3182:   int desc;
                   3183:   int read_return;
1.1.1.3 ! root     3184: 
1.1.1.2   root     3185:   desc = -1;
                   3186:   if (!entry->textrel)
                   3187:     {
                   3188:       reloc = (struct relocation_info *) xmalloc (entry->header.a_trsize);
                   3189:       desc = file_open (entry);
                   3190:       lseek (desc,
                   3191:             text_offset (entry) + entry->header.a_text + entry->header.a_data,
                   3192:             L_SET);
                   3193:       if (entry->header.a_trsize != (read_return = read (desc, reloc, entry->header.a_trsize)))
                   3194:        {
                   3195:          fprintf (stderr, "Return from read: %d\n", read_return);
                   3196:          fatal_with_file ("premature eof in text relocatino of ", entry);
                   3197:        }
                   3198:       entry->textrel = reloc;
                   3199:     }
                   3200: 
1.1.1.3 ! root     3201:   if (!entry->datarel)
1.1.1.2   root     3202:     {
                   3203:       reloc = (struct relocation_info *) xmalloc (entry->header.a_drsize);
                   3204:       if (desc == -1) desc = file_open (entry);
                   3205:       lseek (desc,
                   3206:             text_offset (entry) + entry->header.a_text
                   3207:             + entry->header.a_data + entry->header.a_trsize,
                   3208:             L_SET);
                   3209:       if (entry->header.a_drsize != read (desc, reloc, entry->header.a_drsize))
1.1.1.3 ! root     3210:        fatal_with_file ("premature eof in text relocation of ", entry);
1.1.1.2   root     3211:       entry->datarel = reloc;
                   3212:     }
                   3213: }
1.1.1.3 ! root     3214: 
1.1       root     3215: /* Read the text segment contents of ENTRY, relocate them,
                   3216:    and write the result to the output file.
                   3217:    If `-r', save the text relocation for later reuse.  */
                   3218: 
                   3219: void
                   3220: copy_text (entry)
                   3221:      struct file_entry *entry;
                   3222: {
                   3223:   register char *bytes;
                   3224:   register int desc;
                   3225:   register struct relocation_info *reloc;
                   3226: 
                   3227:   if (trace_files)
                   3228:     prline_file_name (entry, stderr);
                   3229: 
                   3230:   desc = file_open (entry);
                   3231: 
1.1.1.2   root     3232:   /* Allocate space for the file's text section */
1.1       root     3233: 
                   3234:   bytes = (char *) alloca (entry->header.a_text);
                   3235: 
1.1.1.2   root     3236:   /* Deal with relocation information however is appropriate */
1.1.1.3 ! root     3237: 
1.1.1.2   root     3238:   if (entry->textrel)  reloc = entry->textrel;
                   3239:   else if (relocatable_output)
                   3240:     {
                   3241:       read_file_relocation (entry);
                   3242:       reloc = entry->textrel;
                   3243:     }
1.1       root     3244:   else
1.1.1.2   root     3245:     {
                   3246:       reloc = (struct relocation_info *) alloca (entry->header.a_trsize);
                   3247:       lseek (desc, text_offset (entry) + entry->header.a_text + entry->header.a_data, 0);
                   3248:       if (entry->header.a_trsize != read (desc, reloc, entry->header.a_trsize))
                   3249:        fatal_with_file ("premature eof in text relocation of ", entry);
                   3250:     }
1.1       root     3251: 
1.1.1.2   root     3252:   /* Read the text section into core.  */
1.1       root     3253: 
                   3254:   lseek (desc, text_offset (entry), 0);
                   3255:   if (entry->header.a_text != read (desc, bytes, entry->header.a_text))
                   3256:     fatal_with_file ("premature eof in text section of ", entry);
                   3257: 
                   3258: 
                   3259:   /* Relocate the text according to the text relocation.  */
                   3260: 
                   3261:   perform_relocation (bytes, entry->text_start_address, entry->header.a_text,
                   3262:                      reloc, entry->header.a_trsize, entry);
                   3263: 
                   3264:   /* Write the relocated text to the output file.  */
                   3265: 
                   3266:   mywrite (bytes, 1, entry->header.a_text, outdesc);
                   3267: }
                   3268: 
                   3269: /* Relocate the data segment of each input file
                   3270:    and write to the output file.  */
                   3271: 
                   3272: void
                   3273: write_data ()
                   3274: {
                   3275:   if (trace_files)
                   3276:     fprintf (stderr, "Copying and relocating data:\n\n");
                   3277: 
                   3278:   each_full_file (copy_data);
                   3279:   file_close ();
                   3280: 
                   3281:   if (trace_files)
                   3282:     fprintf (stderr, "\n");
                   3283: 
                   3284:   padfile (data_pad, outdesc);
                   3285: }
                   3286: 
                   3287: /* Read the data segment contents of ENTRY, relocate them,
                   3288:    and write the result to the output file.
                   3289:    If `-r', save the data relocation for later reuse.
                   3290:    See comments in `copy_text'.  */
                   3291: 
                   3292: void
                   3293: copy_data (entry)
                   3294:      struct file_entry *entry;
                   3295: {
                   3296:   register struct relocation_info *reloc;
                   3297:   register char *bytes;
                   3298:   register int desc;
                   3299: 
                   3300:   if (trace_files)
                   3301:     prline_file_name (entry, stderr);
                   3302: 
                   3303:   desc = file_open (entry);
                   3304: 
                   3305:   bytes = (char *) alloca (entry->header.a_data);
1.1.1.3 ! root     3306: 
1.1.1.2   root     3307:   if (entry->datarel) reloc = entry->datarel;
                   3308:   else if (relocatable_output) /* Will need this again */
                   3309:     {
                   3310:       read_file_relocation (entry);
                   3311:       reloc = entry->datarel;
                   3312:     }
1.1       root     3313:   else
1.1.1.2   root     3314:     {
                   3315:       reloc = (struct relocation_info *) alloca (entry->header.a_drsize);
                   3316:       lseek (desc, text_offset (entry) + entry->header.a_text
                   3317:             + entry->header.a_data + entry->header.a_trsize,
                   3318:             0);
                   3319:       if (entry->header.a_drsize != read (desc, reloc, entry->header.a_drsize))
                   3320:        fatal_with_file ("premature eof in data relocation of ", entry);
                   3321:     }
1.1.1.3 ! root     3322: 
1.1       root     3323:   lseek (desc, text_offset (entry) + entry->header.a_text, 0);
                   3324:   if (entry->header.a_data != read (desc, bytes, entry->header.a_data))
                   3325:     fatal_with_file ("premature eof in data section of ", entry);
                   3326: 
                   3327:   perform_relocation (bytes, entry->data_start_address - entry->header.a_text,
                   3328:                      entry->header.a_data, reloc, entry->header.a_drsize, entry);
                   3329: 
                   3330:   mywrite (bytes, 1, entry->header.a_data, outdesc);
                   3331: }
                   3332: 
                   3333: /* Relocate ENTRY's text or data section contents.
                   3334:    DATA is the address of the contents, in core.
                   3335:    DATA_SIZE is the length of the contents.
                   3336:    PC_RELOCATION is the difference between the address of the contents
                   3337:      in the output file and its address in the input file.
                   3338:    RELOC_INFO is the address of the relocation info, in core.
                   3339:    RELOC_SIZE is its length in bytes.  */
1.1.1.3 ! root     3340: /* This version is about to be severley hacked by Randy.  Hope it
        !          3341:    works afterwards. */
1.1       root     3342: void
                   3343: perform_relocation (data, pc_relocation, data_size, reloc_info, reloc_size, entry)
                   3344:      char *data;
                   3345:      struct relocation_info *reloc_info;
                   3346:      struct file_entry *entry;
                   3347:      int pc_relocation;
                   3348:      int data_size;
                   3349:      int reloc_size;
                   3350: {
                   3351:   register struct relocation_info *p = reloc_info;
                   3352:   struct relocation_info *end
                   3353:     = reloc_info + reloc_size / sizeof (struct relocation_info);
                   3354:   int text_relocation = entry->text_start_address;
                   3355:   int data_relocation = entry->data_start_address - entry->header.a_text;
                   3356:   int bss_relocation
                   3357:     = entry->bss_start_address - entry->header.a_text - entry->header.a_data;
                   3358: 
                   3359:   for (; p < end; p++)
                   3360:     {
                   3361:       register int relocation = 0;
1.1.1.3 ! root     3362:       register int addr = RELOC_ADDRESS(p);
        !          3363:       register unsigned int mask = 0;
1.1       root     3364: 
                   3365:       if (addr >= data_size)
                   3366:        fatal_with_file ("relocation address out of range in ", entry);
1.1.1.3 ! root     3367: 
        !          3368:       if (RELOC_EXTERN_P(p))
1.1       root     3369:        {
1.1.1.3 ! root     3370:          int symindex = RELOC_SYMBOL (p) * sizeof (struct nlist);
1.1       root     3371:          symbol *sp = ((symbol *)
                   3372:                        (((struct nlist *)
                   3373:                          (((char *)entry->symbols) + symindex))
                   3374:                         ->n_un.n_name));
                   3375: 
1.1.1.3 ! root     3376: #ifdef N_INDR
1.1.1.2   root     3377:          /* Resolve indirection */
                   3378:          if ((sp->defined & ~N_EXT) == N_INDR)
                   3379:            sp = (symbol *) sp->value;
1.1.1.3 ! root     3380: #endif
1.1.1.2   root     3381: 
1.1       root     3382:          if (symindex >= entry->header.a_syms)
                   3383:            fatal_with_file ("relocation symbolnum out of range in ", entry);
                   3384: 
                   3385:          /* If the symbol is undefined, leave it at zero.  */
                   3386:          if (! sp->defined)
                   3387:            relocation = 0;
                   3388:          else
                   3389:            relocation = sp->value;
                   3390:        }
1.1.1.3 ! root     3391:       else switch (RELOC_TYPE(p))
1.1       root     3392:        {
                   3393:        case N_TEXT:
                   3394:        case N_TEXT | N_EXT:
                   3395:          relocation = text_relocation;
                   3396:          break;
                   3397: 
                   3398:        case N_DATA:
                   3399:        case N_DATA | N_EXT:
                   3400:          /* A word that points to beginning of the the data section
                   3401:             initially contains not 0 but rather the "address" of that section
                   3402:             in the input file, which is the length of the file's text.  */
                   3403:          relocation = data_relocation;
                   3404:          break;
                   3405: 
                   3406:        case N_BSS:
                   3407:        case N_BSS | N_EXT:
                   3408:          /* Similarly, an input word pointing to the beginning of the bss
                   3409:             initially contains the length of text plus data of the file.  */
                   3410:          relocation = bss_relocation;
                   3411:          break;
                   3412: 
                   3413:        case N_ABS:
                   3414:        case N_ABS | N_EXT:
                   3415:          /* Don't know why this code would occur, but apparently it does.  */
                   3416:          break;
                   3417: 
                   3418:        default:
                   3419:          fatal_with_file ("nonexternal relocation code invalid in ", entry);
                   3420:        }
                   3421: 
1.1.1.3 ! root     3422:       if (RELOC_PCREL_P(p))
1.1       root     3423:        relocation -= pc_relocation;
                   3424: 
1.1.1.3 ! root     3425: #ifdef RELOC_ADD_EXTRA
        !          3426:       relocation += RELOC_ADD_EXTRA(p);
        !          3427: #endif
        !          3428: 
        !          3429:       relocation >>= RELOC_VALUE_RIGHTSHIFT(p);
        !          3430: 
        !          3431:       /* Unshifted mask for relocation */
        !          3432:       mask = 1 << RELOC_TARGET_BITSIZE(p) - 1;
        !          3433:       mask |= mask - 1;
        !          3434:       relocation &= mask;
        !          3435: 
        !          3436:       /* Shift everything up to where it's going to be used */
        !          3437:       relocation <<= RELOC_TARGET_BITPOS(p);
        !          3438:       mask <<= RELOC_TARGET_BITPOS(p);
        !          3439: 
        !          3440:       switch (RELOC_TARGET_SIZE(p))
1.1       root     3441:        {
                   3442:        case 0:
1.1.1.3 ! root     3443:          if (RELOC_MEMORY_ADD_P(p))
        !          3444:            relocation += mask & *(char *) (data + addr);
        !          3445:          *(char *) (data + addr) &= ~mask;
        !          3446:          *(char *) (data + addr) |= relocation;
1.1       root     3447:          break;
1.1.1.3 ! root     3448: 
1.1       root     3449:        case 1:
1.1.1.3 ! root     3450:          if (RELOC_MEMORY_ADD_P(p))
        !          3451:            relocation += mask & *(short *) (data + addr);
        !          3452:          *(short *) (data + addr) &= ~mask;
        !          3453:          *(short *) (data + addr) |= relocation;
1.1       root     3454:          break;
1.1.1.3 ! root     3455: 
1.1       root     3456:        case 2:
1.1.1.3 ! root     3457:          if (RELOC_MEMORY_ADD_P(p))
        !          3458:            relocation += mask & *(long *) (data + addr);
        !          3459:          *(long *) (data + addr) &= ~mask;
        !          3460:          *(long *) (data + addr) |= relocation;
1.1       root     3461:          break;
1.1.1.3 ! root     3462: 
1.1       root     3463:        default:
1.1.1.3 ! root     3464:          fatal_with_file ("Unimplemented relocation field length in ", entry);
1.1       root     3465:        }
                   3466:     }
                   3467: }
                   3468: 
                   3469: /* For relocatable_output only: write out the relocation,
                   3470:    relocating the addresses-to-be-relocated.  */
                   3471: 
                   3472: void coptxtrel (), copdatrel ();
                   3473: 
                   3474: void
                   3475: write_rel ()
                   3476: {
                   3477:   register int i;
                   3478:   register int count = 0;
                   3479: 
                   3480:   if (trace_files)
                   3481:     fprintf (stderr, "Writing text relocation:\n\n");
                   3482: 
                   3483:   /* Assign each global symbol a sequence number, giving the order
                   3484:      in which `write_syms' will write it.
                   3485:      This is so we can store the proper symbolnum fields
                   3486:      in relocation entries we write.  */
                   3487: 
                   3488:   for (i = 0; i < TABSIZE; i++)
                   3489:     {
                   3490:       symbol *sp;
                   3491:       for (sp = symtab[i]; sp; sp = sp->link)
                   3492:        if (sp->referenced || sp->defined)
                   3493:          sp->def_count = count++;
                   3494:     }
                   3495:   if (count != defined_global_sym_count + undefined_global_sym_count)
                   3496:     fatal ("internal error");
                   3497: 
                   3498:   /* Write out the relocations of all files, remembered from copy_text.  */
                   3499: 
                   3500:   each_full_file (coptxtrel);
                   3501: 
                   3502:   if (trace_files)
                   3503:     fprintf (stderr, "\nWriting data relocation:\n\n");
                   3504: 
                   3505:   each_full_file (copdatrel);
                   3506: 
                   3507:   if (trace_files)
                   3508:     fprintf (stderr, "\n");
                   3509: }
                   3510: 
                   3511: void
                   3512: coptxtrel (entry)
                   3513:      struct file_entry *entry;
                   3514: {
                   3515:   register struct relocation_info *p, *end;
                   3516:   register int reloc = entry->text_start_address;
                   3517: 
                   3518:   p = entry->textrel;
                   3519:   end = (struct relocation_info *) (entry->header.a_trsize + (char *) p);
                   3520:   while (p < end)
                   3521:     {
1.1.1.3 ! root     3522:       RELOC_ADDRESS(p) += reloc;
        !          3523:       if (RELOC_EXTERN_P(p))
1.1       root     3524:        {
1.1.1.3 ! root     3525:          register int symindex = RELOC_SYMBOL(p) * sizeof (struct nlist);
1.1       root     3526:          symbol *symptr = ((symbol *)
                   3527:                            (((struct nlist *)
                   3528:                              (((char *)entry->symbols) + symindex))
                   3529:                             ->n_un.n_name));
                   3530: 
                   3531:          if (symindex >= entry->header.a_syms)
                   3532:            fatal_with_file ("relocation symbolnum out of range in ", entry);
1.1.1.2   root     3533: 
1.1       root     3534:          /* If the symbol is now defined, change the external relocation
                   3535:             to an internal one.  */
1.1.1.2   root     3536: 
1.1.1.3 ! root     3537:          if (symptr->defined)
1.1       root     3538:            {
1.1.1.3 ! root     3539:              RELOC_EXTERN_P(p) = 0;
        !          3540:              RELOC_SYMBOL(p) = (symptr->defined & N_TYPE);
1.1       root     3541:            }
                   3542:          else
1.1.1.3 ! root     3543:              RELOC_SYMBOL(p) = (symptr->def_count + nsyms
        !          3544:                                 - defined_global_sym_count
        !          3545:                                 - undefined_global_sym_count);
1.1       root     3546:        }
                   3547:       p++;
                   3548:     }
                   3549:   mywrite (entry->textrel, 1, entry->header.a_trsize, outdesc);
                   3550: }
                   3551: 
                   3552: void
                   3553: copdatrel (entry)
                   3554:      struct file_entry *entry;
                   3555: {
                   3556:   register struct relocation_info *p, *end;
                   3557:   /* Relocate the address of the relocation.
                   3558:      Old address is relative to start of the input file's data section.
                   3559:      New address is relative to start of the output file's data section.  */
                   3560:   register int reloc = entry->data_start_address - text_size;
                   3561: 
                   3562:   p = entry->datarel;
                   3563:   end = (struct relocation_info *) (entry->header.a_drsize + (char *) p);
                   3564:   while (p < end)
                   3565:     {
1.1.1.3 ! root     3566:       RELOC_ADDRESS(p) += reloc;
        !          3567:       if (RELOC_EXTERN_P(p))
1.1       root     3568:        {
1.1.1.3 ! root     3569:          register int symindex = RELOC_SYMBOL(p) * sizeof (struct nlist);
1.1       root     3570:          symbol *symptr = ((symbol *)
                   3571:                            (((struct nlist *)
                   3572:                              (((char *)entry->symbols) + symindex))
                   3573:                             ->n_un.n_name));
                   3574:          int symtype = symptr->defined & N_TYPE;
                   3575: 
                   3576:          if (symindex >= entry->header.a_syms)
                   3577:            fatal_with_file ("relocation symbolnum out of range in ", entry);
                   3578:          if (force_common_definition
                   3579:              || symtype == N_DATA || symtype == N_TEXT || symtype == N_ABS)
                   3580:            {
1.1.1.3 ! root     3581:              RELOC_EXTERN_P(p) = 0;
        !          3582:              RELOC_SYMBOL(p) = symtype;
1.1       root     3583:            }
                   3584:          else
1.1.1.3 ! root     3585:            RELOC_SYMBOL(p)
1.1       root     3586:              = (((symbol *)
                   3587:                  (((struct nlist *)
                   3588:                    (((char *)entry->symbols) + symindex))
                   3589:                   ->n_un.n_name))
                   3590:                 ->def_count
                   3591:                 + nsyms - defined_global_sym_count
                   3592:                 - undefined_global_sym_count);
                   3593:        }
                   3594:       p++;
                   3595:     }
                   3596:   mywrite (entry->datarel, 1, entry->header.a_drsize, outdesc);
                   3597: }
                   3598: 
                   3599: void write_file_syms ();
                   3600: void write_string_table ();
                   3601: 
                   3602: /* Offsets and current lengths of symbol and string tables in output file. */
                   3603: 
                   3604: int symbol_table_offset;
                   3605: int symbol_table_len;
                   3606: 
                   3607: /* Address in output file where string table starts.  */
                   3608: int string_table_offset;
                   3609: 
                   3610: /* Offset within string table
                   3611:    where the strings in `strtab_vector' should be written.  */
                   3612: int string_table_len;
                   3613: 
                   3614: /* Total size of string table strings allocated so far,
                   3615:    including strings in `strtab_vector'.  */
                   3616: int strtab_size;
                   3617: 
                   3618: /* Vector whose elements are strings to be added to the string table.  */
                   3619: char **strtab_vector;
                   3620: 
                   3621: /* Vector whose elements are the lengths of those strings.  */
                   3622: int *strtab_lens;
                   3623: 
                   3624: /* Index in `strtab_vector' at which the next string will be stored.  */
                   3625: int strtab_index;
                   3626: 
                   3627: /* Add the string NAME to the output file string table.
                   3628:    Record it in `strtab_vector' to be output later.
                   3629:    Return the index within the string table that this string will have.  */
                   3630: 
                   3631: int
                   3632: assign_string_table_index (name)
                   3633:      char *name;
                   3634: {
                   3635:   register int index = strtab_size;
                   3636:   register int len = strlen (name) + 1;
                   3637: 
                   3638:   strtab_size += len;
                   3639:   strtab_vector[strtab_index] = name;
                   3640:   strtab_lens[strtab_index++] = len;
                   3641: 
                   3642:   return index;
                   3643: }
                   3644: 
                   3645: FILE *outstream = (FILE *) 0;
                   3646: 
                   3647: /* Write the contents of `strtab_vector' into the string table.
                   3648:    This is done once for each file's local&debugger symbols
                   3649:    and once for the global symbols.  */
                   3650: 
                   3651: void
                   3652: write_string_table ()
                   3653: {
                   3654:   register int i;
                   3655: 
                   3656:   lseek (outdesc, string_table_offset + string_table_len, 0);
                   3657: 
                   3658:   if (!outstream)
                   3659:     outstream = fdopen (outdesc, "w");
                   3660: 
                   3661:   for (i = 0; i < strtab_index; i++)
                   3662:     {
                   3663:       fwrite (strtab_vector[i], 1, strtab_lens[i], outstream);
                   3664:       string_table_len += strtab_lens[i];
                   3665:     }
                   3666: 
                   3667:   fflush (outstream);
                   3668: 
                   3669:   /* Report I/O error such as disk full.  */
                   3670:   if (ferror (outstream))
                   3671:     perror_name (output_filename);
                   3672: }
                   3673: 
                   3674: /* Write the symbol table and string table of the output file.  */
                   3675: 
                   3676: void
                   3677: write_syms ()
                   3678: {
                   3679:   /* Number of symbols written so far.  */
                   3680:   int syms_written = 0;
                   3681:   register int i;
                   3682:   register symbol *sp;
                   3683: 
1.1.1.2   root     3684:   /* Buffer big enough for all the global symbols.  One
                   3685:      extra struct for each indirect symbol to hold the extra reference
                   3686:      following. */
1.1       root     3687:   struct nlist *buf
1.1.1.2   root     3688:     = (struct nlist *) alloca ((defined_global_sym_count
                   3689:                                + undefined_global_sym_count
                   3690:                                + global_indirect_count)
1.1       root     3691:                               * sizeof (struct nlist));
                   3692:   /* Pointer for storing into BUF.  */
                   3693:   register struct nlist *bufp = buf;
                   3694: 
                   3695:   /* Size of string table includes the bytes that store the size.  */
                   3696:   strtab_size = sizeof strtab_size;
                   3697: 
                   3698:   symbol_table_offset = N_SYMOFF (outheader);
                   3699:   symbol_table_len = 0;
                   3700:   string_table_offset = N_STROFF (outheader);
                   3701:   string_table_len = strtab_size;
                   3702: 
                   3703:   if (strip_symbols == STRIP_ALL)
                   3704:     return;
                   3705: 
                   3706:   /* Write the local symbols defined by the various files.  */
                   3707: 
                   3708:   each_file (write_file_syms, &syms_written);
                   3709:   file_close ();
                   3710: 
                   3711:   /* Now write out the global symbols.  */
                   3712: 
                   3713:   /* Allocate two vectors that record the data to generate the string
1.1.1.2   root     3714:      table from the global symbols written so far.  This must include
                   3715:      extra space for the references following indirect outputs. */
1.1       root     3716: 
1.1.1.2   root     3717:   strtab_vector = (char **) alloca ((num_hash_tab_syms
                   3718:                                     + global_indirect_count) * sizeof (char *));
                   3719:   strtab_lens = (int *) alloca ((num_hash_tab_syms
                   3720:                                 + global_indirect_count) * sizeof (int));
1.1       root     3721:   strtab_index = 0;
                   3722: 
                   3723:   /* Scan the symbol hash table, bucket by bucket.  */
                   3724: 
                   3725:   for (i = 0; i < TABSIZE; i++)
                   3726:     for (sp = symtab[i]; sp; sp = sp->link)
                   3727:       {
                   3728:        struct nlist nl;
                   3729: 
                   3730:        nl.n_other = 0;
                   3731:        nl.n_desc = 0;
                   3732: 
                   3733:        /* Compute a `struct nlist' for the symbol.  */
                   3734: 
                   3735:        if (sp->defined || sp->referenced)
                   3736:          {
1.1.1.2   root     3737:            /* common condition needs to be before undefined condition */
                   3738:            /* because unallocated commons are set undefined in */
                   3739:            /* digest_symbols */
                   3740:            if (sp->defined > 1) /* defined with known type */
1.1       root     3741:              {
1.1.1.2   root     3742:                /* If the target of an indirect symbol has been
                   3743:                   defined and we are outputting an executable,
                   3744:                   resolve the indirection; it's no longer needed */
                   3745:                if (!relocatable_output
                   3746:                    && ((sp->defined & N_TYPE) == N_INDR)
                   3747:                    && (((symbol *) sp->value)->defined > 1))
                   3748:                  {
                   3749:                    symbol *newsp = (symbol *) sp->value;
                   3750:                    nl.n_type = newsp->defined;
                   3751:                    nl.n_value = newsp->value;
                   3752:                  }
                   3753:                else
                   3754:                  {
                   3755:                    nl.n_type = sp->defined;
                   3756:                    if (sp->defined != (N_INDR | N_EXT))
                   3757:                      nl.n_value = sp->value;
                   3758:                    else
                   3759:                      nl.n_value = 0;
                   3760:                  }
1.1       root     3761:              }
                   3762:            else if (sp->max_common_size) /* defined as common but not allocated. */
                   3763:              {
                   3764:                /* happens only with -r and not -d */
                   3765:                /* write out a common definition */
                   3766:                nl.n_type = N_UNDF | N_EXT;
                   3767:                nl.n_value = sp->max_common_size;
                   3768:              }
1.1.1.2   root     3769:            else if (!sp->defined)            /* undefined -- legit only if -r */
                   3770:              {
                   3771:                nl.n_type = N_UNDF | N_EXT;
                   3772:                nl.n_value = 0;
                   3773:              }
1.1.1.3 ! root     3774:            else
1.1       root     3775:              fatal ("internal error: %s defined in mysterious way", sp->name);
                   3776: 
                   3777:            /* Allocate string table space for the symbol name.  */
                   3778: 
                   3779:            nl.n_un.n_strx = assign_string_table_index (sp->name);
                   3780: 
                   3781:            /* Output to the buffer and count it.  */
                   3782: 
                   3783:            *bufp++ = nl;
                   3784:            syms_written++;
1.1.1.2   root     3785:            if (nl.n_type == (N_INDR | N_EXT))
                   3786:              {
                   3787:                struct nlist xtra_ref;
                   3788:                xtra_ref.n_type == N_EXT | N_UNDF;
                   3789:                xtra_ref.n_un.n_strx =
                   3790:                  assign_string_table_index (((symbol *) sp->value)->name);
                   3791:                xtra_ref.n_other = 0;
                   3792:                xtra_ref.n_desc = 0;
                   3793:                xtra_ref.n_value = 0;
                   3794:                *bufp++ = nl;
                   3795:                syms_written++;
                   3796:              }
1.1       root     3797:          }
                   3798:       }
                   3799: 
                   3800:   /* Output the buffer full of `struct nlist's.  */
                   3801: 
                   3802:   lseek (outdesc, symbol_table_offset + symbol_table_len, 0);
                   3803:   mywrite (buf, sizeof (struct nlist), bufp - buf, outdesc);
                   3804:   symbol_table_len += sizeof (struct nlist) * (bufp - buf);
                   3805: 
                   3806:   if (syms_written != nsyms)
                   3807:     fatal ("internal error: wrong number of symbols written into output file", 0);
                   3808: 
                   3809:   if (symbol_table_offset + symbol_table_len != string_table_offset)
                   3810:     fatal ("internal error: inconsistent symbol table length", 0);
                   3811: 
                   3812:   /* Now the total string table size is known, so write it.
                   3813:      We are already positioned at the right place in the file.  */
                   3814: 
                   3815:   mywrite (&strtab_size, sizeof (int), 1, outdesc);  /* we're at right place */
                   3816: 
                   3817:   /* Write the strings for the global symbols.  */
                   3818: 
                   3819:   write_string_table ();
                   3820: }
                   3821: 
                   3822: /* Write the local and debugger symbols of file ENTRY.
                   3823:    Increment *SYMS_WRITTEN_ADDR for each symbol that is written.  */
                   3824: 
                   3825: /* Note that we do not combine identical names of local symbols.
                   3826:    dbx or gdb would be confused if we did that.  */
                   3827: 
                   3828: void
                   3829: write_file_syms (entry, syms_written_addr)
                   3830:      struct file_entry *entry;
                   3831:      int *syms_written_addr;
                   3832: {
                   3833:   register struct nlist *p = entry->symbols;
                   3834:   register struct nlist *end = p + entry->header.a_syms / sizeof (struct nlist);
                   3835: 
                   3836:   /* Buffer to accumulate all the syms before writing them.
                   3837:      It has one extra slot for the local symbol we generate here.  */
                   3838:   struct nlist *buf
                   3839:     = (struct nlist *) alloca (entry->header.a_syms + sizeof (struct nlist));
                   3840:   register struct nlist *bufp = buf;
                   3841: 
                   3842:   /* Upper bound on number of syms to be written here.  */
                   3843:   int max_syms = (entry->header.a_syms / sizeof (struct nlist)) + 1;
                   3844: 
                   3845:   /* Make tables that record, for each symbol, its name and its name's length.
                   3846:      The elements are filled in by `assign_string_table_index'.  */
                   3847: 
                   3848:   strtab_vector = (char **) alloca (max_syms * sizeof (char *));
                   3849:   strtab_lens = (int *) alloca (max_syms * sizeof (int));
                   3850:   strtab_index = 0;
                   3851: 
                   3852:   /* Generate a local symbol for the start of this file's text.  */
                   3853: 
                   3854:   if (discard_locals != DISCARD_ALL)
                   3855:     {
                   3856:       struct nlist nl;
                   3857: 
                   3858:       nl.n_type = N_TEXT;
                   3859:       nl.n_un.n_strx = assign_string_table_index (entry->local_sym_name);
                   3860:       nl.n_value = entry->text_start_address;
                   3861:       nl.n_desc = 0;
                   3862:       nl.n_other = 0;
                   3863:       *bufp++ = nl;
                   3864:       (*syms_written_addr)++;
                   3865:       entry->local_syms_offset = *syms_written_addr * sizeof (struct nlist);
                   3866:     }
                   3867: 
                   3868:   /* Read the file's string table.  */
                   3869: 
                   3870:   entry->strings = (char *) alloca (entry->string_size);
                   3871:   read_entry_strings (file_open (entry), entry);
                   3872: 
                   3873:   for (; p < end; p++)
                   3874:     {
                   3875:       register int type = p->n_type;
                   3876:       register int write = 0;
                   3877: 
                   3878:       /* WRITE gets 1 for a non-global symbol that should be written.  */
                   3879: 
1.1.1.2   root     3880: 
                   3881:       if (SET_ELEMENT_P (type))        /* This occurs even if global.  These */
                   3882:                                /* types of symbols are never written */
                   3883:                                /* globally, though they are stored */
                   3884:                                /* globally.  */
                   3885:         write = relocatable_output;
                   3886:       else if (!(type & (N_STAB | N_EXT)))
1.1       root     3887:         /* ordinary local symbol */
1.1.1.3 ! root     3888:        write = ((discard_locals != DISCARD_ALL)
        !          3889:                 && !(discard_locals == DISCARD_L &&
        !          3890:                      (p->n_un.n_strx + entry->strings)[0] == 'L')
        !          3891:                 && type != N_WARNING);
1.1       root     3892:       else if (!(type & N_EXT))
                   3893:        /* debugger symbol */
                   3894:         write = (strip_symbols == STRIP_NONE);
                   3895: 
                   3896:       if (write)
                   3897:        {
                   3898:          /* If this symbol has a name,
                   3899:             allocate space for it in the output string table.  */
                   3900: 
1.1.1.2   root     3901: #if 0                          /* Following no longer true  */
                   3902:          /* Sigh.  If this is a set element, it has been entered in */
                   3903:          /* the global symbol table *and* is being output as a */
                   3904:          /* local.  This means that p->n_un.n_strx has been */
                   3905:          /* trashed.  */
                   3906:          if (SET_ELEMENT_P (type))
                   3907:            p->n_un.n_strx =
                   3908:              assign_string_table_index (((symbol *) p->n_un.n_name)->name);
                   3909:          else
                   3910: #endif
1.1       root     3911:          if (p->n_un.n_strx)
1.1.1.2   root     3912:            p->n_un.n_strx = assign_string_table_index (p->n_un.n_strx
                   3913:                                                        + entry->strings);
1.1       root     3914: 
                   3915:          /* Output this symbol to the buffer and count it.  */
                   3916: 
                   3917:          *bufp++ = *p;
                   3918:          (*syms_written_addr)++;
                   3919:        }
                   3920:     }
                   3921: 
                   3922:   /* All the symbols are now in BUF; write them.  */
                   3923: 
1.1.1.3 ! root     3924:   lseek (outdesc, symbol_table_offset + symbol_table_len, 0);
1.1       root     3925:   mywrite (buf, sizeof (struct nlist), bufp - buf, outdesc);
                   3926:   symbol_table_len += sizeof (struct nlist) * (bufp - buf);
                   3927: 
                   3928:   /* Write the string-table data for the symbols just written,
                   3929:      using the data in vectors `strtab_vector' and `strtab_lens'.  */
                   3930: 
                   3931:   write_string_table ();
                   3932: }
                   3933: 
                   3934: /* Copy any GDB symbol segments from the input files to the output file.
                   3935:    The contents of the symbol segment is copied without change
                   3936:    except that we store some information into the beginning of it.  */
                   3937: 
                   3938: void write_file_symseg ();
                   3939: 
1.1.1.2   root     3940: void
1.1       root     3941: write_symsegs ()
                   3942: {
                   3943:   each_file (write_file_symseg, 0);
                   3944: }
                   3945: 
                   3946: void
                   3947: write_file_symseg (entry)
                   3948:      struct file_entry *entry;
                   3949: {
                   3950:   char buffer[4096];
                   3951:   struct symbol_root root;
                   3952:   int indesc;
                   3953:   int len;
                   3954: 
                   3955:   if (entry->symseg_offset == 0)
                   3956:     return;
                   3957: 
                   3958:   /* This entry has a symbol segment.  Read the root of the segment.  */
                   3959: 
                   3960:   indesc = file_open (entry);
                   3961:   lseek (indesc, entry->symseg_offset + entry->starting_offset, 0);
                   3962:   if (sizeof root != read (indesc, &root, sizeof root))
                   3963:     fatal_with_file ("premature end of file in symbol segment of ", entry);
                   3964: 
                   3965:   /* Store some relocation info into the root.  */
                   3966: 
                   3967:   root.ldsymoff = entry->local_syms_offset;
                   3968:   root.textrel = entry->text_start_address;
                   3969:   root.datarel = entry->data_start_address - entry->header.a_text;
                   3970:   root.bssrel = entry->bss_start_address
                   3971:     - entry->header.a_text - entry->header.a_data;
                   3972:   root.databeg = entry->data_start_address - root.datarel;
                   3973:   root.bssbeg = entry->bss_start_address - root.bssrel;
                   3974: 
                   3975:   /* Write the modified root into the output file.  */
                   3976: 
                   3977:   mywrite (&root, sizeof root, 1, outdesc);
                   3978: 
                   3979:   /* Copy the rest of the symbol segment unchanged.  */
                   3980: 
                   3981:   if (entry->superfile)
                   3982:     {
                   3983:       /* Library member: number of bytes to copy is determined
                   3984:         from the member's total size.  */
                   3985: 
                   3986:       int total = entry->total_size - entry->symseg_offset - sizeof root;
                   3987: 
                   3988:       while (total > 0)
                   3989:        {
                   3990:          len = read (indesc, buffer, min (sizeof buffer, total));
                   3991: 
                   3992:          if (len != min (sizeof buffer, total))
                   3993:            fatal_with_file ("premature end of file in symbol segment of ", entry);
                   3994:          total -= len;
                   3995:          mywrite (buffer, len, 1, outdesc);
                   3996:        }
                   3997:     }
                   3998:   else
                   3999:     {
                   4000:       /* A separate file: copy until end of file.  */
                   4001: 
                   4002:       while (len = read (indesc, buffer, sizeof buffer))
                   4003:        {
                   4004:          mywrite (buffer, len, 1, outdesc);
                   4005:          if (len < sizeof buffer)
                   4006:            break;
                   4007:        }
                   4008:     }
                   4009: 
                   4010:   file_close ();
                   4011: }
                   4012: 
                   4013: /* Create the symbol table entries for `etext', `edata' and `end'.  */
                   4014: 
1.1.1.2   root     4015: void
1.1       root     4016: symtab_init ()
                   4017: {
                   4018: #ifndef nounderscore
                   4019:   edata_symbol = getsym ("_edata");
                   4020:   etext_symbol = getsym ("_etext");
                   4021:   end_symbol = getsym ("_end");
                   4022: #else
                   4023:   edata_symbol = getsym ("edata");
                   4024:   etext_symbol = getsym ("etext");
                   4025:   end_symbol = getsym ("end");
                   4026: #endif
                   4027: 
                   4028:   edata_symbol->defined = N_DATA | N_EXT;
                   4029:   etext_symbol->defined = N_TEXT | N_EXT;
                   4030:   end_symbol->defined = N_BSS | N_EXT;
                   4031: 
                   4032:   edata_symbol->referenced = 1;
                   4033:   etext_symbol->referenced = 1;
                   4034:   end_symbol->referenced = 1;
                   4035: }
                   4036: 
                   4037: /* Compute the hash code for symbol name KEY.  */
                   4038: 
                   4039: int
                   4040: hash_string (key)
                   4041:      char *key;
                   4042: {
                   4043:   register char *cp;
                   4044:   register int k;
                   4045: 
                   4046:   cp = key;
                   4047:   k = 0;
                   4048:   while (*cp)
                   4049:     k = (((k << 1) + (k >> 14)) ^ (*cp++)) & 0x3fff;
                   4050: 
                   4051:   return k;
                   4052: }
                   4053: 
                   4054: /* Get the symbol table entry for the global symbol named KEY.
                   4055:    Create one if there is none.  */
                   4056: 
                   4057: symbol *
                   4058: getsym (key)
                   4059:      char *key;
                   4060: {
                   4061:   register int hashval;
                   4062:   register symbol *bp;
                   4063: 
                   4064:   /* Determine the proper bucket.  */
                   4065: 
                   4066:   hashval = hash_string (key) % TABSIZE;
                   4067: 
                   4068:   /* Search the bucket.  */
                   4069: 
                   4070:   for (bp = symtab[hashval]; bp; bp = bp->link)
                   4071:     if (! strcmp (key, bp->name))
                   4072:       return bp;
                   4073: 
                   4074:   /* Nothing was found; create a new symbol table entry.  */
                   4075: 
                   4076:   bp = (symbol *) xmalloc (sizeof (symbol));
                   4077:   bp->refs = 0;
                   4078:   bp->name = (char *) xmalloc (strlen (key) + 1);
                   4079:   strcpy (bp->name, key);
                   4080:   bp->defined = 0;
                   4081:   bp->referenced = 0;
                   4082:   bp->trace = 0;
                   4083:   bp->value = 0;
                   4084:   bp->max_common_size = 0;
1.1.1.3 ! root     4085:   bp->warning = 0;
1.1       root     4086: 
                   4087:   /* Add the entry to the bucket.  */
                   4088: 
                   4089:   bp->link = symtab[hashval];
                   4090:   symtab[hashval] = bp;
                   4091: 
                   4092:   ++num_hash_tab_syms;
                   4093: 
                   4094:   return bp;
                   4095: }
                   4096: 
                   4097: /* Like `getsym' but return 0 if the symbol is not already known.  */
                   4098: 
                   4099: symbol *
                   4100: getsym_soft (key)
                   4101:      char *key;
                   4102: {
                   4103:   register int hashval;
                   4104:   register symbol *bp;
                   4105: 
                   4106:   /* Determine which bucket.  */
                   4107: 
                   4108:   hashval = hash_string (key) % TABSIZE;
                   4109: 
                   4110:   /* Search the bucket.  */
                   4111: 
                   4112:   for (bp = symtab[hashval]; bp; bp = bp->link)
                   4113:     if (! strcmp (key, bp->name))
                   4114:       return bp;
                   4115: 
                   4116:   return 0;
                   4117: }
                   4118: 
                   4119: /* Report a fatal error.
                   4120:    STRING is a printf format string and ARG is one arg for it.  */
                   4121: 
1.1.1.2   root     4122: void
1.1       root     4123: fatal (string, arg)
                   4124:      char *string, *arg;
                   4125: {
                   4126:   fprintf (stderr, "ld: ");
                   4127:   fprintf (stderr, string, arg);
                   4128:   fprintf (stderr, "\n");
                   4129:   exit (1);
                   4130: }
                   4131: 
                   4132: /* Report a fatal error.  The error message is STRING
                   4133:    followed by the filename of ENTRY.  */
                   4134: 
1.1.1.2   root     4135: void
1.1       root     4136: fatal_with_file (string, entry)
                   4137:      char *string;
                   4138:      struct file_entry *entry;
                   4139: {
                   4140:   fprintf (stderr, "ld: ");
                   4141:   fprintf (stderr, string);
                   4142:   print_file_name (entry, stderr);
                   4143:   fprintf (stderr, "\n");
                   4144:   exit (1);
                   4145: }
                   4146: 
                   4147: /* Report a fatal error using the message for the last failed system call,
                   4148:    followed by the string NAME.  */
                   4149: 
1.1.1.2   root     4150: void
1.1       root     4151: perror_name (name)
                   4152:      char *name;
                   4153: {
                   4154:   extern int errno, sys_nerr;
                   4155:   extern char *sys_errlist[];
                   4156:   char *s;
                   4157: 
                   4158:   if (errno < sys_nerr)
                   4159:     s = concat ("", sys_errlist[errno], " for %s");
                   4160:   else
                   4161:     s = "cannot open %s";
                   4162:   fatal (s, name);
                   4163: }
                   4164: 
                   4165: /* Report a fatal error using the message for the last failed system call,
                   4166:    followed by the name of file ENTRY.  */
                   4167: 
1.1.1.2   root     4168: void
1.1       root     4169: perror_file (entry)
                   4170:      struct file_entry *entry;
                   4171: {
                   4172:   extern int errno, sys_nerr;
                   4173:   extern char *sys_errlist[];
                   4174:   char *s;
                   4175: 
                   4176:   if (errno < sys_nerr)
                   4177:     s = concat ("", sys_errlist[errno], " for ");
                   4178:   else
                   4179:     s = "cannot open ";
                   4180:   fatal_with_file (s, entry);
                   4181: }
                   4182: 
                   4183: /* Report a nonfatal error.
                   4184:    STRING is a format for printf, and ARG1 ... ARG3 are args for it.  */
                   4185: 
1.1.1.2   root     4186: void
1.1       root     4187: error (string, arg1, arg2, arg3)
                   4188:      char *string, *arg1, *arg2, *arg3;
                   4189: {
1.1.1.3 ! root     4190:   fprintf (stderr, "%s: ", progname);
1.1       root     4191:   fprintf (stderr, string, arg1, arg2, arg3);
                   4192:   fprintf (stderr, "\n");
                   4193: }
1.1.1.2   root     4194: 
1.1       root     4195: 
                   4196: /* Output COUNT*ELTSIZE bytes of data at BUF
                   4197:    to the descriptor DESC.  */
                   4198: 
1.1.1.2   root     4199: void
1.1       root     4200: mywrite (buf, count, eltsize, desc)
                   4201:      char *buf;
                   4202:      int count;
                   4203:      int eltsize;
                   4204:      int desc;
                   4205: {
                   4206:   register int val;
                   4207:   register int bytes = count * eltsize;
                   4208: 
                   4209:   while (bytes > 0)
                   4210:     {
                   4211:       val = write (desc, buf, bytes);
                   4212:       if (val <= 0)
                   4213:        perror_name (output_filename);
                   4214:       buf += val;
                   4215:       bytes -= val;
                   4216:     }
                   4217: }
                   4218: 
                   4219: /* Output PADDING zero-bytes to descriptor OUTDESC.
                   4220:    PADDING may be negative; in that case, do nothing.  */
                   4221: 
                   4222: void
                   4223: padfile (padding, outdesc)
                   4224:      int padding;
                   4225:      int outdesc;
                   4226: {
                   4227:   register char *buf;
                   4228:   if (padding <= 0)
                   4229:     return;
                   4230: 
                   4231:   buf = (char *) alloca (padding);
                   4232:   bzero (buf, padding);
                   4233:   mywrite (buf, padding, 1, outdesc);
                   4234: }
                   4235: 
                   4236: /* Return a newly-allocated string
                   4237:    whose contents concatenate the strings S1, S2, S3.  */
                   4238: 
                   4239: char *
                   4240: concat (s1, s2, s3)
                   4241:      char *s1, *s2, *s3;
                   4242: {
                   4243:   register int len1 = strlen (s1), len2 = strlen (s2), len3 = strlen (s3);
                   4244:   register char *result = (char *) xmalloc (len1 + len2 + len3 + 1);
                   4245: 
                   4246:   strcpy (result, s1);
                   4247:   strcpy (result + len1, s2);
                   4248:   strcpy (result + len1 + len2, s3);
                   4249:   result[len1 + len2 + len3] = 0;
                   4250: 
                   4251:   return result;
                   4252: }
                   4253: 
                   4254: /* Parse the string ARG using scanf format FORMAT, and return the result.
                   4255:    If it does not parse, report fatal error
                   4256:    generating the error message using format string ERROR and ARG as arg.  */
                   4257: 
                   4258: int
                   4259: parse (arg, format, error)
                   4260:      char *arg, *format;
                   4261: {
                   4262:   int x;
                   4263:   if (1 != sscanf (arg, format, &x))
                   4264:     fatal (error, arg);
                   4265:   return x;
                   4266: }
                   4267: 
                   4268: /* Like malloc but get fatal error if memory is exhausted.  */
                   4269: 
                   4270: int
                   4271: xmalloc (size)
                   4272:      int size;
                   4273: {
                   4274:   register int result = malloc (size);
                   4275:   if (!result)
                   4276:     fatal ("virtual memory exhausted", 0);
                   4277:   return result;
                   4278: }
                   4279: 
                   4280: /* Like realloc but get fatal error if memory is exhausted.  */
                   4281: 
                   4282: int
                   4283: xrealloc (ptr, size)
                   4284:      char *ptr;
                   4285:      int size;
                   4286: {
                   4287:   register int result = realloc (ptr, size);
                   4288:   if (!result)
                   4289:     fatal ("virtual memory exhausted", 0);
                   4290:   return result;
                   4291: }
1.1.1.3 ! root     4292: 
        !          4293: #ifdef USG
        !          4294: 
        !          4295: void
        !          4296: bzero (p, n)
        !          4297:      char *p;
        !          4298: {
        !          4299:   memset (p, 0, n);
        !          4300: }
        !          4301: 
        !          4302: void
        !          4303: bcopy (from, to, n)
        !          4304:      char *from, *to;
        !          4305: {
        !          4306:   memcpy (to, from, n);
        !          4307: }
        !          4308: 
        !          4309: getpagesize ()
        !          4310: {
        !          4311:   return (4096);
        !          4312: }
        !          4313: 
        !          4314: #endif

unix.superglobalmegacorp.com