1 /* ldcref.c -- output a cross reference table
2 Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2006
3 Free Software Foundation, Inc.
4 Written by Ian Lance Taylor <ian@cygnus.com>
6 This file is part of GLD, the Gnu Linker.
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
22 /* This file holds routines that manage the cross reference table.
23 The table is used to generate cross reference reports. It is also
24 used to implement the NOCROSSREFS command in the linker script. */
29 #include "libiberty.h"
37 /* We keep an instance of this structure for each reference to a
38 symbol from a given object. */
41 /* The next reference. */
42 struct cref_ref
*next
;
45 /* True if the symbol is defined. */
47 /* True if the symbol is common. */
48 unsigned int common
: 1;
49 /* True if the symbol is undefined. */
50 unsigned int undef
: 1;
53 /* We keep a hash table of symbols. Each entry looks like this. */
55 struct cref_hash_entry
{
56 struct bfd_hash_entry root
;
57 /* The demangled name. */
59 /* References to and definitions of this symbol. */
60 struct cref_ref
*refs
;
63 /* This is what the hash table looks like. */
65 struct cref_hash_table
{
66 struct bfd_hash_table root
;
69 /* Forward declarations. */
71 static void output_one_cref (FILE *, struct cref_hash_entry
*);
72 static void check_local_sym_xref (lang_input_statement_type
*);
73 static bfd_boolean
check_nocrossref (struct cref_hash_entry
*, void *);
74 static void check_refs (const char *, bfd_boolean
, asection
*, bfd
*,
75 struct lang_nocrossrefs
*);
76 static void check_reloc_refs (bfd
*, asection
*, void *);
78 /* Look up an entry in the cref hash table. */
80 #define cref_hash_lookup(table, string, create, copy) \
81 ((struct cref_hash_entry *) \
82 bfd_hash_lookup (&(table)->root, (string), (create), (copy)))
84 /* Traverse the cref hash table. */
86 #define cref_hash_traverse(table, func, info) \
89 (bfd_boolean (*) (struct bfd_hash_entry *, void *)) (func), \
92 /* The cref hash table. */
94 static struct cref_hash_table cref_table
;
96 /* Whether the cref hash table has been initialized. */
98 static bfd_boolean cref_initialized
;
100 /* The number of symbols seen so far. */
102 static size_t cref_symcount
;
104 /* Create an entry in a cref hash table. */
106 static struct bfd_hash_entry
*
107 cref_hash_newfunc (struct bfd_hash_entry
*entry
,
108 struct bfd_hash_table
*table
,
111 struct cref_hash_entry
*ret
= (struct cref_hash_entry
*) entry
;
113 /* Allocate the structure if it has not already been allocated by a
116 ret
= ((struct cref_hash_entry
*)
117 bfd_hash_allocate (table
, sizeof (struct cref_hash_entry
)));
121 /* Call the allocation method of the superclass. */
122 ret
= ((struct cref_hash_entry
*)
123 bfd_hash_newfunc ((struct bfd_hash_entry
*) ret
, table
, string
));
126 /* Set local fields. */
127 ret
->demangled
= NULL
;
130 /* Keep a count of the number of entries created in the hash
138 /* Add a symbol to the cref hash table. This is called for every
139 global symbol that is seen during the link. */
142 add_cref (const char *name
,
145 bfd_vma value ATTRIBUTE_UNUSED
)
147 struct cref_hash_entry
*h
;
150 if (! cref_initialized
)
152 if (!bfd_hash_table_init (&cref_table
.root
, cref_hash_newfunc
,
153 sizeof (struct cref_hash_entry
)))
154 einfo (_("%X%P: bfd_hash_table_init of cref table failed: %E\n"));
155 cref_initialized
= TRUE
;
158 h
= cref_hash_lookup (&cref_table
, name
, TRUE
, FALSE
);
160 einfo (_("%X%P: cref_hash_lookup failed: %E\n"));
162 for (r
= h
->refs
; r
!= NULL
; r
= r
->next
)
168 r
= xmalloc (sizeof *r
);
177 if (bfd_is_und_section (section
))
179 else if (bfd_is_com_section (section
))
185 /* Copy the addresses of the hash table entries into an array. This
186 is called via cref_hash_traverse. We also fill in the demangled
190 cref_fill_array (struct cref_hash_entry
*h
, void *data
)
192 struct cref_hash_entry
***pph
= data
;
194 ASSERT (h
->demangled
== NULL
);
195 h
->demangled
= demangle (h
->root
.string
);
204 /* Sort an array of cref hash table entries by name. */
207 cref_sort_array (const void *a1
, const void *a2
)
209 const struct cref_hash_entry
* const *p1
= a1
;
210 const struct cref_hash_entry
* const *p2
= a2
;
212 return strcmp ((*p1
)->demangled
, (*p2
)->demangled
);
215 /* Write out the cref table. */
220 output_cref (FILE *fp
)
223 struct cref_hash_entry
**csyms
, **csym_fill
, **csym
, **csym_end
;
226 fprintf (fp
, _("\nCross Reference Table\n\n"));
228 fprintf (fp
, "%s", msg
);
230 while (len
< FILECOL
)
235 fprintf (fp
, _("File\n"));
237 if (! cref_initialized
)
239 fprintf (fp
, _("No symbols\n"));
243 csyms
= xmalloc (cref_symcount
* sizeof (*csyms
));
246 cref_hash_traverse (&cref_table
, cref_fill_array
, &csym_fill
);
247 ASSERT ((size_t) (csym_fill
- csyms
) == cref_symcount
);
249 qsort (csyms
, cref_symcount
, sizeof (*csyms
), cref_sort_array
);
251 csym_end
= csyms
+ cref_symcount
;
252 for (csym
= csyms
; csym
< csym_end
; csym
++)
253 output_one_cref (fp
, *csym
);
256 /* Output one entry in the cross reference table. */
259 output_one_cref (FILE *fp
, struct cref_hash_entry
*h
)
262 struct bfd_link_hash_entry
*hl
;
265 hl
= bfd_link_hash_lookup (link_info
.hash
, h
->root
.string
, FALSE
,
268 einfo ("%P: symbol `%T' missing from main hash table\n",
272 /* If this symbol is defined in a dynamic object but never
273 referenced by a normal object, then don't print it. */
274 if (hl
->type
== bfd_link_hash_defined
)
276 if (hl
->u
.def
.section
->output_section
== NULL
)
278 if (hl
->u
.def
.section
->owner
!= NULL
279 && (hl
->u
.def
.section
->owner
->flags
& DYNAMIC
) != 0)
281 for (r
= h
->refs
; r
!= NULL
; r
= r
->next
)
282 if ((r
->abfd
->flags
& DYNAMIC
) == 0)
290 fprintf (fp
, "%s ", h
->demangled
);
291 len
= strlen (h
->demangled
) + 1;
293 for (r
= h
->refs
; r
!= NULL
; r
= r
->next
)
297 while (len
< FILECOL
)
302 lfinfo (fp
, "%B\n", r
->abfd
);
307 for (r
= h
->refs
; r
!= NULL
; r
= r
->next
)
311 while (len
< FILECOL
)
316 lfinfo (fp
, "%B\n", r
->abfd
);
324 /* Check for prohibited cross references. */
327 check_nocrossrefs (void)
329 if (! cref_initialized
)
332 cref_hash_traverse (&cref_table
, check_nocrossref
, NULL
);
334 lang_for_each_file (check_local_sym_xref
);
337 /* Check for prohibited cross references to local and section symbols. */
340 check_local_sym_xref (lang_input_statement_type
*statement
)
343 lang_input_statement_type
*li
;
344 asymbol
**asymbols
, **syms
;
346 abfd
= statement
->the_bfd
;
351 if (li
!= NULL
&& li
->asymbols
!= NULL
)
352 asymbols
= li
->asymbols
;
358 symsize
= bfd_get_symtab_upper_bound (abfd
);
360 einfo (_("%B%F: could not read symbols; %E\n"), abfd
);
361 asymbols
= xmalloc (symsize
);
362 symbol_count
= bfd_canonicalize_symtab (abfd
, asymbols
);
363 if (symbol_count
< 0)
364 einfo (_("%B%F: could not read symbols: %E\n"), abfd
);
367 li
->asymbols
= asymbols
;
368 li
->symbol_count
= symbol_count
;
372 for (syms
= asymbols
; *syms
; ++syms
)
374 asymbol
*sym
= *syms
;
375 if (sym
->flags
& (BSF_GLOBAL
| BSF_WARNING
| BSF_INDIRECT
| BSF_FILE
))
377 if ((sym
->flags
& (BSF_LOCAL
| BSF_SECTION_SYM
)) != 0
378 && sym
->section
->output_section
!= NULL
)
380 const char *outsecname
, *symname
;
381 struct lang_nocrossrefs
*ncrs
;
382 struct lang_nocrossref
*ncr
;
384 outsecname
= sym
->section
->output_section
->name
;
386 if ((sym
->flags
& BSF_SECTION_SYM
) == 0)
388 for (ncrs
= nocrossref_list
; ncrs
!= NULL
; ncrs
= ncrs
->next
)
389 for (ncr
= ncrs
->list
; ncr
!= NULL
; ncr
= ncr
->next
)
390 if (strcmp (ncr
->name
, outsecname
) == 0)
391 check_refs (symname
, FALSE
, sym
->section
, abfd
, ncrs
);
399 /* Check one symbol to see if it is a prohibited cross reference. */
402 check_nocrossref (struct cref_hash_entry
*h
, void *ignore ATTRIBUTE_UNUSED
)
404 struct bfd_link_hash_entry
*hl
;
406 const char *defsecname
;
407 struct lang_nocrossrefs
*ncrs
;
408 struct lang_nocrossref
*ncr
;
409 struct cref_ref
*ref
;
411 hl
= bfd_link_hash_lookup (link_info
.hash
, h
->root
.string
, FALSE
,
415 einfo (_("%P: symbol `%T' missing from main hash table\n"),
420 if (hl
->type
!= bfd_link_hash_defined
421 && hl
->type
!= bfd_link_hash_defweak
)
424 defsec
= hl
->u
.def
.section
->output_section
;
427 defsecname
= bfd_get_section_name (defsec
->owner
, defsec
);
429 for (ncrs
= nocrossref_list
; ncrs
!= NULL
; ncrs
= ncrs
->next
)
430 for (ncr
= ncrs
->list
; ncr
!= NULL
; ncr
= ncr
->next
)
431 if (strcmp (ncr
->name
, defsecname
) == 0)
432 for (ref
= h
->refs
; ref
!= NULL
; ref
= ref
->next
)
433 check_refs (hl
->root
.string
, TRUE
, hl
->u
.def
.section
,
439 /* The struct is used to pass information from check_refs to
440 check_reloc_refs through bfd_map_over_sections. */
442 struct check_refs_info
{
443 const char *sym_name
;
445 struct lang_nocrossrefs
*ncrs
;
450 /* This function is called for each symbol defined in a section which
451 prohibits cross references. We need to look through all references
452 to this symbol, and ensure that the references are not from
453 prohibited sections. */
456 check_refs (const char *name
,
460 struct lang_nocrossrefs
*ncrs
)
462 lang_input_statement_type
*li
;
464 struct check_refs_info info
;
466 /* We need to look through the relocations for this BFD, to see
467 if any of the relocations which refer to this symbol are from
468 a prohibited section. Note that we need to do this even for
469 the BFD in which the symbol is defined, since even a single
470 BFD might contain a prohibited cross reference. */
473 if (li
!= NULL
&& li
->asymbols
!= NULL
)
474 asymbols
= li
->asymbols
;
480 symsize
= bfd_get_symtab_upper_bound (abfd
);
482 einfo (_("%B%F: could not read symbols; %E\n"), abfd
);
483 asymbols
= xmalloc (symsize
);
484 symbol_count
= bfd_canonicalize_symtab (abfd
, asymbols
);
485 if (symbol_count
< 0)
486 einfo (_("%B%F: could not read symbols: %E\n"), abfd
);
489 li
->asymbols
= asymbols
;
490 li
->symbol_count
= symbol_count
;
494 info
.sym_name
= name
;
495 info
.global
= global
;
498 info
.asymbols
= asymbols
;
499 bfd_map_over_sections (abfd
, check_reloc_refs
, &info
);
505 /* This is called via bfd_map_over_sections. INFO->SYM_NAME is a symbol
506 defined in INFO->DEFSECNAME. If this section maps into any of the
507 sections listed in INFO->NCRS, other than INFO->DEFSECNAME, then we
508 look through the relocations. If any of the relocations are to
509 INFO->SYM_NAME, then we report a prohibited cross reference error. */
512 check_reloc_refs (bfd
*abfd
, asection
*sec
, void *iarg
)
514 struct check_refs_info
*info
= iarg
;
516 const char *outsecname
;
518 const char *outdefsecname
;
519 struct lang_nocrossref
*ncr
;
527 outsec
= sec
->output_section
;
528 outsecname
= bfd_get_section_name (outsec
->owner
, outsec
);
530 outdefsec
= info
->defsec
->output_section
;
531 outdefsecname
= bfd_get_section_name (outdefsec
->owner
, outdefsec
);
533 /* The section where the symbol is defined is permitted. */
534 if (strcmp (outsecname
, outdefsecname
) == 0)
537 for (ncr
= info
->ncrs
->list
; ncr
!= NULL
; ncr
= ncr
->next
)
538 if (strcmp (outsecname
, ncr
->name
) == 0)
544 /* This section is one for which cross references are prohibited.
545 Look through the relocations, and see if any of them are to
546 INFO->SYM_NAME. If INFO->SYMNAME is NULL, check for relocations
547 against the section symbol. If INFO->GLOBAL is TRUE, the
548 definition is global, check for relocations against the global
549 symbols. Otherwise check for relocations against the local and
552 symname
= info
->sym_name
;
553 global
= info
->global
;
555 relsize
= bfd_get_reloc_upper_bound (abfd
, sec
);
557 einfo (_("%B%F: could not read relocs: %E\n"), abfd
);
561 relpp
= xmalloc (relsize
);
562 relcount
= bfd_canonicalize_reloc (abfd
, sec
, relpp
, info
->asymbols
);
564 einfo (_("%B%F: could not read relocs: %E\n"), abfd
);
568 for (; p
< pend
&& *p
!= NULL
; p
++)
572 if (q
->sym_ptr_ptr
!= NULL
573 && *q
->sym_ptr_ptr
!= NULL
575 && (bfd_is_und_section (bfd_get_section (*q
->sym_ptr_ptr
))
576 || bfd_is_com_section (bfd_get_section (*q
->sym_ptr_ptr
))
577 || ((*q
->sym_ptr_ptr
)->flags
& (BSF_GLOBAL
580 && ((*q
->sym_ptr_ptr
)->flags
& (BSF_LOCAL
581 | BSF_SECTION_SYM
)) != 0))
583 ? strcmp (bfd_asymbol_name (*q
->sym_ptr_ptr
), symname
) == 0
584 : (((*q
->sym_ptr_ptr
)->flags
& BSF_SECTION_SYM
) != 0
585 && bfd_get_section (*q
->sym_ptr_ptr
) == info
->defsec
)))
587 /* We found a reloc for the symbol. The symbol is defined
588 in OUTSECNAME. This reloc is from a section which is
589 mapped into a section from which references to OUTSECNAME
590 are prohibited. We must report an error. */
591 einfo (_("%X%C: prohibited cross reference from %s to `%T' in %s\n"),
592 abfd
, sec
, q
->address
, outsecname
,
593 bfd_asymbol_name (*q
->sym_ptr_ptr
), outdefsecname
);