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