This commit was generated by cvs2svn to track changes on a CVS vendor
[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.3 1991/03/27 02:29:21 steve
24 * *** empty log message ***
25 *
26 * Revision 1.2 1991/03/22 23:02:38 steve
27 * Brought up to sync with Intel again.
28 *
29 * Revision 1.1 1991/03/13 00:48:32 chrisb
30 * Initial revision
31 *
32 * Revision 1.4 1991/03/10 09:31:36 rich
33 * Modified Files:
34 * Makefile config.h ld-emul.c ld-emul.h ld-gld.c ld-gld960.c
35 * ld-lnk960.c ld.h lddigest.c ldexp.c ldexp.h ldfile.c ldfile.h
36 * ldgram.y ldinfo.h ldlang.c ldlang.h ldlex.h ldlex.l ldmain.c
37 * ldmain.h ldmisc.c ldmisc.h ldsym.c ldsym.h ldversion.c
38 * ldversion.h ldwarn.h ldwrite.c ldwrite.h y.tab.h
39 *
40 * As of this round of changes, ld now builds on all hosts of (Intel960)
41 * interest and copy passes my copy test on big endian hosts again.
42 *
43 * Revision 1.3 1991/03/06 02:28:56 sac
44 * Cleaned up
45 *
46 * Revision 1.2 1991/02/22 17:15:06 sac
47 * Added RCS keywords and copyrights
48 *
49 */
50
51 /*
52 Written by Steve Chamberlain steve@cygnus.com
53
54 All symbol handling for the linker
55 */
56
57
58 #include "sysdep.h"
59 #include "bfd.h"
60
61 #include "ld.h"
62 #include "ldsym.h"
63 #include "ldmisc.h"
64 #include "ldlang.h"
65 /* IMPORT */
66
67 extern bfd *output_bfd;
68 /* Head and tail of global symbol table chronological list */
69
70 ldsym_type *symbol_head = (ldsym_type *)NULL;
71 ldsym_type **symbol_tail_ptr = &symbol_head;
72
73 /*
74 incremented for each symbol in the ldsym_type table
75 no matter what flavour it is
76 */
77 unsigned int global_symbol_count;
78
79 /* IMPORTS */
80
81 extern boolean option_longmap ;
82
83 /* LOCALS */
84 #define TABSIZE 1009
85 static ldsym_type *global_symbol_hash_table[TABSIZE];
86
87 /* Compute the hash code for symbol name KEY. */
88
89 int
90 hash_string (key)
91 char *key;
92 {
93 register char *cp;
94 register int k;
95
96 cp = key;
97 k = 0;
98 while (*cp)
99 k = (((k << 1) + (k >> 14)) ^ (*cp++)) & 0x3fff;
100
101 return k;
102 }
103
104 /* Get the symbol table entry for the global symbol named KEY.
105 Create one if there is none. */
106 ldsym_type *
107 ldsym_get (key)
108 char *key;
109 {
110 register int hashval;
111 register ldsym_type *bp;
112
113 /* Determine the proper bucket. */
114
115 hashval = hash_string (key) % TABSIZE;
116
117 /* Search the bucket. */
118
119 for (bp = global_symbol_hash_table[hashval]; bp; bp = bp->link)
120 if (! strcmp (key, bp->name))
121 return bp;
122
123 /* Nothing was found; create a new symbol table entry. */
124
125 bp = (ldsym_type *) ldmalloc (sizeof (ldsym_type));
126 bp->srefs_chain = (asymbol **)NULL;
127 bp->sdefs_chain = (asymbol **)NULL;
128 bp->scoms_chain = (asymbol **)NULL;
129 bp->name = (char *) ldmalloc (strlen (key) + 1);
130 strcpy (bp->name, key);
131
132
133
134
135 /* Add the entry to the bucket. */
136
137 bp->link = global_symbol_hash_table[hashval];
138 global_symbol_hash_table[hashval] = bp;
139
140 /* Keep the chronological list up to date too */
141 *symbol_tail_ptr = bp;
142 symbol_tail_ptr = &bp->next;
143 bp->next = 0;
144 global_symbol_count++;
145
146 return bp;
147 }
148
149 /* Like `ldsym_get' but return 0 if the symbol is not already known. */
150
151 ldsym_type *
152 ldsym_get_soft (key)
153 char *key;
154 {
155 register int hashval;
156 register ldsym_type *bp;
157
158 /* Determine which bucket. */
159
160 hashval = hash_string (key) % TABSIZE;
161
162 /* Search the bucket. */
163
164 for (bp = global_symbol_hash_table[hashval]; bp; bp = bp->link)
165 if (! strcmp (key, bp->name))
166 return bp;
167
168 return 0;
169 }
170
171
172
173
174
175 static void
176 list_file_locals (entry)
177 lang_input_statement_type *entry;
178 {
179 asymbol **q;
180 fprintf (stderr, "\nLocal symbols of ");
181 info("%I", entry);
182 fprintf (stderr, ":\n\n");
183 if (entry->asymbols) {
184 for (q = entry->asymbols; *q; q++)
185 {
186 asymbol *p = *q;
187 /* If this is a definition,
188 update it if necessary by this file's start address. */
189 if (p->flags & BSF_LOCAL)
190 info(" %V %s\n",p->value, p->name);
191 }
192 }
193 }
194
195
196 static void
197 print_file_stuff(f)
198 lang_input_statement_type *f;
199 {
200 fprintf (stderr, " %s", f->filename);
201 fprintf (stderr, " ");
202 if (f->just_syms_flag)
203 {
204 fprintf (stderr, " symbols only\n");
205 }
206 else
207 {
208 asection *s;
209 if (option_longmap) {
210 for (s = f->the_bfd->sections;
211 s != (asection *)NULL;
212 s = s->next) {
213 fprintf (stderr, "%08lx %08x 2**%2ud %s\n",
214 s->output_offset,
215 (unsigned)s->size, s->alignment_power, s->name);
216 }
217 }
218 else {
219 for (s = f->the_bfd->sections;
220 s != (asection *)NULL;
221 s = s->next) {
222 fprintf (stderr, "%s %lx(%x) ",
223 s->name,
224 s->output_offset,
225 (unsigned) s->size);
226 }
227 fprintf (stderr, "hex \n");
228 }
229 }
230 }
231
232 void
233 ldsym_print_symbol_table ()
234 {
235 fprintf (stderr, "\nFiles:\n\n");
236
237 lang_for_each_file(print_file_stuff);
238
239 fprintf (stderr, "\nGlobal symbols:\n\n");
240 {
241 register ldsym_type *sp;
242
243 for (sp = symbol_head; sp; sp = sp->next)
244 {
245 if (sp->sdefs_chain)
246 {
247 asymbol *defsym = *(sp->sdefs_chain);
248 asection *defsec = bfd_get_section(defsym);
249 fprintf(stderr,"%08lx ",defsym->value);
250 if (defsec)
251 {
252 fprintf(stderr,"%08lx ",defsym->value+defsec->vma);
253 fprintf(stderr,
254 "%7s",
255 bfd_section_name(output_bfd,
256 defsec));
257
258 }
259 else
260 {
261 fprintf(stderr," .......");
262 }
263
264 }
265 else {
266 fprintf(stderr,"undefined");
267 }
268
269
270 if (sp->scoms_chain) {
271 fprintf(stderr, " common size %5lu %s",
272 (*(sp->scoms_chain))->value, sp->name);
273 }
274 if (sp->sdefs_chain) {
275 fprintf(stderr, " symbol def %08lx %s",
276 (*(sp->sdefs_chain))->value,
277 sp->name);
278 }
279 else {
280 fprintf(stderr, " undefined %s",
281 sp->name);
282 }
283 fprintf(stderr, "\n");
284
285 }
286 }
287 lang_for_each_file(list_file_locals);
288 }
289
290 extern lang_output_section_statement_type *create_object_symbols;
291 extern char lprefix;
292 static asymbol **
293 write_file_locals(output_buffer)
294 asymbol **output_buffer;
295 {
296 LANG_FOR_EACH_INPUT_STATEMENT(entry)
297 {
298 /* Run trough the symbols and work out what to do with them */
299 unsigned int i;
300
301 /* Add one for the filename symbol if needed */
302 if (create_object_symbols
303 != (lang_output_section_statement_type *)NULL) {
304 asection *s;
305 for (s = entry->the_bfd->sections;
306 s != (asection *)NULL;
307 s = s->next) {
308 if (s->output_section == create_object_symbols->bfd_section) {
309 /* Add symbol to this section */
310 asymbol * newsym =
311 (asymbol *)bfd_make_empty_symbol(entry->the_bfd);
312 newsym->name = entry->local_sym_name;
313 /* The symbol belongs to the output file's text section */
314
315 /* The value is the start of this section in the output file*/
316 newsym->value = 0;
317 newsym->flags = BSF_LOCAL;
318 newsym->section = s;
319 *output_buffer++ = newsym;
320 break;
321 }
322 }
323 }
324 for (i = 0; i < entry->symbol_count; i++)
325 {
326 asymbol *p = entry->asymbols[i];
327
328 if (flag_is_global(p->flags) || flag_is_absolute(p->flags))
329 {
330 /* We are only interested in outputting
331 globals at this stage in special circumstances */
332 if (p->the_bfd == entry->the_bfd
333 && flag_is_not_at_end(p->flags)) {
334 /* And this is one of them */
335 *(output_buffer++) = p;
336 p->flags |= BSF_KEEP;
337 }
338 }
339 else {
340 if (flag_is_ordinary_local(p->flags))
341 {
342 if (discard_locals == DISCARD_ALL)
343 { }
344 else if (discard_locals == DISCARD_L &&
345 (p->name[0] == lprefix))
346 { }
347 else if (p->flags == BSF_WARNING)
348 { }
349 else
350 { *output_buffer++ = p; }
351 }
352 else if (flag_is_debugger(p->flags))
353 {
354 /* Only keep the debugger symbols if no stripping required */
355 if (strip_symbols == STRIP_NONE) {
356 *output_buffer++ = p;
357 }
358 }
359 else if (flag_is_undefined(p->flags))
360 { /* This must be global */
361 }
362 else if (flag_is_common(p->flags)) {
363 /* And so must this */
364 }
365 else if (p->flags & BSF_CTOR) {
366 /* Throw it away */
367 }
368 else
369 {
370 FAIL();
371 }
372 }
373 }
374
375
376 }
377 return output_buffer;
378 }
379
380
381 static asymbol **
382 write_file_globals(symbol_table)
383 asymbol **symbol_table;
384 {
385 FOR_EACH_LDSYM(sp)
386 {
387 if (sp->sdefs_chain != (asymbol **)NULL) {
388 asymbol *bufp = (*(sp->sdefs_chain));
389
390 if ((bufp->flags & BSF_KEEP) ==0) {
391 ASSERT(bufp != (asymbol *)NULL);
392
393 bufp->name = sp->name;
394
395 if (sp->scoms_chain != (asymbol **)NULL)
396
397 {
398 /*
399 defined as common but not allocated, this happens
400 only with -r and not -d, write out a common
401 definition
402 */
403 bufp = *(sp->scoms_chain);
404 }
405 *symbol_table++ = bufp;
406 }
407 }
408 else if (sp->scoms_chain != (asymbol **)NULL) {
409 /* This symbol is a common - just output */
410 asymbol *bufp = (*(sp->scoms_chain));
411 *symbol_table++ = bufp;
412 }
413 else if (sp->srefs_chain != (asymbol **)NULL) {
414 /* This symbol is undefined but has a reference */
415 asymbol *bufp = (*(sp->srefs_chain));
416 *symbol_table++ = bufp;
417 }
418 else {
419 /*
420 This symbol has neither defs nor refs, it must have come
421 from the command line, since noone has used it it has no
422 data attatched, so we'll ignore it
423 */
424 }
425 }
426 return symbol_table;
427 }
428
429
430
431 void
432 ldsym_write()
433 {
434 if (strip_symbols != STRIP_ALL) {
435 /* We know the maximum size of the symbol table -
436 it's the size of all the global symbols ever seen +
437 the size of all the symbols from all the files +
438 the number of files (for the per file symbols)
439 +1 (for the null at the end)
440 */
441 extern unsigned int total_files_seen;
442 extern unsigned int total_symbols_seen;
443
444 asymbol ** symbol_table = (asymbol **)
445 ldmalloc ((size_t)(global_symbol_count +
446 total_files_seen +
447 total_symbols_seen + 1) * sizeof (asymbol *));
448 asymbol ** tablep = write_file_locals(symbol_table);
449
450 tablep = write_file_globals(tablep);
451
452 *tablep = (asymbol *)NULL;
453 bfd_set_symtab(output_bfd, symbol_table, (unsigned)( tablep - symbol_table));
454 }
455 }
456
457 /*
458 return true if the supplied symbol name is not in the
459 linker symbol table
460 */
461 boolean
462 ldsym_undefined(sym)
463 char *sym;
464 {
465 ldsym_type *from_table = ldsym_get_soft(sym);
466 if (from_table != (ldsym_type *)NULL) {
467 if (from_table->sdefs_chain != (asymbol **)NULL) return false;
468 }
469 return true;
470 }
This page took 0.038669 seconds and 4 git commands to generate.