Remove rcfonts.tex after building refcard.
[deliverable/binutils-gdb.git] / ld / ldsym.c
index 24272a926c5c54630ebd674daa8ba3267ed84434..98a1b8b5f73d1d002965071929c82194fdaa7552 100644 (file)
@@ -19,29 +19,6 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 /*
  *  $Id$ 
  *
- *  $Log$
- *  Revision 1.2  1991/03/22 23:02:38  steve
- *  Brought up to sync with Intel again.
- *
- * Revision 1.1  1991/03/13  00:48:32  chrisb
- * Initial revision
- *
- * Revision 1.4  1991/03/10  09:31:36  rich
- *  Modified Files:
- *     Makefile config.h ld-emul.c ld-emul.h ld-gld.c ld-gld960.c
- *     ld-lnk960.c ld.h lddigest.c ldexp.c ldexp.h ldfile.c ldfile.h
- *     ldgram.y ldinfo.h ldlang.c ldlang.h ldlex.h ldlex.l ldmain.c
- *     ldmain.h ldmisc.c ldmisc.h ldsym.c ldsym.h ldversion.c
- *     ldversion.h ldwarn.h ldwrite.c ldwrite.h y.tab.h
- *
- * As of this round of changes, ld now builds on all hosts of (Intel960)
- * interest and copy passes my copy test on big endian hosts again.
- *
- * Revision 1.3  1991/03/06  02:28:56  sac
- * Cleaned up
- *
- * Revision 1.2  1991/02/22  17:15:06  sac
- * Added RCS keywords and copyrights
  *
 */
 
@@ -49,9 +26,40 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
    Written by Steve Chamberlain steve@cygnus.com
  
    All symbol handling for the linker
- */
 
 
+
+
+   We keep a hash table of global symbols. Each entry in a hash table
+   is called an ldsym_type. Each has three chains; a pointer to a
+   chain of definitions for the symbol (hopefully one long), a pointer
+   to a chain of references to the symbol, and a pointer to a chain of
+   common symbols. Each pointer points into the canonical symbol table
+   provided by bfd, each one of which points to an asymbol. Duringing
+   linkage, the linker uses the udata field to point to the next entry
+   in a canonical table....
+
+
+   ld_sym
+                       |          |
+   +----------+                +----------+
+   | defs     |      a canonical symbol table
+   +----------+         +----------+
+   | refs     | ----->  | one entry|  -----> asymbol
+   +----------+                +----------+       |         |
+   | coms     |                |          |       +---------+
+   +----------+                +----------+       | udata   |-----> another canonical symbol
+                                          +---------+                               
+
+
+
+   It is very simple to make all the symbol pointers point to the same
+   definition - just run down the chain and make the asymbols pointers
+   within the canonical table point to the asymbol attacthed to the
+   definition of the symbol.
+
+*/
+
 #include "sysdep.h"
 #include "bfd.h"
 
@@ -62,6 +70,8 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 /* IMPORT */
 
 extern bfd *output_bfd;
+extern strip_symbols_type strip_symbols;
+extern discard_locals_type discard_locals;
 /* Head and tail of global symbol table chronological list */
 
 ldsym_type *symbol_head = (ldsym_type *)NULL;
@@ -82,12 +92,15 @@ extern boolean option_longmap ;
 static ldsym_type *global_symbol_hash_table[TABSIZE];
 
 /* Compute the hash code for symbol name KEY.  */
-
+static 
+#ifdef __GNUC__
+inline
+#endif
 int
-hash_string (key)
-     char *key;
+DEFUN(hash_string,(key),
+      CONST char *key)
 {
-  register char *cp;
+  register CONST char *cp;
   register int k;
 
   cp = key;
@@ -98,11 +111,33 @@ hash_string (key)
   return k;
 }
 
+static
+#ifdef __GNUC__
+inline
+#endif ldsym_type *bp;
+ldsym_type *
+DEFUN(search,(key,hashval) ,
+      CONST char *key AND
+      int hashval)
+{
+  ldsym_type *bp;                                 
+  for (bp = global_symbol_hash_table[hashval]; bp; bp = bp->link)
+    if (! strcmp (key, bp->name)) {
+      if (bp->flags & SYM_INDIRECT) {  
+       /* Use the symbol we're aliased to instead */
+       return (ldsym_type *)(bp->sdefs_chain);
+      }
+      return bp;
+    }
+  return 0;
+}
+
+
 /* Get the symbol table entry for the global symbol named KEY.
    Create one if there is none.  */
 ldsym_type *
-ldsym_get (key)
-     char *key;
+DEFUN(ldsym_get,(key),
+      CONST     char *key)
 {
   register int hashval;
   register ldsym_type *bp;
@@ -112,23 +147,19 @@ ldsym_get (key)
   hashval = hash_string (key) % TABSIZE;
 
   /* Search the bucket.  */
-
-  for (bp = global_symbol_hash_table[hashval]; bp; bp = bp->link)
-    if (! strcmp (key, bp->name))
-      return bp;
+  bp = search(key, hashval);
+  if(bp) {
+    return bp;
+  }
 
   /* Nothing was found; create a new symbol table entry.  */
 
-  bp = (ldsym_type *) ldmalloc (sizeof (ldsym_type));
+  bp = (ldsym_type *) ldmalloc ((bfd_size_type)(sizeof (ldsym_type)));
   bp->srefs_chain = (asymbol **)NULL;
   bp->sdefs_chain = (asymbol **)NULL;
   bp->scoms_chain = (asymbol **)NULL;
-  bp->name = (char *) ldmalloc (strlen (key) + 1);
-  strcpy (bp->name, key);
-
-
-
-
+  bp->name = buystring(key);
+  bp->flags = 0;
   /* Add the entry to the bucket.  */
 
   bp->link = global_symbol_hash_table[hashval];
@@ -146,8 +177,8 @@ ldsym_get (key)
 /* Like `ldsym_get' but return 0 if the symbol is not already known.  */
 
 ldsym_type *
-ldsym_get_soft (key)
-     char *key;
+DEFUN(ldsym_get_soft,(key),
+      CONST char *key)
 {
   register int hashval;
   register ldsym_type *bp;
@@ -157,12 +188,7 @@ ldsym_get_soft (key)
   hashval = hash_string (key) % TABSIZE;
 
   /* Search the bucket.  */
-
-  for (bp = global_symbol_hash_table[hashval]; bp; bp = bp->link)
-    if (! strcmp (key, bp->name))
-      return bp;
-
-  return 0;
+return search(key, hashval);
 }
 
 
@@ -174,9 +200,9 @@ list_file_locals (entry)
 lang_input_statement_type *entry;
 {
   asymbol **q;
-  fprintf (stderr, "\nLocal symbols of ");
+  printf ( "\nLocal symbols of ");
   info("%I", entry);
-  fprintf (stderr, ":\n\n");
+  printf (":\n\n");
   if (entry->asymbols) {
     for (q = entry->asymbols; *q; q++) 
       {
@@ -194,90 +220,93 @@ static void
 print_file_stuff(f)
 lang_input_statement_type *f;
 {
-  fprintf (stderr, "  %s", f->filename);
-  fprintf (stderr, " ");
+  fprintf (stdout, "  %s\n", f->filename);
   if (f->just_syms_flag) 
-    {
-      fprintf (stderr, " symbols only\n");
-    }
+      {
+       fprintf (stdout, " symbols only\n");
+      }
   else 
-    {
-      asection *s;
-      if (option_longmap) {
-       for (s = f->the_bfd->sections;
-            s != (asection *)NULL;
-            s = s->next) {
-         fprintf (stderr, "%08lx %08x 2**%2ud %s\n",
-                  s->output_offset,
-                  (unsigned)s->size, s->alignment_power, s->name);
+      {
+       asection *s;
+       if (true || option_longmap) {
+         for (s = f->the_bfd->sections;
+              s != (asection *)NULL;
+              s = s->next) {
+           print_address(s->output_offset);
+           printf (" %08x 2**%2ud %s\n",
+                   (unsigned)s->size, s->alignment_power, s->name);
+         }
        }
-      }
-      else {         
-       for (s = f->the_bfd->sections;
-            s != (asection *)NULL;
-            s = s->next) {
-         fprintf (stderr, "%s %lx(%x) ",
-                  s->name,
-                  s->output_offset,
-                  (unsigned)   s->size);
+       else {        
+         for (s = f->the_bfd->sections;
+              s != (asection *)NULL;
+              s = s->next) {
+           printf("%s ", s->name);
+           print_address(s->output_offset);
+           printf("(%x)", (unsigned)s->size);
+         }
+         printf("hex \n");
        }
-       fprintf (stderr, "hex \n");
       }
-    }
+  fprintf (stdout, "\n");
 }
 
 void
 ldsym_print_symbol_table ()
 {
-  fprintf (stderr, "\nFiles:\n\n");
+  fprintf (stdout, "**FILES**\n\n");
 
   lang_for_each_file(print_file_stuff);
 
-  fprintf (stderr, "\nGlobal symbols:\n\n");
+  fprintf(stdout, "**GLOBAL SYMBOLS**\n\n");
+  fprintf(stdout, "offset    section    offset   symbol\n");
   {
     register ldsym_type *sp;
 
     for (sp = symbol_head; sp; sp = sp->next)
       {
+       if (sp->flags & SYM_INDIRECT) {
+         fprintf(stdout,"indirect %s to %s\n",
+                 sp->name, (((ldsym_type *)(sp->sdefs_chain))->name));
+      }
+    else {
        if (sp->sdefs_chain) 
          {
            asymbol *defsym = *(sp->sdefs_chain);
            asection *defsec = bfd_get_section(defsym);
-           fprintf(stderr,"%08lx ",defsym->value);
+           print_address(defsym->value);
            if (defsec)
              {
-               fprintf(stderr,"%08lx ",defsym->value+defsec->vma);
-               fprintf(stderr,
-                       "%7s",
+               printf("  %-10s",
                        bfd_section_name(output_bfd,
                                         defsec));
+               print_space();
+               print_address(defsym->value+defsec->vma);
 
              }
            else 
              {
-               fprintf(stderr,"         .......");
+               printf("         .......");
              }
 
          }     
-       else {
-         fprintf(stderr,"undefined");
-       }
 
 
        if (sp->scoms_chain) {
-         fprintf(stderr, " common size %5lu    %s",
-                 (*(sp->scoms_chain))->value, sp->name);
+         printf("common               ");
+         print_address((*(sp->scoms_chain))->value);
+         printf(" %s ",sp->name);
        }
-       if (sp->sdefs_chain) {
-         fprintf(stderr, " symbol def %08lx    %s",
-                 (*(sp->sdefs_chain))->value,
-                 sp->name);
+       else if (sp->sdefs_chain) {
+         printf(" %s ",sp->name);
        }
        else {
-         fprintf(stderr, " undefined    %s",
-                 sp->name);
+         printf("undefined                     ");
+         printf("%s ",sp->name);
+
        }
-       fprintf(stderr, "\n");
+      }
+       print_nl();
 
       }
   }
@@ -381,7 +410,7 @@ asymbol **symbol_table;
 {
   FOR_EACH_LDSYM(sp)
     {
-      if (sp->sdefs_chain != (asymbol **)NULL) {
+      if ((sp->flags & SYM_INDIRECT) == 0 && sp->sdefs_chain != (asymbol **)NULL) {
        asymbol *bufp = (*(sp->sdefs_chain));
 
        if ((bufp->flags & BSF_KEEP) ==0) {
@@ -439,7 +468,7 @@ ldsym_write()
     extern unsigned int total_symbols_seen;
 
     asymbol **  symbol_table =  (asymbol **) 
-      ldmalloc ((size_t)(global_symbol_count +
+      ldmalloc ((bfd_size_type)(global_symbol_count +
                         total_files_seen +
                         total_symbols_seen + 1) *     sizeof (asymbol *));
     asymbol ** tablep = write_file_locals(symbol_table);
@@ -450,3 +479,18 @@ ldsym_write()
     bfd_set_symtab(output_bfd, symbol_table, (unsigned)( tablep - symbol_table));
   }
 }
+
+/*
+return true if the supplied symbol name is not in the 
+linker symbol table
+*/
+boolean 
+DEFUN(ldsym_undefined,(sym),
+      CONST char *sym)
+{
+  ldsym_type *from_table = ldsym_get_soft(sym);
+  if (from_table != (ldsym_type *)NULL) {
+    if (from_table->sdefs_chain != (asymbol **)NULL) return false;
+  }
+  return true;
+}
This page took 0.027006 seconds and 4 git commands to generate.