1 /* All symbol handling for the linker
2 Copyright (C) 1991 Free Software Foundation, Inc.
5 This file is part of GLD, the Gnu Linker.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
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....
38 +----------+ +----------+
39 | defs | a canonical symbol table
40 +----------+ +----------+
41 | refs | -----> | one entry| -----> asymbol
42 +----------+ +----------+ | |
43 | coms | | | +---------+
44 +----------+ +----------+ | udata |-----> another canonical symbol
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.
65 extern bfd *output_bfd;
66 extern strip_symbols_type strip_symbols;
67 extern discard_locals_type discard_locals;
68 /* Head and tail of global symbol table chronological list */
70 ldsym_type *symbol_head = (ldsym_type *)NULL;
71 ldsym_type **symbol_tail_ptr = &symbol_head;
74 incremented for each symbol in the ldsym_type table
75 no matter what flavour it is
77 unsigned int global_symbol_count;
81 extern boolean option_longmap ;
85 static ldsym_type *global_symbol_hash_table[TABSIZE];
87 /* Compute the hash code for symbol name KEY. */
94 DEFUN(hash_string,(key),
97 register CONST char *cp;
103 k = (((k << 1) + (k >> 14)) ^ (*cp++)) & 0x3fff;
111 #endif ldsym_type *bp;
113 DEFUN(search,(key,hashval) ,
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);
130 /* Get the symbol table entry for the global symbol named KEY.
131 Create one if there is none. */
133 DEFUN(ldsym_get,(key),
136 register int hashval;
137 register ldsym_type *bp;
139 /* Determine the proper bucket. */
141 hashval = hash_string (key) % TABSIZE;
143 /* Search the bucket. */
144 bp = search(key, hashval);
149 /* Nothing was found; create a new symbol table entry. */
151 bp = (ldsym_type *) ldmalloc ((bfd_size_type)(sizeof (ldsym_type)));
152 bp->srefs_chain = (asymbol **)NULL;
153 bp->sdefs_chain = (asymbol **)NULL;
154 bp->scoms_chain = (asymbol **)NULL;
155 bp->name = buystring(key);
157 /* Add the entry to the bucket. */
159 bp->link = global_symbol_hash_table[hashval];
160 global_symbol_hash_table[hashval] = bp;
162 /* Keep the chronological list up to date too */
163 *symbol_tail_ptr = bp;
164 symbol_tail_ptr = &bp->next;
166 global_symbol_count++;
171 /* Like `ldsym_get' but return 0 if the symbol is not already known. */
174 DEFUN(ldsym_get_soft,(key),
177 register int hashval;
178 /* Determine which bucket. */
180 hashval = hash_string (key) % TABSIZE;
182 /* Search the bucket. */
183 return search(key, hashval);
191 list_file_locals (entry)
192 lang_input_statement_type *entry;
195 printf ( "\nLocal symbols of ");
198 if (entry->asymbols) {
199 for (q = entry->asymbols; *q; 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);
213 lang_input_statement_type *f;
215 fprintf (stdout, " %s\n", f->filename);
216 if (f->just_syms_flag)
218 fprintf (stdout, " symbols only\n");
223 if (true || option_longmap) {
224 for (s = f->the_bfd->sections;
225 s != (asection *)NULL;
227 print_address(s->output_offset);
228 printf (" %08x 2**%2ud %s\n",
229 (unsigned)s->size, s->alignment_power, s->name);
233 for (s = f->the_bfd->sections;
234 s != (asection *)NULL;
236 printf("%s ", s->name);
237 print_address(s->output_offset);
238 printf("(%x)", (unsigned)s->size);
243 fprintf (stdout, "\n");
247 ldsym_print_symbol_table ()
249 fprintf (stdout, "**FILES**\n\n");
251 lang_for_each_file(print_file_stuff);
253 fprintf(stdout, "**GLOBAL SYMBOLS**\n\n");
254 fprintf(stdout, "offset section offset symbol\n");
256 register ldsym_type *sp;
258 for (sp = symbol_head; sp; sp = sp->next)
260 if (sp->flags & SYM_INDIRECT) {
261 fprintf(stdout,"indirect %s to %s\n",
262 sp->name, (((ldsym_type *)(sp->sdefs_chain))->name));
267 asymbol *defsym = *(sp->sdefs_chain);
268 asection *defsec = bfd_get_section(defsym);
269 print_address(defsym->value);
273 bfd_section_name(output_bfd,
276 print_address(defsym->value+defsec->vma);
287 if (sp->scoms_chain) {
289 print_address((*(sp->scoms_chain))->value);
290 printf(" %s ",sp->name);
292 else if (sp->sdefs_chain) {
293 printf(" %s ",sp->name);
296 printf("undefined ");
297 printf("%s ",sp->name);
305 if (option_longmap) {
306 lang_for_each_file(list_file_locals);
310 extern lang_output_section_statement_type *create_object_symbols;
313 write_file_locals(output_buffer)
314 asymbol **output_buffer;
316 LANG_FOR_EACH_INPUT_STATEMENT(entry)
318 /* Run trough the symbols and work out what to do with them */
321 /* Add one for the filename symbol if needed */
322 if (create_object_symbols
323 != (lang_output_section_statement_type *)NULL) {
325 for (s = entry->the_bfd->sections;
326 s != (asection *)NULL;
328 if (s->output_section == create_object_symbols->bfd_section) {
329 /* Add symbol to this section */
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 */
335 /* The value is the start of this section in the output file*/
337 newsym->flags = BSF_LOCAL;
339 *output_buffer++ = newsym;
344 for (i = 0; i < entry->symbol_count; i++)
346 asymbol *p = entry->asymbols[i];
348 if (flag_is_global(p->flags) || flag_is_absolute(p->flags))
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;
360 if (flag_is_ordinary_local(p->flags))
362 if (discard_locals == DISCARD_ALL)
364 else if (discard_locals == DISCARD_L &&
365 (p->name[0] == lprefix))
367 else if (p->flags == BSF_WARNING)
370 { *output_buffer++ = p; }
372 else if (flag_is_debugger(p->flags))
374 /* Only keep the debugger symbols if no stripping required */
375 if (strip_symbols == STRIP_NONE) {
376 *output_buffer++ = p;
379 else if (flag_is_undefined(p->flags))
380 { /* This must be global */
382 else if (flag_is_common(p->flags)) {
383 /* And so must this */
385 else if (p->flags & BSF_CTOR) {
397 return output_buffer;
402 write_file_globals(symbol_table)
403 asymbol **symbol_table;
407 if ((sp->flags & SYM_INDIRECT) == 0 && sp->sdefs_chain != (asymbol **)NULL) {
408 asymbol *bufp = (*(sp->sdefs_chain));
410 if ((bufp->flags & BSF_KEEP) ==0) {
411 ASSERT(bufp != (asymbol *)NULL);
413 bufp->name = sp->name;
415 if (sp->scoms_chain != (asymbol **)NULL)
419 defined as common but not allocated, this happens
420 only with -r and not -d, write out a common
423 bufp = *(sp->scoms_chain);
425 *symbol_table++ = bufp;
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;
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;
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
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)
461 extern unsigned int total_files_seen;
462 extern unsigned int total_symbols_seen;
464 asymbol ** symbol_table = (asymbol **)
465 ldmalloc ((bfd_size_type)(global_symbol_count +
467 total_symbols_seen + 1) * sizeof (asymbol *));
468 asymbol ** tablep = write_file_locals(symbol_table);
470 tablep = write_file_globals(tablep);
472 *tablep = (asymbol *)NULL;
473 bfd_set_symtab(output_bfd, symbol_table, (unsigned)( tablep - symbol_table));
478 return true if the supplied symbol name is not in the
482 DEFUN(ldsym_undefined,(sym),
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;