Diff for /binutils/ld.c between versions 1.1.1.3 and 1.1.1.4

version 1.1.1.3, 2018/04/24 16:07:02 version 1.1.1.4, 2018/04/24 16:07:04
Line 1 Line 1
 /* Linker `ld' for GNU  /* Linker `ld' for GNU
    Copyright (C) 1988 Free Software Foundation, Inc.     Copyright (C) 1988 Free Software Foundation, Inc.
   
                        NO WARRANTY     This program is free software; you can redistribute it and/or modify
      it under the terms of the GNU General Public License as published by
   BECAUSE THIS PROGRAM IS LICENSED FREE OF CHARGE, WE PROVIDE ABSOLUTELY     the Free Software Foundation; either version 1, or (at your option)
 NO WARRANTY, TO THE EXTENT PERMITTED BY APPLICABLE STATE LAW.  EXCEPT     any later version.
 WHEN OTHERWISE STATED IN WRITING, FREE SOFTWARE FOUNDATION, INC,  
 RICHARD M. STALLMAN AND/OR OTHER PARTIES PROVIDE THIS PROGRAM "AS IS"     This program is distributed in the hope that it will be useful,
 WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,     but WITHOUT ANY WARRANTY; without even the implied warranty of
 BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY     GNU General Public License for more details.
 AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE PROGRAM PROVE  
 DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR     You should have received a copy of the GNU General Public License
 CORRECTION.     along with this program; if not, write to the Free Software
      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW WILL RICHARD M.  
 STALLMAN, THE FREE SOFTWARE FOUNDATION, INC., AND/OR ANY OTHER PARTY  
 WHO MAY MODIFY AND REDISTRIBUTE THIS PROGRAM AS PERMITTED BELOW, BE  
 LIABLE TO YOU FOR DAMAGES, INCLUDING ANY LOST PROFITS, LOST MONIES, OR  
 OTHER SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE  
 USE OR INABILITY TO USE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR  
 DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY THIRD PARTIES OR  
 A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS) THIS  
 PROGRAM, EVEN IF YOU HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH  
 DAMAGES, OR FOR ANY CLAIM BY ANY OTHER PARTY.  
   
                 GENERAL PUBLIC LICENSE TO COPY  
   
   1. You may copy and distribute verbatim copies of this source file  
 as you receive it, in any medium, provided that you conspicuously  
 and appropriately publish on each copy a valid copyright notice  
 "Copyright (C) 1988 Free Software Foundation, Inc.", and include  
 following the copyright notice a verbatim copy of the above disclaimer  
 of warranty and of this License.  
   
   2. You may modify your copy or copies of this source file or  
 any portion of it, and copy and distribute such modifications under  
 the terms of Paragraph 1 above, provided that you also do the following:  
   
     a) cause the modified files to carry prominent notices stating  
     that you changed the files and the date of any change; and  
   
     b) cause the whole of any work that you distribute or publish,  
     that in whole or in part contains or is a derivative of this  
     program or any part thereof, to be licensed at no charge to all  
     third parties on terms identical to those contained in this  
     License Agreement (except that you may choose to grant more extensive  
     warranty protection to some or all third parties, at your option).  
   
     c) You may charge a distribution fee for the physical act of  
     transferring a copy, and you may at your option offer warranty  
     protection in exchange for a fee.  
   
 Mere aggregation of another unrelated program with this program (or its  
 derivative) on a volume of a storage or distribution medium does not bring  
 the other program under the scope of these terms.  
   
   3. You may copy and distribute this program (or a portion or derivative  
 of it, under Paragraph 2) in object code or executable form under the terms  
 of Paragraphs 1 and 2 above provided that you also do one of the following:  
   
     a) accompany it with the complete corresponding machine-readable  
     source code, which must be distributed under the terms of  
     Paragraphs 1 and 2 above; or,  
   
     b) accompany it with a written offer, valid for at least three  
     years, to give any third party free (except for a nominal  
     shipping charge) a complete machine-readable copy of the  
     corresponding source code, to be distributed under the terms of  
     Paragraphs 1 and 2 above; or,  
   
     c) accompany it with the information you received as to where the  
     corresponding source code may be obtained.  (This alternative is  
     allowed only for noncommercial distribution and only if you  
     received the program in object code or executable form alone.)  
   
 For an executable file, complete source code means all the source code for  
 all modules it contains; but, as a special exception, it need not include  
 source code for modules which are standard libraries that accompany the  
 operating system on which the executable file runs.  
   
   4. You may not copy, sublicense, distribute or transfer this program  
 except as expressly provided under this License Agreement.  Any attempt  
 otherwise to copy, sublicense, distribute or transfer this program is void and  
 your rights to use the program under this License agreement shall be  
 automatically terminated.  However, parties who have received computer  
 software programs from you with this License Agreement will not have  
 their licenses terminated so long as such parties remain in full compliance.  
   
   5. If you wish to incorporate parts of this program into other free  
 programs whose distribution conditions are different, write to the Free  
 Software Foundation at 675 Mass Ave, Cambridge, MA 02139.  We have not yet  
 worked out a simple rule that can be stated here, but we will often permit  
 this.  We will be guided by the two goals of preserving the free status of  
 all derivatives of our free software and of promoting the sharing and reuse of  
 software.  
   
  In other words, you are welcome to use, share and improve this program.  
  You are forbidden to forbid anyone else to use, share and improve  
  what you give them.   Help stamp out software-hoarding!  */  
   
 /* Written by Richard Stallman with some help from Eric Albert.  /* Written by Richard Stallman with some help from Eric Albert.
    Set and indirect features added by Randy Smith.  */     Set and indirect features added by Randy Smith.  */
Line 108  software. Line 23  software.
 #include <sys/types.h>  #include <sys/types.h>
 #include <sys/stat.h>  #include <sys/stat.h>
 #include <sys/file.h>  #include <sys/file.h>
   #ifndef sony_news
 #include <fcntl.h>  #include <fcntl.h>
   #endif
   
 #ifdef COFF_ENCAPSULATE  #ifdef COFF_ENCAPSULATE
 #include "a.out.encap.h"  #include "a.out.encap.h"
Line 116  software. Line 33  software.
 #include <a.out.h>  #include <a.out.h>
 #endif  #endif
   
   #ifndef N_SET_MAGIC
   #define N_SET_MAGIC(exec, val)  ((exec).a_magic = val)
   #endif
   
 /* If compiled with GNU C, use the built-in alloca */  /* If compiled with GNU C, use the built-in alloca */
 #ifdef __GNUC__  #ifdef __GNUC__
 #define alloca __builtin_alloca  #define alloca __builtin_alloca
Line 197  char *progname; Line 118  char *progname;
 #endif  #endif
 #endif  #endif
   
 #ifdef hpux  
 #define getpagesize() EXEC_PAGESIZE  
 #endif  
   
 /* Define how to initialize system-dependent header fields.  */  /* Define how to initialize system-dependent header fields.  */
 #ifdef sun  #ifdef sun
 #ifdef sparc  #ifdef sparc
 #define INITIALIZE_HEADER \  #define INITIALIZE_HEADER \
   {outheader.a_machtype = M_SPARC; outheader.a_toolversion = 1;}    {outheader.a_machtype = M_SPARC; outheader.a_toolversion = 1;}
 #endif  #endif
 #if defined(mc68010) || defined(m68010) || (TARGET == SUN2)  #if defined(mc68010) || defined(m68010)
 #define INITIALIZE_HEADER outheader.a_machtype = M_68010  #define INITIALIZE_HEADER outheader.a_machtype = M_68010
 #endif  #endif
 #ifndef INITIALIZE_HEADER  #ifndef INITIALIZE_HEADER
Line 223  char *progname; Line 140  char *progname;
 #endif  #endif
 #endif  #endif
 #ifdef hpux  #ifdef hpux
 #define INITIALIZE_HEADER outheader.a_machtype = HP9000S200_ID  #define INITIALIZE_HEADER N_SET_MACHTYPE (outheader, HP9000S200_ID)
 #endif  #endif
 #ifdef i386  #ifdef i386
 #define INITIALIZE_HEADER outheader.a_machtype = M_386  #define INITIALIZE_HEADER N_SET_MACHTYPE (outheader, M_386)
 #endif  #endif
   
 #ifdef is68k  #ifdef is68k
Line 252  char *progname; Line 169  char *progname;
  * system should not be able to use the default set (below), you must   * system should not be able to use the default set (below), you must
  * define the following:   * define the following:
   
  *   relocation_info: This must be typedef'd (or #define'd to the type   *   relocation_info: This must be typedef'd (or #define'd) to the type
  * of structure that is stored in the relocation info section of your   * of structure that is stored in the relocation info section of your
  * a.out files.  Often this is defined in the a.out.h for your system.   * a.out files.  Often this is defined in the a.out.h for your system.
  *   *
Line 279  char *progname; Line 196  char *progname;
  *   *
  *   RELOC_ADD_EXTRA (rval): (Optional) This macro, if defined, gives   *   RELOC_ADD_EXTRA (rval): (Optional) This macro, if defined, gives
  * an extra value to be added to the relocation value based on the   * an extra value to be added to the relocation value based on the
  * individual relocation entry.   * individual relocation entry.  *Must be an lvalue if defined*.
  *   *
  *   RELOC_PCREL_P (rval): True if the relocation value described is   *   RELOC_PCREL_P (rval): True if the relocation value described is
  * pc relative.   * pc relative.
Line 345  static int reloc_target_size[] = { Line 262  static int reloc_target_size[] = {
 static int reloc_target_bitsize[] = {  static int reloc_target_bitsize[] = {
   8, 16, 32, 8, 16, 32, 30, 22, 22, 22, 13, 10, 32, 32, 16,    8, 16, 32, 8, 16, 32, 30, 22, 22, 22, 13, 10, 32, 32, 16,
 };  };
   
   #define MAX_ALIGNMENT   (sizeof (double))
 #endif  #endif
   
 /* Default macros */  /* Default macros */
Line 354  static int reloc_target_bitsize[] = { Line 273  static int reloc_target_bitsize[] = {
 #define RELOC_TYPE(r)           ((r)->r_symbolnum)  #define RELOC_TYPE(r)           ((r)->r_symbolnum)
 #define RELOC_SYMBOL(r)         ((r)->r_symbolnum)  #define RELOC_SYMBOL(r)         ((r)->r_symbolnum)
 #define RELOC_MEMORY_ADD_P(r)   1  #define RELOC_MEMORY_ADD_P(r)   1
 /* #define RELOC_ADD_EXTRA(r)           0       /* Don't need to define */  #undef RELOC_ADD_EXTRA
 #define RELOC_PCREL_P(r)                ((r)->r_pcrel)  #define RELOC_PCREL_P(r)                ((r)->r_pcrel)
 #define RELOC_VALUE_RIGHTSHIFT(r)       0  #define RELOC_VALUE_RIGHTSHIFT(r)       0
 #define RELOC_TARGET_SIZE(r)            ((r)->r_length)  #define RELOC_TARGET_SIZE(r)            ((r)->r_length)
 #define RELOC_TARGET_BITPOS(r)  0  #define RELOC_TARGET_BITPOS(r)  0
 #define RELOC_TARGET_BITSIZE(r) 32  #define RELOC_TARGET_BITSIZE(r) 32
 #endif  #endif
   
   #ifndef MAX_ALIGNMENT
   #define MAX_ALIGNMENT   (sizeof (int))
   #endif
   
   #ifdef nounderscore
   #define LPREFIX '.'
   #else
   #define LPREFIX 'L'
   #endif
   
   
 /* Special global symbol types understood by GNU LD.  */  /* Special global symbol types understood by GNU LD.  */
   
Line 384  static int reloc_target_bitsize[] = { Line 314  static int reloc_target_bitsize[] = {
   
    The address of the set is made into an N_SETV symbol     The address of the set is made into an N_SETV symbol
    whose name is the same as the name of the set.     whose name is the same as the name of the set.
    This symbol acts like a N_TEXT global symbol     This symbol acts like a N_DATA global symbol
    in that it can satisfy undefined external references.  */     in that it can satisfy undefined external references.  */
   
 #ifndef N_SETA  #ifndef N_SETA
Line 408  static int reloc_target_bitsize[] = { Line 338  static int reloc_target_bitsize[] = {
 #define TYPE_OF_SET_ELEMENT(x)  ((x)-N_SETA+N_ABS)  #define TYPE_OF_SET_ELEMENT(x)  ((x)-N_SETA+N_ABS)
   
 #ifndef N_SETV  #ifndef N_SETV
 #define N_SETV  0x1C            /* Pointer to set vector in text area.  */  #define N_SETV  0x1C            /* Pointer to set vector in data area.  */
 #endif                          /* This is output from LD.  */  #endif                          /* This is output from LD.  */
   
 #ifndef N_WARNING  #ifndef N_WARNING
Line 475  typedef Line 405  typedef
          each symbol here.  When the number hits MAX_UREFS_PRINTED,           each symbol here.  When the number hits MAX_UREFS_PRINTED,
          messages stop. */           messages stop. */
       unsigned char undef_refs;        unsigned char undef_refs;
         /* 1 means that this symbol has multiple definitions.  2 means
            that it has multiple definitions, and some of them are set
            elements, one of which has been printed out already.  */
         unsigned char multiply_defined;
       /* Nonzero means print a message at all refs or defs of this symbol */        /* Nonzero means print a message at all refs or defs of this symbol */
       char trace;        char trace;
     }      }
Line 504  int debugger_sym_count; Line 438  int debugger_sym_count;
 /* Count the number of global symbols referenced and not defined.  */  /* Count the number of global symbols referenced and not defined.  */
 int undefined_global_sym_count;  int undefined_global_sym_count;
   
   /* Count the number of global symbols multiply defined.  */
   int multiple_def_count;
   
 /* Count the number of defined global symbols.  /* Count the number of defined global symbols.
    Each symbol is counted only once     Each symbol is counted only once
    regardless of how many different nlist entries refer to it,     regardless of how many different nlist entries refer to it,
Line 869  main (argc, argv) Line 806  main (argc, argv)
   set_vector_count = 0;    set_vector_count = 0;
   global_indirect_count = 0;    global_indirect_count = 0;
   warning_count = 0;    warning_count = 0;
     multiple_def_count = 0;
   
   /* Keep a list of symbols referenced from the command line */    /* Keep a list of symbols referenced from the command line */
   cl_refs_allocated = 10;    cl_refs_allocated = 10;
Line 889  main (argc, argv) Line 827  main (argc, argv)
      the text size, and initialize the text size accordingly.       the text size, and initialize the text size accordingly.
      This depends on the kind of system and on the output format selected.  */       This depends on the kind of system and on the output format selected.  */
   
   outheader.a_magic = magic;    N_SET_MAGIC (outheader, magic);
 #ifdef INITIALIZE_HEADER  #ifdef INITIALIZE_HEADER
   INITIALIZE_HEADER;    INITIALIZE_HEADER;
 #endif  #endif
Line 899  main (argc, argv) Line 837  main (argc, argv)
   if (relocatable_output == 0)    if (relocatable_output == 0)
     {      {
       need_coff_header = 1;        need_coff_header = 1;
       /* set A_ENCAP now, since it will change the values of N_TXTOFF, etc */        /* set this flag now, since it will change the values of N_TXTOFF, etc */
       outheader.a_flags |= A_ENCAP;        N_SET_FLAGS (outheader, N_FLAGS_COFF_ENCAPSULATE);
       text_size += sizeof (struct coffheader);        text_size += sizeof (struct coffheader);
     }      }
 #endif  #endif
Line 1648  enter_file_symbols (entry) Line 1586  enter_file_symbols (entry)
       enter_global_ref (p, p->n_un.n_strx + entry->strings, entry);        enter_global_ref (p, p->n_un.n_strx + entry->strings, entry);
     else if (p->n_un.n_strx && !(p->n_type & (N_STAB | N_EXT)))      else if (p->n_un.n_strx && !(p->n_type & (N_STAB | N_EXT)))
       {        {
         if ((p->n_un.n_strx + entry->strings)[0] != 'L')          if ((p->n_un.n_strx + entry->strings)[0] != LPREFIX)
           non_L_local_sym_count++;            non_L_local_sym_count++;
         local_sym_count++;          local_sym_count++;
       }        }
Line 1783  enter_global_ref (nlist_p, name, entry) Line 1721  enter_global_ref (nlist_p, name, entry)
           break;            break;
   
         case N_SETV:          case N_SETV:
           reftype = "defined in text section as vector";            reftype = "defined in data section as vector";
           break;            break;
   
         case N_INDR:          case N_INDR:
Line 2047  symdef_library (desc, entry, member_leng Line 1985  symdef_library (desc, entry, member_leng
   
                 /* We'll read the strings again if we need them again.  */                  /* We'll read the strings again if we need them again.  */
                 free (subentry->strings);                  free (subentry->strings);
                   subentry->strings = 0;
               }                }
           }            }
     }      }
Line 2071  linear_library (desc, entry) Line 2010  linear_library (desc, entry)
       int member_length;        int member_length;
       register struct file_entry *subentry;        register struct file_entry *subentry;
   
       subentry = decode_library_subfile (desc, entry, this_subfile_offset, &member_length);        subentry = decode_library_subfile (desc, entry, this_subfile_offset,
                                            &member_length);
   
       if (!subentry) return;        if (!subentry) return;
   
Line 2092  linear_library (desc, entry) Line 2032  linear_library (desc, entry)
             prev->chain = subentry;              prev->chain = subentry;
           else entry->subfiles = subentry;            else entry->subfiles = subentry;
           prev = subentry;            prev = subentry;
             subentry->strings = 0; /* Since space will dissapear on return */
         }          }
   
       this_subfile_offset += member_length + sizeof (struct ar_hdr);        this_subfile_offset += member_length + sizeof (struct ar_hdr);
Line 2183  subfile_wanted_p (entry) Line 2124  subfile_wanted_p (entry)
 }  }
   
 void consider_file_section_lengths (), relocate_file_addresses ();  void consider_file_section_lengths (), relocate_file_addresses ();
 void print_files_defining_symbol ();  
   
 /* Having entered all the global symbols and found the sizes of sections  /* Having entered all the global symbols and found the sizes of sections
    of all files to be linked, make all appropriate deductions from this data.     of all files to be linked, make all appropriate deductions from this data.
Line 2205  digest_symbols () Line 2145  digest_symbols ()
   
   each_file (consider_file_section_lengths, 0);    each_file (consider_file_section_lengths, 0);
   
   /* Setup the set element vector */  
   
   if (!relocatable_output)  
     {  
       set_sect_size =  
         (set_symbol_count + set_vector_count) * sizeof (unsigned long);  
       set_sect_start = text_start + text_size;  
       text_size += set_sect_size;  
       set_vectors = (unsigned long *) xmalloc (set_sect_size);  
       setv_fill_count = 0;  
     }  
   /* If necessary, pad text section to full page in the file.    /* If necessary, pad text section to full page in the file.
      Include the padding in the text segment size.  */       Include the padding in the text segment size.  */
   
Line 2233  digest_symbols () Line 2162  digest_symbols ()
   if (! Tdata_flag_specified)    if (! Tdata_flag_specified)
     data_start = N_DATADDR (outheader) + text_start - N_TXTADDR (outheader);      data_start = N_DATADDR (outheader) + text_start - N_TXTADDR (outheader);
   
     /* Set up the set element vector */
   
     if (!relocatable_output)
       {
         /* The set sector size is the number of set elements + a word
            for each symbol for the length word at the beginning of the
            vector, plus a word for each symbol for a zero at the end of
            the vector (for incremental linking).  */
         set_sect_size =
           (2 * set_symbol_count + set_vector_count) * sizeof (unsigned long);
         set_sect_start = data_start + data_size;
         data_size += set_sect_size;
         set_vectors = (unsigned long *) xmalloc (set_sect_size);
         setv_fill_count = 0;
       }
   
   /* Compute start addresses of each file's sections and symbols.  */    /* Compute start addresses of each file's sections and symbols.  */
   
   each_full_file (relocate_file_addresses, 0);    each_full_file (relocate_file_addresses, 0);
Line 2277  digest_symbols () Line 2222  digest_symbols ()
                     }                      }
                   else if ((sp->defined & ~N_EXT) != N_SETV)                    else if ((sp->defined & ~N_EXT) != N_SETV)
                     {                      {
                       make_executable = 0;                        sp->multiply_defined = 1;
                       error ("text symbol `%s' redefined as set vector.  Files:",                        multiple_def_count++;
                              sp->name);  
                       print_files_defining_symbol (first_definition, p);  
                     }                      }
                   set_vectors[setv_fill_count++] = p->n_value;                    set_vectors[setv_fill_count++] = p->n_value;
                 }                  }
Line 2288  digest_symbols () Line 2231  digest_symbols ()
                 {                  {
                   /* non-common definition */                    /* non-common definition */
                   if (defs++ && sp->value != p->n_value)                    if (defs++ && sp->value != p->n_value)
                     if (!erred++)                      {
                       {                        sp->multiply_defined = 1;
                         make_executable = 0;                        multiple_def_count++;
                         error ("multiple definitions of symbol `%s'.  Files:",                      }
                                sp->name);  
                         print_files_defining_symbol (first_definition, p);  
                       }  
                   sp->value = p->n_value;                    sp->value = p->n_value;
                   sp->defined = type;                    sp->defined = type;
                   first_definition = p;                    first_definition = p;
Line 2307  digest_symbols () Line 2247  digest_symbols ()
             {              {
               if (!relocatable_output || force_common_definition)                if (!relocatable_output || force_common_definition)
                 {                  {
                     int align = sizeof (int);
   
                     /* Round up to nearest sizeof (int).  I don't know
                        whether this is necessary or not (given that
                        alignment is taken care of later), but it's
                        traditional, so I'll leave it in.  Note that if
                        this size alignment is ever removed, ALIGN above
                        will have to be initialized to 1 instead of
                        sizeof (int).  */
                     
                   com = (com + sizeof (int) - 1) & (- sizeof (int));                    com = (com + sizeof (int) - 1) & (- sizeof (int));
   
                     while (!(com & align))
                       align <<= 1;
   
                     align = align > MAX_ALIGNMENT ? MAX_ALIGNMENT : align;
   
                     bss_size = ((((bss_size + data_size + data_start)
                                 + (align - 1)) & (- align))
                                 - data_size - data_start);
   
                   sp->value = data_start + data_size + bss_size;                    sp->value = data_start + data_size + bss_size;
                   sp->defined = N_BSS | N_EXT;                    sp->defined = N_BSS | N_EXT;
                   bss_size += com;                    bss_size += com;
Line 2322  digest_symbols () Line 2281  digest_symbols ()
                   undefined_global_sym_count++;                    undefined_global_sym_count++;
                 }                  }
             }              }
           /* Set length word at front of vector */            /* Set length word at front of vector and zero byte at end.  */
           if ((sp->defined & ~N_EXT) == N_SETV)            if ((sp->defined & ~N_EXT) == N_SETV)
             {              {
               unsigned long length_word_index =                unsigned long length_word_index =
                 (sp->value - set_sect_start) / sizeof (unsigned long);                  (sp->value - set_sect_start) / sizeof (unsigned long);
   
               set_vectors[length_word_index] = setv_fill_count - 1 - length_word_index;                set_vectors[length_word_index] = setv_fill_count - 1 - length_word_index;
                 set_vectors[setv_fill_count++] = 0;
             }              }
           if (sp->defined)            if (sp->defined)
             defined_global_sym_count++;              defined_global_sym_count++;
Line 2415  relocate_file_addresses (entry) Line 2375  relocate_file_addresses (entry)
         switch (type)          switch (type)
           {            {
           case N_TEXT:            case N_TEXT:
           case N_SETV:  
           case N_SETT:            case N_SETT:
             p->n_value += entry->text_start_address;              p->n_value += entry->text_start_address;
             break;              break;
           case N_DATA:            case N_DATA:
             case N_SETV:
           case N_SETD:            case N_SETD:
             /* A symbol whose value is in the data section              /* A symbol whose value is in the data section
                is present in the input file as if the data section                 is present in the input file as if the data section
Line 2491  list_file_locals (entry, outfile) Line 2451  list_file_locals (entry, outfile)
      struct file_entry *entry;       struct file_entry *entry;
      FILE *outfile;       FILE *outfile;
 {  {
   register struct nlist *p, *end = entry->symbols + entry->header.a_syms / sizeof (struct nlist);    register struct nlist
       *p,
       *end = entry->symbols + entry->header.a_syms / sizeof (struct nlist);
   
   entry->strings = (char *) alloca (entry->string_size);    entry->strings = (char *) alloca (entry->string_size);
   read_entry_strings (file_open (entry), entry);    read_entry_strings (file_open (entry), entry);
Line 2506  list_file_locals (entry, outfile) Line 2468  list_file_locals (entry, outfile)
     if (!(p->n_type & (N_STAB | N_EXT)))      if (!(p->n_type & (N_STAB | N_EXT)))
       fprintf (outfile, "  %s: 0x%x\n",        fprintf (outfile, "  %s: 0x%x\n",
                entry->strings + p->n_un.n_strx, p->n_value);                 entry->strings + p->n_un.n_strx, p->n_value);
   
     entry->strings = 0;           /* All done with them.  */
 }  }
   
   
 /* Static vars for do_warnings and subroutines of it */  /* Static vars for do_warnings and subroutines of it */
 int list_unresolved_refs;       /* List unresolved refs */  int list_unresolved_refs;       /* List unresolved refs */
 int list_warning_symbols;       /* List warning syms */  int list_warning_symbols;       /* List warning syms */
 int list_multple_defs;          /* List multiple definitions */  int list_multiple_defs;         /* List multiple definitions */
   
 /*  /*
  * Structure for communication between do_file_warnings and it's   * Structure for communication between do_file_warnings and it's
Line 2527  struct line_debug_entry Line 2491  struct line_debug_entry
 };  };
   
 void qsort ();  void qsort ();
   
 struct line_debug_entry *init_debug_scan ();  
 int next_debug_entry ();  
 int address_to_line ();  
 int relocation_entries_relation ();  
   
 /* Print on OUTFILE a list of all warnings generated by references  
    and/or definitions in the file ENTRY.  List source file and line  
    number if possible, just the .o file if not. */  
   
 void  
 do_file_warnings (entry, outfile)  
      struct file_entry *entry;  
      FILE *outfile;  
 {  
   struct relocation_info *txt_reloc, *data_reloc;  
   struct line_debug_entry *state_pointer;  
   register struct line_debug_entry *current, *next, *source;  
   char *errfmt;                         /* Assigned to generally */  
                                         /* static values; should not */  
                                         /* be written into */  
   char *errmsg;                         /* Assigned to malloc'd values */  
                                         /* and copied into; should be */  
                                         /* freed when done */  
   int invalidate_line_number;  
   
   /* Read in the files strings if they aren't available */  
   if (!entry->strings)  
     {  
       int desc;  
   
       entry->strings = (char *) alloca (entry->string_size);  
       desc = file_open (entry);  
       read_entry_strings (desc, entry);  
     }  
   
   state_pointer = init_debug_scan (0, entry);  
   current = state_pointer;  
   next = state_pointer + 1;  
   source = state_pointer + 2;  
   
   read_file_relocation (entry);  
   
   /* We need to sort the relocation info here.  Sheesh, so much effort  
      for one lousy error optimization. */  
   
   qsort (entry->textrel,  
          entry->header.a_trsize/sizeof (struct relocation_info),  
          sizeof (struct relocation_info),  
          relocation_entries_relation);  
   
   for (txt_reloc = entry->textrel;  
        txt_reloc < (entry->textrel  
                     + entry->header.a_trsize/sizeof (struct relocation_info));  
        txt_reloc++)  
     {  
       register struct nlist *s;  
       register symbol *g;  
   
       /* If the relocation isn't resolved through a symbol, continue */  
       if (!RELOC_EXTERN_P(txt_reloc))  
         continue;  
   
       s = &(entry->symbols[RELOC_SYMBOL(txt_reloc)]);  
   
       /* Local symbols shouldn't ever be used by relocation info, so  
          the next should be safe.  
          This is, of course, wrong.  References to local BSS symbols can be  
          the targets of relocation info, and they can (must) be  
          resolved through symbols.  However, these must be defined properly,  
          (the compiler would have caught it otherwise), so we can  
          ignore these cases.  */  
       if (!(s->n_type & N_EXT))  
         continue;  
   
       g = (symbol *) s->n_un.n_name;  
   
       if (!g->defined)                       /* Reference */  
         {  
           if (!list_unresolved_refs ||               /* Don't list any */  
               g->undef_refs >= MAX_UREFS_PRINTED)    /* Listed too many */  
             continue;  
   
           /* Undefined symbol which we should mention */  
   
           if (++(g->undef_refs) == MAX_UREFS_PRINTED)  
             {  
               errfmt = "More undefined symbol %s refs follow";  
               invalidate_line_number = 1;  
             }  
           else  
             {  
               errfmt = "Undefined symbol %s referenced from text";  
               invalidate_line_number = 0;  
             }  
         }  
       else                                           /* Defined */  
         {  
           /* Potential symbol warning here */  
           if (!g->warning) continue;  
   
           errfmt = g->warning;  
           invalidate_line_number = 0;  
         }  
         
       errmsg = (char *) xmalloc (strlen (errfmt) + strlen (g->name) + 1);  
       sprintf(errmsg, errfmt, g->name);  
       address_to_line ( (RELOC_ADDRESS (txt_reloc)  
                          + entry->text_start_address),  
                        state_pointer);  
   
       if (current->line >=0)  
         fprintf (outfile, "%s:%d: %s\n", current->filename,  
                  invalidate_line_number ? 0 : current->line, errmsg);  
       else  
         fprintf (outfile, "%s: %s\n", current->filename, errmsg);  
   
       free (errmsg);  
     }  
   
   free (state_pointer);  
   state_pointer = init_debug_scan (1, entry);  
   current = state_pointer;  
   next = state_pointer + 1;  
   source = state_pointer + 2;  
   
   /*  
    * Once again, time to sort the relocation info.  
    */  
   
   qsort (entry->datarel,  
          entry->header.a_drsize/sizeof (struct relocation_info),  
          sizeof (struct relocation_info),  
          relocation_entries_relation);  
   
   for (data_reloc = entry->datarel;  
        data_reloc < (entry->datarel  
                      + entry->header.a_drsize/sizeof (struct relocation_info));  
        data_reloc++)  
     {  
       register struct nlist *s;  
       register symbol *g;  
   
       /* If the relocation isn't resolved through a symbol, continue */  
       if (!RELOC_EXTERN_P(data_reloc))  
         continue;  
   
       s = &(entry->symbols[RELOC_SYMBOL(data_reloc)]);  
       g = (symbol *) s->n_un.n_name;  
   
       if (!g->defined)                       /* Reference */  
         {  
           if (!list_unresolved_refs ||               /* Don't list any */  
               g->undef_refs >= MAX_UREFS_PRINTED)    /* Listed too many */  
             continue;  
   
           /* Undefined symbol which we should mention */  
   
           if (++(g->undef_refs) == MAX_UREFS_PRINTED)  
             {  
               errfmt = "More undefined symbol %s refs follow";  
               invalidate_line_number = 1;  
             }  
           else  
             {  
               errfmt = "Undefined symbol %s referenced from data";  
               invalidate_line_number = 0;  
             }  
         }  
       else                                           /* Defined */  
         {  
           /* Potential symbol warning here */  
           if (!g->warning) continue;  
   
           errfmt = g->warning;  
           invalidate_line_number = 0;  
         }  
         
       errmsg = (char *) xmalloc (strlen (errfmt) + strlen (g->name) + 1);  
       sprintf(errmsg, errfmt, g->name);  
       address_to_line ( (RELOC_ADDRESS (data_reloc)  
                          + entry->text_start_address),  
                        state_pointer);  
   
       if (current->line >=0)  
         fprintf (outfile, "%s:%d: %s\n", current->filename,  
                  invalidate_line_number ? 0 : current->line, errmsg);  
       else  
         fprintf (outfile, "%s: %s\n", current->filename, errmsg);  
   
       free (errmsg);  
     }  
 }  
 /*  /*
  * Helper routines for do_file_warnings.   * Helper routines for do_file_warnings.
  */   */
   
 /*  /* Return an integer less than, equal to, or greater than 0 as per the
  * Return an integer less than, equal to, or greater than 0 as per the     relation between the two relocation entries.  Used by qsort.  */
  * relation between the two relocation entries.  
  * Used by qsort.  
  */  
 int  int
 relocation_entries_relation (rel1, rel2)  relocation_entries_relation (rel1, rel2)
      struct relocation_info *rel1, *rel2;       struct relocation_info *rel1, *rel2;
Line 2736  relocation_entries_relation (rel1, rel2) Line 2505  relocation_entries_relation (rel1, rel2)
   return RELOC_ADDRESS(rel1) - RELOC_ADDRESS(rel2);    return RELOC_ADDRESS(rel1) - RELOC_ADDRESS(rel2);
 }  }
   
 /*  /* Moves to the next debugging symbol in the file.  USE_DATA_SYMBOLS
  * Takes the values in state_pointer and moves onward to the next     determines the type of the debugging symbol to look for (DSLINE or
  * debug line symbol.  It assumes that state_pointer[1] is valid; ie     SLINE).  STATE_POINTER keeps track of the old and new locatiosn in
  * that it.sym points into some entry in the symbol table.  If     the file.  It assumes that state_pointer[1] is valid; ie
  * state_pointer[1].sym == 0, this routine should not be called.     that it.sym points into some entry in the symbol table.  If
  */     state_pointer[1].sym == 0, this routine should not be called.  */
   
 int  int
 next_debug_entry (use_data_symbols, state_pointer)  next_debug_entry (use_data_symbols, state_pointer)
      register int use_data_symbols;       register int use_data_symbols;
      struct line_debug_entry state_pointer[3]; /* Must be passed by reference! */       /* Next must be passed by reference! */
        struct line_debug_entry state_pointer[3];
 {  {
   register struct line_debug_entry    register struct line_debug_entry
     *current = state_pointer,      *current = state_pointer,
     *next = state_pointer + 1,      *next = state_pointer + 1,
     *source = state_pointer + 2; /* Used to store source file */      /* Used to store source file */
       *source = state_pointer + 2;
   struct file_entry *entry = (struct file_entry *) source->sym;    struct file_entry *entry = (struct file_entry *) source->sym;
   
   current->sym = next->sym;    current->sym = next->sym;
Line 2761  next_debug_entry (use_data_symbols, stat Line 2532  next_debug_entry (use_data_symbols, stat
   while (++(next->sym) < (entry->symbols    while (++(next->sym) < (entry->symbols
                           + entry->header.a_syms/sizeof (struct nlist)))                            + entry->header.a_syms/sizeof (struct nlist)))
     {      {
       switch (next->sym->n_type)        /* n_type is a char, and N_SOL, N_EINCL and N_BINCL are > 0x80, so
          * may look negative...therefore, must mask to low bits
          */
         switch (next->sym->n_type & 0xff) 
         {          {
         case N_SLINE:          case N_SLINE:
           if (use_data_symbols) continue;            if (use_data_symbols) continue;
Line 2793  next_debug_entry (use_data_symbols, stat Line 2567  next_debug_entry (use_data_symbols, stat
   return 0;    return 0;
 }  }
   
 int  /* Create a structure to save the state of a scan through the debug
 address_to_line (address, state_pointer)     symbols.  USE_DATA_SYMBOLS is set if we should be scanning for
      unsigned long address;     DSLINE's instead of SLINE's.  entry is the file entry which points
      struct line_debug_entry state_pointer[3]; /* Must be passed by reference! */     at the symbols to use.  */
 {  
   struct line_debug_entry  
     *current = state_pointer,  
     *next = state_pointer + 1;  
   
   int use_data_symbols;  
   
   if (next->sym)  
     use_data_symbols = (next->sym->n_type & N_TYPE) == N_DATA;  
   
   while (next->sym  
          && next->sym->n_value < address  
          && next_debug_entry (use_data_symbols, state_pointer))  
     ;  
   return current->line;  
 }  
   
 struct line_debug_entry *  struct line_debug_entry *
 init_debug_scan (use_data_symbols, entry)  init_debug_scan (use_data_symbols, entry)
Line 2821  init_debug_scan (use_data_symbols, entry Line 2579  init_debug_scan (use_data_symbols, entry
 {  {
   struct line_debug_entry    struct line_debug_entry
     *state_pointer =      *state_pointer =
       (struct line_debug_entry *) xmalloc (3 * sizeof (struct line_debug_entry));        (struct line_debug_entry *)
           xmalloc (3 * sizeof (struct line_debug_entry));
   register struct line_debug_entry    register struct line_debug_entry
     *current = state_pointer,      *current = state_pointer,
     *next = state_pointer + 1,      *next = state_pointer + 1,
Line 2833  init_debug_scan (use_data_symbols, entry Line 2592  init_debug_scan (use_data_symbols, entry
        tmp < (entry->symbols         tmp < (entry->symbols
               + entry->header.a_syms/sizeof (struct nlist));                + entry->header.a_syms/sizeof (struct nlist));
        tmp++)         tmp++)
     if (tmp->n_type == (int) N_SO) break;      if (tmp->n_type == (int) N_SO)
         break;
   
   if (tmp >= (entry->symbols    if (tmp >= (entry->symbols
               + entry->header.a_syms/sizeof (struct nlist)))                + entry->header.a_syms/sizeof (struct nlist)))
Line 2874  init_debug_scan (use_data_symbols, entry Line 2634  init_debug_scan (use_data_symbols, entry
   
   return state_pointer;    return state_pointer;
 }  }
   
   /* Takes an ADDRESS (in either text or data space) and a STATE_POINTER
      which describes the current location in the implied scan through
      the debug symbols within the file which ADDRESS is within, and
      returns the source line number which corresponds to ADDRESS.  */
     
   int
   address_to_line (address, state_pointer)
        unsigned long address;
        /* Next must be passed by reference! */
        struct line_debug_entry state_pointer[3];
   {
     struct line_debug_entry
       *current = state_pointer,
       *next = state_pointer + 1;
     struct line_debug_entry *tmp_pointer;
   
     int use_data_symbols;
   
     if (next->sym)
       use_data_symbols = (next->sym->n_type & N_TYPE) == N_DATA;
     else
       return current->line;
   
     /* Go back to the beginning if we've already passed it.  */
     if (current->sym->n_value > address)
       {
         tmp_pointer = init_debug_scan (use_data_symbols,
                                        (struct file_entry *)
                                        ((state_pointer + 2)->sym));
         state_pointer[0] = tmp_pointer[0];
         state_pointer[1] = tmp_pointer[1];
         state_pointer[2] = tmp_pointer[2];
         free (tmp_pointer);
       }
   
     /* If we're still in a bad way, return -1, meaning invalid line.  */
     if (current->sym->n_value > address)
       return -1;
   
     while (next->sym
            && next->sym->n_value <= address
            && next_debug_entry (use_data_symbols, state_pointer))
       ;
     return current->line;
   }
   
   
   /* Macros for manipulating bitvectors.  */
   #define BIT_SET_P(bv, index)    ((bv)[(index) >> 3] & 1 << ((index) & 0x7))
   #define SET_BIT(bv, index)      ((bv)[(index) >> 3] |= 1 << ((index) & 0x7))
   
   /* This routine will scan through the relocation data of file ENTRY,
      printing out references to undefined symbols and references to
      symbols defined in files with N_WARNING symbols.  If DATA_SEGMENT
      is non-zero, it will scan the data relocation segment (and use
      N_DSLINE symbols to track line number); otherwise it will scan the
      text relocation segment.  Warnings will be printed on the output
      stream OUTFILE.  Eventually, every nlist symbol mapped through will
      be marked in the NLIST_BITVECTOR, so we don't repeat ourselves when
      we scan the nlists themselves.  */
   
   do_relocation_warnings (entry, data_segment, outfile, nlist_bitvector)
        struct file_entry *entry;
        int data_segment;
        FILE *outfile;
        unsigned char *nlist_bitvector;
   {
     struct relocation_info
       *reloc_start = data_segment ? entry->datarel : entry->textrel,
       *reloc;
     int reloc_size =
       (data_segment ? entry->header.a_drsize : entry->header.a_trsize)
         / sizeof (struct relocation_info);
     int start_of_segment =
       (data_segment ? entry->data_start_address : entry->text_start_address);
     struct nlist *start_of_syms = entry->symbols;
     struct line_debug_entry *state_pointer =
       init_debug_scan (data_segment != 0, entry);
     register struct line_debug_entry
       *current = state_pointer,
       *next = state_pointer + 1,
       *source = state_pointer + 2;
     /* Assigned to generally static values; should not be written into.  */
     char *errfmt;
     /* Assigned to alloca'd values cand copied into; should be freed
        when done.  */
     char *errmsg;
     int invalidate_line_number;
   
     /* We need to sort the relocation info here.  Sheesh, so much effort
        for one lousy error optimization. */
   
     qsort (reloc_start, reloc_size, sizeof (struct relocation_info),
            relocation_entries_relation);
   
     for (reloc = reloc_start;
          reloc < (reloc_start + reloc_size);
          reloc++)
       {
         register struct nlist *s;
         register symbol *g;
   
         /* If the relocation isn't resolved through a symbol, continue */
         if (!RELOC_EXTERN_P(reloc))
           continue;
   
         s = &(entry->symbols[RELOC_SYMBOL(reloc)]);
   
         /* Local symbols shouldn't ever be used by relocation info, so
            the next should be safe.
            This is, of course, wrong.  References to local BSS symbols can be
            the targets of relocation info, and they can (must) be
            resolved through symbols.  However, these must be defined properly,
            (the compiler would have caught it otherwise), so we can
            ignore these cases.  */
         if (!(s->n_type & N_EXT))
           continue;
   
         g = (symbol *) s->n_un.n_name;
   
         if (!g->defined && list_unresolved_refs) /* Reference */
           {
             /* Mark as being noted by relocation warning pass.  */
             SET_BIT (nlist_bitvector, s - start_of_syms);
             
             if (g->undef_refs >= MAX_UREFS_PRINTED)    /* Listed too many */
               continue;
   
             /* Undefined symbol which we should mention */
   
             if (++(g->undef_refs) == MAX_UREFS_PRINTED)
               {
                 errfmt = "More undefined symbol %s refs follow";
                 invalidate_line_number = 1;
               }
             else
               {
                 errfmt = "Undefined symbol %s referenced from %s segment";
                 invalidate_line_number = 0;
               }
           }
         else                                           /* Defined */
           {
             /* Potential symbol warning here */
             if (!g->warning) continue;
   
             /* Mark as being noted by relocation warning pass.  */
             SET_BIT (nlist_bitvector, s - start_of_syms);
             
             errfmt = g->warning;
             invalidate_line_number = 0;
           }
         
         errmsg = (char *) alloca (strlen (errfmt) + strlen (g->name) + 1);
         sprintf (errmsg, errfmt, g->name, data_segment ? "data" : "text");
         address_to_line (RELOC_ADDRESS (reloc) + start_of_segment,
                          state_pointer);
   
         if (current->line >=0)
           fprintf (outfile, "%s:%d: %s\n", current->filename,
                    invalidate_line_number ? 0 : current->line, errmsg);
         else
           fprintf (outfile, "%s: %s\n", current->filename, errmsg);
   
         free (errmsg);
       }
   
     free (state_pointer);
   }
   
   /* Print on OUTFILE a list of all warnings generated by references
      and/or definitions in the file ENTRY.  List source file and line
      number if possible, just the .o file if not. */
   
   void
   do_file_warnings (entry, outfile)
        struct file_entry *entry;
        FILE *outfile;
   {
     int number_of_syms = entry->header.a_syms / sizeof (struct nlist);
     unsigned char *nlist_bitvector =
       (unsigned char *) alloca ((number_of_syms >> 3) + 1);
     struct line_debug_entry *text_scan, *data_scan;
     int i;
     char *errfmt, *file_name;
     int line_number;
   
     bzero (nlist_bitvector, (number_of_syms >> 3) + 1);
   
     /* Read in the files strings if they aren't available */
     if (!entry->strings)
       {
         int desc;
   
         entry->strings = (char *) alloca (entry->string_size);
         desc = file_open (entry);
         read_entry_strings (desc, entry);
       }
   
     read_file_relocation (entry);
   
     /* Do text warnings based on a scan through the relocation info.  */
     do_relocation_warnings (entry, 0, outfile, nlist_bitvector);
   
     /* Do data warnings based on a scan through the relocation info.  */
     do_relocation_warnings (entry, 1, outfile, nlist_bitvector);
   
     /* Scan through all of the nlist entries in this file and pick up
        anything that the scan through the relocation stuff didn't.  */
   
     text_scan = init_debug_scan (0, entry);
     data_scan = init_debug_scan (1, entry);
   
     for (i = 0; i < number_of_syms; i++)
       {
         struct nlist *s;
         struct glosym *g;
   
         s = entry->symbols + i;
   
         if (!(s->n_type & N_EXT))
           continue;
   
         g = (symbol *) s->n_un.n_name;
   
         if (list_multiple_defs && g->multiply_defined)
           {
             errfmt = "Definition of symbol %s (multiply defined)";
             switch (s->n_type)
               {
               case N_TEXT | N_EXT:
                 line_number = address_to_line (s->n_value, text_scan);
                 file_name = text_scan[0].filename;
                 break;
               case N_DATA | N_EXT:
                 line_number = address_to_line (s->n_value, data_scan);
                 file_name = data_scan[0].filename;
                 break;
               case N_SETA | N_EXT:
               case N_SETT | N_EXT:
               case N_SETD | N_EXT:
               case N_SETB | N_EXT:
                 if (g->multiply_defined == 2)
                   continue;
                 errfmt = "First set element definition of symbol %s (multiply defined)";
                 break;
               default:
                 line_number = -1;
                 break;
               }
           }
         else if (BIT_SET_P (nlist_bitvector, i))
           continue;
         else if (list_unresolved_refs && !g->defined)
           {
             if (g->undef_refs >= MAX_UREFS_PRINTED)
               continue;
             
             if (++(g->undef_refs) == MAX_UREFS_PRINTED)
               errfmt = "More undefined %s refs follow";
             else
               errfmt = "Undefined symbol %s referenced";
             line_number = -1;
           }
         else if (g->warning)
           {
             errfmt = g->warning;
             line_number = -1;
           }
         else
           continue;
         
         if (line_number == -1)
           fprintf (outfile, "%s: ", entry->filename);
         else
           fprintf (outfile, "%s:%d: ", file_name, line_number);
   
         fprintf (outfile, errfmt, g->name);
   
         fputc ('\n', outfile);
       }
     free (text_scan);
     free (data_scan);
     entry->strings = 0;           /* Since it will dissapear anyway.  */
   }
   
 void   void 
 mark_flagged_symbols (entry, outfile)  mark_flagged_symbols (entry, outfile)
Line 2903  mark_flagged_symbols (entry, outfile) Line 2949  mark_flagged_symbols (entry, outfile)
 do_warnings (outfile)  do_warnings (outfile)
      FILE *outfile;       FILE *outfile;
 {  {
   struct glosym **clrefs;    int i;
   
   list_unresolved_refs = !relocatable_output && undefined_global_sym_count;    list_unresolved_refs = !relocatable_output && undefined_global_sym_count;
   list_warning_symbols = warning_count;    list_warning_symbols = warning_count;
   list_multple_defs = 0;                /* Not currently done here */    list_multiple_defs = multiple_def_count != 0;
   
   if (!(list_unresolved_refs ||    if (!(list_unresolved_refs ||
         list_warning_symbols ||          list_warning_symbols ||
         list_multple_defs      ))          list_multiple_defs      ))
     /* No need to run this routine */      /* No need to run this routine */
     return;      return;
   
   if (list_warning_symbols)    if (list_warning_symbols)
     each_full_file (mark_flagged_symbols, outfile);      each_file (mark_flagged_symbols, outfile);
   
   each_full_file (do_file_warnings, outfile);    each_file (do_file_warnings, outfile);
   
   if (!relocatable_output)  
     for (clrefs = cmdline_references;  
          clrefs < cmdline_references + cl_refs_allocated && *clrefs;  
          clrefs++)  
       if ((*clrefs)->referenced && !(*clrefs)->defined)  
         fprintf(stderr, "Error: Unresolved reference to symbol %s\n",  
                 (*clrefs)->name);  
   
   fprintf (outfile, "\n");    fprintf (outfile, "\n");
   
   if (list_unresolved_refs || list_multple_defs)    if (list_unresolved_refs || list_multiple_defs)
     make_executable = 0;      make_executable = 0;
 }  }
   
   
   #if 0
 /* Print the files which have the definitions for a given symbol.  /* Print the files which have the definitions for a given symbol.
    FIRST_DEF is the first nlist entry which defines the symbol, and     FIRST_DEF is the first nlist entry which defines the symbol, and
    REST_OF_REFS is a chain of nlist entries which may or may not be     REST_OF_REFS is a chain of nlist entries which may or may not be
Line 2973  print_files_defining_symbol (first_def,  Line 3013  print_files_defining_symbol (first_def, 
       else        else
         fatal ("internal: file not found containing nlist entry");          fatal ("internal: file not found containing nlist entry");
 }  }
   #endif
   
 /* Write the output file */  /* Write the output file */
   
Line 3019  void modify_location (), perform_relocat Line 3060  void modify_location (), perform_relocat
 void  void
 write_header ()  write_header ()
 {  {
   outheader.a_magic = magic;    N_SET_MAGIC (outheader, magic);
   outheader.a_text = text_size;    outheader.a_text = text_size;
   outheader.a_data = data_size;    outheader.a_data = data_size;
   outheader.a_bss = bss_size;    outheader.a_bss = bss_size;
Line 3068  write_header () Line 3109  write_header ()
   
       coffheader.f_magic = COFF_MAGIC;        coffheader.f_magic = COFF_MAGIC;
       coffheader.f_nscns = 3;        coffheader.f_nscns = 3;
       coffheader.f_timdat = 0;        /* store an unlikely time so programs can
          * tell that there is a bsd header
          */
         coffheader.f_timdat = 1;
       coffheader.f_symptr = 0;        coffheader.f_symptr = 0;
       coffheader.f_nsyms = 0;        coffheader.f_nsyms = 0;
       coffheader.f_opthdr = 28;        coffheader.f_opthdr = 28;
Line 3146  write_text () Line 3190  write_text ()
   each_full_file (copy_text);    each_full_file (copy_text);
   file_close ();    file_close ();
   
   /* Write out the set element vectors */  
   
   if (set_vector_count)  
     mywrite (set_vectors, set_symbol_count + set_vector_count, sizeof (unsigned long), outdesc);  
   
   if (trace_files)    if (trace_files)
     fprintf (stderr, "\n");      fprintf (stderr, "\n");
   
Line 3278  write_data () Line 3317  write_data ()
   each_full_file (copy_data);    each_full_file (copy_data);
   file_close ();    file_close ();
   
     /* Write out the set element vectors.  See digest symbols for
        description of length of the set vector section.  */
   
     if (set_vector_count)
       mywrite (set_vectors, 2 * set_symbol_count + set_vector_count,
                sizeof (unsigned long), outdesc);
   
   if (trace_files)    if (trace_files)
     fprintf (stderr, "\n");      fprintf (stderr, "\n");
   
Line 3490  write_rel () Line 3536  write_rel ()
       symbol *sp;        symbol *sp;
       for (sp = symtab[i]; sp; sp = sp->link)        for (sp = symtab[i]; sp; sp = sp->link)
         if (sp->referenced || sp->defined)          if (sp->referenced || sp->defined)
           sp->def_count = count++;            {
               sp->def_count = count++;
               /* Leave room for the reference required by N_INDR, if
                  necessary.  */
               if ((sp->defined & ~N_EXT) == N_INDR)
                 count++;
             }
     }      }
   if (count != defined_global_sym_count + undefined_global_sym_count)    /* Correct, because if (reloatable_output), we will also be writing
        whatever indirect blocks we have.  */
     if (count != defined_global_sym_count
         + undefined_global_sym_count + global_indirect_count)
     fatal ("internal error");      fatal ("internal error");
   
   /* Write out the relocations of all files, remembered from copy_text.  */    /* Write out the relocations of all files, remembered from copy_text.  */
Line 3531  coptxtrel (entry) Line 3586  coptxtrel (entry)
           if (symindex >= entry->header.a_syms)            if (symindex >= entry->header.a_syms)
             fatal_with_file ("relocation symbolnum out of range in ", entry);              fatal_with_file ("relocation symbolnum out of range in ", entry);
   
   #ifdef N_INDR
             /* Resolve indirection.  */
             if ((symptr->defined & ~N_EXT) == N_INDR)
               symptr = (symbol *) symptr->value;
   #endif
   
           /* If the symbol is now defined, change the external relocation            /* If the symbol is now defined, change the external relocation
              to an internal one.  */               to an internal one.  */
   
Line 3538  coptxtrel (entry) Line 3599  coptxtrel (entry)
             {              {
               RELOC_EXTERN_P(p) = 0;                RELOC_EXTERN_P(p) = 0;
               RELOC_SYMBOL(p) = (symptr->defined & N_TYPE);                RELOC_SYMBOL(p) = (symptr->defined & N_TYPE);
   #ifdef RELOC_ADD_EXTRA
                 /* If we aren't going to be adding in the value in
                    memory on the next pass of the loader, then we need
                    to add it in from the relocation entry.  Otherwise
                    the work we did in this pass is lost.  */
                 if (!RELOC_MEMORY_ADD_P(p))
                   RELOC_ADD_EXTRA (p) += symptr->value;
   #endif
             }              }
           else            else
               /* Debugger symbols come first, so have to start this
                  after them.  */
               RELOC_SYMBOL(p) = (symptr->def_count + nsyms                RELOC_SYMBOL(p) = (symptr->def_count + nsyms
                                  - defined_global_sym_count                                   - defined_global_sym_count
                                  - undefined_global_sym_count);                                   - undefined_global_sym_count
                                    - global_indirect_count);
         }          }
       p++;        p++;
     }      }
Line 3571  copdatrel (entry) Line 3643  copdatrel (entry)
                             (((struct nlist *)                              (((struct nlist *)
                               (((char *)entry->symbols) + symindex))                                (((char *)entry->symbols) + symindex))
                              ->n_un.n_name));                               ->n_un.n_name));
           int symtype = symptr->defined & N_TYPE;            int symtype;
   
           if (symindex >= entry->header.a_syms)            if (symindex >= entry->header.a_syms)
             fatal_with_file ("relocation symbolnum out of range in ", entry);              fatal_with_file ("relocation symbolnum out of range in ", entry);
   
   #ifdef N_INDR
             /* Resolve indirection.  */
             if ((symptr->defined & ~N_EXT) == N_INDR)
               symptr = (symbol *) symptr->value;
   #endif
   
              symtype = symptr->defined & N_TYPE;
   
           if (force_common_definition            if (force_common_definition
               || symtype == N_DATA || symtype == N_TEXT || symtype == N_ABS)                || symtype == N_DATA || symtype == N_TEXT || symtype == N_ABS)
             {              {
Line 3582  copdatrel (entry) Line 3663  copdatrel (entry)
               RELOC_SYMBOL(p) = symtype;                RELOC_SYMBOL(p) = symtype;
             }              }
           else            else
               /* Debugger symbols come first, so have to start this
                  after them.  */
             RELOC_SYMBOL(p)              RELOC_SYMBOL(p)
               = (((symbol *)                = (((symbol *)
                   (((struct nlist *)                    (((struct nlist *)
Line 3589  copdatrel (entry) Line 3672  copdatrel (entry)
                    ->n_un.n_name))                     ->n_un.n_name))
                  ->def_count                   ->def_count
                  + nsyms - defined_global_sym_count                   + nsyms - defined_global_sym_count
                  - undefined_global_sym_count);                   - undefined_global_sym_count
                    - global_indirect_count);
         }          }
       p++;        p++;
     }      }
Line 3791  write_syms () Line 3875  write_syms ()
                 xtra_ref.n_other = 0;                  xtra_ref.n_other = 0;
                 xtra_ref.n_desc = 0;                  xtra_ref.n_desc = 0;
                 xtra_ref.n_value = 0;                  xtra_ref.n_value = 0;
                 *bufp++ = nl;                  *bufp++ = xtra_ref;
                 syms_written++;                  syms_written++;
               }                }
           }            }
Line 3878  write_file_syms (entry, syms_written_add Line 3962  write_file_syms (entry, syms_written_add
       /* WRITE gets 1 for a non-global symbol that should be written.  */        /* WRITE gets 1 for a non-global symbol that should be written.  */
   
   
       if (SET_ELEMENT_P (type))         /* This occurs even if global.  These */        if (SET_ELEMENT_P (type)) /* This occurs even if global.  These */
                                 /* types of symbols are never written */                                  /* types of symbols are never written */
                                 /* globally, though they are stored */                                  /* globally, though they are stored */
                                 /* globally.  */                                  /* globally.  */
Line 3887  write_file_syms (entry, syms_written_add Line 3971  write_file_syms (entry, syms_written_add
         /* ordinary local symbol */          /* ordinary local symbol */
         write = ((discard_locals != DISCARD_ALL)          write = ((discard_locals != DISCARD_ALL)
                  && !(discard_locals == DISCARD_L &&                   && !(discard_locals == DISCARD_L &&
                       (p->n_un.n_strx + entry->strings)[0] == 'L')                        (p->n_un.n_strx + entry->strings)[0] == LPREFIX)
                  && type != N_WARNING);                   && type != N_WARNING);
       else if (!(type & N_EXT))        else if (!(type & N_EXT))
         /* debugger symbol */          /* debugger symbol */
Line 3929  write_file_syms (entry, syms_written_add Line 4013  write_file_syms (entry, syms_written_add
      using the data in vectors `strtab_vector' and `strtab_lens'.  */       using the data in vectors `strtab_vector' and `strtab_lens'.  */
   
   write_string_table ();    write_string_table ();
     entry->strings = 0;           /* Since it will dissapear anyway.  */
 }  }
   
 /* Copy any GDB symbol segments from the input files to the output file.  /* Copy any GDB symbol segments from the input files to the output file.
Line 4083  getsym (key) Line 4168  getsym (key)
   bp->value = 0;    bp->value = 0;
   bp->max_common_size = 0;    bp->max_common_size = 0;
   bp->warning = 0;    bp->warning = 0;
     bp->undef_refs = 0;
     bp->multiply_defined = 0;
   
   /* Add the entry to the bucket.  */    /* Add the entry to the bucket.  */
   

Removed from v.1.1.1.3  
changed lines
  Added in v.1.1.1.4


unix.superglobalmegacorp.com