Strange link script support
[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
DHW
20
21/*
22 * $Id$
2d1a2445 23 */
2fa0b342
DHW
24
25/*
1af27af8
SC
26 We keep a hash table of global symbols. Each entry in a hash table
27 is called an ldsym_type. Each has three chains; a pointer to a
28 chain of definitions for the symbol (hopefully one long), a pointer
29 to a chain of references to the symbol, and a pointer to a chain of
30 common symbols. Each pointer points into the canonical symbol table
31 provided by bfd, each one of which points to an asymbol. Duringing
32 linkage, the linker uses the udata field to point to the next entry
33 in a canonical table....
34
35
36 ld_sym
37 | |
38 +----------+ +----------+
39 | defs | a canonical symbol table
40 +----------+ +----------+
41 | refs | -----> | one entry| -----> asymbol
42 +----------+ +----------+ | |
43 | coms | | | +---------+
44 +----------+ +----------+ | udata |-----> another canonical symbol
45 +---------+
46
47
48
49 It is very simple to make all the symbol pointers point to the same
50 definition - just run down the chain and make the asymbols pointers
51 within the canonical table point to the asymbol attacthed to the
52 definition of the symbol.
53
54*/
55
2fa0b342 56#include "bfd.h"
f177a611 57#include "sysdep.h"
2fa0b342
DHW
58
59#include "ld.h"
60#include "ldsym.h"
61#include "ldmisc.h"
62#include "ldlang.h"
63/* IMPORT */
64
65extern bfd *output_bfd;
d646b568
SC
66extern strip_symbols_type strip_symbols;
67extern discard_locals_type discard_locals;
2fa0b342
DHW
68/* Head and tail of global symbol table chronological list */
69
70ldsym_type *symbol_head = (ldsym_type *)NULL;
71ldsym_type **symbol_tail_ptr = &symbol_head;
72
6fd50a20
SC
73extern ld_config_type config;
74
2fa0b342
DHW
75/*
76 incremented for each symbol in the ldsym_type table
77 no matter what flavour it is
78*/
79unsigned int global_symbol_count;
80
81/* IMPORTS */
82
83extern boolean option_longmap ;
84
85/* LOCALS */
86#define TABSIZE 1009
87static ldsym_type *global_symbol_hash_table[TABSIZE];
88
89/* Compute the hash code for symbol name KEY. */
1af27af8
SC
90static
91#ifdef __GNUC__
b773e0e5 92__inline
1af27af8 93#endif
b773e0e5 94
2fa0b342 95int
1af27af8
SC
96DEFUN(hash_string,(key),
97 CONST char *key)
2fa0b342 98{
1af27af8 99 register CONST char *cp;
2fa0b342
DHW
100 register int k;
101
102 cp = key;
103 k = 0;
104 while (*cp)
105 k = (((k << 1) + (k >> 14)) ^ (*cp++)) & 0x3fff;
106
107 return k;
108}
109
1af27af8
SC
110static
111#ifdef __GNUC__
b773e0e5 112__inline
1af27af8
SC
113#endif ldsym_type *bp;
114ldsym_type *
115DEFUN(search,(key,hashval) ,
116 CONST char *key AND
117 int hashval)
118{
119 ldsym_type *bp;
120 for (bp = global_symbol_hash_table[hashval]; bp; bp = bp->link)
121 if (! strcmp (key, bp->name)) {
122 if (bp->flags & SYM_INDIRECT) {
123 /* Use the symbol we're aliased to instead */
124 return (ldsym_type *)(bp->sdefs_chain);
125 }
126 return bp;
127 }
128 return 0;
129}
130
131
2fa0b342
DHW
132/* Get the symbol table entry for the global symbol named KEY.
133 Create one if there is none. */
134ldsym_type *
99fe4553
SC
135DEFUN(ldsym_get,(key),
136 CONST char *key)
2fa0b342
DHW
137{
138 register int hashval;
139 register ldsym_type *bp;
140
141 /* Determine the proper bucket. */
142
143 hashval = hash_string (key) % TABSIZE;
144
145 /* Search the bucket. */
1af27af8
SC
146 bp = search(key, hashval);
147 if(bp) {
148 return bp;
149 }
2fa0b342
DHW
150
151 /* Nothing was found; create a new symbol table entry. */
152
19b03b7a 153 bp = (ldsym_type *) ldmalloc ((bfd_size_type)(sizeof (ldsym_type)));
2fa0b342
DHW
154 bp->srefs_chain = (asymbol **)NULL;
155 bp->sdefs_chain = (asymbol **)NULL;
156 bp->scoms_chain = (asymbol **)NULL;
99fe4553 157 bp->name = buystring(key);
81016051 158 bp->flags = 0;
2fa0b342
DHW
159 /* Add the entry to the bucket. */
160
161 bp->link = global_symbol_hash_table[hashval];
162 global_symbol_hash_table[hashval] = bp;
163
164 /* Keep the chronological list up to date too */
165 *symbol_tail_ptr = bp;
166 symbol_tail_ptr = &bp->next;
167 bp->next = 0;
168 global_symbol_count++;
169
170 return bp;
171}
172
173/* Like `ldsym_get' but return 0 if the symbol is not already known. */
174
175ldsym_type *
99fe4553
SC
176DEFUN(ldsym_get_soft,(key),
177 CONST char *key)
2fa0b342
DHW
178{
179 register int hashval;
2fa0b342
DHW
180 /* Determine which bucket. */
181
182 hashval = hash_string (key) % TABSIZE;
183
184 /* Search the bucket. */
7fe11a82 185 return search(key, hashval);
2fa0b342
DHW
186}
187
188
189
190
191
192static void
193list_file_locals (entry)
194lang_input_statement_type *entry;
195{
196 asymbol **q;
6fd50a20
SC
197 fprintf (config.map_file, "\nLocal symbols of ");
198 minfo("%I", entry);
199 fprintf (config.map_file, ":\n\n");
2fa0b342
DHW
200 if (entry->asymbols) {
201 for (q = entry->asymbols; *q; q++)
202 {
203 asymbol *p = *q;
204 /* If this is a definition,
205 update it if necessary by this file's start address. */
206 if (p->flags & BSF_LOCAL)
207 info(" %V %s\n",p->value, p->name);
208 }
209 }
210}
211
212
213static void
6fd50a20
SC
214DEFUN(print_file_stuff,(f),
215 lang_input_statement_type *f)
2fa0b342 216{
6fd50a20 217 fprintf (config.map_file," %s\n", f->filename);
2fa0b342 218 if (f->just_syms_flag)
c611e285 219 {
6fd50a20 220 fprintf (config.map_file, " symbols only\n");
c611e285 221 }
2fa0b342 222 else
c611e285
SC
223 {
224 asection *s;
225 if (true || option_longmap) {
226 for (s = f->the_bfd->sections;
227 s != (asection *)NULL;
228 s = s->next) {
48491e2e 229 print_address(s->output_offset);
870f54b2 230 if (s->reloc_done)
c611e285 231 {
6fd50a20 232 fprintf (config.map_file, " %08x 2**%2ud %s\n",
c611e285
SC
233 (unsigned)bfd_get_section_size_after_reloc(s),
234 s->alignment_power, s->name);
235 }
236
237 else
238 {
6fd50a20 239 fprintf (config.map_file, " %08x 2**%2ud %s\n",
c611e285
SC
240 (unsigned)bfd_get_section_size_before_reloc(s),
241 s->alignment_power, s->name);
242 }
243
244
245
48491e2e 246 }
c611e285
SC
247 }
248 else {
249 for (s = f->the_bfd->sections;
250 s != (asection *)NULL;
251 s = s->next) {
6fd50a20 252 fprintf(config.map_file, "%s ", s->name);
48491e2e 253 print_address(s->output_offset);
6fd50a20 254 fprintf(config.map_file, "(%x)", (unsigned)bfd_get_section_size_after_reloc(s));
48491e2e 255 }
6fd50a20 256 fprintf(config.map_file, "hex \n");
2fa0b342 257 }
c611e285 258 }
6fd50a20 259 fprintf (config.map_file, "\n");
2fa0b342
DHW
260}
261
262void
263ldsym_print_symbol_table ()
264{
6fd50a20 265 fprintf (config.map_file, "**FILES**\n\n");
2fa0b342
DHW
266
267 lang_for_each_file(print_file_stuff);
268
6fd50a20
SC
269 fprintf(config.map_file, "**GLOBAL SYMBOLS**\n\n");
270 fprintf(config.map_file, "offset section offset symbol\n");
2fa0b342
DHW
271 {
272 register ldsym_type *sp;
273
274 for (sp = symbol_head; sp; sp = sp->next)
275 {
1af27af8 276 if (sp->flags & SYM_INDIRECT) {
6fd50a20 277 fprintf(config.map_file,"indirect %s to %s\n",
1af27af8 278 sp->name, (((ldsym_type *)(sp->sdefs_chain))->name));
2fa0b342
DHW
279 }
280 else {
d9c53949
SC
281 if (sp->sdefs_chain)
282 {
283 asymbol *defsym = *(sp->sdefs_chain);
284 asection *defsec = bfd_get_section(defsym);
285 print_address(defsym->value);
286 if (defsec)
287 {
6fd50a20 288 fprintf(config.map_file, " %-10s",
d9c53949
SC
289 bfd_section_name(output_bfd,
290 defsec));
291 print_space();
292 print_address(defsym->value+defsec->vma);
293
294 }
295 else
296 {
6fd50a20 297 fprintf(config.map_file, " .......");
d9c53949
SC
298 }
299
300 }
301
302
303 if (sp->scoms_chain) {
6fd50a20 304 fprintf(config.map_file, "common ");
d9c53949 305 print_address((*(sp->scoms_chain))->value);
6fd50a20 306 fprintf(config.map_file, " %s ",sp->name);
d9c53949
SC
307 }
308 else if (sp->sdefs_chain) {
6fd50a20 309 fprintf(config.map_file, " %s ",sp->name);
d9c53949
SC
310 }
311 else {
6fd50a20
SC
312 fprintf(config.map_file, "undefined ");
313 fprintf(config.map_file, "%s ",sp->name);
1af27af8 314
d9c53949 315 }
2fa0b342 316 }
19b03b7a 317 print_nl();
2fa0b342
DHW
318
319 }
320 }
d9c53949
SC
321 if (option_longmap) {
322 lang_for_each_file(list_file_locals);
323 }
2fa0b342
DHW
324}
325
326extern lang_output_section_statement_type *create_object_symbols;
327extern char lprefix;
328static asymbol **
329write_file_locals(output_buffer)
330asymbol **output_buffer;
331{
332LANG_FOR_EACH_INPUT_STATEMENT(entry)
333 {
334 /* Run trough the symbols and work out what to do with them */
335 unsigned int i;
336
337 /* Add one for the filename symbol if needed */
338 if (create_object_symbols
339 != (lang_output_section_statement_type *)NULL) {
340 asection *s;
341 for (s = entry->the_bfd->sections;
342 s != (asection *)NULL;
343 s = s->next) {
344 if (s->output_section == create_object_symbols->bfd_section) {
345 /* Add symbol to this section */
346 asymbol * newsym =
347 (asymbol *)bfd_make_empty_symbol(entry->the_bfd);
348 newsym->name = entry->local_sym_name;
349 /* The symbol belongs to the output file's text section */
350
351 /* The value is the start of this section in the output file*/
352 newsym->value = 0;
353 newsym->flags = BSF_LOCAL;
354 newsym->section = s;
355 *output_buffer++ = newsym;
356 break;
357 }
358 }
359 }
360 for (i = 0; i < entry->symbol_count; i++)
361 {
362 asymbol *p = entry->asymbols[i];
58216160 363 /* FIXME, temporary hack, since not all of ld knows about the new abs section convention */
2fa0b342 364
58216160
MT
365 if (p->section == 0)
366 p->section = &bfd_abs_section;
c611e285 367 if (flag_is_global(p->flags) )
2fa0b342
DHW
368 {
369 /* We are only interested in outputting
370 globals at this stage in special circumstances */
371 if (p->the_bfd == entry->the_bfd
372 && flag_is_not_at_end(p->flags)) {
373 /* And this is one of them */
374 *(output_buffer++) = p;
375 p->flags |= BSF_KEEP;
376 }
377 }
378 else {
379 if (flag_is_ordinary_local(p->flags))
380 {
381 if (discard_locals == DISCARD_ALL)
382 { }
383 else if (discard_locals == DISCARD_L &&
384 (p->name[0] == lprefix))
385 { }
386 else if (p->flags == BSF_WARNING)
387 { }
388 else
389 { *output_buffer++ = p; }
390 }
391 else if (flag_is_debugger(p->flags))
392 {
393 /* Only keep the debugger symbols if no stripping required */
394 if (strip_symbols == STRIP_NONE) {
395 *output_buffer++ = p;
396 }
397 }
c611e285 398 else if (p->section == &bfd_und_section)
2fa0b342
DHW
399 { /* This must be global */
400 }
c611e285 401 else if (p->section == &bfd_com_section) {
2fa0b342
DHW
402 /* And so must this */
403 }
404 else if (p->flags & BSF_CTOR) {
405 /* Throw it away */
406 }
407else
408 {
409 FAIL();
410 }
411 }
412 }
413
414
415 }
416 return output_buffer;
417}
418
419
420static asymbol **
421write_file_globals(symbol_table)
422asymbol **symbol_table;
423{
424 FOR_EACH_LDSYM(sp)
425 {
1af27af8 426 if ((sp->flags & SYM_INDIRECT) == 0 && sp->sdefs_chain != (asymbol **)NULL) {
2fa0b342
DHW
427 asymbol *bufp = (*(sp->sdefs_chain));
428
429 if ((bufp->flags & BSF_KEEP) ==0) {
430 ASSERT(bufp != (asymbol *)NULL);
431
432 bufp->name = sp->name;
433
434 if (sp->scoms_chain != (asymbol **)NULL)
435
436 {
437 /*
438 defined as common but not allocated, this happens
439 only with -r and not -d, write out a common
440 definition
441 */
442 bufp = *(sp->scoms_chain);
443 }
444 *symbol_table++ = bufp;
445 }
446 }
447 else if (sp->scoms_chain != (asymbol **)NULL) {
448 /* This symbol is a common - just output */
449 asymbol *bufp = (*(sp->scoms_chain));
450 *symbol_table++ = bufp;
451 }
452 else if (sp->srefs_chain != (asymbol **)NULL) {
453 /* This symbol is undefined but has a reference */
454 asymbol *bufp = (*(sp->srefs_chain));
455 *symbol_table++ = bufp;
456 }
457 else {
458 /*
459 This symbol has neither defs nor refs, it must have come
460 from the command line, since noone has used it it has no
461 data attatched, so we'll ignore it
462 */
463 }
464 }
465 return symbol_table;
466}
467
468
469
470void
471ldsym_write()
472{
473 if (strip_symbols != STRIP_ALL) {
474 /* We know the maximum size of the symbol table -
475 it's the size of all the global symbols ever seen +
476 the size of all the symbols from all the files +
477 the number of files (for the per file symbols)
478 +1 (for the null at the end)
479 */
480 extern unsigned int total_files_seen;
481 extern unsigned int total_symbols_seen;
482
483 asymbol ** symbol_table = (asymbol **)
19b03b7a 484 ldmalloc ((bfd_size_type)(global_symbol_count +
2fa0b342
DHW
485 total_files_seen +
486 total_symbols_seen + 1) * sizeof (asymbol *));
487 asymbol ** tablep = write_file_locals(symbol_table);
488
489 tablep = write_file_globals(tablep);
490
491 *tablep = (asymbol *)NULL;
492 bfd_set_symtab(output_bfd, symbol_table, (unsigned)( tablep - symbol_table));
493 }
494}
c660714f
SC
495
496/*
497return true if the supplied symbol name is not in the
498linker symbol table
499*/
500boolean
99fe4553
SC
501DEFUN(ldsym_undefined,(sym),
502 CONST char *sym)
c660714f
SC
503{
504 ldsym_type *from_table = ldsym_get_soft(sym);
505 if (from_table != (ldsym_type *)NULL) {
506 if (from_table->sdefs_chain != (asymbol **)NULL) return false;
507 }
508 return true;
509}
This page took 0.078255 seconds and 4 git commands to generate.