keep everything that's present now
[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
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
2fa0b342 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
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
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
66ldsym_type *symbol_head = (ldsym_type *)NULL;
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
79 no matter what flavour it is
80*/
81unsigned int global_symbol_count;
82
83/* IMPORTS */
84
85extern boolean option_longmap ;
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. */
1af27af8
SC
92static
93#ifdef __GNUC__
b773e0e5 94__inline
1af27af8 95#endif
b773e0e5 96
2fa0b342 97int
1af27af8
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;
0b5995da 106 while (*cp && l < symbol_truncate) {
2fa0b342 107 k = (((k << 1) + (k >> 14)) ^ (*cp++)) & 0x3fff;
0b5995da
SC
108 l++;
109 }
2fa0b342
DHW
110 return k;
111}
112
1af27af8
SC
113static
114#ifdef __GNUC__
b773e0e5 115__inline
04dd7520 116#endif
1af27af8
SC
117ldsym_type *
118DEFUN(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)
0b5995da 124 if (! strncmp (key, bp->name, symbol_truncate)) {
1af27af8
SC
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
2fa0b342
DHW
135/* Get the symbol table entry for the global symbol named KEY.
136 Create one if there is none. */
137ldsym_type *
99fe4553
SC
138DEFUN(ldsym_get,(key),
139 CONST char *key)
2fa0b342
DHW
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. */
1af27af8
SC
149 bp = search(key, hashval);
150 if(bp) {
151 return bp;
152 }
2fa0b342
DHW
153
154 /* Nothing was found; create a new symbol table entry. */
155
bfbdc80f 156 bp = (ldsym_type *) obstack_alloc (&global_sym_obstack, (bfd_size_type)(sizeof (ldsym_type)));
2fa0b342
DHW
157 bp->srefs_chain = (asymbol **)NULL;
158 bp->sdefs_chain = (asymbol **)NULL;
159 bp->scoms_chain = (asymbol **)NULL;
bfbdc80f 160 bp->name = obstack_copy(&global_sym_obstack, key, strlen(key)+1);
81016051 161 bp->flags = 0;
2fa0b342
DHW
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
178ldsym_type *
99fe4553
SC
179DEFUN(ldsym_get_soft,(key),
180 CONST char *key)
2fa0b342
DHW
181{
182 register int hashval;
2fa0b342
DHW
183 /* Determine which bucket. */
184
185 hashval = hash_string (key) % TABSIZE;
186
187 /* Search the bucket. */
7fe11a82 188 return search(key, hashval);
2fa0b342
DHW
189}
190
f3b36ecb
KR
191static asymbol **
192process_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;
2fa0b342 216
f3b36ecb
KR
217#define KEEP(S) \
218 do { asymbol **p=(S), *tmp=*out; *out=*p; *p=tmp; out++; } while (0)
2fa0b342 219
f3b36ecb
KR
220 while (!feof (ks_file) && !ferror (ks_file))
221 {
222 int c;
223 char *ptr;
224 int found = 0;
2fa0b342 225
f3b36ecb
KR
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++)
0b5995da 263 if (!strncmp ((*sym)->name, ptr, symbol_truncate))
f3b36ecb
KR
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
8a045e50 278 || bfd_is_com_section (s->section)
f3b36ecb
KR
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}
2fa0b342
DHW
288
289static void
290list_file_locals (entry)
291lang_input_statement_type *entry;
292{
293 asymbol **q;
6fd50a20
SC
294 fprintf (config.map_file, "\nLocal symbols of ");
295 minfo("%I", entry);
296 fprintf (config.map_file, ":\n\n");
2fa0b342
DHW
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
310static void
6fd50a20
SC
311DEFUN(print_file_stuff,(f),
312 lang_input_statement_type *f)
2fa0b342 313{
6fd50a20 314 fprintf (config.map_file," %s\n", f->filename);
2fa0b342 315 if (f->just_syms_flag)
c611e285 316 {
6fd50a20 317 fprintf (config.map_file, " symbols only\n");
c611e285 318 }
2fa0b342 319 else
c611e285
SC
320 {
321 asection *s;
322 if (true || option_longmap) {
bfbdc80f
SC
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 }
c611e285 333
bfbdc80f
SC
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 }
c611e285 340 }
bfbdc80f
SC
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));
2fa0b342 350 }
bfbdc80f
SC
351 fprintf(config.map_file, "hex \n");
352 }
c611e285 353 }
6fd50a20 354 fprintf (config.map_file, "\n");
2fa0b342
DHW
355}
356
357void
358ldsym_print_symbol_table ()
359{
6fd50a20 360 fprintf (config.map_file, "**FILES**\n\n");
2fa0b342
DHW
361
362 lang_for_each_file(print_file_stuff);
363
6fd50a20
SC
364 fprintf(config.map_file, "**GLOBAL SYMBOLS**\n\n");
365 fprintf(config.map_file, "offset section offset symbol\n");
2fa0b342
DHW
366 {
367 register ldsym_type *sp;
368
369 for (sp = symbol_head; sp; sp = sp->next)
370 {
1af27af8 371 if (sp->flags & SYM_INDIRECT) {
6fd50a20 372 fprintf(config.map_file,"indirect %s to %s\n",
1af27af8 373 sp->name, (((ldsym_type *)(sp->sdefs_chain))->name));
2fa0b342
DHW
374 }
375 else {
d9c53949
SC
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 {
6fd50a20 383 fprintf(config.map_file, " %-10s",
d9c53949
SC
384 bfd_section_name(output_bfd,
385 defsec));
386 print_space();
387 print_address(defsym->value+defsec->vma);
388
389 }
390 else
391 {
6fd50a20 392 fprintf(config.map_file, " .......");
d9c53949
SC
393 }
394
395 }
396
397
398 if (sp->scoms_chain) {
6fd50a20 399 fprintf(config.map_file, "common ");
d9c53949 400 print_address((*(sp->scoms_chain))->value);
6fd50a20 401 fprintf(config.map_file, " %s ",sp->name);
d9c53949
SC
402 }
403 else if (sp->sdefs_chain) {
6fd50a20 404 fprintf(config.map_file, " %s ",sp->name);
d9c53949
SC
405 }
406 else {
6fd50a20
SC
407 fprintf(config.map_file, "undefined ");
408 fprintf(config.map_file, "%s ",sp->name);
1af27af8 409
d9c53949 410 }
2fa0b342 411 }
19b03b7a 412 print_nl();
2fa0b342
DHW
413
414 }
415 }
d9c53949
SC
416 if (option_longmap) {
417 lang_for_each_file(list_file_locals);
418 }
2fa0b342
DHW
419}
420
421extern lang_output_section_statement_type *create_object_symbols;
422extern char lprefix;
423static asymbol **
424write_file_locals(output_buffer)
425asymbol **output_buffer;
426{
bfbdc80f
SC
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;
f3b36ecb
KR
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;
bfbdc80f
SC
453 newsym->section = s;
454 *output_buffer++ = newsym;
455 break;
456 }
457 }
458 }
459 for (i = 0; i < entry->symbol_count; i++)
2fa0b342 460 {
bfbdc80f
SC
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 */
086c5e37 470 if (bfd_asymbol_bfd(p) == entry->the_bfd
bfbdc80f
SC
471 && flag_is_not_at_end(p->flags)) {
472 /* And this is one of them */
473 *(output_buffer++) = p;
474 p->flags |= BSF_KEEP;
2fa0b342
DHW
475 }
476 }
bfbdc80f 477 else {
571c4c26
KR
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
8a045e50 486 || bfd_is_com_section (p->section))
571c4c26
KR
487 {
488 /* These must be global. */
489 }
490 else if (flag_is_ordinary_local(p->flags))
2fa0b342 491 {
bfbdc80f
SC
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 }
bfbdc80f
SC
502 else if (p->flags & BSF_CTOR) {
503 /* Throw it away */
504 }
505 else
506 {
507 FAIL();
508 }
509 }
510 }
2fa0b342
DHW
511
512
bfbdc80f 513 }
2fa0b342
DHW
514 return output_buffer;
515}
516
517
518static asymbol **
519write_file_globals(symbol_table)
520asymbol **symbol_table;
521{
522 FOR_EACH_LDSYM(sp)
523 {
1af27af8 524 if ((sp->flags & SYM_INDIRECT) == 0 && sp->sdefs_chain != (asymbol **)NULL) {
2fa0b342
DHW
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
2fa0b342
DHW
566void
567ldsym_write()
568{
f3b36ecb
KR
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 }
2fa0b342
DHW
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 **)
19b03b7a 586 ldmalloc ((bfd_size_type)(global_symbol_count +
2fa0b342
DHW
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);
f3b36ecb 592 tablep = process_keepsyms (symbol_table, tablep - symbol_table);
2fa0b342
DHW
593
594 *tablep = (asymbol *)NULL;
595 bfd_set_symtab(output_bfd, symbol_table, (unsigned)( tablep - symbol_table));
596 }
597}
c660714f
SC
598
599/*
600return true if the supplied symbol name is not in the
601linker symbol table
602*/
603boolean
99fe4553
SC
604DEFUN(ldsym_undefined,(sym),
605 CONST char *sym)
c660714f
SC
606{
607 ldsym_type *from_table = ldsym_get_soft(sym);
bfbdc80f
SC
608 if (from_table != (ldsym_type *)NULL)
609 {
c660714f
SC
610 if (from_table->sdefs_chain != (asymbol **)NULL) return false;
611 }
612 return true;
613}
bfbdc80f
SC
614
615void
616DEFUN_VOID(ldsym_init)
617{
618 obstack_begin(&global_sym_obstack, 20000);
619}
This page took 0.086883 seconds and 4 git commands to generate.