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