Add or update copyright notices.
[external/binutils.git] / ld / ldsym.c
1 /* All symbol handling for the linker
2    Copyright (C) 1991 Free Software Foundation, Inc.
3    Written by Steve Chamberlain steve@cygnus.com
4  
5 This file is part of GLD, the Gnu Linker.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
20
21 /*
22  *  $Id$ 
23  */
24
25 /* 
26    We keep a hash table of global symbols. Each entry in a hash table
27    is called an ldsym_type. Each has three chains; a pointer to a
28    chain of definitions for the symbol (hopefully one long), a pointer
29    to a chain of references to the symbol, and a pointer to a chain of
30    common symbols. Each pointer points into the canonical symbol table
31    provided by bfd, each one of which points to an asymbol. Duringing
32    linkage, the linker uses the udata field to point to the next entry
33    in a canonical table....
34
35
36    ld_sym
37                         |          |
38    +----------+         +----------+
39    | defs     |      a canonical symbol table
40    +----------+         +----------+
41    | refs     | ----->  | one entry|  -----> asymbol
42    +----------+         +----------+       |         |
43    | coms     |         |          |       +---------+
44    +----------+         +----------+       | udata   |-----> another canonical symbol
45                                            +---------+                               
46
47
48
49    It is very simple to make all the symbol pointers point to the same
50    definition - just run down the chain and make the asymbols pointers
51    within the canonical table point to the asymbol attacthed to the
52    definition of the symbol.
53
54 */
55
56 #include "bfd.h"
57 #include "sysdep.h"
58
59 #include "ld.h"
60 #include "ldsym.h"
61 #include "ldmisc.h"
62 #include "ldlang.h"
63 /* IMPORT */
64
65 extern bfd *output_bfd;
66 extern strip_symbols_type strip_symbols;
67 extern discard_locals_type discard_locals;
68 /* Head and tail of global symbol table chronological list */
69
70 ldsym_type *symbol_head = (ldsym_type *)NULL;
71 ldsym_type **symbol_tail_ptr = &symbol_head;
72
73 /*
74   incremented for each symbol in the ldsym_type table
75   no matter what flavour it is 
76 */
77 unsigned int global_symbol_count;
78
79 /* IMPORTS */
80
81 extern boolean option_longmap ;
82
83 /* LOCALS */
84 #define TABSIZE 1009
85 static ldsym_type *global_symbol_hash_table[TABSIZE];
86
87 /* Compute the hash code for symbol name KEY.  */
88 static 
89 #ifdef __GNUC__
90 inline
91 #endif
92 int
93 DEFUN(hash_string,(key),
94       CONST char *key)
95 {
96   register CONST char *cp;
97   register int k;
98
99   cp = key;
100   k = 0;
101   while (*cp)
102     k = (((k << 1) + (k >> 14)) ^ (*cp++)) & 0x3fff;
103
104   return k;
105 }
106
107 static
108 #ifdef __GNUC__
109 inline
110 #endif ldsym_type *bp;
111 ldsym_type *
112 DEFUN(search,(key,hashval) ,
113       CONST char *key AND
114       int hashval)
115 {
116   ldsym_type *bp;                                  
117   for (bp = global_symbol_hash_table[hashval]; bp; bp = bp->link)
118     if (! strcmp (key, bp->name)) {
119       if (bp->flags & SYM_INDIRECT) {   
120         /* Use the symbol we're aliased to instead */
121         return (ldsym_type *)(bp->sdefs_chain);
122       }
123       return bp;
124     }
125   return 0;
126 }
127
128
129 /* Get the symbol table entry for the global symbol named KEY.
130    Create one if there is none.  */
131 ldsym_type *
132 DEFUN(ldsym_get,(key),
133       CONST     char *key)
134 {
135   register int hashval;
136   register ldsym_type *bp;
137
138   /* Determine the proper bucket.  */
139
140   hashval = hash_string (key) % TABSIZE;
141
142   /* Search the bucket.  */
143   bp = search(key, hashval);
144   if(bp) {
145     return bp;
146   }
147
148   /* Nothing was found; create a new symbol table entry.  */
149
150   bp = (ldsym_type *) ldmalloc ((bfd_size_type)(sizeof (ldsym_type)));
151   bp->srefs_chain = (asymbol **)NULL;
152   bp->sdefs_chain = (asymbol **)NULL;
153   bp->scoms_chain = (asymbol **)NULL;
154   bp->name = buystring(key);
155   bp->flags = 0;
156   /* Add the entry to the bucket.  */
157
158   bp->link = global_symbol_hash_table[hashval];
159   global_symbol_hash_table[hashval] = bp;
160
161   /* Keep the chronological list up to date too */
162   *symbol_tail_ptr = bp;
163   symbol_tail_ptr = &bp->next;
164   bp->next = 0;
165   global_symbol_count++;
166
167   return bp;
168 }
169
170 /* Like `ldsym_get' but return 0 if the symbol is not already known.  */
171
172 ldsym_type *
173 DEFUN(ldsym_get_soft,(key),
174       CONST char *key)
175 {
176   register int hashval;
177   /* Determine which bucket.  */
178
179   hashval = hash_string (key) % TABSIZE;
180
181   /* Search the bucket.  */
182   return search(key, hashval);
183 }
184
185
186
187
188
189 static void
190 list_file_locals (entry)
191 lang_input_statement_type *entry;
192 {
193   asymbol **q;
194   printf ( "\nLocal symbols of ");
195   info("%I", entry);
196   printf (":\n\n");
197   if (entry->asymbols) {
198     for (q = entry->asymbols; *q; q++) 
199       {
200         asymbol *p = *q;
201         /* If this is a definition,
202            update it if necessary by this file's start address.  */
203         if (p->flags & BSF_LOCAL)
204          info("  %V %s\n",p->value, p->name);
205       }
206   }
207 }
208
209
210 static void
211 print_file_stuff(f)
212 lang_input_statement_type *f;
213 {
214   fprintf (stdout, "  %s\n", f->filename);
215   if (f->just_syms_flag) 
216       {
217         fprintf (stdout, " symbols only\n");
218       }
219   else 
220       {
221         asection *s;
222         if (true || option_longmap) {
223           for (s = f->the_bfd->sections;
224                s != (asection *)NULL;
225                s = s->next) {
226             print_address(s->output_offset);
227             printf (" %08x 2**%2ud %s\n",
228                     (unsigned)s->size, s->alignment_power, s->name);
229           }
230         }
231         else {        
232           for (s = f->the_bfd->sections;
233                s != (asection *)NULL;
234                s = s->next) {
235             printf("%s ", s->name);
236             print_address(s->output_offset);
237             printf("(%x)", (unsigned)s->size);
238           }
239           printf("hex \n");
240         }
241       }
242   fprintf (stdout, "\n");
243 }
244
245 void
246 ldsym_print_symbol_table ()
247 {
248   fprintf (stdout, "**FILES**\n\n");
249
250   lang_for_each_file(print_file_stuff);
251
252   fprintf(stdout, "**GLOBAL SYMBOLS**\n\n");
253   fprintf(stdout, "offset    section    offset   symbol\n");
254   {
255     register ldsym_type *sp;
256
257     for (sp = symbol_head; sp; sp = sp->next)
258       {
259         if (sp->flags & SYM_INDIRECT) {
260           fprintf(stdout,"indirect %s to %s\n",
261                   sp->name, (((ldsym_type *)(sp->sdefs_chain))->name));
262       }
263     else {
264         if (sp->sdefs_chain) 
265           {
266             asymbol *defsym = *(sp->sdefs_chain);
267             asection *defsec = bfd_get_section(defsym);
268             print_address(defsym->value);
269             if (defsec)
270               {
271                 printf("  %-10s",
272                         bfd_section_name(output_bfd,
273                                          defsec));
274                 print_space();
275                 print_address(defsym->value+defsec->vma);
276
277               }
278             else 
279               {
280                 printf("         .......");
281               }
282
283           }     
284
285
286         if (sp->scoms_chain) {
287           printf("common               ");
288           print_address((*(sp->scoms_chain))->value);
289           printf(" %s ",sp->name);
290         }
291         else if (sp->sdefs_chain) {
292           printf(" %s ",sp->name);
293         }
294         else {
295           printf("undefined                     ");
296           printf("%s ",sp->name);
297
298         }
299       }
300         print_nl();
301
302       }
303   }
304   lang_for_each_file(list_file_locals);
305 }
306
307 extern lang_output_section_statement_type *create_object_symbols;
308 extern char lprefix;
309 static asymbol **
310 write_file_locals(output_buffer)
311 asymbol **output_buffer;
312 {
313 LANG_FOR_EACH_INPUT_STATEMENT(entry)
314     {
315       /* Run trough the symbols and work out what to do with them */
316       unsigned int i;
317
318       /* Add one for the filename symbol if needed */
319       if (create_object_symbols 
320           != (lang_output_section_statement_type *)NULL) {
321         asection *s;
322         for (s = entry->the_bfd->sections;
323              s != (asection *)NULL;
324              s = s->next) {
325           if (s->output_section == create_object_symbols->bfd_section) {
326             /* Add symbol to this section */
327             asymbol * newsym  =
328               (asymbol *)bfd_make_empty_symbol(entry->the_bfd);
329             newsym->name = entry->local_sym_name;
330             /* The symbol belongs to the output file's text section */
331
332             /* The value is the start of this section in the output file*/
333             newsym->value  = 0;
334             newsym->flags = BSF_LOCAL;
335             newsym->section = s;
336             *output_buffer++ = newsym;
337             break;
338           }
339         }
340       }
341       for (i = 0; i < entry->symbol_count; i++) 
342         {
343           asymbol *p = entry->asymbols[i];
344
345           if (flag_is_global(p->flags) || flag_is_absolute(p->flags))
346             {
347               /* We are only interested in outputting 
348                  globals at this stage in special circumstances */
349               if (p->the_bfd == entry->the_bfd 
350                   && flag_is_not_at_end(p->flags)) {
351                 /* And this is one of them */
352                 *(output_buffer++) = p;
353                 p->flags |= BSF_KEEP;
354               }
355             }
356           else {
357             if (flag_is_ordinary_local(p->flags)) 
358               {
359                 if (discard_locals == DISCARD_ALL)
360                   {  }
361                 else if (discard_locals == DISCARD_L &&
362                          (p->name[0] == lprefix)) 
363                   {  }
364                 else if (p->flags ==  BSF_WARNING) 
365                   {  }
366                 else 
367                   { *output_buffer++ = p; }
368               }
369             else if (flag_is_debugger(p->flags)) 
370               {
371                 /* Only keep the debugger symbols if no stripping required */
372                 if (strip_symbols == STRIP_NONE) {
373                   *output_buffer++ = p;
374                 }
375               }
376             else if (flag_is_undefined(p->flags)) 
377               { /* This must be global */
378               }
379             else if (flag_is_common(p->flags)) {
380            /* And so must this */
381             } 
382             else if (p->flags & BSF_CTOR) {
383               /* Throw it away */
384             }
385 else
386               {
387                 FAIL();
388               }
389           }
390         }
391
392
393     }
394   return output_buffer;
395 }
396
397
398 static asymbol **
399 write_file_globals(symbol_table)
400 asymbol **symbol_table;
401 {
402   FOR_EACH_LDSYM(sp)
403     {
404       if ((sp->flags & SYM_INDIRECT) == 0 && sp->sdefs_chain != (asymbol **)NULL) {
405         asymbol *bufp = (*(sp->sdefs_chain));
406
407         if ((bufp->flags & BSF_KEEP) ==0) {
408           ASSERT(bufp != (asymbol *)NULL);
409
410           bufp->name = sp->name;
411
412           if (sp->scoms_chain != (asymbol **)NULL)      
413
414             {
415               /* 
416                  defined as common but not allocated, this happens
417                  only with -r and not -d, write out a common
418                  definition
419                  */
420               bufp = *(sp->scoms_chain);
421             }
422           *symbol_table++ = bufp;
423         }
424       }
425       else if (sp->scoms_chain != (asymbol **)NULL) {
426         /* This symbol is a common - just output */
427         asymbol *bufp = (*(sp->scoms_chain));
428         *symbol_table++ = bufp;
429       }
430       else if (sp->srefs_chain != (asymbol **)NULL) {
431         /* This symbol is undefined but has a reference */
432         asymbol *bufp = (*(sp->srefs_chain));
433         *symbol_table++ = bufp;
434       }
435       else {
436         /*
437            This symbol has neither defs nor refs, it must have come
438            from the command line, since noone has used it it has no
439            data attatched, so we'll ignore it 
440            */
441       }
442     }
443   return symbol_table;
444 }
445
446
447
448 void
449 ldsym_write()
450 {
451   if (strip_symbols != STRIP_ALL) {
452     /* We know the maximum size of the symbol table -
453        it's the size of all the global symbols ever seen +
454        the size of all the symbols from all the files +
455        the number of files (for the per file symbols)
456        +1 (for the null at the end)
457        */
458     extern unsigned int total_files_seen;
459     extern unsigned int total_symbols_seen;
460
461     asymbol **  symbol_table =  (asymbol **) 
462       ldmalloc ((bfd_size_type)(global_symbol_count +
463                          total_files_seen +
464                          total_symbols_seen + 1) *     sizeof (asymbol *));
465     asymbol ** tablep = write_file_locals(symbol_table);
466
467     tablep = write_file_globals(tablep);
468
469     *tablep =  (asymbol *)NULL;
470     bfd_set_symtab(output_bfd, symbol_table, (unsigned)( tablep - symbol_table));
471   }
472 }
473
474 /*
475 return true if the supplied symbol name is not in the 
476 linker symbol table
477 */
478 boolean 
479 DEFUN(ldsym_undefined,(sym),
480       CONST char *sym)
481 {
482   ldsym_type *from_table = ldsym_get_soft(sym);
483   if (from_table != (ldsym_type *)NULL) {
484     if (from_table->sdefs_chain != (asymbol **)NULL) return false;
485   }
486   return true;
487 }