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;
73 extern ld_config_type config;
75 struct obstack global_sym_obstack;
76 #define obstack_chunk_alloc ldmalloc
77 #define obstack_chunk_free free
80 incremented for each symbol in the ldsym_type table
81 no matter what flavour it is
83 unsigned int global_symbol_count;
87 extern boolean option_longmap ;
91 static ldsym_type *global_symbol_hash_table[TABSIZE];
93 /* Compute the hash code for symbol name KEY. */
100 DEFUN(hash_string,(key),
103 register CONST char *cp;
109 k = (((k << 1) + (k >> 14)) ^ (*cp++)) & 0x3fff;
117 #endif ldsym_type *bp;
119 DEFUN(search,(key,hashval) ,
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);
136 /* Get the symbol table entry for the global symbol named KEY.
137 Create one if there is none. */
139 DEFUN(ldsym_get,(key),
142 register int hashval;
143 register ldsym_type *bp;
145 /* Determine the proper bucket. */
147 hashval = hash_string (key) % TABSIZE;
149 /* Search the bucket. */
150 bp = search(key, hashval);
155 /* Nothing was found; create a new symbol table entry. */
157 bp = (ldsym_type *) obstack_alloc (&global_sym_obstack, (bfd_size_type)(sizeof (ldsym_type)));
158 bp->srefs_chain = (asymbol **)NULL;
159 bp->sdefs_chain = (asymbol **)NULL;
160 bp->scoms_chain = (asymbol **)NULL;
161 bp->name = obstack_copy(&global_sym_obstack, key, strlen(key)+1);
163 /* Add the entry to the bucket. */
165 bp->link = global_symbol_hash_table[hashval];
166 global_symbol_hash_table[hashval] = bp;
168 /* Keep the chronological list up to date too */
169 *symbol_tail_ptr = bp;
170 symbol_tail_ptr = &bp->next;
172 global_symbol_count++;
177 /* Like `ldsym_get' but return 0 if the symbol is not already known. */
180 DEFUN(ldsym_get_soft,(key),
183 register int hashval;
184 /* Determine which bucket. */
186 hashval = hash_string (key) % TABSIZE;
188 /* Search the bucket. */
189 return search(key, hashval);
197 list_file_locals (entry)
198 lang_input_statement_type *entry;
201 fprintf (config.map_file, "\nLocal symbols of ");
203 fprintf (config.map_file, ":\n\n");
204 if (entry->asymbols) {
205 for (q = entry->asymbols; *q; 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);
218 DEFUN(print_file_stuff,(f),
219 lang_input_statement_type *f)
221 fprintf (config.map_file," %s\n", f->filename);
222 if (f->just_syms_flag)
224 fprintf (config.map_file, " symbols only\n");
229 if (true || option_longmap) {
230 for (s = f->the_bfd->sections;
231 s != (asection *)NULL;
233 print_address(s->output_offset);
236 fprintf (config.map_file, " %08x 2**%2ud %s\n",
237 (unsigned)bfd_get_section_size_after_reloc(s),
238 s->alignment_power, s->name);
243 fprintf (config.map_file, " %08x 2**%2ud %s\n",
244 (unsigned)bfd_get_section_size_before_reloc(s),
245 s->alignment_power, s->name);
251 for (s = f->the_bfd->sections;
252 s != (asection *)NULL;
254 fprintf(config.map_file, "%s ", s->name);
255 print_address(s->output_offset);
256 fprintf(config.map_file, "(%x)", (unsigned)bfd_get_section_size_after_reloc(s));
258 fprintf(config.map_file, "hex \n");
261 fprintf (config.map_file, "\n");
265 ldsym_print_symbol_table ()
267 fprintf (config.map_file, "**FILES**\n\n");
269 lang_for_each_file(print_file_stuff);
271 fprintf(config.map_file, "**GLOBAL SYMBOLS**\n\n");
272 fprintf(config.map_file, "offset section offset symbol\n");
274 register ldsym_type *sp;
276 for (sp = symbol_head; sp; sp = sp->next)
278 if (sp->flags & SYM_INDIRECT) {
279 fprintf(config.map_file,"indirect %s to %s\n",
280 sp->name, (((ldsym_type *)(sp->sdefs_chain))->name));
285 asymbol *defsym = *(sp->sdefs_chain);
286 asection *defsec = bfd_get_section(defsym);
287 print_address(defsym->value);
290 fprintf(config.map_file, " %-10s",
291 bfd_section_name(output_bfd,
294 print_address(defsym->value+defsec->vma);
299 fprintf(config.map_file, " .......");
305 if (sp->scoms_chain) {
306 fprintf(config.map_file, "common ");
307 print_address((*(sp->scoms_chain))->value);
308 fprintf(config.map_file, " %s ",sp->name);
310 else if (sp->sdefs_chain) {
311 fprintf(config.map_file, " %s ",sp->name);
314 fprintf(config.map_file, "undefined ");
315 fprintf(config.map_file, "%s ",sp->name);
323 if (option_longmap) {
324 lang_for_each_file(list_file_locals);
328 extern lang_output_section_statement_type *create_object_symbols;
331 write_file_locals(output_buffer)
332 asymbol **output_buffer;
334 LANG_FOR_EACH_INPUT_STATEMENT(entry)
336 /* Run trough the symbols and work out what to do with them */
339 /* Add one for the filename symbol if needed */
340 if (create_object_symbols
341 != (lang_output_section_statement_type *)NULL) {
343 for (s = entry->the_bfd->sections;
344 s != (asection *)NULL;
346 if (s->output_section == create_object_symbols->bfd_section) {
347 /* Add symbol to this section */
349 (asymbol *)bfd_make_empty_symbol(entry->the_bfd);
350 newsym->name = entry->local_sym_name;
351 /* The symbol belongs to the output file's text section */
353 /* The value is the start of this section in the output file*/
355 newsym->flags = BSF_LOCAL;
357 *output_buffer++ = newsym;
362 for (i = 0; i < entry->symbol_count; i++)
364 asymbol *p = entry->asymbols[i];
365 /* FIXME, temporary hack, since not all of ld knows about the new abs section convention */
368 p->section = &bfd_abs_section;
369 if (flag_is_global(p->flags) )
371 /* We are only interested in outputting
372 globals at this stage in special circumstances */
373 if (p->the_bfd == entry->the_bfd
374 && flag_is_not_at_end(p->flags)) {
375 /* And this is one of them */
376 *(output_buffer++) = p;
377 p->flags |= BSF_KEEP;
381 if (flag_is_ordinary_local(p->flags))
383 if (discard_locals == DISCARD_ALL)
385 else if (discard_locals == DISCARD_L &&
386 (p->name[0] == lprefix))
388 else if (p->flags == BSF_WARNING)
391 { *output_buffer++ = p; }
393 else if (flag_is_debugger(p->flags))
395 /* Only keep the debugger symbols if no stripping required */
396 if (strip_symbols == STRIP_NONE) {
397 *output_buffer++ = p;
400 else if (p->section == &bfd_und_section)
401 { /* This must be global */
403 else if (p->section == &bfd_com_section) {
404 /* And so must this */
406 else if (p->flags & BSF_CTOR) {
418 return output_buffer;
423 write_file_globals(symbol_table)
424 asymbol **symbol_table;
428 if ((sp->flags & SYM_INDIRECT) == 0 && sp->sdefs_chain != (asymbol **)NULL) {
429 asymbol *bufp = (*(sp->sdefs_chain));
431 if ((bufp->flags & BSF_KEEP) ==0) {
432 ASSERT(bufp != (asymbol *)NULL);
434 bufp->name = sp->name;
436 if (sp->scoms_chain != (asymbol **)NULL)
440 defined as common but not allocated, this happens
441 only with -r and not -d, write out a common
444 bufp = *(sp->scoms_chain);
446 *symbol_table++ = bufp;
449 else if (sp->scoms_chain != (asymbol **)NULL) {
450 /* This symbol is a common - just output */
451 asymbol *bufp = (*(sp->scoms_chain));
452 *symbol_table++ = bufp;
454 else if (sp->srefs_chain != (asymbol **)NULL) {
455 /* This symbol is undefined but has a reference */
456 asymbol *bufp = (*(sp->srefs_chain));
457 *symbol_table++ = bufp;
461 This symbol has neither defs nor refs, it must have come
462 from the command line, since noone has used it it has no
463 data attatched, so we'll ignore it
475 if (strip_symbols != STRIP_ALL) {
476 /* We know the maximum size of the symbol table -
477 it's the size of all the global symbols ever seen +
478 the size of all the symbols from all the files +
479 the number of files (for the per file symbols)
480 +1 (for the null at the end)
482 extern unsigned int total_files_seen;
483 extern unsigned int total_symbols_seen;
485 asymbol ** symbol_table = (asymbol **)
486 ldmalloc ((bfd_size_type)(global_symbol_count +
488 total_symbols_seen + 1) * sizeof (asymbol *));
489 asymbol ** tablep = write_file_locals(symbol_table);
491 tablep = write_file_globals(tablep);
493 *tablep = (asymbol *)NULL;
494 bfd_set_symtab(output_bfd, symbol_table, (unsigned)( tablep - symbol_table));
499 return true if the supplied symbol name is not in the
503 DEFUN(ldsym_undefined,(sym),
506 ldsym_type *from_table = ldsym_get_soft(sym);
507 if (from_table != (ldsym_type *)NULL)
509 if (from_table->sdefs_chain != (asymbol **)NULL) return false;
515 DEFUN_VOID(ldsym_init)
517 obstack_begin(&global_sym_obstack, 20000);