bfd/
[binutils.git] / ld / ldcref.c
blobfb1d3c907f3141947edc023c1a7fe0ac6f73d101
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. */
26 #include "bfd.h"
27 #include "sysdep.h"
28 #include "bfdlink.h"
29 #include "libiberty.h"
30 #include "objalloc.h"
32 #include "ld.h"
33 #include "ldmain.h"
34 #include "ldmisc.h"
35 #include "ldexp.h"
36 #include "ldlang.h"
38 /* We keep an instance of this structure for each reference to a
39 symbol from a given object. */
41 struct cref_ref {
42 /* The next reference. */
43 struct cref_ref *next;
44 /* The object. */
45 bfd *abfd;
46 /* True if the symbol is defined. */
47 unsigned int def : 1;
48 /* True if the symbol is common. */
49 unsigned int common : 1;
50 /* True if the symbol is undefined. */
51 unsigned int undef : 1;
54 /* We keep a hash table of symbols. Each entry looks like this. */
56 struct cref_hash_entry {
57 struct bfd_hash_entry root;
58 /* The demangled name. */
59 char *demangled;
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 {
67 struct bfd_hash_table root;
70 /* Forward declarations. */
72 static void output_one_cref (FILE *, struct cref_hash_entry *);
73 static void check_local_sym_xref (lang_input_statement_type *);
74 static bfd_boolean check_nocrossref (struct cref_hash_entry *, void *);
75 static void check_refs (const char *, bfd_boolean, asection *, bfd *,
76 struct lang_nocrossrefs *);
77 static void check_reloc_refs (bfd *, asection *, void *);
79 /* Look up an entry in the cref hash table. */
81 #define cref_hash_lookup(table, string, create, copy) \
82 ((struct cref_hash_entry *) \
83 bfd_hash_lookup (&(table)->root, (string), (create), (copy)))
85 /* Traverse the cref hash table. */
87 #define cref_hash_traverse(table, func, info) \
88 (bfd_hash_traverse \
89 (&(table)->root, \
90 (bfd_boolean (*) (struct bfd_hash_entry *, void *)) (func), \
91 (info)))
93 /* The cref hash table. */
95 static struct cref_hash_table cref_table;
97 /* Whether the cref hash table has been initialized. */
99 static bfd_boolean cref_initialized;
101 /* The number of symbols seen so far. */
103 static size_t cref_symcount;
105 /* Used to take a snapshot of the cref hash table when starting to
106 add syms from an as-needed library. */
107 static struct bfd_hash_entry **old_table;
108 static unsigned int old_size;
109 static unsigned int old_count;
110 static void *old_tab;
111 static void *alloc_mark;
112 static size_t tabsize, entsize, refsize;
113 static size_t old_symcount;
115 /* Create an entry in a cref hash table. */
117 static struct bfd_hash_entry *
118 cref_hash_newfunc (struct bfd_hash_entry *entry,
119 struct bfd_hash_table *table,
120 const char *string)
122 struct cref_hash_entry *ret = (struct cref_hash_entry *) entry;
124 /* Allocate the structure if it has not already been allocated by a
125 subclass. */
126 if (ret == NULL)
127 ret = ((struct cref_hash_entry *)
128 bfd_hash_allocate (table, sizeof (struct cref_hash_entry)));
129 if (ret == NULL)
130 return NULL;
132 /* Call the allocation method of the superclass. */
133 ret = ((struct cref_hash_entry *)
134 bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string));
135 if (ret != NULL)
137 /* Set local fields. */
138 ret->demangled = NULL;
139 ret->refs = NULL;
141 /* Keep a count of the number of entries created in the hash
142 table. */
143 ++cref_symcount;
146 return &ret->root;
149 /* Add a symbol to the cref hash table. This is called for every
150 global symbol that is seen during the link. */
152 void
153 add_cref (const char *name,
154 bfd *abfd,
155 asection *section,
156 bfd_vma value ATTRIBUTE_UNUSED)
158 struct cref_hash_entry *h;
159 struct cref_ref *r;
161 if (! cref_initialized)
163 if (!bfd_hash_table_init (&cref_table.root, cref_hash_newfunc,
164 sizeof (struct cref_hash_entry)))
165 einfo (_("%X%P: bfd_hash_table_init of cref table failed: %E\n"));
166 cref_initialized = TRUE;
169 h = cref_hash_lookup (&cref_table, name, TRUE, FALSE);
170 if (h == NULL)
171 einfo (_("%X%P: cref_hash_lookup failed: %E\n"));
173 for (r = h->refs; r != NULL; r = r->next)
174 if (r->abfd == abfd)
175 break;
177 if (r == NULL)
179 r = bfd_hash_allocate (&cref_table.root, sizeof *r);
180 if (r == NULL)
181 einfo (_("%X%P: cref alloc failed: %E\n"));
182 r->next = h->refs;
183 h->refs = r;
184 r->abfd = abfd;
185 r->def = FALSE;
186 r->common = FALSE;
187 r->undef = FALSE;
190 if (bfd_is_und_section (section))
191 r->undef = TRUE;
192 else if (bfd_is_com_section (section))
193 r->common = TRUE;
194 else
195 r->def = TRUE;
198 /* Called before loading an as-needed library to take a snapshot of
199 the cref hash table, and after we have loaded or found that the
200 library was not needed. */
202 bfd_boolean
203 handle_asneeded_cref (bfd *abfd ATTRIBUTE_UNUSED,
204 enum notice_asneeded_action act)
206 unsigned int i;
208 if (!cref_initialized)
209 return TRUE;
211 if (act == notice_as_needed)
213 char *old_ent, *old_ref;
215 for (i = 0; i < cref_table.root.size; i++)
217 struct bfd_hash_entry *p;
218 struct cref_hash_entry *c;
219 struct cref_ref *r;
221 for (p = cref_table.root.table[i]; p != NULL; p = p->next)
223 entsize += cref_table.root.entsize;
224 c = (struct cref_hash_entry *) p;
225 for (r = c->refs; r != NULL; r = r->next)
226 refsize += sizeof (struct cref_hash_entry);
230 tabsize = cref_table.root.size * sizeof (struct bfd_hash_entry *);
231 old_tab = xmalloc (tabsize + entsize + refsize);
233 alloc_mark = bfd_hash_allocate (&cref_table.root, 1);
234 if (alloc_mark == NULL)
235 return FALSE;
237 memcpy (old_tab, cref_table.root.table, tabsize);
238 old_ent = (char *) old_tab + tabsize;
239 old_ref = (char *) old_ent + entsize;
240 old_table = cref_table.root.table;
241 old_size = cref_table.root.size;
242 old_count = cref_table.root.count;
243 old_symcount = cref_symcount;
245 for (i = 0; i < cref_table.root.size; i++)
247 struct bfd_hash_entry *p;
248 struct cref_hash_entry *c;
249 struct cref_ref *r;
251 for (p = cref_table.root.table[i]; p != NULL; p = p->next)
253 memcpy (old_ent, p, cref_table.root.entsize);
254 old_ent = (char *) old_ent + cref_table.root.entsize;
255 c = (struct cref_hash_entry *) p;
256 for (r = c->refs; r != NULL; r = r->next)
258 memcpy (old_ref, r, sizeof (struct cref_hash_entry));
259 old_ref = (char *) old_ref + sizeof (struct cref_hash_entry);
263 return TRUE;
266 if (act == notice_not_needed)
268 char *old_ent, *old_ref;
270 if (old_tab == NULL)
272 /* The only way old_tab can be NULL is if the cref hash table
273 had not been initialised when notice_as_needed. */
274 bfd_hash_table_free (&cref_table.root);
275 cref_initialized = FALSE;
276 return TRUE;
279 old_ent = (char *) old_tab + tabsize;
280 old_ref = (char *) old_ent + entsize;
281 cref_table.root.table = old_table;
282 cref_table.root.size = old_size;
283 cref_table.root.count = old_count;
284 memcpy (cref_table.root.table, old_tab, tabsize);
285 cref_symcount = old_symcount;
287 for (i = 0; i < cref_table.root.size; i++)
289 struct bfd_hash_entry *p;
290 struct cref_hash_entry *c;
291 struct cref_ref *r;
293 for (p = cref_table.root.table[i]; p != NULL; p = p->next)
295 memcpy (p, old_ent, cref_table.root.entsize);
296 old_ent = (char *) old_ent + cref_table.root.entsize;
297 c = (struct cref_hash_entry *) p;
298 for (r = c->refs; r != NULL; r = r->next)
300 memcpy (r, old_ref, sizeof (struct cref_hash_entry));
301 old_ref = (char *) old_ref + sizeof (struct cref_hash_entry);
306 objalloc_free_block ((struct objalloc *) cref_table.root.memory,
307 alloc_mark);
309 else if (act != notice_needed)
310 return FALSE;
312 free (old_tab);
313 old_tab = NULL;
314 return TRUE;
317 /* Copy the addresses of the hash table entries into an array. This
318 is called via cref_hash_traverse. We also fill in the demangled
319 name. */
321 static bfd_boolean
322 cref_fill_array (struct cref_hash_entry *h, void *data)
324 struct cref_hash_entry ***pph = data;
326 ASSERT (h->demangled == NULL);
327 h->demangled = demangle (h->root.string);
329 **pph = h;
331 ++*pph;
333 return TRUE;
336 /* Sort an array of cref hash table entries by name. */
338 static int
339 cref_sort_array (const void *a1, const void *a2)
341 const struct cref_hash_entry * const *p1 = a1;
342 const struct cref_hash_entry * const *p2 = a2;
344 return strcmp ((*p1)->demangled, (*p2)->demangled);
347 /* Write out the cref table. */
349 #define FILECOL (50)
351 void
352 output_cref (FILE *fp)
354 int len;
355 struct cref_hash_entry **csyms, **csym_fill, **csym, **csym_end;
356 const char *msg;
358 fprintf (fp, _("\nCross Reference Table\n\n"));
359 msg = _("Symbol");
360 fprintf (fp, "%s", msg);
361 len = strlen (msg);
362 while (len < FILECOL)
364 putc (' ', fp);
365 ++len;
367 fprintf (fp, _("File\n"));
369 if (! cref_initialized)
371 fprintf (fp, _("No symbols\n"));
372 return;
375 csyms = xmalloc (cref_symcount * sizeof (*csyms));
377 csym_fill = csyms;
378 cref_hash_traverse (&cref_table, cref_fill_array, &csym_fill);
379 ASSERT ((size_t) (csym_fill - csyms) == cref_symcount);
381 qsort (csyms, cref_symcount, sizeof (*csyms), cref_sort_array);
383 csym_end = csyms + cref_symcount;
384 for (csym = csyms; csym < csym_end; csym++)
385 output_one_cref (fp, *csym);
388 /* Output one entry in the cross reference table. */
390 static void
391 output_one_cref (FILE *fp, struct cref_hash_entry *h)
393 int len;
394 struct bfd_link_hash_entry *hl;
395 struct cref_ref *r;
397 hl = bfd_link_hash_lookup (link_info.hash, h->root.string, FALSE,
398 FALSE, TRUE);
399 if (hl == NULL)
400 einfo ("%P: symbol `%T' missing from main hash table\n",
401 h->root.string);
402 else
404 /* If this symbol is defined in a dynamic object but never
405 referenced by a normal object, then don't print it. */
406 if (hl->type == bfd_link_hash_defined)
408 if (hl->u.def.section->output_section == NULL)
409 return;
410 if (hl->u.def.section->owner != NULL
411 && (hl->u.def.section->owner->flags & DYNAMIC) != 0)
413 for (r = h->refs; r != NULL; r = r->next)
414 if ((r->abfd->flags & DYNAMIC) == 0)
415 break;
416 if (r == NULL)
417 return;
422 fprintf (fp, "%s ", h->demangled);
423 len = strlen (h->demangled) + 1;
425 for (r = h->refs; r != NULL; r = r->next)
427 if (r->def)
429 while (len < FILECOL)
431 putc (' ', fp);
432 ++len;
434 lfinfo (fp, "%B\n", r->abfd);
435 len = 0;
439 for (r = h->refs; r != NULL; r = r->next)
441 if (! r->def)
443 while (len < FILECOL)
445 putc (' ', fp);
446 ++len;
448 lfinfo (fp, "%B\n", r->abfd);
449 len = 0;
453 ASSERT (len == 0);
456 /* Check for prohibited cross references. */
458 void
459 check_nocrossrefs (void)
461 if (! cref_initialized)
462 return;
464 cref_hash_traverse (&cref_table, check_nocrossref, NULL);
466 lang_for_each_file (check_local_sym_xref);
469 /* Check for prohibited cross references to local and section symbols. */
471 static void
472 check_local_sym_xref (lang_input_statement_type *statement)
474 bfd *abfd;
475 lang_input_statement_type *li;
476 asymbol **asymbols, **syms;
478 abfd = statement->the_bfd;
479 if (abfd == NULL)
480 return;
482 li = abfd->usrdata;
483 if (li != NULL && li->asymbols != NULL)
484 asymbols = li->asymbols;
485 else
487 long symsize;
488 long symbol_count;
490 symsize = bfd_get_symtab_upper_bound (abfd);
491 if (symsize < 0)
492 einfo (_("%B%F: could not read symbols; %E\n"), abfd);
493 asymbols = xmalloc (symsize);
494 symbol_count = bfd_canonicalize_symtab (abfd, asymbols);
495 if (symbol_count < 0)
496 einfo (_("%B%F: could not read symbols: %E\n"), abfd);
497 if (li != NULL)
499 li->asymbols = asymbols;
500 li->symbol_count = symbol_count;
504 for (syms = asymbols; *syms; ++syms)
506 asymbol *sym = *syms;
507 if (sym->flags & (BSF_GLOBAL | BSF_WARNING | BSF_INDIRECT | BSF_FILE))
508 continue;
509 if ((sym->flags & (BSF_LOCAL | BSF_SECTION_SYM)) != 0
510 && sym->section->output_section != NULL)
512 const char *outsecname, *symname;
513 struct lang_nocrossrefs *ncrs;
514 struct lang_nocrossref *ncr;
516 outsecname = sym->section->output_section->name;
517 symname = NULL;
518 if ((sym->flags & BSF_SECTION_SYM) == 0)
519 symname = sym->name;
520 for (ncrs = nocrossref_list; ncrs != NULL; ncrs = ncrs->next)
521 for (ncr = ncrs->list; ncr != NULL; ncr = ncr->next)
522 if (strcmp (ncr->name, outsecname) == 0)
523 check_refs (symname, FALSE, sym->section, abfd, ncrs);
527 if (li == NULL)
528 free (asymbols);
531 /* Check one symbol to see if it is a prohibited cross reference. */
533 static bfd_boolean
534 check_nocrossref (struct cref_hash_entry *h, void *ignore ATTRIBUTE_UNUSED)
536 struct bfd_link_hash_entry *hl;
537 asection *defsec;
538 const char *defsecname;
539 struct lang_nocrossrefs *ncrs;
540 struct lang_nocrossref *ncr;
541 struct cref_ref *ref;
543 hl = bfd_link_hash_lookup (link_info.hash, h->root.string, FALSE,
544 FALSE, TRUE);
545 if (hl == NULL)
547 einfo (_("%P: symbol `%T' missing from main hash table\n"),
548 h->root.string);
549 return TRUE;
552 if (hl->type != bfd_link_hash_defined
553 && hl->type != bfd_link_hash_defweak)
554 return TRUE;
556 defsec = hl->u.def.section->output_section;
557 if (defsec == NULL)
558 return TRUE;
559 defsecname = bfd_get_section_name (defsec->owner, defsec);
561 for (ncrs = nocrossref_list; ncrs != NULL; ncrs = ncrs->next)
562 for (ncr = ncrs->list; ncr != NULL; ncr = ncr->next)
563 if (strcmp (ncr->name, defsecname) == 0)
564 for (ref = h->refs; ref != NULL; ref = ref->next)
565 check_refs (hl->root.string, TRUE, hl->u.def.section,
566 ref->abfd, ncrs);
568 return TRUE;
571 /* The struct is used to pass information from check_refs to
572 check_reloc_refs through bfd_map_over_sections. */
574 struct check_refs_info {
575 const char *sym_name;
576 asection *defsec;
577 struct lang_nocrossrefs *ncrs;
578 asymbol **asymbols;
579 bfd_boolean global;
582 /* This function is called for each symbol defined in a section which
583 prohibits cross references. We need to look through all references
584 to this symbol, and ensure that the references are not from
585 prohibited sections. */
587 static void
588 check_refs (const char *name,
589 bfd_boolean global,
590 asection *sec,
591 bfd *abfd,
592 struct lang_nocrossrefs *ncrs)
594 lang_input_statement_type *li;
595 asymbol **asymbols;
596 struct check_refs_info info;
598 /* We need to look through the relocations for this BFD, to see
599 if any of the relocations which refer to this symbol are from
600 a prohibited section. Note that we need to do this even for
601 the BFD in which the symbol is defined, since even a single
602 BFD might contain a prohibited cross reference. */
604 li = abfd->usrdata;
605 if (li != NULL && li->asymbols != NULL)
606 asymbols = li->asymbols;
607 else
609 long symsize;
610 long symbol_count;
612 symsize = bfd_get_symtab_upper_bound (abfd);
613 if (symsize < 0)
614 einfo (_("%B%F: could not read symbols; %E\n"), abfd);
615 asymbols = xmalloc (symsize);
616 symbol_count = bfd_canonicalize_symtab (abfd, asymbols);
617 if (symbol_count < 0)
618 einfo (_("%B%F: could not read symbols: %E\n"), abfd);
619 if (li != NULL)
621 li->asymbols = asymbols;
622 li->symbol_count = symbol_count;
626 info.sym_name = name;
627 info.global = global;
628 info.defsec = sec;
629 info.ncrs = ncrs;
630 info.asymbols = asymbols;
631 bfd_map_over_sections (abfd, check_reloc_refs, &info);
633 if (li == NULL)
634 free (asymbols);
637 /* This is called via bfd_map_over_sections. INFO->SYM_NAME is a symbol
638 defined in INFO->DEFSECNAME. If this section maps into any of the
639 sections listed in INFO->NCRS, other than INFO->DEFSECNAME, then we
640 look through the relocations. If any of the relocations are to
641 INFO->SYM_NAME, then we report a prohibited cross reference error. */
643 static void
644 check_reloc_refs (bfd *abfd, asection *sec, void *iarg)
646 struct check_refs_info *info = iarg;
647 asection *outsec;
648 const char *outsecname;
649 asection *outdefsec;
650 const char *outdefsecname;
651 struct lang_nocrossref *ncr;
652 const char *symname;
653 bfd_boolean global;
654 long relsize;
655 arelent **relpp;
656 long relcount;
657 arelent **p, **pend;
659 outsec = sec->output_section;
660 outsecname = bfd_get_section_name (outsec->owner, outsec);
662 outdefsec = info->defsec->output_section;
663 outdefsecname = bfd_get_section_name (outdefsec->owner, outdefsec);
665 /* The section where the symbol is defined is permitted. */
666 if (strcmp (outsecname, outdefsecname) == 0)
667 return;
669 for (ncr = info->ncrs->list; ncr != NULL; ncr = ncr->next)
670 if (strcmp (outsecname, ncr->name) == 0)
671 break;
673 if (ncr == NULL)
674 return;
676 /* This section is one for which cross references are prohibited.
677 Look through the relocations, and see if any of them are to
678 INFO->SYM_NAME. If INFO->SYMNAME is NULL, check for relocations
679 against the section symbol. If INFO->GLOBAL is TRUE, the
680 definition is global, check for relocations against the global
681 symbols. Otherwise check for relocations against the local and
682 section symbols. */
684 symname = info->sym_name;
685 global = info->global;
687 relsize = bfd_get_reloc_upper_bound (abfd, sec);
688 if (relsize < 0)
689 einfo (_("%B%F: could not read relocs: %E\n"), abfd);
690 if (relsize == 0)
691 return;
693 relpp = xmalloc (relsize);
694 relcount = bfd_canonicalize_reloc (abfd, sec, relpp, info->asymbols);
695 if (relcount < 0)
696 einfo (_("%B%F: could not read relocs: %E\n"), abfd);
698 p = relpp;
699 pend = p + relcount;
700 for (; p < pend && *p != NULL; p++)
702 arelent *q = *p;
704 if (q->sym_ptr_ptr != NULL
705 && *q->sym_ptr_ptr != NULL
706 && ((global
707 && (bfd_is_und_section (bfd_get_section (*q->sym_ptr_ptr))
708 || bfd_is_com_section (bfd_get_section (*q->sym_ptr_ptr))
709 || ((*q->sym_ptr_ptr)->flags & (BSF_GLOBAL
710 | BSF_WEAK)) != 0))
711 || (!global
712 && ((*q->sym_ptr_ptr)->flags & (BSF_LOCAL
713 | BSF_SECTION_SYM)) != 0))
714 && (symname != NULL
715 ? strcmp (bfd_asymbol_name (*q->sym_ptr_ptr), symname) == 0
716 : (((*q->sym_ptr_ptr)->flags & BSF_SECTION_SYM) != 0
717 && bfd_get_section (*q->sym_ptr_ptr) == info->defsec)))
719 /* We found a reloc for the symbol. The symbol is defined
720 in OUTSECNAME. This reloc is from a section which is
721 mapped into a section from which references to OUTSECNAME
722 are prohibited. We must report an error. */
723 einfo (_("%X%C: prohibited cross reference from %s to `%T' in %s\n"),
724 abfd, sec, q->address, outsecname,
725 bfd_asymbol_name (*q->sym_ptr_ptr), outdefsecname);
729 free (relpp);