1 /* Copyright (C) 1991 Free Software Foundation, Inc.
3 This file is part of GLD, the Gnu Linker.
5 GLD is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 1, or (at your option)
10 GLD is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with GLD; see the file COPYING. If not, write to
17 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
23 * Revision 1.2 1991/03/22 23:02:38 steve
24 * Brought up to sync with Intel again.
26 * Revision 1.1 1991/03/13 00:48:32 chrisb
29 * Revision 1.4 1991/03/10 09:31:36 rich
31 * Makefile config.h ld-emul.c ld-emul.h ld-gld.c ld-gld960.c
32 * ld-lnk960.c ld.h lddigest.c ldexp.c ldexp.h ldfile.c ldfile.h
33 * ldgram.y ldinfo.h ldlang.c ldlang.h ldlex.h ldlex.l ldmain.c
34 * ldmain.h ldmisc.c ldmisc.h ldsym.c ldsym.h ldversion.c
35 * ldversion.h ldwarn.h ldwrite.c ldwrite.h y.tab.h
37 * As of this round of changes, ld now builds on all hosts of (Intel960)
38 * interest and copy passes my copy test on big endian hosts again.
40 * Revision 1.3 1991/03/06 02:28:56 sac
43 * Revision 1.2 1991/02/22 17:15:06 sac
44 * Added RCS keywords and copyrights
51 All symbol handling for the linker
64 extern bfd *output_bfd;
65 /* Head and tail of global symbol table chronological list */
67 ldsym_type *symbol_head = (ldsym_type *)NULL;
68 ldsym_type **symbol_tail_ptr = &symbol_head;
71 incremented for each symbol in the ldsym_type table
72 no matter what flavour it is
74 unsigned int global_symbol_count;
78 extern boolean option_longmap ;
82 static ldsym_type *global_symbol_hash_table[TABSIZE];
84 /* Compute the hash code for symbol name KEY. */
96 k = (((k << 1) + (k >> 14)) ^ (*cp++)) & 0x3fff;
101 /* Get the symbol table entry for the global symbol named KEY.
102 Create one if there is none. */
107 register int hashval;
108 register ldsym_type *bp;
110 /* Determine the proper bucket. */
112 hashval = hash_string (key) % TABSIZE;
114 /* Search the bucket. */
116 for (bp = global_symbol_hash_table[hashval]; bp; bp = bp->link)
117 if (! strcmp (key, bp->name))
120 /* Nothing was found; create a new symbol table entry. */
122 bp = (ldsym_type *) ldmalloc (sizeof (ldsym_type));
123 bp->srefs_chain = (asymbol **)NULL;
124 bp->sdefs_chain = (asymbol **)NULL;
125 bp->scoms_chain = (asymbol **)NULL;
126 bp->name = (char *) ldmalloc (strlen (key) + 1);
127 strcpy (bp->name, key);
132 /* Add the entry to the bucket. */
134 bp->link = global_symbol_hash_table[hashval];
135 global_symbol_hash_table[hashval] = bp;
137 /* Keep the chronological list up to date too */
138 *symbol_tail_ptr = bp;
139 symbol_tail_ptr = &bp->next;
141 global_symbol_count++;
146 /* Like `ldsym_get' but return 0 if the symbol is not already known. */
152 register int hashval;
153 register ldsym_type *bp;
155 /* Determine which bucket. */
157 hashval = hash_string (key) % TABSIZE;
159 /* Search the bucket. */
161 for (bp = global_symbol_hash_table[hashval]; bp; bp = bp->link)
162 if (! strcmp (key, bp->name))
173 list_file_locals (entry)
174 lang_input_statement_type *entry;
177 fprintf (stderr, "\nLocal symbols of ");
179 fprintf (stderr, ":\n\n");
180 if (entry->asymbols) {
181 for (q = entry->asymbols; *q; q++)
184 /* If this is a definition,
185 update it if necessary by this file's start address. */
186 if (p->flags & BSF_LOCAL)
187 info(" %V %s\n",p->value, p->name);
195 lang_input_statement_type *f;
197 fprintf (stderr, " %s", f->filename);
198 fprintf (stderr, " ");
199 if (f->just_syms_flag)
201 fprintf (stderr, " symbols only\n");
206 if (option_longmap) {
207 for (s = f->the_bfd->sections;
208 s != (asection *)NULL;
210 fprintf (stderr, "%08lx %08x 2**%2ud %s\n",
212 (unsigned)s->size, s->alignment_power, s->name);
216 for (s = f->the_bfd->sections;
217 s != (asection *)NULL;
219 fprintf (stderr, "%s %lx(%x) ",
224 fprintf (stderr, "hex \n");
230 ldsym_print_symbol_table ()
232 fprintf (stderr, "\nFiles:\n\n");
234 lang_for_each_file(print_file_stuff);
236 fprintf (stderr, "\nGlobal symbols:\n\n");
238 register ldsym_type *sp;
240 for (sp = symbol_head; sp; sp = sp->next)
244 asymbol *defsym = *(sp->sdefs_chain);
245 asection *defsec = bfd_get_section(defsym);
246 fprintf(stderr,"%08lx ",defsym->value);
249 fprintf(stderr,"%08lx ",defsym->value+defsec->vma);
252 bfd_section_name(output_bfd,
258 fprintf(stderr," .......");
263 fprintf(stderr,"undefined");
267 if (sp->scoms_chain) {
268 fprintf(stderr, " common size %5lu %s",
269 (*(sp->scoms_chain))->value, sp->name);
271 if (sp->sdefs_chain) {
272 fprintf(stderr, " symbol def %08lx %s",
273 (*(sp->sdefs_chain))->value,
277 fprintf(stderr, " undefined %s",
280 fprintf(stderr, "\n");
284 lang_for_each_file(list_file_locals);
287 extern lang_output_section_statement_type *create_object_symbols;
290 write_file_locals(output_buffer)
291 asymbol **output_buffer;
293 LANG_FOR_EACH_INPUT_STATEMENT(entry)
295 /* Run trough the symbols and work out what to do with them */
298 /* Add one for the filename symbol if needed */
299 if (create_object_symbols
300 != (lang_output_section_statement_type *)NULL) {
302 for (s = entry->the_bfd->sections;
303 s != (asection *)NULL;
305 if (s->output_section == create_object_symbols->bfd_section) {
306 /* Add symbol to this section */
308 (asymbol *)bfd_make_empty_symbol(entry->the_bfd);
309 newsym->name = entry->local_sym_name;
310 /* The symbol belongs to the output file's text section */
312 /* The value is the start of this section in the output file*/
314 newsym->flags = BSF_LOCAL;
316 *output_buffer++ = newsym;
321 for (i = 0; i < entry->symbol_count; i++)
323 asymbol *p = entry->asymbols[i];
325 if (flag_is_global(p->flags) || flag_is_absolute(p->flags))
327 /* We are only interested in outputting
328 globals at this stage in special circumstances */
329 if (p->the_bfd == entry->the_bfd
330 && flag_is_not_at_end(p->flags)) {
331 /* And this is one of them */
332 *(output_buffer++) = p;
333 p->flags |= BSF_KEEP;
337 if (flag_is_ordinary_local(p->flags))
339 if (discard_locals == DISCARD_ALL)
341 else if (discard_locals == DISCARD_L &&
342 (p->name[0] == lprefix))
344 else if (p->flags == BSF_WARNING)
347 { *output_buffer++ = p; }
349 else if (flag_is_debugger(p->flags))
351 /* Only keep the debugger symbols if no stripping required */
352 if (strip_symbols == STRIP_NONE) {
353 *output_buffer++ = p;
356 else if (flag_is_undefined(p->flags))
357 { /* This must be global */
359 else if (flag_is_common(p->flags)) {
360 /* And so must this */
362 else if (p->flags & BSF_CTOR) {
374 return output_buffer;
379 write_file_globals(symbol_table)
380 asymbol **symbol_table;
384 if (sp->sdefs_chain != (asymbol **)NULL) {
385 asymbol *bufp = (*(sp->sdefs_chain));
387 if ((bufp->flags & BSF_KEEP) ==0) {
388 ASSERT(bufp != (asymbol *)NULL);
390 bufp->name = sp->name;
392 if (sp->scoms_chain != (asymbol **)NULL)
396 defined as common but not allocated, this happens
397 only with -r and not -d, write out a common
400 bufp = *(sp->scoms_chain);
402 *symbol_table++ = bufp;
405 else if (sp->scoms_chain != (asymbol **)NULL) {
406 /* This symbol is a common - just output */
407 asymbol *bufp = (*(sp->scoms_chain));
408 *symbol_table++ = bufp;
410 else if (sp->srefs_chain != (asymbol **)NULL) {
411 /* This symbol is undefined but has a reference */
412 asymbol *bufp = (*(sp->srefs_chain));
413 *symbol_table++ = bufp;
417 This symbol has neither defs nor refs, it must have come
418 from the command line, since noone has used it it has no
419 data attatched, so we'll ignore it
431 if (strip_symbols != STRIP_ALL) {
432 /* We know the maximum size of the symbol table -
433 it's the size of all the global symbols ever seen +
434 the size of all the symbols from all the files +
435 the number of files (for the per file symbols)
436 +1 (for the null at the end)
438 extern unsigned int total_files_seen;
439 extern unsigned int total_symbols_seen;
441 asymbol ** symbol_table = (asymbol **)
442 ldmalloc ((size_t)(global_symbol_count +
444 total_symbols_seen + 1) * sizeof (asymbol *));
445 asymbol ** tablep = write_file_locals(symbol_table);
447 tablep = write_file_globals(tablep);
449 *tablep = (asymbol *)NULL;
450 bfd_set_symtab(output_bfd, symbol_table, (unsigned)( tablep - symbol_table));