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