1 /* ldcref.c -- output a cross reference table
2 Copyright (C) 1996, 97, 98, 99, 2000 Free Software Foundation, Inc.
3 Written by Ian Lance Taylor <ian@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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
21 /* This file holds routines that manage the cross reference table.
22 The table is used to generate cross reference reports. It is also
23 used to implement the NOCROSSREFS command in the linker script. */
28 #include "libiberty.h"
36 /* We keep an instance of this structure for each reference to a
37 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
57 struct bfd_hash_entry root;
58 /* The demangled name. */
60 /* References to and definitions of this symbol. */
61 struct cref_ref *refs;
64 /* This is what the hash table looks like. */
66 struct cref_hash_table
68 struct bfd_hash_table root;
71 /* Local functions. */
73 static struct bfd_hash_entry *cref_hash_newfunc
74 PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
75 static boolean cref_fill_array PARAMS ((struct cref_hash_entry *, PTR));
76 static int cref_sort_array PARAMS ((const PTR, const PTR));
77 static void output_one_cref PARAMS ((FILE *, struct cref_hash_entry *));
78 static boolean check_nocrossref PARAMS ((struct cref_hash_entry *, PTR));
79 static void check_refs
80 PARAMS ((struct cref_hash_entry *, struct bfd_link_hash_entry *,
81 struct lang_nocrossrefs *));
82 static void check_reloc_refs PARAMS ((bfd *, asection *, PTR));
84 /* Look up an entry in the cref hash table. */
86 #define cref_hash_lookup(table, string, create, copy) \
87 ((struct cref_hash_entry *) \
88 bfd_hash_lookup (&(table)->root, (string), (create), (copy)))
90 /* Traverse the cref hash table. */
92 #define cref_hash_traverse(table, func, info) \
95 (boolean (*) PARAMS ((struct bfd_hash_entry *, PTR))) (func), \
98 /* The cref hash table. */
100 static struct cref_hash_table cref_table;
102 /* Whether the cref hash table has been initialized. */
104 static boolean cref_initialized;
106 /* The number of symbols seen so far. */
108 static size_t cref_symcount;
110 /* Create an entry in a cref hash table. */
112 static struct bfd_hash_entry *
113 cref_hash_newfunc (entry, table, string)
114 struct bfd_hash_entry *entry;
115 struct bfd_hash_table *table;
118 struct cref_hash_entry *ret = (struct cref_hash_entry *) entry;
120 /* Allocate the structure if it has not already been allocated by a
123 ret = ((struct cref_hash_entry *)
124 bfd_hash_allocate (table, sizeof (struct cref_hash_entry)));
126 return (struct bfd_hash_entry *) ret;
128 /* Call the allocation method of the superclass. */
129 ret = ((struct cref_hash_entry *)
130 bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string));
133 /* Set local fields. */
134 ret->demangled = NULL;
137 /* Keep a count of the number of entries created in the hash
142 return (struct bfd_hash_entry *) ret;
145 /* Add a symbol to the cref hash table. This is called for every
146 symbol that is seen during the link. */
149 add_cref (name, abfd, section, value)
153 bfd_vma value ATTRIBUTE_UNUSED;
155 struct cref_hash_entry *h;
158 if (! cref_initialized)
160 if (! bfd_hash_table_init (&cref_table.root, cref_hash_newfunc))
161 einfo (_("%X%P: bfd_hash_table_init of cref table failed: %E\n"));
162 cref_initialized = true;
165 h = cref_hash_lookup (&cref_table, name, true, false);
167 einfo (_("%X%P: cref_hash_lookup failed: %E\n"));
169 for (r = h->refs; r != NULL; r = r->next)
175 r = (struct cref_ref *) xmalloc (sizeof *r);
184 if (bfd_is_und_section (section))
186 else if (bfd_is_com_section (section))
192 /* Copy the addresses of the hash table entries into an array. This
193 is called via cref_hash_traverse. We also fill in the demangled
197 cref_fill_array (h, data)
198 struct cref_hash_entry *h;
201 struct cref_hash_entry ***pph = (struct cref_hash_entry ***) data;
203 ASSERT (h->demangled == NULL);
204 h->demangled = demangle (h->root.string);
213 /* Sort an array of cref hash table entries by name. */
216 cref_sort_array (a1, a2)
220 const struct cref_hash_entry **p1 = (const struct cref_hash_entry **) a1;
221 const struct cref_hash_entry **p2 = (const struct cref_hash_entry **) a2;
223 return strcmp ((*p1)->demangled, (*p2)->demangled);
226 /* Write out the cref table. */
235 struct cref_hash_entry **csyms, **csym_fill, **csym, **csym_end;
238 fprintf (fp, _("\nCross Reference Table\n\n"));
240 fprintf (fp, "%s", msg);
242 while (len < FILECOL)
247 fprintf (fp, _("File\n"));
249 if (! cref_initialized)
251 fprintf (fp, _("No symbols\n"));
255 csyms = ((struct cref_hash_entry **)
256 xmalloc (cref_symcount * sizeof (*csyms)));
259 cref_hash_traverse (&cref_table, cref_fill_array, &csym_fill);
260 ASSERT ((size_t) (csym_fill - csyms) == cref_symcount);
262 qsort (csyms, cref_symcount, sizeof (*csyms), cref_sort_array);
264 csym_end = csyms + cref_symcount;
265 for (csym = csyms; csym < csym_end; csym++)
266 output_one_cref (fp, *csym);
269 /* Output one entry in the cross reference table. */
272 output_one_cref (fp, h)
274 struct cref_hash_entry *h;
277 struct bfd_link_hash_entry *hl;
280 hl = bfd_link_hash_lookup (link_info.hash, h->root.string, false,
283 einfo ("%P: symbol `%T' missing from main hash table\n",
287 /* If this symbol is defined in a dynamic object but never
288 referenced by a normal object, then don't print it. */
289 if (hl->type == bfd_link_hash_defined)
291 if (hl->u.def.section->output_section == NULL)
293 if (hl->u.def.section->owner != NULL
294 && (hl->u.def.section->owner->flags & DYNAMIC) != 0)
296 for (r = h->refs; r != NULL; r = r->next)
297 if ((r->abfd->flags & DYNAMIC) == 0)
305 fprintf (fp, "%s ", h->demangled);
306 len = strlen (h->demangled) + 1;
308 for (r = h->refs; r != NULL; r = r->next)
312 while (len < FILECOL)
317 lfinfo (fp, "%B\n", r->abfd);
322 for (r = h->refs; r != NULL; r = r->next)
326 while (len < FILECOL)
331 lfinfo (fp, "%B\n", r->abfd);
339 /* Check for prohibited cross references. */
344 if (! cref_initialized)
347 cref_hash_traverse (&cref_table, check_nocrossref, (PTR) NULL);
350 /* Check one symbol to see if it is a prohibited cross reference. */
353 check_nocrossref (h, ignore)
354 struct cref_hash_entry *h;
355 PTR ignore ATTRIBUTE_UNUSED;
357 struct bfd_link_hash_entry *hl;
359 const char *defsecname;
360 struct lang_nocrossrefs *ncrs;
361 struct lang_nocrossref *ncr;
363 hl = bfd_link_hash_lookup (link_info.hash, h->root.string, false,
367 einfo (_("%P: symbol `%T' missing from main hash table\n"),
372 if (hl->type != bfd_link_hash_defined
373 && hl->type != bfd_link_hash_defweak)
376 defsec = hl->u.def.section->output_section;
379 defsecname = bfd_get_section_name (defsec->owner, defsec);
381 for (ncrs = nocrossref_list; ncrs != NULL; ncrs = ncrs->next)
382 for (ncr = ncrs->list; ncr != NULL; ncr = ncr->next)
383 if (strcmp (ncr->name, defsecname) == 0)
384 check_refs (h, hl, ncrs);
389 /* The struct is used to pass information from check_refs to
390 check_reloc_refs through bfd_map_over_sections. */
392 struct check_refs_info
394 struct cref_hash_entry *h;
396 struct lang_nocrossrefs *ncrs;
401 /* This function is called for each symbol defined in a section which
402 prohibits cross references. We need to look through all references
403 to this symbol, and ensure that the references are not from
404 prohibited sections. */
407 check_refs (h, hl, ncrs)
408 struct cref_hash_entry *h;
409 struct bfd_link_hash_entry *hl;
410 struct lang_nocrossrefs *ncrs;
412 struct cref_ref *ref;
414 for (ref = h->refs; ref != NULL; ref = ref->next)
416 lang_input_statement_type *li;
418 struct check_refs_info info;
420 /* We need to look through the relocations for this BFD, to see
421 if any of the relocations which refer to this symbol are from
422 a prohibited section. Note that we need to do this even for
423 the BFD in which the symbol is defined, since even a single
424 BFD might contain a prohibited cross reference; for this
425 case, we set the SAME field in INFO, which will cause
426 CHECK_RELOCS_REFS to check for relocations against the
427 section as well as against the symbol. */
429 li = (lang_input_statement_type *) ref->abfd->usrdata;
430 if (li != NULL && li->asymbols != NULL)
431 asymbols = li->asymbols;
437 symsize = bfd_get_symtab_upper_bound (ref->abfd);
439 einfo (_("%B%F: could not read symbols; %E\n"), ref->abfd);
440 asymbols = (asymbol **) xmalloc (symsize);
441 symbol_count = bfd_canonicalize_symtab (ref->abfd, asymbols);
442 if (symbol_count < 0)
443 einfo (_("%B%F: could not read symbols: %E\n"), ref->abfd);
446 li->asymbols = asymbols;
447 li->symbol_count = symbol_count;
452 info.defsec = hl->u.def.section;
454 info.asymbols = asymbols;
455 if (ref->abfd == hl->u.def.section->owner)
459 bfd_map_over_sections (ref->abfd, check_reloc_refs, (PTR) &info);
466 /* This is called via bfd_map_over_sections. INFO->H is a symbol
467 defined in INFO->DEFSECNAME. If this section maps into any of the
468 sections listed in INFO->NCRS, other than INFO->DEFSECNAME, then we
469 look through the relocations. If any of the relocations are to
470 INFO->H, then we report a prohibited cross reference error. */
473 check_reloc_refs (abfd, sec, iarg)
478 struct check_refs_info *info = (struct check_refs_info *) iarg;
480 const char *outsecname;
482 const char *outdefsecname;
483 struct lang_nocrossref *ncr;
490 outsec = sec->output_section;
491 outsecname = bfd_get_section_name (outsec->owner, outsec);
493 outdefsec = info->defsec->output_section;
494 outdefsecname = bfd_get_section_name (outdefsec->owner, outdefsec);
496 /* The section where the symbol is defined is permitted. */
497 if (strcmp (outsecname, outdefsecname) == 0)
500 for (ncr = info->ncrs->list; ncr != NULL; ncr = ncr->next)
501 if (strcmp (outsecname, ncr->name) == 0)
507 /* This section is one for which cross references are prohibited.
508 Look through the relocations, and see if any of them are to
511 symname = info->h->root.string;
513 relsize = bfd_get_reloc_upper_bound (abfd, sec);
515 einfo (_("%B%F: could not read relocs: %E\n"), abfd);
519 relpp = (arelent **) xmalloc (relsize);
520 relcount = bfd_canonicalize_reloc (abfd, sec, relpp, info->asymbols);
522 einfo (_("%B%F: could not read relocs: %E\n"), abfd);
526 for (; p < pend && *p != NULL; p++)
530 if (q->sym_ptr_ptr != NULL
531 && *q->sym_ptr_ptr != NULL
532 && (strcmp (bfd_asymbol_name (*q->sym_ptr_ptr), symname) == 0
534 && bfd_get_section (*q->sym_ptr_ptr) == info->defsec)))
536 /* We found a reloc for the symbol. The symbol is defined
537 in OUTSECNAME. This reloc is from a section which is
538 mapped into a section from which references to OUTSECNAME
539 are prohibited. We must report an error. */
540 einfo (_("%X%C: prohibited cross reference from %s to `%T' in %s\n"),
541 abfd, sec, q->address, outsecname,
542 bfd_asymbol_name (*q->sym_ptr_ptr), outdefsecname);