6199c1bf3cd859cf85c6ba0101fa8f14c0a835a2
[binutils-gdb.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 }