Tue Mar 30 09:40:25 1993 Steve Chamberlain (sac@thepub.cygnus.com)
[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 | | | +---------+
40 +----------+ +----------+ | udata |-----> another canonical symbol
29f33467 41 +---------+
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 }
531 else if (p->flags & BSF_CTOR)
532 {
533 /* Throw it away */
534 }
535 else
536 {
537 FAIL ();
538 }
539 }
bfbdc80f 540 }
2fa0b342
DHW
541
542
bfbdc80f 543 }
2fa0b342
DHW
544 return output_buffer;
545}
546
547
548static asymbol **
29f33467
SC
549write_file_globals (symbol_table)
550 asymbol **symbol_table;
2fa0b342 551{
29f33467
SC
552 FOR_EACH_LDSYM (sp)
553 {
554 if (sp->flags & SYM_INDIRECT)
555 {
556 asymbol *bufp = (*(sp->srefs_chain));
557 ldsym_type *aliased_to = (ldsym_type *) (sp->sdefs_chain);
558 if (aliased_to->sdefs_chain)
559 {
560 asymbol *p = aliased_to->sdefs_chain[0];
561 bufp->value = p->value;
562 bufp->section = p->section;
563 bufp->flags = p->flags;
564 }
565 else
566 {
567 bufp->value = 0;
568 bufp->flags = 0;
569 bufp->section = &bfd_und_section;
570 }
571 *symbol_table++ = bufp;
572 }
573 else if ((sp->flags & SYM_INDIRECT) == 0 && sp->sdefs_chain != (asymbol **) NULL)
574 {
2fa0b342
DHW
575 asymbol *bufp = (*(sp->sdefs_chain));
576
29f33467
SC
577 if ((bufp->flags & BSF_KEEP) == 0)
578 {
579 ASSERT (bufp != (asymbol *) NULL);
2fa0b342 580
29f33467 581 bufp->name = sp->name;
2fa0b342 582
29f33467 583 if (sp->scoms_chain != (asymbol **) NULL)
2fa0b342 584
29f33467
SC
585 {
586 /*
2fa0b342
DHW
587 defined as common but not allocated, this happens
588 only with -r and not -d, write out a common
589 definition
590 */
29f33467
SC
591 bufp = *(sp->scoms_chain);
592 }
593 *symbol_table++ = bufp;
594 }
2fa0b342 595 }
29f33467
SC
596 else if (sp->scoms_chain != (asymbol **) NULL)
597 {
2fa0b342
DHW
598 /* This symbol is a common - just output */
599 asymbol *bufp = (*(sp->scoms_chain));
600 *symbol_table++ = bufp;
601 }
29f33467
SC
602 else if (sp->srefs_chain != (asymbol **) NULL)
603 {
2fa0b342
DHW
604 /* This symbol is undefined but has a reference */
605 asymbol *bufp = (*(sp->srefs_chain));
606 *symbol_table++ = bufp;
607 }
29f33467
SC
608 else
609 {
2fa0b342
DHW
610 /*
611 This symbol has neither defs nor refs, it must have come
612 from the command line, since noone has used it it has no
29f33467 613 data attatched, so we'll ignore it
2fa0b342
DHW
614 */
615 }
29f33467 616 }
2fa0b342
DHW
617 return symbol_table;
618}
619
2fa0b342 620void
29f33467 621ldsym_write ()
2fa0b342 622{
f3b36ecb
KR
623 if (keepsyms_file != 0
624 && strip_symbols != STRIP_SOME)
625 {
626 info ("%P `-retain-symbols-file' overrides `-s' and `-S'\n");
627 strip_symbols = STRIP_SOME;
628 }
29f33467
SC
629 if (strip_symbols != STRIP_ALL)
630 {
631 /* We know the maximum size of the symbol table -
2fa0b342
DHW
632 it's the size of all the global symbols ever seen +
633 the size of all the symbols from all the files +
634 the number of files (for the per file symbols)
635 +1 (for the null at the end)
636 */
29f33467
SC
637 extern unsigned int total_files_seen;
638 extern unsigned int total_symbols_seen;
2fa0b342 639
29f33467
SC
640 asymbol **symbol_table = (asymbol **)
641 ldmalloc ((bfd_size_type) (global_symbol_count +
642 total_files_seen +
643 total_symbols_seen + 1) * sizeof (asymbol *));
644 asymbol **tablep = write_file_locals (symbol_table);
2fa0b342 645
29f33467
SC
646 tablep = write_file_globals (tablep);
647 tablep = process_keepsyms (symbol_table, tablep - symbol_table);
2fa0b342 648
29f33467
SC
649 *tablep = (asymbol *) NULL;
650 bfd_set_symtab (output_bfd, symbol_table, (unsigned) (tablep - symbol_table));
651 }
2fa0b342 652}
c660714f
SC
653
654/*
29f33467 655return true if the supplied symbol name is not in the
c660714f
SC
656linker symbol table
657*/
29f33467
SC
658boolean
659DEFUN (ldsym_undefined, (sym),
660 CONST char *sym)
c660714f 661{
29f33467
SC
662 ldsym_type *from_table = ldsym_get_soft (sym);
663 if (from_table != (ldsym_type *) NULL)
664 {
665 if (from_table->sdefs_chain != (asymbol **) NULL)
666 return false;
667 }
c660714f
SC
668 return true;
669}
bfbdc80f
SC
670
671void
29f33467 672DEFUN_VOID (ldsym_init)
bfbdc80f 673{
29f33467 674 obstack_begin (&global_sym_obstack, 20000);
bfbdc80f 675}
This page took 0.097344 seconds and 4 git commands to generate.