1 /* ldcref.c -- output a cross reference table
2 Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2006,
3 2007 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"
39 /* We keep an instance of this structure for each reference to a
40 symbol from a given object. */
43 /* The next reference. */
44 struct cref_ref
*next
;
47 /* True if the symbol is defined. */
49 /* True if the symbol is common. */
50 unsigned int common
: 1;
51 /* True if the symbol is undefined. */
52 unsigned int undef
: 1;
55 /* We keep a hash table of symbols. Each entry looks like this. */
57 struct cref_hash_entry
{
58 struct bfd_hash_entry root
;
59 /* The demangled name. */
60 const char *demangled
;
61 /* References to and definitions of this symbol. */
62 struct cref_ref
*refs
;
65 /* This is what the hash table looks like. */
67 struct cref_hash_table
{
68 struct bfd_hash_table root
;
71 /* Forward declarations. */
73 static void output_one_cref (FILE *, struct cref_hash_entry
*);
74 static void check_local_sym_xref (lang_input_statement_type
*);
75 static bfd_boolean
check_nocrossref (struct cref_hash_entry
*, void *);
76 static void check_refs (const char *, bfd_boolean
, asection
*, bfd
*,
77 struct lang_nocrossrefs
*);
78 static void check_reloc_refs (bfd
*, asection
*, void *);
80 /* Look up an entry in the cref hash table. */
82 #define cref_hash_lookup(table, string, create, copy) \
83 ((struct cref_hash_entry *) \
84 bfd_hash_lookup (&(table)->root, (string), (create), (copy)))
86 /* Traverse the cref hash table. */
88 #define cref_hash_traverse(table, func, info) \
91 (bfd_boolean (*) (struct bfd_hash_entry *, void *)) (func), \
94 /* The cref hash table. */
96 static struct cref_hash_table cref_table
;
98 /* Whether the cref hash table has been initialized. */
100 static bfd_boolean cref_initialized
;
102 /* The number of symbols seen so far. */
104 static size_t cref_symcount
;
106 /* Used to take a snapshot of the cref hash table when starting to
107 add syms from an as-needed library. */
108 static struct bfd_hash_entry
**old_table
;
109 static unsigned int old_size
;
110 static unsigned int old_count
;
111 static void *old_tab
;
112 static void *alloc_mark
;
113 static size_t tabsize
, entsize
, refsize
;
114 static size_t old_symcount
;
116 /* Create an entry in a cref hash table. */
118 static struct bfd_hash_entry
*
119 cref_hash_newfunc (struct bfd_hash_entry
*entry
,
120 struct bfd_hash_table
*table
,
123 struct cref_hash_entry
*ret
= (struct cref_hash_entry
*) entry
;
125 /* Allocate the structure if it has not already been allocated by a
128 ret
= ((struct cref_hash_entry
*)
129 bfd_hash_allocate (table
, sizeof (struct cref_hash_entry
)));
133 /* Call the allocation method of the superclass. */
134 ret
= ((struct cref_hash_entry
*)
135 bfd_hash_newfunc ((struct bfd_hash_entry
*) ret
, table
, string
));
138 /* Set local fields. */
139 ret
->demangled
= NULL
;
142 /* Keep a count of the number of entries created in the hash
150 /* Add a symbol to the cref hash table. This is called for every
151 global symbol that is seen during the link. */
154 add_cref (const char *name
,
157 bfd_vma value ATTRIBUTE_UNUSED
)
159 struct cref_hash_entry
*h
;
162 if (! cref_initialized
)
164 if (!bfd_hash_table_init (&cref_table
.root
, cref_hash_newfunc
,
165 sizeof (struct cref_hash_entry
)))
166 einfo (_("%X%P: bfd_hash_table_init of cref table failed: %E\n"));
167 cref_initialized
= TRUE
;
170 h
= cref_hash_lookup (&cref_table
, name
, TRUE
, FALSE
);
172 einfo (_("%X%P: cref_hash_lookup failed: %E\n"));
174 for (r
= h
->refs
; r
!= NULL
; r
= r
->next
)
180 r
= bfd_hash_allocate (&cref_table
.root
, sizeof *r
);
182 einfo (_("%X%P: cref alloc failed: %E\n"));
191 if (bfd_is_und_section (section
))
193 else if (bfd_is_com_section (section
))
199 /* Called before loading an as-needed library to take a snapshot of
200 the cref hash table, and after we have loaded or found that the
201 library was not needed. */
204 handle_asneeded_cref (bfd
*abfd ATTRIBUTE_UNUSED
,
205 enum notice_asneeded_action act
)
209 if (!cref_initialized
)
212 if (act
== notice_as_needed
)
214 char *old_ent
, *old_ref
;
216 for (i
= 0; i
< cref_table
.root
.size
; i
++)
218 struct bfd_hash_entry
*p
;
219 struct cref_hash_entry
*c
;
222 for (p
= cref_table
.root
.table
[i
]; p
!= NULL
; p
= p
->next
)
224 entsize
+= cref_table
.root
.entsize
;
225 c
= (struct cref_hash_entry
*) p
;
226 for (r
= c
->refs
; r
!= NULL
; r
= r
->next
)
227 refsize
+= sizeof (struct cref_hash_entry
);
231 tabsize
= cref_table
.root
.size
* sizeof (struct bfd_hash_entry
*);
232 old_tab
= xmalloc (tabsize
+ entsize
+ refsize
);
234 alloc_mark
= bfd_hash_allocate (&cref_table
.root
, 1);
235 if (alloc_mark
== NULL
)
238 memcpy (old_tab
, cref_table
.root
.table
, tabsize
);
239 old_ent
= (char *) old_tab
+ tabsize
;
240 old_ref
= (char *) old_ent
+ entsize
;
241 old_table
= cref_table
.root
.table
;
242 old_size
= cref_table
.root
.size
;
243 old_count
= cref_table
.root
.count
;
244 old_symcount
= cref_symcount
;
246 for (i
= 0; i
< cref_table
.root
.size
; i
++)
248 struct bfd_hash_entry
*p
;
249 struct cref_hash_entry
*c
;
252 for (p
= cref_table
.root
.table
[i
]; p
!= NULL
; p
= p
->next
)
254 memcpy (old_ent
, p
, cref_table
.root
.entsize
);
255 old_ent
= (char *) old_ent
+ cref_table
.root
.entsize
;
256 c
= (struct cref_hash_entry
*) p
;
257 for (r
= c
->refs
; r
!= NULL
; r
= r
->next
)
259 memcpy (old_ref
, r
, sizeof (struct cref_hash_entry
));
260 old_ref
= (char *) old_ref
+ sizeof (struct cref_hash_entry
);
267 if (act
== notice_not_needed
)
269 char *old_ent
, *old_ref
;
273 /* The only way old_tab can be NULL is if the cref hash table
274 had not been initialised when notice_as_needed. */
275 bfd_hash_table_free (&cref_table
.root
);
276 cref_initialized
= FALSE
;
280 old_ent
= (char *) old_tab
+ tabsize
;
281 old_ref
= (char *) old_ent
+ entsize
;
282 cref_table
.root
.table
= old_table
;
283 cref_table
.root
.size
= old_size
;
284 cref_table
.root
.count
= old_count
;
285 memcpy (cref_table
.root
.table
, old_tab
, tabsize
);
286 cref_symcount
= old_symcount
;
288 for (i
= 0; i
< cref_table
.root
.size
; i
++)
290 struct bfd_hash_entry
*p
;
291 struct cref_hash_entry
*c
;
294 for (p
= cref_table
.root
.table
[i
]; p
!= NULL
; p
= p
->next
)
296 memcpy (p
, old_ent
, cref_table
.root
.entsize
);
297 old_ent
= (char *) old_ent
+ cref_table
.root
.entsize
;
298 c
= (struct cref_hash_entry
*) p
;
299 for (r
= c
->refs
; r
!= NULL
; r
= r
->next
)
301 memcpy (r
, old_ref
, sizeof (struct cref_hash_entry
));
302 old_ref
= (char *) old_ref
+ sizeof (struct cref_hash_entry
);
307 objalloc_free_block ((struct objalloc
*) cref_table
.root
.memory
,
310 else if (act
!= notice_needed
)
318 /* Copy the addresses of the hash table entries into an array. This
319 is called via cref_hash_traverse. We also fill in the demangled
323 cref_fill_array (struct cref_hash_entry
*h
, void *data
)
325 struct cref_hash_entry
***pph
= data
;
327 ASSERT (h
->demangled
== NULL
);
328 h
->demangled
= bfd_demangle (output_bfd
, h
->root
.string
,
329 DMGL_ANSI
| DMGL_PARAMS
);
330 if (h
->demangled
== NULL
)
331 h
->demangled
= h
->root
.string
;
340 /* Sort an array of cref hash table entries by name. */
343 cref_sort_array (const void *a1
, const void *a2
)
345 const struct cref_hash_entry
* const *p1
= a1
;
346 const struct cref_hash_entry
* const *p2
= a2
;
348 return strcmp ((*p1
)->demangled
, (*p2
)->demangled
);
351 /* Write out the cref table. */
356 output_cref (FILE *fp
)
359 struct cref_hash_entry
**csyms
, **csym_fill
, **csym
, **csym_end
;
362 fprintf (fp
, _("\nCross Reference Table\n\n"));
364 fprintf (fp
, "%s", msg
);
366 while (len
< FILECOL
)
371 fprintf (fp
, _("File\n"));
373 if (! cref_initialized
)
375 fprintf (fp
, _("No symbols\n"));
379 csyms
= xmalloc (cref_symcount
* sizeof (*csyms
));
382 cref_hash_traverse (&cref_table
, cref_fill_array
, &csym_fill
);
383 ASSERT ((size_t) (csym_fill
- csyms
) == cref_symcount
);
385 qsort (csyms
, cref_symcount
, sizeof (*csyms
), cref_sort_array
);
387 csym_end
= csyms
+ cref_symcount
;
388 for (csym
= csyms
; csym
< csym_end
; csym
++)
389 output_one_cref (fp
, *csym
);
392 /* Output one entry in the cross reference table. */
395 output_one_cref (FILE *fp
, struct cref_hash_entry
*h
)
398 struct bfd_link_hash_entry
*hl
;
401 hl
= bfd_link_hash_lookup (link_info
.hash
, h
->root
.string
, FALSE
,
404 einfo ("%P: symbol `%T' missing from main hash table\n",
408 /* If this symbol is defined in a dynamic object but never
409 referenced by a normal object, then don't print it. */
410 if (hl
->type
== bfd_link_hash_defined
)
412 if (hl
->u
.def
.section
->output_section
== NULL
)
414 if (hl
->u
.def
.section
->owner
!= NULL
415 && (hl
->u
.def
.section
->owner
->flags
& DYNAMIC
) != 0)
417 for (r
= h
->refs
; r
!= NULL
; r
= r
->next
)
418 if ((r
->abfd
->flags
& DYNAMIC
) == 0)
426 fprintf (fp
, "%s ", h
->demangled
);
427 len
= strlen (h
->demangled
) + 1;
429 for (r
= h
->refs
; r
!= NULL
; r
= r
->next
)
433 while (len
< FILECOL
)
438 lfinfo (fp
, "%B\n", r
->abfd
);
443 for (r
= h
->refs
; r
!= NULL
; r
= r
->next
)
447 while (len
< FILECOL
)
452 lfinfo (fp
, "%B\n", r
->abfd
);
460 /* Check for prohibited cross references. */
463 check_nocrossrefs (void)
465 if (! cref_initialized
)
468 cref_hash_traverse (&cref_table
, check_nocrossref
, NULL
);
470 lang_for_each_file (check_local_sym_xref
);
473 /* Check for prohibited cross references to local and section symbols. */
476 check_local_sym_xref (lang_input_statement_type
*statement
)
479 lang_input_statement_type
*li
;
480 asymbol
**asymbols
, **syms
;
482 abfd
= statement
->the_bfd
;
487 if (li
!= NULL
&& li
->asymbols
!= NULL
)
488 asymbols
= li
->asymbols
;
494 symsize
= bfd_get_symtab_upper_bound (abfd
);
496 einfo (_("%B%F: could not read symbols; %E\n"), abfd
);
497 asymbols
= xmalloc (symsize
);
498 symbol_count
= bfd_canonicalize_symtab (abfd
, asymbols
);
499 if (symbol_count
< 0)
500 einfo (_("%B%F: could not read symbols: %E\n"), abfd
);
503 li
->asymbols
= asymbols
;
504 li
->symbol_count
= symbol_count
;
508 for (syms
= asymbols
; *syms
; ++syms
)
510 asymbol
*sym
= *syms
;
511 if (sym
->flags
& (BSF_GLOBAL
| BSF_WARNING
| BSF_INDIRECT
| BSF_FILE
))
513 if ((sym
->flags
& (BSF_LOCAL
| BSF_SECTION_SYM
)) != 0
514 && sym
->section
->output_section
!= NULL
)
516 const char *outsecname
, *symname
;
517 struct lang_nocrossrefs
*ncrs
;
518 struct lang_nocrossref
*ncr
;
520 outsecname
= sym
->section
->output_section
->name
;
522 if ((sym
->flags
& BSF_SECTION_SYM
) == 0)
524 for (ncrs
= nocrossref_list
; ncrs
!= NULL
; ncrs
= ncrs
->next
)
525 for (ncr
= ncrs
->list
; ncr
!= NULL
; ncr
= ncr
->next
)
526 if (strcmp (ncr
->name
, outsecname
) == 0)
527 check_refs (symname
, FALSE
, sym
->section
, abfd
, ncrs
);
535 /* Check one symbol to see if it is a prohibited cross reference. */
538 check_nocrossref (struct cref_hash_entry
*h
, void *ignore ATTRIBUTE_UNUSED
)
540 struct bfd_link_hash_entry
*hl
;
542 const char *defsecname
;
543 struct lang_nocrossrefs
*ncrs
;
544 struct lang_nocrossref
*ncr
;
545 struct cref_ref
*ref
;
547 hl
= bfd_link_hash_lookup (link_info
.hash
, h
->root
.string
, FALSE
,
551 einfo (_("%P: symbol `%T' missing from main hash table\n"),
556 if (hl
->type
!= bfd_link_hash_defined
557 && hl
->type
!= bfd_link_hash_defweak
)
560 defsec
= hl
->u
.def
.section
->output_section
;
563 defsecname
= bfd_get_section_name (defsec
->owner
, defsec
);
565 for (ncrs
= nocrossref_list
; ncrs
!= NULL
; ncrs
= ncrs
->next
)
566 for (ncr
= ncrs
->list
; ncr
!= NULL
; ncr
= ncr
->next
)
567 if (strcmp (ncr
->name
, defsecname
) == 0)
568 for (ref
= h
->refs
; ref
!= NULL
; ref
= ref
->next
)
569 check_refs (hl
->root
.string
, TRUE
, hl
->u
.def
.section
,
575 /* The struct is used to pass information from check_refs to
576 check_reloc_refs through bfd_map_over_sections. */
578 struct check_refs_info
{
579 const char *sym_name
;
581 struct lang_nocrossrefs
*ncrs
;
586 /* This function is called for each symbol defined in a section which
587 prohibits cross references. We need to look through all references
588 to this symbol, and ensure that the references are not from
589 prohibited sections. */
592 check_refs (const char *name
,
596 struct lang_nocrossrefs
*ncrs
)
598 lang_input_statement_type
*li
;
600 struct check_refs_info info
;
602 /* We need to look through the relocations for this BFD, to see
603 if any of the relocations which refer to this symbol are from
604 a prohibited section. Note that we need to do this even for
605 the BFD in which the symbol is defined, since even a single
606 BFD might contain a prohibited cross reference. */
609 if (li
!= NULL
&& li
->asymbols
!= NULL
)
610 asymbols
= li
->asymbols
;
616 symsize
= bfd_get_symtab_upper_bound (abfd
);
618 einfo (_("%B%F: could not read symbols; %E\n"), abfd
);
619 asymbols
= xmalloc (symsize
);
620 symbol_count
= bfd_canonicalize_symtab (abfd
, asymbols
);
621 if (symbol_count
< 0)
622 einfo (_("%B%F: could not read symbols: %E\n"), abfd
);
625 li
->asymbols
= asymbols
;
626 li
->symbol_count
= symbol_count
;
630 info
.sym_name
= name
;
631 info
.global
= global
;
634 info
.asymbols
= asymbols
;
635 bfd_map_over_sections (abfd
, check_reloc_refs
, &info
);
641 /* This is called via bfd_map_over_sections. INFO->SYM_NAME is a symbol
642 defined in INFO->DEFSECNAME. If this section maps into any of the
643 sections listed in INFO->NCRS, other than INFO->DEFSECNAME, then we
644 look through the relocations. If any of the relocations are to
645 INFO->SYM_NAME, then we report a prohibited cross reference error. */
648 check_reloc_refs (bfd
*abfd
, asection
*sec
, void *iarg
)
650 struct check_refs_info
*info
= iarg
;
652 const char *outsecname
;
654 const char *outdefsecname
;
655 struct lang_nocrossref
*ncr
;
663 outsec
= sec
->output_section
;
664 outsecname
= bfd_get_section_name (outsec
->owner
, outsec
);
666 outdefsec
= info
->defsec
->output_section
;
667 outdefsecname
= bfd_get_section_name (outdefsec
->owner
, outdefsec
);
669 /* The section where the symbol is defined is permitted. */
670 if (strcmp (outsecname
, outdefsecname
) == 0)
673 for (ncr
= info
->ncrs
->list
; ncr
!= NULL
; ncr
= ncr
->next
)
674 if (strcmp (outsecname
, ncr
->name
) == 0)
680 /* This section is one for which cross references are prohibited.
681 Look through the relocations, and see if any of them are to
682 INFO->SYM_NAME. If INFO->SYMNAME is NULL, check for relocations
683 against the section symbol. If INFO->GLOBAL is TRUE, the
684 definition is global, check for relocations against the global
685 symbols. Otherwise check for relocations against the local and
688 symname
= info
->sym_name
;
689 global
= info
->global
;
691 relsize
= bfd_get_reloc_upper_bound (abfd
, sec
);
693 einfo (_("%B%F: could not read relocs: %E\n"), abfd
);
697 relpp
= xmalloc (relsize
);
698 relcount
= bfd_canonicalize_reloc (abfd
, sec
, relpp
, info
->asymbols
);
700 einfo (_("%B%F: could not read relocs: %E\n"), abfd
);
704 for (; p
< pend
&& *p
!= NULL
; p
++)
708 if (q
->sym_ptr_ptr
!= NULL
709 && *q
->sym_ptr_ptr
!= NULL
711 && (bfd_is_und_section (bfd_get_section (*q
->sym_ptr_ptr
))
712 || bfd_is_com_section (bfd_get_section (*q
->sym_ptr_ptr
))
713 || ((*q
->sym_ptr_ptr
)->flags
& (BSF_GLOBAL
716 && ((*q
->sym_ptr_ptr
)->flags
& (BSF_LOCAL
717 | BSF_SECTION_SYM
)) != 0
718 && bfd_get_section (*q
->sym_ptr_ptr
) == info
->defsec
))
720 ? strcmp (bfd_asymbol_name (*q
->sym_ptr_ptr
), symname
) == 0
721 : ((*q
->sym_ptr_ptr
)->flags
& BSF_SECTION_SYM
) != 0))
723 /* We found a reloc for the symbol. The symbol is defined
724 in OUTSECNAME. This reloc is from a section which is
725 mapped into a section from which references to OUTSECNAME
726 are prohibited. We must report an error. */
727 einfo (_("%X%C: prohibited cross reference from %s to `%T' in %s\n"),
728 abfd
, sec
, q
->address
, outsecname
,
729 bfd_asymbol_name (*q
->sym_ptr_ptr
), outdefsecname
);