1 /* All symbol handling for the linker
2 Copyright (C) 1991 Free Software Foundation, Inc.
3 Written by Steve Chamberlain steve@cygnus.com
5 This file is part of GLD, the Gnu Linker.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
26 We keep a hash table of global symbols. Each entry in a hash table
27 is called an ldsym_type. Each has three chains; a pointer to a
28 chain of definitions for the symbol (hopefully one long), a pointer
29 to a chain of references to the symbol, and a pointer to a chain of
30 common symbols. Each pointer points into the canonical symbol table
31 provided by bfd, each one of which points to an asymbol. Duringing
32 linkage, the linker uses the udata field to point to the next entry
33 in a canonical table....
38 +----------+ +----------+
39 | defs | a canonical symbol table
40 +----------+ +----------+
41 | refs | -----> | one entry| -----> asymbol
42 +----------+ +----------+ | |
43 | coms | | | +---------+
44 +----------+ +----------+ | udata |-----> another canonical symbol
49 It is very simple to make all the symbol pointers point to the same
50 definition - just run down the chain and make the asymbols pointers
51 within the canonical table point to the asymbol attacthed to the
52 definition of the symbol.
65 extern bfd
*output_bfd
;
66 extern strip_symbols_type strip_symbols
;
67 extern discard_locals_type discard_locals
;
68 /* Head and tail of global symbol table chronological list */
70 ldsym_type
*symbol_head
= (ldsym_type
*)NULL
;
71 ldsym_type
**symbol_tail_ptr
= &symbol_head
;
73 extern ld_config_type config
;
76 incremented for each symbol in the ldsym_type table
77 no matter what flavour it is
79 unsigned int global_symbol_count
;
83 extern boolean option_longmap
;
87 static ldsym_type
*global_symbol_hash_table
[TABSIZE
];
89 /* Compute the hash code for symbol name KEY. */
96 DEFUN(hash_string
,(key
),
99 register CONST
char *cp
;
105 k
= (((k
<< 1) + (k
>> 14)) ^ (*cp
++)) & 0x3fff;
113 #endif ldsym_type *bp;
115 DEFUN(search
,(key
,hashval
) ,
120 for (bp
= global_symbol_hash_table
[hashval
]; bp
; bp
= bp
->link
)
121 if (! strcmp (key
, bp
->name
)) {
122 if (bp
->flags
& SYM_INDIRECT
) {
123 /* Use the symbol we're aliased to instead */
124 return (ldsym_type
*)(bp
->sdefs_chain
);
132 /* Get the symbol table entry for the global symbol named KEY.
133 Create one if there is none. */
135 DEFUN(ldsym_get
,(key
),
138 register int hashval
;
139 register ldsym_type
*bp
;
141 /* Determine the proper bucket. */
143 hashval
= hash_string (key
) % TABSIZE
;
145 /* Search the bucket. */
146 bp
= search(key
, hashval
);
151 /* Nothing was found; create a new symbol table entry. */
153 bp
= (ldsym_type
*) ldmalloc ((bfd_size_type
)(sizeof (ldsym_type
)));
154 bp
->srefs_chain
= (asymbol
**)NULL
;
155 bp
->sdefs_chain
= (asymbol
**)NULL
;
156 bp
->scoms_chain
= (asymbol
**)NULL
;
157 bp
->name
= buystring(key
);
159 /* Add the entry to the bucket. */
161 bp
->link
= global_symbol_hash_table
[hashval
];
162 global_symbol_hash_table
[hashval
] = bp
;
164 /* Keep the chronological list up to date too */
165 *symbol_tail_ptr
= bp
;
166 symbol_tail_ptr
= &bp
->next
;
168 global_symbol_count
++;
173 /* Like `ldsym_get' but return 0 if the symbol is not already known. */
176 DEFUN(ldsym_get_soft
,(key
),
179 register int hashval
;
180 /* Determine which bucket. */
182 hashval
= hash_string (key
) % TABSIZE
;
184 /* Search the bucket. */
185 return search(key
, hashval
);
193 list_file_locals (entry
)
194 lang_input_statement_type
*entry
;
197 fprintf (config
.map_file
, "\nLocal symbols of ");
199 fprintf (config
.map_file
, ":\n\n");
200 if (entry
->asymbols
) {
201 for (q
= entry
->asymbols
; *q
; q
++)
204 /* If this is a definition,
205 update it if necessary by this file's start address. */
206 if (p
->flags
& BSF_LOCAL
)
207 info(" %V %s\n",p
->value
, p
->name
);
214 DEFUN(print_file_stuff
,(f
),
215 lang_input_statement_type
*f
)
217 fprintf (config
.map_file
," %s\n", f
->filename
);
218 if (f
->just_syms_flag
)
220 fprintf (config
.map_file
, " symbols only\n");
225 if (true || option_longmap
) {
226 for (s
= f
->the_bfd
->sections
;
227 s
!= (asection
*)NULL
;
229 print_address(s
->output_offset
);
232 fprintf (config
.map_file
, " %08x 2**%2ud %s\n",
233 (unsigned)bfd_get_section_size_after_reloc(s
),
234 s
->alignment_power
, s
->name
);
239 fprintf (config
.map_file
, " %08x 2**%2ud %s\n",
240 (unsigned)bfd_get_section_size_before_reloc(s
),
241 s
->alignment_power
, s
->name
);
249 for (s
= f
->the_bfd
->sections
;
250 s
!= (asection
*)NULL
;
252 fprintf(config
.map_file
, "%s ", s
->name
);
253 print_address(s
->output_offset
);
254 fprintf(config
.map_file
, "(%x)", (unsigned)bfd_get_section_size_after_reloc(s
));
256 fprintf(config
.map_file
, "hex \n");
259 fprintf (config
.map_file
, "\n");
263 ldsym_print_symbol_table ()
265 fprintf (config
.map_file
, "**FILES**\n\n");
267 lang_for_each_file(print_file_stuff
);
269 fprintf(config
.map_file
, "**GLOBAL SYMBOLS**\n\n");
270 fprintf(config
.map_file
, "offset section offset symbol\n");
272 register ldsym_type
*sp
;
274 for (sp
= symbol_head
; sp
; sp
= sp
->next
)
276 if (sp
->flags
& SYM_INDIRECT
) {
277 fprintf(config
.map_file
,"indirect %s to %s\n",
278 sp
->name
, (((ldsym_type
*)(sp
->sdefs_chain
))->name
));
283 asymbol
*defsym
= *(sp
->sdefs_chain
);
284 asection
*defsec
= bfd_get_section(defsym
);
285 print_address(defsym
->value
);
288 fprintf(config
.map_file
, " %-10s",
289 bfd_section_name(output_bfd
,
292 print_address(defsym
->value
+defsec
->vma
);
297 fprintf(config
.map_file
, " .......");
303 if (sp
->scoms_chain
) {
304 fprintf(config
.map_file
, "common ");
305 print_address((*(sp
->scoms_chain
))->value
);
306 fprintf(config
.map_file
, " %s ",sp
->name
);
308 else if (sp
->sdefs_chain
) {
309 fprintf(config
.map_file
, " %s ",sp
->name
);
312 fprintf(config
.map_file
, "undefined ");
313 fprintf(config
.map_file
, "%s ",sp
->name
);
321 if (option_longmap
) {
322 lang_for_each_file(list_file_locals
);
326 extern lang_output_section_statement_type
*create_object_symbols
;
329 write_file_locals(output_buffer
)
330 asymbol
**output_buffer
;
332 LANG_FOR_EACH_INPUT_STATEMENT(entry
)
334 /* Run trough the symbols and work out what to do with them */
337 /* Add one for the filename symbol if needed */
338 if (create_object_symbols
339 != (lang_output_section_statement_type
*)NULL
) {
341 for (s
= entry
->the_bfd
->sections
;
342 s
!= (asection
*)NULL
;
344 if (s
->output_section
== create_object_symbols
->bfd_section
) {
345 /* Add symbol to this section */
347 (asymbol
*)bfd_make_empty_symbol(entry
->the_bfd
);
348 newsym
->name
= entry
->local_sym_name
;
349 /* The symbol belongs to the output file's text section */
351 /* The value is the start of this section in the output file*/
353 newsym
->flags
= BSF_LOCAL
;
355 *output_buffer
++ = newsym
;
360 for (i
= 0; i
< entry
->symbol_count
; i
++)
362 asymbol
*p
= entry
->asymbols
[i
];
363 /* FIXME, temporary hack, since not all of ld knows about the new abs section convention */
366 p
->section
= &bfd_abs_section
;
367 if (flag_is_global(p
->flags
) )
369 /* We are only interested in outputting
370 globals at this stage in special circumstances */
371 if (p
->the_bfd
== entry
->the_bfd
372 && flag_is_not_at_end(p
->flags
)) {
373 /* And this is one of them */
374 *(output_buffer
++) = p
;
375 p
->flags
|= BSF_KEEP
;
379 if (flag_is_ordinary_local(p
->flags
))
381 if (discard_locals
== DISCARD_ALL
)
383 else if (discard_locals
== DISCARD_L
&&
384 (p
->name
[0] == lprefix
))
386 else if (p
->flags
== BSF_WARNING
)
389 { *output_buffer
++ = p
; }
391 else if (flag_is_debugger(p
->flags
))
393 /* Only keep the debugger symbols if no stripping required */
394 if (strip_symbols
== STRIP_NONE
) {
395 *output_buffer
++ = p
;
398 else if (p
->section
== &bfd_und_section
)
399 { /* This must be global */
401 else if (p
->section
== &bfd_com_section
) {
402 /* And so must this */
404 else if (p
->flags
& BSF_CTOR
) {
416 return output_buffer
;
421 write_file_globals(symbol_table
)
422 asymbol
**symbol_table
;
426 if ((sp
->flags
& SYM_INDIRECT
) == 0 && sp
->sdefs_chain
!= (asymbol
**)NULL
) {
427 asymbol
*bufp
= (*(sp
->sdefs_chain
));
429 if ((bufp
->flags
& BSF_KEEP
) ==0) {
430 ASSERT(bufp
!= (asymbol
*)NULL
);
432 bufp
->name
= sp
->name
;
434 if (sp
->scoms_chain
!= (asymbol
**)NULL
)
438 defined as common but not allocated, this happens
439 only with -r and not -d, write out a common
442 bufp
= *(sp
->scoms_chain
);
444 *symbol_table
++ = bufp
;
447 else if (sp
->scoms_chain
!= (asymbol
**)NULL
) {
448 /* This symbol is a common - just output */
449 asymbol
*bufp
= (*(sp
->scoms_chain
));
450 *symbol_table
++ = bufp
;
452 else if (sp
->srefs_chain
!= (asymbol
**)NULL
) {
453 /* This symbol is undefined but has a reference */
454 asymbol
*bufp
= (*(sp
->srefs_chain
));
455 *symbol_table
++ = bufp
;
459 This symbol has neither defs nor refs, it must have come
460 from the command line, since noone has used it it has no
461 data attatched, so we'll ignore it
473 if (strip_symbols
!= STRIP_ALL
) {
474 /* We know the maximum size of the symbol table -
475 it's the size of all the global symbols ever seen +
476 the size of all the symbols from all the files +
477 the number of files (for the per file symbols)
478 +1 (for the null at the end)
480 extern unsigned int total_files_seen
;
481 extern unsigned int total_symbols_seen
;
483 asymbol
** symbol_table
= (asymbol
**)
484 ldmalloc ((bfd_size_type
)(global_symbol_count
+
486 total_symbols_seen
+ 1) * sizeof (asymbol
*));
487 asymbol
** tablep
= write_file_locals(symbol_table
);
489 tablep
= write_file_globals(tablep
);
491 *tablep
= (asymbol
*)NULL
;
492 bfd_set_symtab(output_bfd
, symbol_table
, (unsigned)( tablep
- symbol_table
));
497 return true if the supplied symbol name is not in the
501 DEFUN(ldsym_undefined
,(sym
),
504 ldsym_type
*from_table
= ldsym_get_soft(sym
);
505 if (from_table
!= (ldsym_type
*)NULL
) {
506 if (from_table
->sdefs_chain
!= (asymbol
**)NULL
) return false;