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