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