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