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