]> Git Repo - binutils.git/blame - ld/ldsym.c
Move all the #msg's from the xconfig files into the tconfig files for Suns.
[binutils.git] / ld / ldsym.c
CommitLineData
2fa0b342
DHW
1/* Copyright (C) 1991 Free Software Foundation, Inc.
2
3This file is part of GLD, the Gnu Linker.
4
5GLD is free software; you can redistribute it and/or modify
6it under the terms of the GNU General Public License as published by
7the Free Software Foundation; either version 1, or (at your option)
8any later version.
9
10GLD is distributed in the hope that it will be useful,
11but WITHOUT ANY WARRANTY; without even the implied warranty of
12MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with GLD; see the file COPYING. If not, write to
17the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
18
19/*
20 * $Id$
21 *
2fa0b342
DHW
22 *
23*/
24
25/*
26 Written by Steve Chamberlain [email protected]
27
28 All symbol handling for the linker
29 */
30
31
32#include "sysdep.h"
33#include "bfd.h"
34
35#include "ld.h"
36#include "ldsym.h"
37#include "ldmisc.h"
38#include "ldlang.h"
39/* IMPORT */
40
41extern bfd *output_bfd;
d646b568
SC
42extern strip_symbols_type strip_symbols;
43extern discard_locals_type discard_locals;
2fa0b342
DHW
44/* Head and tail of global symbol table chronological list */
45
46ldsym_type *symbol_head = (ldsym_type *)NULL;
47ldsym_type **symbol_tail_ptr = &symbol_head;
48
49/*
50 incremented for each symbol in the ldsym_type table
51 no matter what flavour it is
52*/
53unsigned int global_symbol_count;
54
55/* IMPORTS */
56
57extern boolean option_longmap ;
58
59/* LOCALS */
60#define TABSIZE 1009
61static ldsym_type *global_symbol_hash_table[TABSIZE];
62
63/* Compute the hash code for symbol name KEY. */
64
65int
66hash_string (key)
67 char *key;
68{
69 register char *cp;
70 register int k;
71
72 cp = key;
73 k = 0;
74 while (*cp)
75 k = (((k << 1) + (k >> 14)) ^ (*cp++)) & 0x3fff;
76
77 return k;
78}
79
80/* Get the symbol table entry for the global symbol named KEY.
81 Create one if there is none. */
82ldsym_type *
99fe4553
SC
83DEFUN(ldsym_get,(key),
84 CONST char *key)
2fa0b342
DHW
85{
86 register int hashval;
87 register ldsym_type *bp;
88
89 /* Determine the proper bucket. */
90
91 hashval = hash_string (key) % TABSIZE;
92
93 /* Search the bucket. */
94
95 for (bp = global_symbol_hash_table[hashval]; bp; bp = bp->link)
96 if (! strcmp (key, bp->name))
97 return bp;
98
99 /* Nothing was found; create a new symbol table entry. */
100
19b03b7a 101 bp = (ldsym_type *) ldmalloc ((bfd_size_type)(sizeof (ldsym_type)));
2fa0b342
DHW
102 bp->srefs_chain = (asymbol **)NULL;
103 bp->sdefs_chain = (asymbol **)NULL;
104 bp->scoms_chain = (asymbol **)NULL;
99fe4553 105 bp->name = buystring(key);
2fa0b342
DHW
106
107 /* Add the entry to the bucket. */
108
109 bp->link = global_symbol_hash_table[hashval];
110 global_symbol_hash_table[hashval] = bp;
111
112 /* Keep the chronological list up to date too */
113 *symbol_tail_ptr = bp;
114 symbol_tail_ptr = &bp->next;
115 bp->next = 0;
116 global_symbol_count++;
117
118 return bp;
119}
120
121/* Like `ldsym_get' but return 0 if the symbol is not already known. */
122
123ldsym_type *
99fe4553
SC
124DEFUN(ldsym_get_soft,(key),
125 CONST char *key)
2fa0b342
DHW
126{
127 register int hashval;
128 register ldsym_type *bp;
129
130 /* Determine which bucket. */
131
132 hashval = hash_string (key) % TABSIZE;
133
134 /* Search the bucket. */
135
136 for (bp = global_symbol_hash_table[hashval]; bp; bp = bp->link)
137 if (! strcmp (key, bp->name))
138 return bp;
139
140 return 0;
141}
142
143
144
145
146
147static void
148list_file_locals (entry)
149lang_input_statement_type *entry;
150{
151 asymbol **q;
19b03b7a 152 printf ( "\nLocal symbols of ");
2fa0b342 153 info("%I", entry);
19b03b7a 154 printf (":\n\n");
2fa0b342
DHW
155 if (entry->asymbols) {
156 for (q = entry->asymbols; *q; q++)
157 {
158 asymbol *p = *q;
159 /* If this is a definition,
160 update it if necessary by this file's start address. */
161 if (p->flags & BSF_LOCAL)
162 info(" %V %s\n",p->value, p->name);
163 }
164 }
165}
166
167
168static void
169print_file_stuff(f)
170lang_input_statement_type *f;
171{
19b03b7a
SC
172 fprintf (stdout, " %s", f->filename);
173 fprintf (stdout, " ");
2fa0b342
DHW
174 if (f->just_syms_flag)
175 {
19b03b7a 176 fprintf (stdout, " symbols only\n");
2fa0b342
DHW
177 }
178 else
179 {
180 asection *s;
19b03b7a 181 if (true || option_longmap) {
2fa0b342
DHW
182 for (s = f->the_bfd->sections;
183 s != (asection *)NULL;
184 s = s->next) {
19b03b7a
SC
185 print_address(s->output_offset);
186 printf ( "%08x 2**%2ud %s\n",
2fa0b342
DHW
187 (unsigned)s->size, s->alignment_power, s->name);
188 }
189 }
190 else {
191 for (s = f->the_bfd->sections;
192 s != (asection *)NULL;
193 s = s->next) {
19b03b7a
SC
194 printf("%s ", s->name);
195 print_address(s->output_offset);
196 printf("(%x)", (unsigned)s->size);
2fa0b342 197 }
19b03b7a 198 printf("hex \n");
2fa0b342
DHW
199 }
200 }
201}
202
203void
204ldsym_print_symbol_table ()
205{
19b03b7a 206 fprintf (stdout, "\nFiles:\n\n");
2fa0b342
DHW
207
208 lang_for_each_file(print_file_stuff);
209
19b03b7a 210 fprintf (stdout, "\nGlobal symbols:\n\n");
2fa0b342
DHW
211 {
212 register ldsym_type *sp;
213
214 for (sp = symbol_head; sp; sp = sp->next)
215 {
216 if (sp->sdefs_chain)
217 {
218 asymbol *defsym = *(sp->sdefs_chain);
219 asection *defsec = bfd_get_section(defsym);
19b03b7a 220 print_address(defsym->value);
2fa0b342
DHW
221 if (defsec)
222 {
19b03b7a
SC
223 print_space();
224 print_address(defsym->value+defsec->vma);
225 printf("%7s",
2fa0b342
DHW
226 bfd_section_name(output_bfd,
227 defsec));
228
229 }
230 else
231 {
19b03b7a 232 printf(" .......");
2fa0b342
DHW
233 }
234
235 }
236 else {
19b03b7a 237 printf("undefined");
2fa0b342
DHW
238 }
239
240
241 if (sp->scoms_chain) {
19b03b7a
SC
242 printf(" common size ");
243 print_address((*(sp->scoms_chain))->value);
244 printf("%s ",sp->name);
2fa0b342
DHW
245 }
246 if (sp->sdefs_chain) {
19b03b7a
SC
247 printf(" symbol def ");
248 print_address((*(sp->sdefs_chain))->value);
249 printf("%s ",sp->name);
2fa0b342
DHW
250 }
251 else {
19b03b7a
SC
252 printf(" undefined ");
253 printf("%s ",sp->name);
2fa0b342 254 }
19b03b7a 255 print_nl();
2fa0b342
DHW
256
257 }
258 }
259 lang_for_each_file(list_file_locals);
260}
261
262extern lang_output_section_statement_type *create_object_symbols;
263extern char lprefix;
264static asymbol **
265write_file_locals(output_buffer)
266asymbol **output_buffer;
267{
268LANG_FOR_EACH_INPUT_STATEMENT(entry)
269 {
270 /* Run trough the symbols and work out what to do with them */
271 unsigned int i;
272
273 /* Add one for the filename symbol if needed */
274 if (create_object_symbols
275 != (lang_output_section_statement_type *)NULL) {
276 asection *s;
277 for (s = entry->the_bfd->sections;
278 s != (asection *)NULL;
279 s = s->next) {
280 if (s->output_section == create_object_symbols->bfd_section) {
281 /* Add symbol to this section */
282 asymbol * newsym =
283 (asymbol *)bfd_make_empty_symbol(entry->the_bfd);
284 newsym->name = entry->local_sym_name;
285 /* The symbol belongs to the output file's text section */
286
287 /* The value is the start of this section in the output file*/
288 newsym->value = 0;
289 newsym->flags = BSF_LOCAL;
290 newsym->section = s;
291 *output_buffer++ = newsym;
292 break;
293 }
294 }
295 }
296 for (i = 0; i < entry->symbol_count; i++)
297 {
298 asymbol *p = entry->asymbols[i];
299
300 if (flag_is_global(p->flags) || flag_is_absolute(p->flags))
301 {
302 /* We are only interested in outputting
303 globals at this stage in special circumstances */
304 if (p->the_bfd == entry->the_bfd
305 && flag_is_not_at_end(p->flags)) {
306 /* And this is one of them */
307 *(output_buffer++) = p;
308 p->flags |= BSF_KEEP;
309 }
310 }
311 else {
312 if (flag_is_ordinary_local(p->flags))
313 {
314 if (discard_locals == DISCARD_ALL)
315 { }
316 else if (discard_locals == DISCARD_L &&
317 (p->name[0] == lprefix))
318 { }
319 else if (p->flags == BSF_WARNING)
320 { }
321 else
322 { *output_buffer++ = p; }
323 }
324 else if (flag_is_debugger(p->flags))
325 {
326 /* Only keep the debugger symbols if no stripping required */
327 if (strip_symbols == STRIP_NONE) {
328 *output_buffer++ = p;
329 }
330 }
331 else if (flag_is_undefined(p->flags))
332 { /* This must be global */
333 }
334 else if (flag_is_common(p->flags)) {
335 /* And so must this */
336 }
337 else if (p->flags & BSF_CTOR) {
338 /* Throw it away */
339 }
340else
341 {
342 FAIL();
343 }
344 }
345 }
346
347
348 }
349 return output_buffer;
350}
351
352
353static asymbol **
354write_file_globals(symbol_table)
355asymbol **symbol_table;
356{
357 FOR_EACH_LDSYM(sp)
358 {
359 if (sp->sdefs_chain != (asymbol **)NULL) {
360 asymbol *bufp = (*(sp->sdefs_chain));
361
362 if ((bufp->flags & BSF_KEEP) ==0) {
363 ASSERT(bufp != (asymbol *)NULL);
364
365 bufp->name = sp->name;
366
367 if (sp->scoms_chain != (asymbol **)NULL)
368
369 {
370 /*
371 defined as common but not allocated, this happens
372 only with -r and not -d, write out a common
373 definition
374 */
375 bufp = *(sp->scoms_chain);
376 }
377 *symbol_table++ = bufp;
378 }
379 }
380 else if (sp->scoms_chain != (asymbol **)NULL) {
381 /* This symbol is a common - just output */
382 asymbol *bufp = (*(sp->scoms_chain));
383 *symbol_table++ = bufp;
384 }
385 else if (sp->srefs_chain != (asymbol **)NULL) {
386 /* This symbol is undefined but has a reference */
387 asymbol *bufp = (*(sp->srefs_chain));
388 *symbol_table++ = bufp;
389 }
390 else {
391 /*
392 This symbol has neither defs nor refs, it must have come
393 from the command line, since noone has used it it has no
394 data attatched, so we'll ignore it
395 */
396 }
397 }
398 return symbol_table;
399}
400
401
402
403void
404ldsym_write()
405{
406 if (strip_symbols != STRIP_ALL) {
407 /* We know the maximum size of the symbol table -
408 it's the size of all the global symbols ever seen +
409 the size of all the symbols from all the files +
410 the number of files (for the per file symbols)
411 +1 (for the null at the end)
412 */
413 extern unsigned int total_files_seen;
414 extern unsigned int total_symbols_seen;
415
416 asymbol ** symbol_table = (asymbol **)
19b03b7a 417 ldmalloc ((bfd_size_type)(global_symbol_count +
2fa0b342
DHW
418 total_files_seen +
419 total_symbols_seen + 1) * sizeof (asymbol *));
420 asymbol ** tablep = write_file_locals(symbol_table);
421
422 tablep = write_file_globals(tablep);
423
424 *tablep = (asymbol *)NULL;
425 bfd_set_symtab(output_bfd, symbol_table, (unsigned)( tablep - symbol_table));
426 }
427}
c660714f
SC
428
429/*
430return true if the supplied symbol name is not in the
431linker symbol table
432*/
433boolean
99fe4553
SC
434DEFUN(ldsym_undefined,(sym),
435 CONST char *sym)
c660714f
SC
436{
437 ldsym_type *from_table = ldsym_get_soft(sym);
438 if (from_table != (ldsym_type *)NULL) {
439 if (from_table->sdefs_chain != (asymbol **)NULL) return false;
440 }
441 return true;
442}
This page took 0.080433 seconds and 4 git commands to generate.