* ldmain.c (lprefix): Change default from a char to a string
[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"
fcf276c4 58#include "ldexp.h"
2fa0b342 59#include "ldlang.h"
fcf276c4
ILT
60#include "mri.h"
61#include "ldmain.h"
62
2fa0b342
DHW
63/* Head and tail of global symbol table chronological list */
64
29f33467 65ldsym_type *symbol_head = (ldsym_type *) NULL;
2fa0b342 66ldsym_type **symbol_tail_ptr = &symbol_head;
f3b36ecb
KR
67CONST char *keepsyms_file;
68int kept_syms;
2fa0b342 69
bfbdc80f
SC
70struct obstack global_sym_obstack;
71#define obstack_chunk_alloc ldmalloc
72#define obstack_chunk_free free
73
2fa0b342
DHW
74/*
75 incremented for each symbol in the ldsym_type table
29f33467 76 no matter what flavour it is
2fa0b342
DHW
77*/
78unsigned int global_symbol_count;
79
2fa0b342
DHW
80/* LOCALS */
81#define TABSIZE 1009
82static ldsym_type *global_symbol_hash_table[TABSIZE];
83
9f629407
ILT
84#ifndef __GNUC__
85#define __inline
1af27af8 86#endif
b773e0e5 87
9f629407
ILT
88static __inline int hash_string PARAMS ((const char *key));
89static __inline ldsym_type *search PARAMS ((const char *key, int hashval));
90static asymbol **process_keepsyms PARAMS ((asymbol **table, int size));
91static void print_file_stuff PARAMS ((lang_input_statement_type * f));
92static asymbol **write_file_locals PARAMS ((asymbol **output_buffer));
93static asymbol **write_file_globals PARAMS ((asymbol **symbol_table));
94
95/* Compute the hash code for symbol name KEY. */
96static __inline int
8ddef552
DM
97hash_string (key)
98 CONST char *key;
2fa0b342 99{
1af27af8 100 register CONST char *cp;
2fa0b342 101 register int k;
0b5995da 102 register int l = 0;
2fa0b342
DHW
103 cp = key;
104 k = 0;
29f33467
SC
105 while (*cp && l < symbol_truncate)
106 {
107 k = (((k << 1) + (k >> 14)) ^ (*cp++)) & 0x3fff;
108 l++;
109 }
2fa0b342
DHW
110 return k;
111}
112
9f629407 113static __inline ldsym_type *
8ddef552
DM
114search (key, hashval)
115 CONST char *key;
116 int hashval;
1af27af8 117{
29f33467 118 ldsym_type *bp;
1af27af8 119 for (bp = global_symbol_hash_table[hashval]; bp; bp = bp->link)
29f33467
SC
120 if (!strncmp (key, bp->name, symbol_truncate))
121 {
122 if (bp->flags & SYM_INDIRECT)
123 {
124 /* Use the symbol we're aliased to instead */
125 return (ldsym_type *) (bp->sdefs_chain);
126 }
127 return bp;
1af27af8 128 }
1af27af8
SC
129 return 0;
130}
131
132
2fa0b342
DHW
133/* Get the symbol table entry for the global symbol named KEY.
134 Create one if there is none. */
135ldsym_type *
8ddef552
DM
136ldsym_get (key)
137 CONST char *key;
2fa0b342
DHW
138{
139 register int hashval;
140 register ldsym_type *bp;
141
142 /* Determine the proper bucket. */
143
144 hashval = hash_string (key) % TABSIZE;
145
146 /* Search the bucket. */
29f33467
SC
147 bp = search (key, hashval);
148 if (bp)
149 {
150 return bp;
151 }
2fa0b342
DHW
152
153 /* Nothing was found; create a new symbol table entry. */
154
29f33467
SC
155 bp = (ldsym_type *) obstack_alloc (&global_sym_obstack, (bfd_size_type) (sizeof (ldsym_type)));
156 bp->srefs_chain = (asymbol **) NULL;
157 bp->sdefs_chain = (asymbol **) NULL;
158 bp->scoms_chain = (asymbol **) NULL;
159 bp->name = obstack_copy (&global_sym_obstack, key, strlen (key) + 1);
81016051 160 bp->flags = 0;
2fa0b342
DHW
161 /* Add the entry to the bucket. */
162
163 bp->link = global_symbol_hash_table[hashval];
164 global_symbol_hash_table[hashval] = bp;
165
166 /* Keep the chronological list up to date too */
167 *symbol_tail_ptr = bp;
168 symbol_tail_ptr = &bp->next;
169 bp->next = 0;
170 global_symbol_count++;
171
172 return bp;
173}
174
175/* Like `ldsym_get' but return 0 if the symbol is not already known. */
176
177ldsym_type *
8ddef552
DM
178ldsym_get_soft (key)
179 CONST char *key;
2fa0b342
DHW
180{
181 register int hashval;
2fa0b342
DHW
182 /* Determine which bucket. */
183
184 hashval = hash_string (key) % TABSIZE;
185
186 /* Search the bucket. */
29f33467 187 return search (key, hashval);
2fa0b342
DHW
188}
189
f3b36ecb
KR
190static asymbol **
191process_keepsyms (table, size)
29f33467 192 asymbol **table;
f3b36ecb
KR
193 int size;
194{
195 struct obstack obstack;
196 char *start_of_obstack;
197 FILE *ks_file = 0;
198 asymbol **out = table;
199 asymbol **end = table + size;
200 asymbol **sym;
201
202 if (!keepsyms_file || size == 0)
203 return end;
204 obstack_init (&obstack);
205 obstack_alloc (&obstack, 1);
206 obstack_finish (&obstack);
207 start_of_obstack = obstack_alloc (&obstack, 1);
208 ks_file = fopen (keepsyms_file, "r");
209 if (!ks_file)
210 {
3f905ec1 211 info_msg ("%X%P: cannot open keep-symbols file `%s'\n", keepsyms_file);
f3b36ecb
KR
212 goto egress;
213 }
214 errno = 0;
2fa0b342 215
f3b36ecb 216#define KEEP(S) \
26483cc6 217 do { asymbol **p = (S), *tmp = *out; *out = *p; *p = tmp; out++; } while (0)
2fa0b342 218
f3b36ecb
KR
219 while (!feof (ks_file) && !ferror (ks_file))
220 {
221 int c;
222 char *ptr;
223 int found = 0;
2fa0b342 224
f3b36ecb
KR
225 obstack_free (&obstack, start_of_obstack);
226 do
227 {
228 c = getc (ks_file);
229 if (c == '\n')
230 c = 0;
231 obstack_1grow (&obstack, c);
232 }
233 while (c > 0);
234 if (c == EOF)
235 {
236 if (!feof (ks_file))
237 /* error occurred */
238 {
3f905ec1 239 info_msg ("%X%P: error reading keep-symbols file `%s': %E\n",
f3b36ecb
KR
240 keepsyms_file);
241 out = end;
242 goto egress;
243 }
244 if (obstack_next_free (&obstack) != obstack_base (&obstack) + 1)
245 /* eof in middle of symbol */
246 {
3f905ec1 247 info_msg ("%X%P: eof reached mid-line while reading keep-symbols file `%s'\n",
f3b36ecb
KR
248 keepsyms_file);
249 out = end;
250 goto egress;
251 }
252 /* All okay -- no incomplete lines, EOF reached. */
253 break;
254 }
255 ptr = obstack_next_free (&obstack) - 2;
256 /* discard trailing trash */
257 while (*ptr == ' '
258 || *ptr == '\t')
259 *ptr-- = 0;
260 ptr = obstack_base (&obstack);
261 for (sym = out; sym < end; sym++)
0b5995da 262 if (!strncmp ((*sym)->name, ptr, symbol_truncate))
f3b36ecb
KR
263 {
264 KEEP (sym);
265 found = 1;
266 }
267 if (!found)
3f905ec1 268 info_msg ("%P: symbol `%s' (requested to be kept) not found\n", ptr);
f3b36ecb
KR
269 }
270 /* It'd be slightly faster to move this pass above the previous one,
271 but that'd mean any symbols preserved in this pass would generate
272 warnings if they were also listed in the keepsyms file. */
273 for (sym = out; sym < end; sym++)
274 {
275 asymbol *s = *sym;
276 if (s->section == &bfd_und_section
8a045e50 277 || bfd_is_com_section (s->section)
f3b36ecb
KR
278 || s->flags & BSF_KEEP_G)
279 KEEP (sym);
280 }
29f33467 281egress:
f3b36ecb
KR
282 obstack_free (&obstack, start_of_obstack);
283 if (ks_file)
284 fclose (ks_file);
285 return out;
286}
2fa0b342 287
fcf276c4
ILT
288#if 0
289
290/* This function is not used. */
291
2fa0b342
DHW
292static void
293list_file_locals (entry)
29f33467 294 lang_input_statement_type *entry;
2fa0b342
DHW
295{
296 asymbol **q;
6fd50a20 297 fprintf (config.map_file, "\nLocal symbols of ");
29f33467 298 minfo ("%I", entry);
6fd50a20 299 fprintf (config.map_file, ":\n\n");
29f33467
SC
300 if (entry->asymbols)
301 {
302 for (q = entry->asymbols; *q; q++)
303 {
304 asymbol *p = *q;
305 /* If this is a definition,
2fa0b342 306 update it if necessary by this file's start address. */
29f33467 307 if (p->flags & BSF_LOCAL)
3f905ec1 308 info_msg (" %V %s\n", p->value, p->name);
29f33467
SC
309 }
310 }
2fa0b342
DHW
311}
312
fcf276c4 313#endif
2fa0b342
DHW
314
315static void
8ddef552
DM
316print_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;
bbd2521f 327 if (true)
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 }
2fa0b342
DHW
429}
430
2fa0b342 431static asymbol **
29f33467
SC
432write_file_locals (output_buffer)
433 asymbol **output_buffer;
2fa0b342 434{
29f33467 435 LANG_FOR_EACH_INPUT_STATEMENT (entry)
bfbdc80f
SC
436 {
437 /* Run trough the symbols and work out what to do with them */
438 unsigned int i;
439
440 /* Add one for the filename symbol if needed */
29f33467
SC
441 if (create_object_symbols
442 != (lang_output_section_statement_type *) NULL)
443 {
444 asection *s;
445 for (s = entry->the_bfd->sections;
446 s != (asection *) NULL;
447 s = s->next)
448 {
449 if (s->output_section == create_object_symbols->bfd_section)
450 {
451 /* Add symbol to this section */
452 asymbol *newsym =
453 (asymbol *) bfd_make_empty_symbol (entry->the_bfd);
454 newsym->name = entry->local_sym_name;
455 /* The symbol belongs to the output file's text section */
456
457 /* The value is the start of this section in the output file*/
458 newsym->value = 0;
459 /* FIXME: Usurping BSF_KEEP_G flag, since it's defined as
31f55aa5
DM
460 "used by the linker" and I can't find any other code that
461 uses it. Should be a cleaner way of doing this (like an
462 "application flags" field in the symbol structure?). */
2fe6619e 463 newsym->flags = BSF_LOCAL | BSF_KEEP_G | BSF_FILE;
29f33467
SC
464 newsym->section = s;
465 *output_buffer++ = newsym;
466 break;
467 }
468 }
bfbdc80f 469 }
29f33467 470 for (i = 0; i < entry->symbol_count; i++)
bfbdc80f 471 {
29f33467
SC
472 asymbol *p = entry->asymbols[i];
473 /* FIXME, temporary hack, since not all of ld knows about the new abs section convention */
474
475 if (p->section == 0)
476 p->section = &bfd_abs_section;
c3b34cfd
ILT
477 if ((p->flags & BSF_GLOBAL)
478 || (p->flags & BSF_WEAK))
29f33467 479 {
9a467cb2
ILT
480 /* If this symbol is marked as occurring now, rather than
481 at the end, output it now. This is used for COFF C_EXT
482 FCN symbols. FIXME: There must be a better way. */
29f33467 483 if (bfd_asymbol_bfd (p) == entry->the_bfd
c3b34cfd 484 && (p->flags & BSF_NOT_AT_END))
29f33467 485 {
29f33467
SC
486 *(output_buffer++) = p;
487 p->flags |= BSF_KEEP;
488 }
571c4c26 489 }
bfbdc80f 490 else
29f33467
SC
491 {
492 if (p->section == &bfd_ind_section)
493 {
494 /* Dont think about indirect symbols */
495 }
c3b34cfd 496 else if (p->flags & BSF_DEBUGGING)
29f33467
SC
497 {
498 /* Only keep the debugger symbols if no stripping required */
499 if (strip_symbols == STRIP_NONE)
500 {
501 *output_buffer++ = p;
502 }
503 }
504 else if (p->section == &bfd_und_section
505 || bfd_is_com_section (p->section))
506 {
507 /* These must be global. */
508 }
c3b34cfd 509 else if (p->flags & BSF_LOCAL)
29f33467
SC
510 {
511 if (discard_locals == DISCARD_ALL)
512 {
513 }
514 else if (discard_locals == DISCARD_L &&
93df4ec5 515 !strncmp (lprefix, p->name, lprefix_len))
29f33467
SC
516 {
517 }
518 else if (p->flags == BSF_WARNING)
519 {
520 }
521 else
522 {
523 *output_buffer++ = p;
524 }
525 }
1cf91c69 526 else if (p->flags & BSF_CONSTRUCTOR)
29f33467 527 {
1cf91c69
PB
528 if (strip_symbols != STRIP_ALL)
529 {
530 *output_buffer++ = p;
531 }
29f33467
SC
532 }
533 else
534 {
535 FAIL ();
536 }
537 }
bfbdc80f 538 }
2fa0b342
DHW
539
540
bfbdc80f 541 }
2fa0b342
DHW
542 return output_buffer;
543}
544
545
546static asymbol **
29f33467
SC
547write_file_globals (symbol_table)
548 asymbol **symbol_table;
2fa0b342 549{
29f33467
SC
550 FOR_EACH_LDSYM (sp)
551 {
552 if (sp->flags & SYM_INDIRECT)
553 {
554 asymbol *bufp = (*(sp->srefs_chain));
555 ldsym_type *aliased_to = (ldsym_type *) (sp->sdefs_chain);
556 if (aliased_to->sdefs_chain)
557 {
558 asymbol *p = aliased_to->sdefs_chain[0];
559 bufp->value = p->value;
560 bufp->section = p->section;
561 bufp->flags = p->flags;
562 }
563 else
564 {
565 bufp->value = 0;
566 bufp->flags = 0;
567 bufp->section = &bfd_und_section;
568 }
569 *symbol_table++ = bufp;
570 }
571 else if ((sp->flags & SYM_INDIRECT) == 0 && sp->sdefs_chain != (asymbol **) NULL)
572 {
2fa0b342
DHW
573 asymbol *bufp = (*(sp->sdefs_chain));
574
29f33467
SC
575 if ((bufp->flags & BSF_KEEP) == 0)
576 {
577 ASSERT (bufp != (asymbol *) NULL);
2fa0b342 578
29f33467 579 bufp->name = sp->name;
2fa0b342 580
29f33467 581 if (sp->scoms_chain != (asymbol **) NULL)
2fa0b342 582
29f33467
SC
583 {
584 /*
2fa0b342
DHW
585 defined as common but not allocated, this happens
586 only with -r and not -d, write out a common
587 definition
588 */
29f33467
SC
589 bufp = *(sp->scoms_chain);
590 }
591 *symbol_table++ = bufp;
592 }
2fa0b342 593 }
29f33467
SC
594 else if (sp->scoms_chain != (asymbol **) NULL)
595 {
2fa0b342
DHW
596 /* This symbol is a common - just output */
597 asymbol *bufp = (*(sp->scoms_chain));
598 *symbol_table++ = bufp;
599 }
29f33467
SC
600 else if (sp->srefs_chain != (asymbol **) NULL)
601 {
2fa0b342
DHW
602 /* This symbol is undefined but has a reference */
603 asymbol *bufp = (*(sp->srefs_chain));
604 *symbol_table++ = bufp;
605 }
29f33467
SC
606 else
607 {
2fa0b342
DHW
608 /*
609 This symbol has neither defs nor refs, it must have come
610 from the command line, since noone has used it it has no
29f33467 611 data attatched, so we'll ignore it
2fa0b342
DHW
612 */
613 }
29f33467 614 }
2fa0b342
DHW
615 return symbol_table;
616}
617
2fa0b342 618void
29f33467 619ldsym_write ()
2fa0b342 620{
f3b36ecb
KR
621 if (keepsyms_file != 0
622 && strip_symbols != STRIP_SOME)
623 {
3f905ec1 624 info_msg ("%P: `-retain-symbols-file' overrides `-s' and `-S'\n");
f3b36ecb
KR
625 strip_symbols = STRIP_SOME;
626 }
29f33467
SC
627 if (strip_symbols != STRIP_ALL)
628 {
629 /* We know the maximum size of the symbol table -
2fa0b342
DHW
630 it's the size of all the global symbols ever seen +
631 the size of all the symbols from all the files +
632 the number of files (for the per file symbols)
633 +1 (for the null at the end)
634 */
fcf276c4
ILT
635 asymbol **symbol_table =
636 ((asymbol **)
637 ldmalloc ((bfd_size_type) ((global_symbol_count
638 + total_files_seen
639 + total_symbols_seen
640 + 1)
641 * sizeof (asymbol *))));
29f33467 642 asymbol **tablep = write_file_locals (symbol_table);
2fa0b342 643
29f33467
SC
644 tablep = write_file_globals (tablep);
645 tablep = process_keepsyms (symbol_table, tablep - symbol_table);
2fa0b342 646
29f33467
SC
647 *tablep = (asymbol *) NULL;
648 bfd_set_symtab (output_bfd, symbol_table, (unsigned) (tablep - symbol_table));
649 }
2fa0b342 650}
c660714f
SC
651
652/*
29f33467 653return true if the supplied symbol name is not in the
c660714f
SC
654linker symbol table
655*/
29f33467 656boolean
8ddef552
DM
657ldsym_undefined (sym)
658 CONST char *sym;
c660714f 659{
29f33467
SC
660 ldsym_type *from_table = ldsym_get_soft (sym);
661 if (from_table != (ldsym_type *) NULL)
662 {
663 if (from_table->sdefs_chain != (asymbol **) NULL)
664 return false;
665 }
c660714f
SC
666 return true;
667}
bfbdc80f
SC
668
669void
8ddef552 670ldsym_init ()
bfbdc80f 671{
29f33467 672 obstack_begin (&global_sym_obstack, 20000);
bfbdc80f 673}
This page took 0.128725 seconds and 4 git commands to generate.