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