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. */
93 DEFUN(hash_string,(key),
96 register CONST char *cp;
102 k = (((k << 1) + (k >> 14)) ^ (*cp++)) & 0x3fff;
110 #endif ldsym_type *bp;
112 DEFUN(search,(key,hashval) ,
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);
129 /* Get the symbol table entry for the global symbol named KEY.
130 Create one if there is none. */
132 DEFUN(ldsym_get,(key),
135 register int hashval;
136 register ldsym_type *bp;
138 /* Determine the proper bucket. */
140 hashval = hash_string (key) % TABSIZE;
142 /* Search the bucket. */
143 bp = search(key, hashval);
148 /* Nothing was found; create a new symbol table entry. */
150 bp = (ldsym_type *) ldmalloc ((bfd_size_type)(sizeof (ldsym_type)));
151 bp->srefs_chain = (asymbol **)NULL;
152 bp->sdefs_chain = (asymbol **)NULL;
153 bp->scoms_chain = (asymbol **)NULL;
154 bp->name = buystring(key);
156 /* Add the entry to the bucket. */
158 bp->link = global_symbol_hash_table[hashval];
159 global_symbol_hash_table[hashval] = bp;
161 /* Keep the chronological list up to date too */
162 *symbol_tail_ptr = bp;
163 symbol_tail_ptr = &bp->next;
165 global_symbol_count++;
170 /* Like `ldsym_get' but return 0 if the symbol is not already known. */
173 DEFUN(ldsym_get_soft,(key),
176 register int hashval;
177 /* Determine which bucket. */
179 hashval = hash_string (key) % TABSIZE;
181 /* Search the bucket. */
182 return search(key, hashval);
190 list_file_locals (entry)
191 lang_input_statement_type *entry;
194 printf ( "\nLocal symbols of ");
197 if (entry->asymbols) {
198 for (q = entry->asymbols; *q; 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);
212 lang_input_statement_type *f;
214 fprintf (stdout, " %s\n", f->filename);
215 if (f->just_syms_flag)
217 fprintf (stdout, " symbols only\n");
222 if (true || option_longmap) {
223 for (s = f->the_bfd->sections;
224 s != (asection *)NULL;
226 print_address(s->output_offset);
227 printf (" %08x 2**%2ud %s\n",
228 (unsigned)s->size, s->alignment_power, s->name);
232 for (s = f->the_bfd->sections;
233 s != (asection *)NULL;
235 printf("%s ", s->name);
236 print_address(s->output_offset);
237 printf("(%x)", (unsigned)s->size);
242 fprintf (stdout, "\n");
246 ldsym_print_symbol_table ()
248 fprintf (stdout, "**FILES**\n\n");
250 lang_for_each_file(print_file_stuff);
252 fprintf(stdout, "**GLOBAL SYMBOLS**\n\n");
253 fprintf(stdout, "offset section offset symbol\n");
255 register ldsym_type *sp;
257 for (sp = symbol_head; sp; sp = sp->next)
259 if (sp->flags & SYM_INDIRECT) {
260 fprintf(stdout,"indirect %s to %s\n",
261 sp->name, (((ldsym_type *)(sp->sdefs_chain))->name));
266 asymbol *defsym = *(sp->sdefs_chain);
267 asection *defsec = bfd_get_section(defsym);
268 print_address(defsym->value);
272 bfd_section_name(output_bfd,
275 print_address(defsym->value+defsec->vma);
286 if (sp->scoms_chain) {
288 print_address((*(sp->scoms_chain))->value);
289 printf(" %s ",sp->name);
291 else if (sp->sdefs_chain) {
292 printf(" %s ",sp->name);
295 printf("undefined ");
296 printf("%s ",sp->name);
304 if (option_longmap) {
305 lang_for_each_file(list_file_locals);
309 extern lang_output_section_statement_type *create_object_symbols;
312 write_file_locals(output_buffer)
313 asymbol **output_buffer;
315 LANG_FOR_EACH_INPUT_STATEMENT(entry)
317 /* Run trough the symbols and work out what to do with them */
320 /* Add one for the filename symbol if needed */
321 if (create_object_symbols
322 != (lang_output_section_statement_type *)NULL) {
324 for (s = entry->the_bfd->sections;
325 s != (asection *)NULL;
327 if (s->output_section == create_object_symbols->bfd_section) {
328 /* Add symbol to this section */
330 (asymbol *)bfd_make_empty_symbol(entry->the_bfd);
331 newsym->name = entry->local_sym_name;
332 /* The symbol belongs to the output file's text section */
334 /* The value is the start of this section in the output file*/
336 newsym->flags = BSF_LOCAL;
338 *output_buffer++ = newsym;
343 for (i = 0; i < entry->symbol_count; i++)
345 asymbol *p = entry->asymbols[i];
347 if (flag_is_global(p->flags) || flag_is_absolute(p->flags))
349 /* We are only interested in outputting
350 globals at this stage in special circumstances */
351 if (p->the_bfd == entry->the_bfd
352 && flag_is_not_at_end(p->flags)) {
353 /* And this is one of them */
354 *(output_buffer++) = p;
355 p->flags |= BSF_KEEP;
359 if (flag_is_ordinary_local(p->flags))
361 if (discard_locals == DISCARD_ALL)
363 else if (discard_locals == DISCARD_L &&
364 (p->name[0] == lprefix))
366 else if (p->flags == BSF_WARNING)
369 { *output_buffer++ = p; }
371 else if (flag_is_debugger(p->flags))
373 /* Only keep the debugger symbols if no stripping required */
374 if (strip_symbols == STRIP_NONE) {
375 *output_buffer++ = p;
378 else if (flag_is_undefined(p->flags))
379 { /* This must be global */
381 else if (flag_is_common(p->flags)) {
382 /* And so must this */
384 else if (p->flags & BSF_CTOR) {
396 return output_buffer;
401 write_file_globals(symbol_table)
402 asymbol **symbol_table;
406 if ((sp->flags & SYM_INDIRECT) == 0 && sp->sdefs_chain != (asymbol **)NULL) {
407 asymbol *bufp = (*(sp->sdefs_chain));
409 if ((bufp->flags & BSF_KEEP) ==0) {
410 ASSERT(bufp != (asymbol *)NULL);
412 bufp->name = sp->name;
414 if (sp->scoms_chain != (asymbol **)NULL)
418 defined as common but not allocated, this happens
419 only with -r and not -d, write out a common
422 bufp = *(sp->scoms_chain);
424 *symbol_table++ = bufp;
427 else if (sp->scoms_chain != (asymbol **)NULL) {
428 /* This symbol is a common - just output */
429 asymbol *bufp = (*(sp->scoms_chain));
430 *symbol_table++ = bufp;
432 else if (sp->srefs_chain != (asymbol **)NULL) {
433 /* This symbol is undefined but has a reference */
434 asymbol *bufp = (*(sp->srefs_chain));
435 *symbol_table++ = bufp;
439 This symbol has neither defs nor refs, it must have come
440 from the command line, since noone has used it it has no
441 data attatched, so we'll ignore it
453 if (strip_symbols != STRIP_ALL) {
454 /* We know the maximum size of the symbol table -
455 it's the size of all the global symbols ever seen +
456 the size of all the symbols from all the files +
457 the number of files (for the per file symbols)
458 +1 (for the null at the end)
460 extern unsigned int total_files_seen;
461 extern unsigned int total_symbols_seen;
463 asymbol ** symbol_table = (asymbol **)
464 ldmalloc ((bfd_size_type)(global_symbol_count +
466 total_symbols_seen + 1) * sizeof (asymbol *));
467 asymbol ** tablep = write_file_locals(symbol_table);
469 tablep = write_file_globals(tablep);
471 *tablep = (asymbol *)NULL;
472 bfd_set_symtab(output_bfd, symbol_table, (unsigned)( tablep - symbol_table));
477 return true if the supplied symbol name is not in the
481 DEFUN(ldsym_undefined,(sym),
484 ldsym_type *from_table = ldsym_get_soft(sym);
485 if (from_table != (ldsym_type *)NULL) {
486 if (from_table->sdefs_chain != (asymbol **)NULL) return false;