Brought up to sync with Intel again.
[deliverable/binutils-gdb.git] / ld / ldsym.c
1 /* Copyright (C) 1991 Free Software Foundation, Inc.
2
3 This file is part of GLD, the Gnu Linker.
4
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)
8 any later version.
9
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.
14
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. */
18
19 /*
20 * $Id$
21 *
22 * $Log$
23 * Revision 1.2 1991/03/22 23:02:38 steve
24 * Brought up to sync with Intel again.
25 *
26 * Revision 1.1 1991/03/13 00:48:32 chrisb
27 * Initial revision
28 *
29 * Revision 1.4 1991/03/10 09:31:36 rich
30 * Modified Files:
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
36 *
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.
39 *
40 * Revision 1.3 1991/03/06 02:28:56 sac
41 * Cleaned up
42 *
43 * Revision 1.2 1991/02/22 17:15:06 sac
44 * Added RCS keywords and copyrights
45 *
46 */
47
48 /*
49 Written by Steve Chamberlain steve@cygnus.com
50
51 All symbol handling for the linker
52 */
53
54
55 #include "sysdep.h"
56 #include "bfd.h"
57
58 #include "ld.h"
59 #include "ldsym.h"
60 #include "ldmisc.h"
61 #include "ldlang.h"
62 /* IMPORT */
63
64 extern bfd *output_bfd;
65 /* Head and tail of global symbol table chronological list */
66
67 ldsym_type *symbol_head = (ldsym_type *)NULL;
68 ldsym_type **symbol_tail_ptr = &symbol_head;
69
70 /*
71 incremented for each symbol in the ldsym_type table
72 no matter what flavour it is
73 */
74 unsigned int global_symbol_count;
75
76 /* IMPORTS */
77
78 extern boolean option_longmap ;
79
80 /* LOCALS */
81 #define TABSIZE 1009
82 static ldsym_type *global_symbol_hash_table[TABSIZE];
83
84 /* Compute the hash code for symbol name KEY. */
85
86 int
87 hash_string (key)
88 char *key;
89 {
90 register char *cp;
91 register int k;
92
93 cp = key;
94 k = 0;
95 while (*cp)
96 k = (((k << 1) + (k >> 14)) ^ (*cp++)) & 0x3fff;
97
98 return k;
99 }
100
101 /* Get the symbol table entry for the global symbol named KEY.
102 Create one if there is none. */
103 ldsym_type *
104 ldsym_get (key)
105 char *key;
106 {
107 register int hashval;
108 register ldsym_type *bp;
109
110 /* Determine the proper bucket. */
111
112 hashval = hash_string (key) % TABSIZE;
113
114 /* Search the bucket. */
115
116 for (bp = global_symbol_hash_table[hashval]; bp; bp = bp->link)
117 if (! strcmp (key, bp->name))
118 return bp;
119
120 /* Nothing was found; create a new symbol table entry. */
121
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);
128
129
130
131
132 /* Add the entry to the bucket. */
133
134 bp->link = global_symbol_hash_table[hashval];
135 global_symbol_hash_table[hashval] = bp;
136
137 /* Keep the chronological list up to date too */
138 *symbol_tail_ptr = bp;
139 symbol_tail_ptr = &bp->next;
140 bp->next = 0;
141 global_symbol_count++;
142
143 return bp;
144 }
145
146 /* Like `ldsym_get' but return 0 if the symbol is not already known. */
147
148 ldsym_type *
149 ldsym_get_soft (key)
150 char *key;
151 {
152 register int hashval;
153 register ldsym_type *bp;
154
155 /* Determine which bucket. */
156
157 hashval = hash_string (key) % TABSIZE;
158
159 /* Search the bucket. */
160
161 for (bp = global_symbol_hash_table[hashval]; bp; bp = bp->link)
162 if (! strcmp (key, bp->name))
163 return bp;
164
165 return 0;
166 }
167
168
169
170
171
172 static void
173 list_file_locals (entry)
174 lang_input_statement_type *entry;
175 {
176 asymbol **q;
177 fprintf (stderr, "\nLocal symbols of ");
178 info("%I", entry);
179 fprintf (stderr, ":\n\n");
180 if (entry->asymbols) {
181 for (q = entry->asymbols; *q; q++)
182 {
183 asymbol *p = *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);
188 }
189 }
190 }
191
192
193 static void
194 print_file_stuff(f)
195 lang_input_statement_type *f;
196 {
197 fprintf (stderr, " %s", f->filename);
198 fprintf (stderr, " ");
199 if (f->just_syms_flag)
200 {
201 fprintf (stderr, " symbols only\n");
202 }
203 else
204 {
205 asection *s;
206 if (option_longmap) {
207 for (s = f->the_bfd->sections;
208 s != (asection *)NULL;
209 s = s->next) {
210 fprintf (stderr, "%08lx %08x 2**%2ud %s\n",
211 s->output_offset,
212 (unsigned)s->size, s->alignment_power, s->name);
213 }
214 }
215 else {
216 for (s = f->the_bfd->sections;
217 s != (asection *)NULL;
218 s = s->next) {
219 fprintf (stderr, "%s %lx(%x) ",
220 s->name,
221 s->output_offset,
222 (unsigned) s->size);
223 }
224 fprintf (stderr, "hex \n");
225 }
226 }
227 }
228
229 void
230 ldsym_print_symbol_table ()
231 {
232 fprintf (stderr, "\nFiles:\n\n");
233
234 lang_for_each_file(print_file_stuff);
235
236 fprintf (stderr, "\nGlobal symbols:\n\n");
237 {
238 register ldsym_type *sp;
239
240 for (sp = symbol_head; sp; sp = sp->next)
241 {
242 if (sp->sdefs_chain)
243 {
244 asymbol *defsym = *(sp->sdefs_chain);
245 asection *defsec = bfd_get_section(defsym);
246 fprintf(stderr,"%08lx ",defsym->value);
247 if (defsec)
248 {
249 fprintf(stderr,"%08lx ",defsym->value+defsec->vma);
250 fprintf(stderr,
251 "%7s",
252 bfd_section_name(output_bfd,
253 defsec));
254
255 }
256 else
257 {
258 fprintf(stderr," .......");
259 }
260
261 }
262 else {
263 fprintf(stderr,"undefined");
264 }
265
266
267 if (sp->scoms_chain) {
268 fprintf(stderr, " common size %5lu %s",
269 (*(sp->scoms_chain))->value, sp->name);
270 }
271 if (sp->sdefs_chain) {
272 fprintf(stderr, " symbol def %08lx %s",
273 (*(sp->sdefs_chain))->value,
274 sp->name);
275 }
276 else {
277 fprintf(stderr, " undefined %s",
278 sp->name);
279 }
280 fprintf(stderr, "\n");
281
282 }
283 }
284 lang_for_each_file(list_file_locals);
285 }
286
287 extern lang_output_section_statement_type *create_object_symbols;
288 extern char lprefix;
289 static asymbol **
290 write_file_locals(output_buffer)
291 asymbol **output_buffer;
292 {
293 LANG_FOR_EACH_INPUT_STATEMENT(entry)
294 {
295 /* Run trough the symbols and work out what to do with them */
296 unsigned int i;
297
298 /* Add one for the filename symbol if needed */
299 if (create_object_symbols
300 != (lang_output_section_statement_type *)NULL) {
301 asection *s;
302 for (s = entry->the_bfd->sections;
303 s != (asection *)NULL;
304 s = s->next) {
305 if (s->output_section == create_object_symbols->bfd_section) {
306 /* Add symbol to this section */
307 asymbol * newsym =
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 */
311
312 /* The value is the start of this section in the output file*/
313 newsym->value = 0;
314 newsym->flags = BSF_LOCAL;
315 newsym->section = s;
316 *output_buffer++ = newsym;
317 break;
318 }
319 }
320 }
321 for (i = 0; i < entry->symbol_count; i++)
322 {
323 asymbol *p = entry->asymbols[i];
324
325 if (flag_is_global(p->flags) || flag_is_absolute(p->flags))
326 {
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;
334 }
335 }
336 else {
337 if (flag_is_ordinary_local(p->flags))
338 {
339 if (discard_locals == DISCARD_ALL)
340 { }
341 else if (discard_locals == DISCARD_L &&
342 (p->name[0] == lprefix))
343 { }
344 else if (p->flags == BSF_WARNING)
345 { }
346 else
347 { *output_buffer++ = p; }
348 }
349 else if (flag_is_debugger(p->flags))
350 {
351 /* Only keep the debugger symbols if no stripping required */
352 if (strip_symbols == STRIP_NONE) {
353 *output_buffer++ = p;
354 }
355 }
356 else if (flag_is_undefined(p->flags))
357 { /* This must be global */
358 }
359 else if (flag_is_common(p->flags)) {
360 /* And so must this */
361 }
362 else if (p->flags & BSF_CTOR) {
363 /* Throw it away */
364 }
365 else
366 {
367 FAIL();
368 }
369 }
370 }
371
372
373 }
374 return output_buffer;
375 }
376
377
378 static asymbol **
379 write_file_globals(symbol_table)
380 asymbol **symbol_table;
381 {
382 FOR_EACH_LDSYM(sp)
383 {
384 if (sp->sdefs_chain != (asymbol **)NULL) {
385 asymbol *bufp = (*(sp->sdefs_chain));
386
387 if ((bufp->flags & BSF_KEEP) ==0) {
388 ASSERT(bufp != (asymbol *)NULL);
389
390 bufp->name = sp->name;
391
392 if (sp->scoms_chain != (asymbol **)NULL)
393
394 {
395 /*
396 defined as common but not allocated, this happens
397 only with -r and not -d, write out a common
398 definition
399 */
400 bufp = *(sp->scoms_chain);
401 }
402 *symbol_table++ = bufp;
403 }
404 }
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;
409 }
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;
414 }
415 else {
416 /*
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
420 */
421 }
422 }
423 return symbol_table;
424 }
425
426
427
428 void
429 ldsym_write()
430 {
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)
437 */
438 extern unsigned int total_files_seen;
439 extern unsigned int total_symbols_seen;
440
441 asymbol ** symbol_table = (asymbol **)
442 ldmalloc ((size_t)(global_symbol_count +
443 total_files_seen +
444 total_symbols_seen + 1) * sizeof (asymbol *));
445 asymbol ** tablep = write_file_locals(symbol_table);
446
447 tablep = write_file_globals(tablep);
448
449 *tablep = (asymbol *)NULL;
450 bfd_set_symtab(output_bfd, symbol_table, (unsigned)( tablep - symbol_table));
451 }
452 }
This page took 0.049008 seconds and 5 git commands to generate.