]> Git Repo - binutils.git/blame - ld/ldsym.c
* language.c (_initialize_language): Fix type check and range
[binutils.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 [email protected]
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;
184 register ldsym_type *bp;
185
186 /* Determine which bucket. */
187
188 hashval = hash_string (key) % TABSIZE;
189
190 /* Search the bucket. */
1af27af8 191return search(key, hashval);
2fa0b342
DHW
192}
193
194
195
196
197
198static void
199list_file_locals (entry)
200lang_input_statement_type *entry;
201{
202 asymbol **q;
19b03b7a 203 printf ( "\nLocal symbols of ");
2fa0b342 204 info("%I", entry);
19b03b7a 205 printf (":\n\n");
2fa0b342
DHW
206 if (entry->asymbols) {
207 for (q = entry->asymbols; *q; q++)
208 {
209 asymbol *p = *q;
210 /* If this is a definition,
211 update it if necessary by this file's start address. */
212 if (p->flags & BSF_LOCAL)
213 info(" %V %s\n",p->value, p->name);
214 }
215 }
216}
217
218
219static void
220print_file_stuff(f)
221lang_input_statement_type *f;
222{
48491e2e 223 fprintf (stdout, " %s\n", f->filename);
2fa0b342 224 if (f->just_syms_flag)
48491e2e
SC
225 {
226 fprintf (stdout, " symbols only\n");
227 }
2fa0b342 228 else
48491e2e
SC
229 {
230 asection *s;
231 if (true || option_longmap) {
232 for (s = f->the_bfd->sections;
233 s != (asection *)NULL;
234 s = s->next) {
235 print_address(s->output_offset);
236 printf (" %08x 2**%2ud %s\n",
237 (unsigned)s->size, s->alignment_power, s->name);
238 }
2fa0b342 239 }
48491e2e
SC
240 else {
241 for (s = f->the_bfd->sections;
242 s != (asection *)NULL;
243 s = s->next) {
244 printf("%s ", s->name);
245 print_address(s->output_offset);
246 printf("(%x)", (unsigned)s->size);
247 }
248 printf("hex \n");
2fa0b342 249 }
2fa0b342 250 }
48491e2e 251 fprintf (stdout, "\n");
2fa0b342
DHW
252}
253
254void
255ldsym_print_symbol_table ()
256{
48491e2e 257 fprintf (stdout, "**FILES**\n\n");
2fa0b342
DHW
258
259 lang_for_each_file(print_file_stuff);
260
48491e2e
SC
261 fprintf(stdout, "**GLOBAL SYMBOLS**\n\n");
262 fprintf(stdout, "offset section offset symbol\n");
2fa0b342
DHW
263 {
264 register ldsym_type *sp;
265
266 for (sp = symbol_head; sp; sp = sp->next)
267 {
1af27af8
SC
268 if (sp->flags & SYM_INDIRECT) {
269 fprintf(stdout,"indirect %s to %s\n",
270 sp->name, (((ldsym_type *)(sp->sdefs_chain))->name));
271 }
272 else {
2fa0b342
DHW
273 if (sp->sdefs_chain)
274 {
275 asymbol *defsym = *(sp->sdefs_chain);
276 asection *defsec = bfd_get_section(defsym);
19b03b7a 277 print_address(defsym->value);
2fa0b342
DHW
278 if (defsec)
279 {
48491e2e 280 printf(" %-10s",
2fa0b342
DHW
281 bfd_section_name(output_bfd,
282 defsec));
48491e2e
SC
283 print_space();
284 print_address(defsym->value+defsec->vma);
2fa0b342
DHW
285
286 }
287 else
288 {
19b03b7a 289 printf(" .......");
2fa0b342
DHW
290 }
291
292 }
2fa0b342
DHW
293
294
295 if (sp->scoms_chain) {
48491e2e 296 printf("common ");
19b03b7a 297 print_address((*(sp->scoms_chain))->value);
48491e2e 298 printf(" %s ",sp->name);
2fa0b342 299 }
48491e2e
SC
300 else if (sp->sdefs_chain) {
301 printf(" %s ",sp->name);
2fa0b342
DHW
302 }
303 else {
48491e2e 304 printf("undefined ");
19b03b7a 305 printf("%s ",sp->name);
1af27af8 306
2fa0b342 307 }
1af27af8 308 }
19b03b7a 309 print_nl();
2fa0b342
DHW
310
311 }
312 }
313 lang_for_each_file(list_file_locals);
314}
315
316extern lang_output_section_statement_type *create_object_symbols;
317extern char lprefix;
318static asymbol **
319write_file_locals(output_buffer)
320asymbol **output_buffer;
321{
322LANG_FOR_EACH_INPUT_STATEMENT(entry)
323 {
324 /* Run trough the symbols and work out what to do with them */
325 unsigned int i;
326
327 /* Add one for the filename symbol if needed */
328 if (create_object_symbols
329 != (lang_output_section_statement_type *)NULL) {
330 asection *s;
331 for (s = entry->the_bfd->sections;
332 s != (asection *)NULL;
333 s = s->next) {
334 if (s->output_section == create_object_symbols->bfd_section) {
335 /* Add symbol to this section */
336 asymbol * newsym =
337 (asymbol *)bfd_make_empty_symbol(entry->the_bfd);
338 newsym->name = entry->local_sym_name;
339 /* The symbol belongs to the output file's text section */
340
341 /* The value is the start of this section in the output file*/
342 newsym->value = 0;
343 newsym->flags = BSF_LOCAL;
344 newsym->section = s;
345 *output_buffer++ = newsym;
346 break;
347 }
348 }
349 }
350 for (i = 0; i < entry->symbol_count; i++)
351 {
352 asymbol *p = entry->asymbols[i];
353
354 if (flag_is_global(p->flags) || flag_is_absolute(p->flags))
355 {
356 /* We are only interested in outputting
357 globals at this stage in special circumstances */
358 if (p->the_bfd == entry->the_bfd
359 && flag_is_not_at_end(p->flags)) {
360 /* And this is one of them */
361 *(output_buffer++) = p;
362 p->flags |= BSF_KEEP;
363 }
364 }
365 else {
366 if (flag_is_ordinary_local(p->flags))
367 {
368 if (discard_locals == DISCARD_ALL)
369 { }
370 else if (discard_locals == DISCARD_L &&
371 (p->name[0] == lprefix))
372 { }
373 else if (p->flags == BSF_WARNING)
374 { }
375 else
376 { *output_buffer++ = p; }
377 }
378 else if (flag_is_debugger(p->flags))
379 {
380 /* Only keep the debugger symbols if no stripping required */
381 if (strip_symbols == STRIP_NONE) {
382 *output_buffer++ = p;
383 }
384 }
385 else if (flag_is_undefined(p->flags))
386 { /* This must be global */
387 }
388 else if (flag_is_common(p->flags)) {
389 /* And so must this */
390 }
391 else if (p->flags & BSF_CTOR) {
392 /* Throw it away */
393 }
394else
395 {
396 FAIL();
397 }
398 }
399 }
400
401
402 }
403 return output_buffer;
404}
405
406
407static asymbol **
408write_file_globals(symbol_table)
409asymbol **symbol_table;
410{
411 FOR_EACH_LDSYM(sp)
412 {
1af27af8 413 if ((sp->flags & SYM_INDIRECT) == 0 && sp->sdefs_chain != (asymbol **)NULL) {
2fa0b342
DHW
414 asymbol *bufp = (*(sp->sdefs_chain));
415
416 if ((bufp->flags & BSF_KEEP) ==0) {
417 ASSERT(bufp != (asymbol *)NULL);
418
419 bufp->name = sp->name;
420
421 if (sp->scoms_chain != (asymbol **)NULL)
422
423 {
424 /*
425 defined as common but not allocated, this happens
426 only with -r and not -d, write out a common
427 definition
428 */
429 bufp = *(sp->scoms_chain);
430 }
431 *symbol_table++ = bufp;
432 }
433 }
434 else if (sp->scoms_chain != (asymbol **)NULL) {
435 /* This symbol is a common - just output */
436 asymbol *bufp = (*(sp->scoms_chain));
437 *symbol_table++ = bufp;
438 }
439 else if (sp->srefs_chain != (asymbol **)NULL) {
440 /* This symbol is undefined but has a reference */
441 asymbol *bufp = (*(sp->srefs_chain));
442 *symbol_table++ = bufp;
443 }
444 else {
445 /*
446 This symbol has neither defs nor refs, it must have come
447 from the command line, since noone has used it it has no
448 data attatched, so we'll ignore it
449 */
450 }
451 }
452 return symbol_table;
453}
454
455
456
457void
458ldsym_write()
459{
460 if (strip_symbols != STRIP_ALL) {
461 /* We know the maximum size of the symbol table -
462 it's the size of all the global symbols ever seen +
463 the size of all the symbols from all the files +
464 the number of files (for the per file symbols)
465 +1 (for the null at the end)
466 */
467 extern unsigned int total_files_seen;
468 extern unsigned int total_symbols_seen;
469
470 asymbol ** symbol_table = (asymbol **)
19b03b7a 471 ldmalloc ((bfd_size_type)(global_symbol_count +
2fa0b342
DHW
472 total_files_seen +
473 total_symbols_seen + 1) * sizeof (asymbol *));
474 asymbol ** tablep = write_file_locals(symbol_table);
475
476 tablep = write_file_globals(tablep);
477
478 *tablep = (asymbol *)NULL;
479 bfd_set_symtab(output_bfd, symbol_table, (unsigned)( tablep - symbol_table));
480 }
481}
c660714f
SC
482
483/*
484return true if the supplied symbol name is not in the
485linker symbol table
486*/
487boolean
99fe4553
SC
488DEFUN(ldsym_undefined,(sym),
489 CONST char *sym)
c660714f
SC
490{
491 ldsym_type *from_table = ldsym_get_soft(sym);
492 if (from_table != (ldsym_type *)NULL) {
493 if (from_table->sdefs_chain != (asymbol **)NULL) return false;
494 }
495 return true;
496}
This page took 0.117679 seconds and 4 git commands to generate.