Annotation of binutils/ld.c, revision 1.1.1.5

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

unix.superglobalmegacorp.com