Remove rcfonts.tex after building refcard.
[deliverable/binutils-gdb.git] / ld / ldsym.c
index 4e6bec5712f1965c96d893bf206968284a36db74..98a1b8b5f73d1d002965071929c82194fdaa7552 100644 (file)
@@ -26,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"
 
@@ -61,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;
@@ -77,6 +111,28 @@ 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 *
@@ -91,10 +147,10 @@ DEFUN(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.  */
 
@@ -103,7 +159,7 @@ DEFUN(ldsym_get,(key),
   bp->sdefs_chain = (asymbol **)NULL;
   bp->scoms_chain = (asymbol **)NULL;
   bp->name = buystring(key);
-
+  bp->flags = 0;
   /* Add the entry to the bucket.  */
 
   bp->link = global_symbol_hash_table[hashval];
@@ -132,12 +188,7 @@ DEFUN(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);
 }
 
 
@@ -169,50 +220,56 @@ static void
 print_file_stuff(f)
 lang_input_statement_type *f;
 {
-  fprintf (stdout, "  %s", f->filename);
-  fprintf (stdout, " ");
+  fprintf (stdout, "  %s\n", f->filename);
   if (f->just_syms_flag) 
-    {
-      fprintf (stdout, " symbols only\n");
-    }
+      {
+       fprintf (stdout, " symbols only\n");
+      }
   else 
-    {
-      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);
+      {
+       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) {
-         printf("%s ", s->name);
-         print_address(s->output_offset);
-         printf("(%x)", (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");
        }
-       printf("hex \n");
       }
-    }
+  fprintf (stdout, "\n");
 }
 
 void
 ldsym_print_symbol_table ()
 {
-  fprintf (stdout, "\nFiles:\n\n");
+  fprintf (stdout, "**FILES**\n\n");
 
   lang_for_each_file(print_file_stuff);
 
-  fprintf (stdout, "\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);
@@ -220,11 +277,11 @@ ldsym_print_symbol_table ()
            print_address(defsym->value);
            if (defsec)
              {
-               print_space();
-               print_address(defsym->value+defsec->vma);
-               printf("%7s",
+               printf("  %-10s",
                        bfd_section_name(output_bfd,
                                         defsec));
+               print_space();
+               print_address(defsym->value+defsec->vma);
 
              }
            else 
@@ -233,25 +290,22 @@ ldsym_print_symbol_table ()
              }
 
          }     
-       else {
-         printf("undefined");
-       }
 
 
        if (sp->scoms_chain) {
-         printf(" common size ");
+         printf("common               ");
          print_address((*(sp->scoms_chain))->value);
-         printf("%s ",sp->name);
+         printf(" %s ",sp->name);
        }
-       if (sp->sdefs_chain) {
-         printf(" symbol def ");
-         print_address((*(sp->sdefs_chain))->value);
-         printf("%s ",sp->name);
+       else if (sp->sdefs_chain) {
+         printf(" %s ",sp->name);
        }
        else {
-         printf(" undefined    ");
+         printf("undefined                     ");
          printf("%s ",sp->name);
+
        }
+      }
        print_nl();
 
       }
@@ -356,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) {
This page took 0.026494 seconds and 4 git commands to generate.