23512794e38eac75940a138c1a48f042bfb1dc20
[binutils-gdb.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 We keep a hash table of global symbols. Each entry in a hash table
23 is called an ldsym_type. Each has three chains; a pointer to a
24 chain of definitions for the symbol (hopefully one long), a pointer
25 to a chain of references to the symbol, and a pointer to a chain of
26 common symbols. Each pointer points into the canonical symbol table
27 provided by bfd, each one of which points to an asymbol. During
28 linkage, the linker uses the udata field to point to the next entry
29 in a canonical table....
30
31
32 ld_sym
33 | |
34 +----------+ +----------+
35 | defs | a canonical symbol table
36 +----------+ +----------+
37 | refs | -----> | one entry| -----> asymbol
38 +----------+ +----------+ | |
39 | coms | | | +---------+
40 +----------+ +----------+ | udata |-----> another canonical symbol
41 +---------+
42
43
44
45 It is very simple to make all the symbol pointers point to the same
46 definition - just run down the chain and make the asymbols pointers
47 within the canonical table point to the asymbol attacthed to the
48 definition of the symbol.
49
50 */
51
52 #include "bfd.h"
53 #include "sysdep.h"
54
55 #include "ld.h"
56 #include "ldsym.h"
57 #include "ldmisc.h"
58 #include "ldlang.h"
59 /* IMPORT */
60 extern int symbol_truncate;
61 extern bfd *output_bfd;
62 extern strip_symbols_type strip_symbols;
63 extern discard_locals_type discard_locals;
64 /* Head and tail of global symbol table chronological list */
65
66 ldsym_type *symbol_head = (ldsym_type *)NULL;
67 ldsym_type **symbol_tail_ptr = &symbol_head;
68 CONST char *keepsyms_file;
69 int kept_syms;
70
71 extern ld_config_type config;
72
73 struct obstack global_sym_obstack;
74 #define obstack_chunk_alloc ldmalloc
75 #define obstack_chunk_free free
76
77 /*
78 incremented for each symbol in the ldsym_type table
79 no matter what flavour it is
80 */
81 unsigned int global_symbol_count;
82
83 /* IMPORTS */
84
85 extern boolean option_longmap ;
86
87 /* LOCALS */
88 #define TABSIZE 1009
89 static ldsym_type *global_symbol_hash_table[TABSIZE];
90
91 /* Compute the hash code for symbol name KEY. */
92 static
93 #ifdef __GNUC__
94 __inline
95 #endif
96
97 int
98 DEFUN(hash_string,(key),
99 CONST char *key)
100 {
101 register CONST char *cp;
102 register int k;
103 register int l = 0;
104 cp = key;
105 k = 0;
106 while (*cp && l < symbol_truncate) {
107 k = (((k << 1) + (k >> 14)) ^ (*cp++)) & 0x3fff;
108 l++;
109 }
110 return k;
111 }
112
113 static
114 #ifdef __GNUC__
115 __inline
116 #endif
117 ldsym_type *
118 DEFUN(search,(key,hashval) ,
119 CONST char *key AND
120 int hashval)
121 {
122 ldsym_type *bp;
123 for (bp = global_symbol_hash_table[hashval]; bp; bp = bp->link)
124 if (! strncmp (key, bp->name, symbol_truncate)) {
125 if (bp->flags & SYM_INDIRECT) {
126 /* Use the symbol we're aliased to instead */
127 return (ldsym_type *)(bp->sdefs_chain);
128 }
129 return bp;
130 }
131 return 0;
132 }
133
134
135 /* Get the symbol table entry for the global symbol named KEY.
136 Create one if there is none. */
137 ldsym_type *
138 DEFUN(ldsym_get,(key),
139 CONST char *key)
140 {
141 register int hashval;
142 register ldsym_type *bp;
143
144 /* Determine the proper bucket. */
145
146 hashval = hash_string (key) % TABSIZE;
147
148 /* Search the bucket. */
149 bp = search(key, hashval);
150 if(bp) {
151 return bp;
152 }
153
154 /* Nothing was found; create a new symbol table entry. */
155
156 bp = (ldsym_type *) obstack_alloc (&global_sym_obstack, (bfd_size_type)(sizeof (ldsym_type)));
157 bp->srefs_chain = (asymbol **)NULL;
158 bp->sdefs_chain = (asymbol **)NULL;
159 bp->scoms_chain = (asymbol **)NULL;
160 bp->name = obstack_copy(&global_sym_obstack, key, strlen(key)+1);
161 bp->flags = 0;
162 /* Add the entry to the bucket. */
163
164 bp->link = global_symbol_hash_table[hashval];
165 global_symbol_hash_table[hashval] = bp;
166
167 /* Keep the chronological list up to date too */
168 *symbol_tail_ptr = bp;
169 symbol_tail_ptr = &bp->next;
170 bp->next = 0;
171 global_symbol_count++;
172
173 return bp;
174 }
175
176 /* Like `ldsym_get' but return 0 if the symbol is not already known. */
177
178 ldsym_type *
179 DEFUN(ldsym_get_soft,(key),
180 CONST char *key)
181 {
182 register int hashval;
183 /* Determine which bucket. */
184
185 hashval = hash_string (key) % TABSIZE;
186
187 /* Search the bucket. */
188 return search(key, hashval);
189 }
190
191 static asymbol **
192 process_keepsyms (table, size)
193 asymbol ** table;
194 int size;
195 {
196 struct obstack obstack;
197 char *start_of_obstack;
198 FILE *ks_file = 0;
199 asymbol **out = table;
200 asymbol **end = table + size;
201 asymbol **sym;
202
203 if (!keepsyms_file || size == 0)
204 return end;
205 obstack_init (&obstack);
206 obstack_alloc (&obstack, 1);
207 obstack_finish (&obstack);
208 start_of_obstack = obstack_alloc (&obstack, 1);
209 ks_file = fopen (keepsyms_file, "r");
210 if (!ks_file)
211 {
212 info ("%X%P: can't open keep-symbols file `%s'\n", keepsyms_file);
213 goto egress;
214 }
215 errno = 0;
216
217 #define KEEP(S) \
218 do { asymbol **p = (S), *tmp = *out; *out = *p; *p = tmp; out++; } while (0)
219
220 while (!feof (ks_file) && !ferror (ks_file))
221 {
222 int c;
223 char *ptr;
224 int found = 0;
225
226 obstack_free (&obstack, start_of_obstack);
227 do
228 {
229 c = getc (ks_file);
230 if (c == '\n')
231 c = 0;
232 obstack_1grow (&obstack, c);
233 }
234 while (c > 0);
235 if (c == EOF)
236 {
237 if (!feof (ks_file))
238 /* error occurred */
239 {
240 info ("%X%P: error reading keep-symbols file `%s': %E\n",
241 keepsyms_file);
242 out = end;
243 goto egress;
244 }
245 if (obstack_next_free (&obstack) != obstack_base (&obstack) + 1)
246 /* eof in middle of symbol */
247 {
248 info ("%X%P: eof reached mid-line while reading keep-symbols file `%s'\n",
249 keepsyms_file);
250 out = end;
251 goto egress;
252 }
253 /* All okay -- no incomplete lines, EOF reached. */
254 break;
255 }
256 ptr = obstack_next_free (&obstack) - 2;
257 /* discard trailing trash */
258 while (*ptr == ' '
259 || *ptr == '\t')
260 *ptr-- = 0;
261 ptr = obstack_base (&obstack);
262 for (sym = out; sym < end; sym++)
263 if (!strncmp ((*sym)->name, ptr, symbol_truncate))
264 {
265 KEEP (sym);
266 found = 1;
267 }
268 if (!found)
269 info ("%P: symbol `%s' (requested to be kept) not found\n", ptr);
270 }
271 /* It'd be slightly faster to move this pass above the previous one,
272 but that'd mean any symbols preserved in this pass would generate
273 warnings if they were also listed in the keepsyms file. */
274 for (sym = out; sym < end; sym++)
275 {
276 asymbol *s = *sym;
277 if (s->section == &bfd_und_section
278 || bfd_is_com_section (s->section)
279 || s->flags & BSF_KEEP_G)
280 KEEP (sym);
281 }
282 egress:
283 obstack_free (&obstack, start_of_obstack);
284 if (ks_file)
285 fclose (ks_file);
286 return out;
287 }
288
289 static void
290 list_file_locals (entry)
291 lang_input_statement_type *entry;
292 {
293 asymbol **q;
294 fprintf (config.map_file, "\nLocal symbols of ");
295 minfo("%I", entry);
296 fprintf (config.map_file, ":\n\n");
297 if (entry->asymbols) {
298 for (q = entry->asymbols; *q; q++)
299 {
300 asymbol *p = *q;
301 /* If this is a definition,
302 update it if necessary by this file's start address. */
303 if (p->flags & BSF_LOCAL)
304 info(" %V %s\n",p->value, p->name);
305 }
306 }
307 }
308
309
310 static void
311 DEFUN(print_file_stuff,(f),
312 lang_input_statement_type *f)
313 {
314 fprintf (config.map_file," %s\n", f->filename);
315 if (f->just_syms_flag)
316 {
317 fprintf (config.map_file, " symbols only\n");
318 }
319 else
320 {
321 asection *s;
322 if (true || option_longmap) {
323 for (s = f->the_bfd->sections;
324 s != (asection *)NULL;
325 s = s->next) {
326 print_address(s->output_offset);
327 if (s->reloc_done)
328 {
329 fprintf (config.map_file, " %08x 2**%2ud %s\n",
330 (unsigned)bfd_get_section_size_after_reloc(s),
331 s->alignment_power, s->name);
332 }
333
334 else
335 {
336 fprintf (config.map_file, " %08x 2**%2ud %s\n",
337 (unsigned)bfd_get_section_size_before_reloc(s),
338 s->alignment_power, s->name);
339 }
340 }
341 }
342 else
343 {
344 for (s = f->the_bfd->sections;
345 s != (asection *)NULL;
346 s = s->next) {
347 fprintf(config.map_file, "%s ", s->name);
348 print_address(s->output_offset);
349 fprintf(config.map_file, "(%x)", (unsigned)bfd_get_section_size_after_reloc(s));
350 }
351 fprintf(config.map_file, "hex \n");
352 }
353 }
354 fprintf (config.map_file, "\n");
355 }
356
357 void
358 ldsym_print_symbol_table ()
359 {
360 fprintf (config.map_file, "**FILES**\n\n");
361
362 lang_for_each_file(print_file_stuff);
363
364 fprintf(config.map_file, "**GLOBAL SYMBOLS**\n\n");
365 fprintf(config.map_file, "offset section offset symbol\n");
366 {
367 register ldsym_type *sp;
368
369 for (sp = symbol_head; sp; sp = sp->next)
370 {
371 if (sp->flags & SYM_INDIRECT) {
372 fprintf(config.map_file,"indirect %s to %s\n",
373 sp->name, (((ldsym_type *)(sp->sdefs_chain))->name));
374 }
375 else {
376 if (sp->sdefs_chain)
377 {
378 asymbol *defsym = *(sp->sdefs_chain);
379 asection *defsec = bfd_get_section(defsym);
380 print_address(defsym->value);
381 if (defsec)
382 {
383 fprintf(config.map_file, " %-10s",
384 bfd_section_name(output_bfd,
385 defsec));
386 print_space();
387 print_address(defsym->value+defsec->vma);
388
389 }
390 else
391 {
392 fprintf(config.map_file, " .......");
393 }
394
395 }
396
397
398 if (sp->scoms_chain) {
399 fprintf(config.map_file, "common ");
400 print_address((*(sp->scoms_chain))->value);
401 fprintf(config.map_file, " %s ",sp->name);
402 }
403 else if (sp->sdefs_chain) {
404 fprintf(config.map_file, " %s ",sp->name);
405 }
406 else {
407 fprintf(config.map_file, "undefined ");
408 fprintf(config.map_file, "%s ",sp->name);
409
410 }
411 }
412 print_nl();
413
414 }
415 }
416 if (option_longmap) {
417 lang_for_each_file(list_file_locals);
418 }
419 }
420
421 extern lang_output_section_statement_type *create_object_symbols;
422 extern char lprefix;
423 static asymbol **
424 write_file_locals(output_buffer)
425 asymbol **output_buffer;
426 {
427 LANG_FOR_EACH_INPUT_STATEMENT(entry)
428 {
429 /* Run trough the symbols and work out what to do with them */
430 unsigned int i;
431
432 /* Add one for the filename symbol if needed */
433 if (create_object_symbols
434 != (lang_output_section_statement_type *)NULL) {
435 asection *s;
436 for (s = entry->the_bfd->sections;
437 s != (asection *)NULL;
438 s = s->next) {
439 if (s->output_section == create_object_symbols->bfd_section) {
440 /* Add symbol to this section */
441 asymbol * newsym =
442 (asymbol *)bfd_make_empty_symbol(entry->the_bfd);
443 newsym->name = entry->local_sym_name;
444 /* The symbol belongs to the output file's text section */
445
446 /* The value is the start of this section in the output file*/
447 newsym->value = 0;
448 /* FIXME: Usurping BSF_KEEP_G flag, since it's defined as
449 "used by the linker" and I can't find any other code that
450 uses it. Should be a cleaner way of doing this (like an
451 "application flags" field in the symbol structure?). */
452 newsym->flags = BSF_LOCAL | BSF_KEEP_G;
453 newsym->section = s;
454 *output_buffer++ = newsym;
455 break;
456 }
457 }
458 }
459 for (i = 0; i < entry->symbol_count; i++)
460 {
461 asymbol *p = entry->asymbols[i];
462 /* FIXME, temporary hack, since not all of ld knows about the new abs section convention */
463
464 if (p->section == 0)
465 p->section = &bfd_abs_section;
466 if (flag_is_global(p->flags) )
467 {
468 /* We are only interested in outputting
469 globals at this stage in special circumstances */
470 if (bfd_asymbol_bfd(p) == entry->the_bfd
471 && flag_is_not_at_end(p->flags)) {
472 /* And this is one of them */
473 *(output_buffer++) = p;
474 p->flags |= BSF_KEEP;
475 }
476 }
477 else {
478 if (flag_is_debugger(p->flags))
479 {
480 /* Only keep the debugger symbols if no stripping required */
481 if (strip_symbols == STRIP_NONE) {
482 *output_buffer++ = p;
483 }
484 }
485 else if (p->section == &bfd_und_section
486 || bfd_is_com_section (p->section))
487 {
488 /* These must be global. */
489 }
490 else if (flag_is_ordinary_local(p->flags))
491 {
492 if (discard_locals == DISCARD_ALL)
493 { }
494 else if (discard_locals == DISCARD_L &&
495 (p->name[0] == lprefix))
496 { }
497 else if (p->flags == BSF_WARNING)
498 { }
499 else
500 { *output_buffer++ = p; }
501 }
502 else if (p->flags & BSF_CTOR) {
503 /* Throw it away */
504 }
505 else
506 {
507 FAIL();
508 }
509 }
510 }
511
512
513 }
514 return output_buffer;
515 }
516
517
518 static asymbol **
519 write_file_globals(symbol_table)
520 asymbol **symbol_table;
521 {
522 FOR_EACH_LDSYM(sp)
523 {
524 if ((sp->flags & SYM_INDIRECT) == 0 && sp->sdefs_chain != (asymbol **)NULL) {
525 asymbol *bufp = (*(sp->sdefs_chain));
526
527 if ((bufp->flags & BSF_KEEP) ==0) {
528 ASSERT(bufp != (asymbol *)NULL);
529
530 bufp->name = sp->name;
531
532 if (sp->scoms_chain != (asymbol **)NULL)
533
534 {
535 /*
536 defined as common but not allocated, this happens
537 only with -r and not -d, write out a common
538 definition
539 */
540 bufp = *(sp->scoms_chain);
541 }
542 *symbol_table++ = bufp;
543 }
544 }
545 else if (sp->scoms_chain != (asymbol **)NULL) {
546 /* This symbol is a common - just output */
547 asymbol *bufp = (*(sp->scoms_chain));
548 *symbol_table++ = bufp;
549 }
550 else if (sp->srefs_chain != (asymbol **)NULL) {
551 /* This symbol is undefined but has a reference */
552 asymbol *bufp = (*(sp->srefs_chain));
553 *symbol_table++ = bufp;
554 }
555 else {
556 /*
557 This symbol has neither defs nor refs, it must have come
558 from the command line, since noone has used it it has no
559 data attatched, so we'll ignore it
560 */
561 }
562 }
563 return symbol_table;
564 }
565
566 void
567 ldsym_write()
568 {
569 if (keepsyms_file != 0
570 && strip_symbols != STRIP_SOME)
571 {
572 info ("%P `-retain-symbols-file' overrides `-s' and `-S'\n");
573 strip_symbols = STRIP_SOME;
574 }
575 if (strip_symbols != STRIP_ALL) {
576 /* We know the maximum size of the symbol table -
577 it's the size of all the global symbols ever seen +
578 the size of all the symbols from all the files +
579 the number of files (for the per file symbols)
580 +1 (for the null at the end)
581 */
582 extern unsigned int total_files_seen;
583 extern unsigned int total_symbols_seen;
584
585 asymbol ** symbol_table = (asymbol **)
586 ldmalloc ((bfd_size_type)(global_symbol_count +
587 total_files_seen +
588 total_symbols_seen + 1) * sizeof (asymbol *));
589 asymbol ** tablep = write_file_locals(symbol_table);
590
591 tablep = write_file_globals(tablep);
592 tablep = process_keepsyms (symbol_table, tablep - symbol_table);
593
594 *tablep = (asymbol *)NULL;
595 bfd_set_symtab(output_bfd, symbol_table, (unsigned)( tablep - symbol_table));
596 }
597 }
598
599 /*
600 return true if the supplied symbol name is not in the
601 linker symbol table
602 */
603 boolean
604 DEFUN(ldsym_undefined,(sym),
605 CONST char *sym)
606 {
607 ldsym_type *from_table = ldsym_get_soft(sym);
608 if (from_table != (ldsym_type *)NULL)
609 {
610 if (from_table->sdefs_chain != (asymbol **)NULL) return false;
611 }
612 return true;
613 }
614
615 void
616 DEFUN_VOID(ldsym_init)
617 {
618 obstack_begin(&global_sym_obstack, 20000);
619 }