1 /* Copyright (C) 1991 Free Software Foundation, Inc.
3 This file is part of GLD, the Gnu Linker.
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)
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.
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. */
26 Written by Steve Chamberlain steve@cygnus.com
28 All symbol handling for the linker
41 extern bfd
*output_bfd
;
42 extern strip_symbols_type strip_symbols
;
43 extern discard_locals_type discard_locals
;
44 /* Head and tail of global symbol table chronological list */
46 ldsym_type
*symbol_head
= (ldsym_type
*)NULL
;
47 ldsym_type
**symbol_tail_ptr
= &symbol_head
;
50 incremented for each symbol in the ldsym_type table
51 no matter what flavour it is
53 unsigned int global_symbol_count
;
57 extern boolean option_longmap
;
61 static ldsym_type
*global_symbol_hash_table
[TABSIZE
];
63 /* Compute the hash code for symbol name KEY. */
75 k
= (((k
<< 1) + (k
>> 14)) ^ (*cp
++)) & 0x3fff;
80 /* Get the symbol table entry for the global symbol named KEY.
81 Create one if there is none. */
83 DEFUN(ldsym_get
,(key
),
87 register ldsym_type
*bp
;
89 /* Determine the proper bucket. */
91 hashval
= hash_string (key
) % TABSIZE
;
93 /* Search the bucket. */
95 for (bp
= global_symbol_hash_table
[hashval
]; bp
; bp
= bp
->link
)
96 if (! strcmp (key
, bp
->name
))
99 /* Nothing was found; create a new symbol table entry. */
101 bp
= (ldsym_type
*) ldmalloc ((bfd_size_type
)(sizeof (ldsym_type
)));
102 bp
->srefs_chain
= (asymbol
**)NULL
;
103 bp
->sdefs_chain
= (asymbol
**)NULL
;
104 bp
->scoms_chain
= (asymbol
**)NULL
;
105 bp
->name
= buystring(key
);
107 /* Add the entry to the bucket. */
109 bp
->link
= global_symbol_hash_table
[hashval
];
110 global_symbol_hash_table
[hashval
] = bp
;
112 /* Keep the chronological list up to date too */
113 *symbol_tail_ptr
= bp
;
114 symbol_tail_ptr
= &bp
->next
;
116 global_symbol_count
++;
121 /* Like `ldsym_get' but return 0 if the symbol is not already known. */
124 DEFUN(ldsym_get_soft
,(key
),
127 register int hashval
;
128 register ldsym_type
*bp
;
130 /* Determine which bucket. */
132 hashval
= hash_string (key
) % TABSIZE
;
134 /* Search the bucket. */
136 for (bp
= global_symbol_hash_table
[hashval
]; bp
; bp
= bp
->link
)
137 if (! strcmp (key
, bp
->name
))
148 list_file_locals (entry
)
149 lang_input_statement_type
*entry
;
152 printf ( "\nLocal symbols of ");
155 if (entry
->asymbols
) {
156 for (q
= entry
->asymbols
; *q
; 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
);
170 lang_input_statement_type
*f
;
172 fprintf (stdout
, " %s", f
->filename
);
173 fprintf (stdout
, " ");
174 if (f
->just_syms_flag
)
176 fprintf (stdout
, " symbols only\n");
181 if (true || option_longmap
) {
182 for (s
= f
->the_bfd
->sections
;
183 s
!= (asection
*)NULL
;
185 print_address(s
->output_offset
);
186 printf ( "%08x 2**%2ud %s\n",
187 (unsigned)s
->size
, s
->alignment_power
, s
->name
);
191 for (s
= f
->the_bfd
->sections
;
192 s
!= (asection
*)NULL
;
194 printf("%s ", s
->name
);
195 print_address(s
->output_offset
);
196 printf("(%x)", (unsigned)s
->size
);
204 ldsym_print_symbol_table ()
206 fprintf (stdout
, "\nFiles:\n\n");
208 lang_for_each_file(print_file_stuff
);
210 fprintf (stdout
, "\nGlobal symbols:\n\n");
212 register ldsym_type
*sp
;
214 for (sp
= symbol_head
; sp
; sp
= sp
->next
)
218 asymbol
*defsym
= *(sp
->sdefs_chain
);
219 asection
*defsec
= bfd_get_section(defsym
);
220 print_address(defsym
->value
);
224 print_address(defsym
->value
+defsec
->vma
);
226 bfd_section_name(output_bfd
,
241 if (sp
->scoms_chain
) {
242 printf(" common size ");
243 print_address((*(sp
->scoms_chain
))->value
);
244 printf("%s ",sp
->name
);
246 if (sp
->sdefs_chain
) {
247 printf(" symbol def ");
248 print_address((*(sp
->sdefs_chain
))->value
);
249 printf("%s ",sp
->name
);
252 printf(" undefined ");
253 printf("%s ",sp
->name
);
259 lang_for_each_file(list_file_locals
);
262 extern lang_output_section_statement_type
*create_object_symbols
;
265 write_file_locals(output_buffer
)
266 asymbol
**output_buffer
;
268 LANG_FOR_EACH_INPUT_STATEMENT(entry
)
270 /* Run trough the symbols and work out what to do with them */
273 /* Add one for the filename symbol if needed */
274 if (create_object_symbols
275 != (lang_output_section_statement_type
*)NULL
) {
277 for (s
= entry
->the_bfd
->sections
;
278 s
!= (asection
*)NULL
;
280 if (s
->output_section
== create_object_symbols
->bfd_section
) {
281 /* Add symbol to this section */
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 */
287 /* The value is the start of this section in the output file*/
289 newsym
->flags
= BSF_LOCAL
;
291 *output_buffer
++ = newsym
;
296 for (i
= 0; i
< entry
->symbol_count
; i
++)
298 asymbol
*p
= entry
->asymbols
[i
];
300 if (flag_is_global(p
->flags
) || flag_is_absolute(p
->flags
))
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
;
312 if (flag_is_ordinary_local(p
->flags
))
314 if (discard_locals
== DISCARD_ALL
)
316 else if (discard_locals
== DISCARD_L
&&
317 (p
->name
[0] == lprefix
))
319 else if (p
->flags
== BSF_WARNING
)
322 { *output_buffer
++ = p
; }
324 else if (flag_is_debugger(p
->flags
))
326 /* Only keep the debugger symbols if no stripping required */
327 if (strip_symbols
== STRIP_NONE
) {
328 *output_buffer
++ = p
;
331 else if (flag_is_undefined(p
->flags
))
332 { /* This must be global */
334 else if (flag_is_common(p
->flags
)) {
335 /* And so must this */
337 else if (p
->flags
& BSF_CTOR
) {
349 return output_buffer
;
354 write_file_globals(symbol_table
)
355 asymbol
**symbol_table
;
359 if (sp
->sdefs_chain
!= (asymbol
**)NULL
) {
360 asymbol
*bufp
= (*(sp
->sdefs_chain
));
362 if ((bufp
->flags
& BSF_KEEP
) ==0) {
363 ASSERT(bufp
!= (asymbol
*)NULL
);
365 bufp
->name
= sp
->name
;
367 if (sp
->scoms_chain
!= (asymbol
**)NULL
)
371 defined as common but not allocated, this happens
372 only with -r and not -d, write out a common
375 bufp
= *(sp
->scoms_chain
);
377 *symbol_table
++ = bufp
;
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
;
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
;
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
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)
413 extern unsigned int total_files_seen
;
414 extern unsigned int total_symbols_seen
;
416 asymbol
** symbol_table
= (asymbol
**)
417 ldmalloc ((bfd_size_type
)(global_symbol_count
+
419 total_symbols_seen
+ 1) * sizeof (asymbol
*));
420 asymbol
** tablep
= write_file_locals(symbol_table
);
422 tablep
= write_file_globals(tablep
);
424 *tablep
= (asymbol
*)NULL
;
425 bfd_set_symtab(output_bfd
, symbol_table
, (unsigned)( tablep
- symbol_table
));
430 return true if the supplied symbol name is not in the
434 DEFUN(ldsym_undefined
,(sym
),
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;