libpam: Trim sources that create empty objects.
[dragonfly.git] / contrib / binutils-2.24 / ld / ldcref.c
blob56b917d4bfe3597e2f100224fb7bedf6693da034
1 /* ldcref.c -- output a cross reference table
2 Copyright 1996-2013 Free Software Foundation, Inc.
3 Written by Ian Lance Taylor <ian@cygnus.com>
5 This file is part of the GNU Binutils.
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 3 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., 51 Franklin Street - Fifth Floor, Boston,
20 MA 02110-1301, USA. */
23 /* This file holds routines that manage the cross reference table.
24 The table is used to generate cross reference reports. It is also
25 used to implement the NOCROSSREFS command in the linker script. */
27 #include "sysdep.h"
28 #include "bfd.h"
29 #include "bfdlink.h"
30 #include "libiberty.h"
31 #include "demangle.h"
32 #include "objalloc.h"
34 #include "ld.h"
35 #include "ldmain.h"
36 #include "ldmisc.h"
37 #include "ldexp.h"
38 #include "ldlang.h"
40 /* We keep an instance of this structure for each reference to a
41 symbol from a given object. */
43 struct cref_ref {
44 /* The next reference. */
45 struct cref_ref *next;
46 /* The object. */
47 bfd *abfd;
48 /* True if the symbol is defined. */
49 unsigned int def : 1;
50 /* True if the symbol is common. */
51 unsigned int common : 1;
52 /* True if the symbol is undefined. */
53 unsigned int undef : 1;
56 /* We keep a hash table of symbols. Each entry looks like this. */
58 struct cref_hash_entry {
59 struct bfd_hash_entry root;
60 /* The demangled name. */
61 const char *demangled;
62 /* References to and definitions of this symbol. */
63 struct cref_ref *refs;
66 /* This is what the hash table looks like. */
68 struct cref_hash_table {
69 struct bfd_hash_table root;
72 /* Forward declarations. */
74 static void output_one_cref (FILE *, struct cref_hash_entry *);
75 static void check_local_sym_xref (lang_input_statement_type *);
76 static bfd_boolean check_nocrossref (struct cref_hash_entry *, void *);
77 static void check_refs (const char *, bfd_boolean, asection *, bfd *,
78 struct lang_nocrossrefs *);
79 static void check_reloc_refs (bfd *, asection *, void *);
81 /* Look up an entry in the cref hash table. */
83 #define cref_hash_lookup(table, string, create, copy) \
84 ((struct cref_hash_entry *) \
85 bfd_hash_lookup (&(table)->root, (string), (create), (copy)))
87 /* Traverse the cref hash table. */
89 #define cref_hash_traverse(table, func, info) \
90 (bfd_hash_traverse \
91 (&(table)->root, \
92 (bfd_boolean (*) (struct bfd_hash_entry *, void *)) (func), \
93 (info)))
95 /* The cref hash table. */
97 static struct cref_hash_table cref_table;
99 /* Whether the cref hash table has been initialized. */
101 static bfd_boolean cref_initialized;
103 /* The number of symbols seen so far. */
105 static size_t cref_symcount;
107 /* Used to take a snapshot of the cref hash table when starting to
108 add syms from an as-needed library. */
109 static struct bfd_hash_entry **old_table;
110 static unsigned int old_size;
111 static unsigned int old_count;
112 static void *old_tab;
113 static void *alloc_mark;
114 static size_t tabsize, entsize, refsize;
115 static size_t old_symcount;
117 /* Create an entry in a cref hash table. */
119 static struct bfd_hash_entry *
120 cref_hash_newfunc (struct bfd_hash_entry *entry,
121 struct bfd_hash_table *table,
122 const char *string)
124 struct cref_hash_entry *ret = (struct cref_hash_entry *) entry;
126 /* Allocate the structure if it has not already been allocated by a
127 subclass. */
128 if (ret == NULL)
129 ret = ((struct cref_hash_entry *)
130 bfd_hash_allocate (table, sizeof (struct cref_hash_entry)));
131 if (ret == NULL)
132 return NULL;
134 /* Call the allocation method of the superclass. */
135 ret = ((struct cref_hash_entry *)
136 bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string));
137 if (ret != NULL)
139 /* Set local fields. */
140 ret->demangled = NULL;
141 ret->refs = NULL;
143 /* Keep a count of the number of entries created in the hash
144 table. */
145 ++cref_symcount;
148 return &ret->root;
151 /* Add a symbol to the cref hash table. This is called for every
152 global symbol that is seen during the link. */
154 void
155 add_cref (const char *name,
156 bfd *abfd,
157 asection *section,
158 bfd_vma value ATTRIBUTE_UNUSED)
160 struct cref_hash_entry *h;
161 struct cref_ref *r;
163 if (! cref_initialized)
165 if (!bfd_hash_table_init (&cref_table.root, cref_hash_newfunc,
166 sizeof (struct cref_hash_entry)))
167 einfo (_("%X%P: bfd_hash_table_init of cref table failed: %E\n"));
168 cref_initialized = TRUE;
171 h = cref_hash_lookup (&cref_table, name, TRUE, FALSE);
172 if (h == NULL)
173 einfo (_("%X%P: cref_hash_lookup failed: %E\n"));
175 for (r = h->refs; r != NULL; r = r->next)
176 if (r->abfd == abfd)
177 break;
179 if (r == NULL)
181 r = (struct cref_ref *) bfd_hash_allocate (&cref_table.root, sizeof *r);
182 if (r == NULL)
183 einfo (_("%X%P: cref alloc failed: %E\n"));
184 r->next = h->refs;
185 h->refs = r;
186 r->abfd = abfd;
187 r->def = FALSE;
188 r->common = FALSE;
189 r->undef = FALSE;
192 if (bfd_is_und_section (section))
193 r->undef = TRUE;
194 else if (bfd_is_com_section (section))
195 r->common = TRUE;
196 else
197 r->def = TRUE;
200 /* Called before loading an as-needed library to take a snapshot of
201 the cref hash table, and after we have loaded or found that the
202 library was not needed. */
204 bfd_boolean
205 handle_asneeded_cref (bfd *abfd ATTRIBUTE_UNUSED,
206 enum notice_asneeded_action act)
208 unsigned int i;
210 if (!cref_initialized)
211 return TRUE;
213 if (act == notice_as_needed)
215 char *old_ent, *old_ref;
217 for (i = 0; i < cref_table.root.size; i++)
219 struct bfd_hash_entry *p;
220 struct cref_hash_entry *c;
221 struct cref_ref *r;
223 for (p = cref_table.root.table[i]; p != NULL; p = p->next)
225 entsize += cref_table.root.entsize;
226 c = (struct cref_hash_entry *) p;
227 for (r = c->refs; r != NULL; r = r->next)
228 refsize += sizeof (struct cref_ref);
232 tabsize = cref_table.root.size * sizeof (struct bfd_hash_entry *);
233 old_tab = xmalloc (tabsize + entsize + refsize);
235 alloc_mark = bfd_hash_allocate (&cref_table.root, 1);
236 if (alloc_mark == NULL)
237 return FALSE;
239 memcpy (old_tab, cref_table.root.table, tabsize);
240 old_ent = (char *) old_tab + tabsize;
241 old_ref = (char *) old_ent + entsize;
242 old_table = cref_table.root.table;
243 old_size = cref_table.root.size;
244 old_count = cref_table.root.count;
245 old_symcount = cref_symcount;
247 for (i = 0; i < cref_table.root.size; i++)
249 struct bfd_hash_entry *p;
250 struct cref_hash_entry *c;
251 struct cref_ref *r;
253 for (p = cref_table.root.table[i]; p != NULL; p = p->next)
255 memcpy (old_ent, p, cref_table.root.entsize);
256 old_ent = (char *) old_ent + cref_table.root.entsize;
257 c = (struct cref_hash_entry *) p;
258 for (r = c->refs; r != NULL; r = r->next)
260 memcpy (old_ref, r, sizeof (struct cref_ref));
261 old_ref = (char *) old_ref + sizeof (struct cref_ref);
265 return TRUE;
268 if (act == notice_not_needed)
270 char *old_ent, *old_ref;
272 if (old_tab == NULL)
274 /* The only way old_tab can be NULL is if the cref hash table
275 had not been initialised when notice_as_needed. */
276 bfd_hash_table_free (&cref_table.root);
277 cref_initialized = FALSE;
278 return TRUE;
281 old_ent = (char *) old_tab + tabsize;
282 old_ref = (char *) old_ent + entsize;
283 cref_table.root.table = old_table;
284 cref_table.root.size = old_size;
285 cref_table.root.count = old_count;
286 memcpy (cref_table.root.table, old_tab, tabsize);
287 cref_symcount = old_symcount;
289 for (i = 0; i < cref_table.root.size; i++)
291 struct bfd_hash_entry *p;
292 struct cref_hash_entry *c;
293 struct cref_ref *r;
295 for (p = cref_table.root.table[i]; p != NULL; p = p->next)
297 memcpy (p, old_ent, cref_table.root.entsize);
298 old_ent = (char *) old_ent + cref_table.root.entsize;
299 c = (struct cref_hash_entry *) p;
300 for (r = c->refs; r != NULL; r = r->next)
302 memcpy (r, old_ref, sizeof (struct cref_ref));
303 old_ref = (char *) old_ref + sizeof (struct cref_ref);
308 objalloc_free_block ((struct objalloc *) cref_table.root.memory,
309 alloc_mark);
311 else if (act != notice_needed)
312 return FALSE;
314 free (old_tab);
315 old_tab = NULL;
316 return TRUE;
319 /* Copy the addresses of the hash table entries into an array. This
320 is called via cref_hash_traverse. We also fill in the demangled
321 name. */
323 static bfd_boolean
324 cref_fill_array (struct cref_hash_entry *h, void *data)
326 struct cref_hash_entry ***pph = (struct cref_hash_entry ***) data;
328 ASSERT (h->demangled == NULL);
329 h->demangled = bfd_demangle (link_info.output_bfd, h->root.string,
330 DMGL_ANSI | DMGL_PARAMS);
331 if (h->demangled == NULL)
332 h->demangled = h->root.string;
334 **pph = h;
336 ++*pph;
338 return TRUE;
341 /* Sort an array of cref hash table entries by name. */
343 static int
344 cref_sort_array (const void *a1, const void *a2)
346 const struct cref_hash_entry * const *p1 =
347 (const struct cref_hash_entry * const *) a1;
348 const struct cref_hash_entry * const *p2 =
349 (const struct cref_hash_entry * const *) a2;
351 return strcmp ((*p1)->demangled, (*p2)->demangled);
354 /* Write out the cref table. */
356 #define FILECOL (50)
358 void
359 output_cref (FILE *fp)
361 int len;
362 struct cref_hash_entry **csyms, **csym_fill, **csym, **csym_end;
363 const char *msg;
365 fprintf (fp, _("\nCross Reference Table\n\n"));
366 msg = _("Symbol");
367 fprintf (fp, "%s", msg);
368 len = strlen (msg);
369 while (len < FILECOL)
371 putc (' ', fp);
372 ++len;
374 fprintf (fp, _("File\n"));
376 if (! cref_initialized)
378 fprintf (fp, _("No symbols\n"));
379 return;
382 csyms = (struct cref_hash_entry **) xmalloc (cref_symcount * sizeof (*csyms));
384 csym_fill = csyms;
385 cref_hash_traverse (&cref_table, cref_fill_array, &csym_fill);
386 ASSERT ((size_t) (csym_fill - csyms) == cref_symcount);
388 qsort (csyms, cref_symcount, sizeof (*csyms), cref_sort_array);
390 csym_end = csyms + cref_symcount;
391 for (csym = csyms; csym < csym_end; csym++)
392 output_one_cref (fp, *csym);
395 /* Output one entry in the cross reference table. */
397 static void
398 output_one_cref (FILE *fp, struct cref_hash_entry *h)
400 int len;
401 struct bfd_link_hash_entry *hl;
402 struct cref_ref *r;
404 hl = bfd_link_hash_lookup (link_info.hash, h->root.string, FALSE,
405 FALSE, TRUE);
406 if (hl == NULL)
407 einfo ("%P: symbol `%T' missing from main hash table\n",
408 h->root.string);
409 else
411 /* If this symbol is defined in a dynamic object but never
412 referenced by a normal object, then don't print it. */
413 if (hl->type == bfd_link_hash_defined)
415 if (hl->u.def.section->output_section == NULL)
416 return;
417 if (hl->u.def.section->owner != NULL
418 && (hl->u.def.section->owner->flags & DYNAMIC) != 0)
420 for (r = h->refs; r != NULL; r = r->next)
421 if ((r->abfd->flags & DYNAMIC) == 0)
422 break;
423 if (r == NULL)
424 return;
429 fprintf (fp, "%s ", h->demangled);
430 len = strlen (h->demangled) + 1;
432 for (r = h->refs; r != NULL; r = r->next)
434 if (r->def)
436 while (len < FILECOL)
438 putc (' ', fp);
439 ++len;
441 lfinfo (fp, "%B\n", r->abfd);
442 len = 0;
446 for (r = h->refs; r != NULL; r = r->next)
448 if (r->common)
450 while (len < FILECOL)
452 putc (' ', fp);
453 ++len;
455 lfinfo (fp, "%B\n", r->abfd);
456 len = 0;
460 for (r = h->refs; r != NULL; r = r->next)
462 if (! r->def && ! r->common)
464 while (len < FILECOL)
466 putc (' ', fp);
467 ++len;
469 lfinfo (fp, "%B\n", r->abfd);
470 len = 0;
474 ASSERT (len == 0);
477 /* Check for prohibited cross references. */
479 void
480 check_nocrossrefs (void)
482 if (! cref_initialized)
483 return;
485 cref_hash_traverse (&cref_table, check_nocrossref, NULL);
487 lang_for_each_file (check_local_sym_xref);
490 /* Check for prohibited cross references to local and section symbols. */
492 static void
493 check_local_sym_xref (lang_input_statement_type *statement)
495 bfd *abfd;
496 asymbol **syms;
498 abfd = statement->the_bfd;
499 if (abfd == NULL)
500 return;
502 if (!bfd_generic_link_read_symbols (abfd))
503 einfo (_("%B%F: could not read symbols: %E\n"), abfd);
505 for (syms = bfd_get_outsymbols (abfd); *syms; ++syms)
507 asymbol *sym = *syms;
508 if (sym->flags & (BSF_GLOBAL | BSF_WARNING | BSF_INDIRECT | BSF_FILE))
509 continue;
510 if ((sym->flags & (BSF_LOCAL | BSF_SECTION_SYM)) != 0
511 && sym->section->output_section != NULL)
513 const char *outsecname, *symname;
514 struct lang_nocrossrefs *ncrs;
515 struct lang_nocrossref *ncr;
517 outsecname = sym->section->output_section->name;
518 symname = NULL;
519 if ((sym->flags & BSF_SECTION_SYM) == 0)
520 symname = sym->name;
521 for (ncrs = nocrossref_list; ncrs != NULL; ncrs = ncrs->next)
522 for (ncr = ncrs->list; ncr != NULL; ncr = ncr->next)
523 if (strcmp (ncr->name, outsecname) == 0)
524 check_refs (symname, FALSE, sym->section, abfd, ncrs);
529 /* Check one symbol to see if it is a prohibited cross reference. */
531 static bfd_boolean
532 check_nocrossref (struct cref_hash_entry *h, void *ignore ATTRIBUTE_UNUSED)
534 struct bfd_link_hash_entry *hl;
535 asection *defsec;
536 const char *defsecname;
537 struct lang_nocrossrefs *ncrs;
538 struct lang_nocrossref *ncr;
539 struct cref_ref *ref;
541 hl = bfd_link_hash_lookup (link_info.hash, h->root.string, FALSE,
542 FALSE, TRUE);
543 if (hl == NULL)
545 einfo (_("%P: symbol `%T' missing from main hash table\n"),
546 h->root.string);
547 return TRUE;
550 if (hl->type != bfd_link_hash_defined
551 && hl->type != bfd_link_hash_defweak)
552 return TRUE;
554 defsec = hl->u.def.section->output_section;
555 if (defsec == NULL)
556 return TRUE;
557 defsecname = bfd_get_section_name (defsec->owner, defsec);
559 for (ncrs = nocrossref_list; ncrs != NULL; ncrs = ncrs->next)
560 for (ncr = ncrs->list; ncr != NULL; ncr = ncr->next)
561 if (strcmp (ncr->name, defsecname) == 0)
562 for (ref = h->refs; ref != NULL; ref = ref->next)
563 check_refs (hl->root.string, TRUE, hl->u.def.section,
564 ref->abfd, ncrs);
566 return TRUE;
569 /* The struct is used to pass information from check_refs to
570 check_reloc_refs through bfd_map_over_sections. */
572 struct check_refs_info {
573 const char *sym_name;
574 asection *defsec;
575 struct lang_nocrossrefs *ncrs;
576 asymbol **asymbols;
577 bfd_boolean global;
580 /* This function is called for each symbol defined in a section which
581 prohibits cross references. We need to look through all references
582 to this symbol, and ensure that the references are not from
583 prohibited sections. */
585 static void
586 check_refs (const char *name,
587 bfd_boolean global,
588 asection *sec,
589 bfd *abfd,
590 struct lang_nocrossrefs *ncrs)
592 struct check_refs_info info;
594 /* We need to look through the relocations for this BFD, to see
595 if any of the relocations which refer to this symbol are from
596 a prohibited section. Note that we need to do this even for
597 the BFD in which the symbol is defined, since even a single
598 BFD might contain a prohibited cross reference. */
600 if (!bfd_generic_link_read_symbols (abfd))
601 einfo (_("%B%F: could not read symbols: %E\n"), abfd);
603 info.sym_name = name;
604 info.global = global;
605 info.defsec = sec;
606 info.ncrs = ncrs;
607 info.asymbols = bfd_get_outsymbols (abfd);
608 bfd_map_over_sections (abfd, check_reloc_refs, &info);
611 /* This is called via bfd_map_over_sections. INFO->SYM_NAME is a symbol
612 defined in INFO->DEFSECNAME. If this section maps into any of the
613 sections listed in INFO->NCRS, other than INFO->DEFSECNAME, then we
614 look through the relocations. If any of the relocations are to
615 INFO->SYM_NAME, then we report a prohibited cross reference error. */
617 static void
618 check_reloc_refs (bfd *abfd, asection *sec, void *iarg)
620 struct check_refs_info *info = (struct check_refs_info *) iarg;
621 asection *outsec;
622 const char *outsecname;
623 asection *outdefsec;
624 const char *outdefsecname;
625 struct lang_nocrossref *ncr;
626 const char *symname;
627 bfd_boolean global;
628 long relsize;
629 arelent **relpp;
630 long relcount;
631 arelent **p, **pend;
633 outsec = sec->output_section;
634 outsecname = bfd_get_section_name (outsec->owner, outsec);
636 outdefsec = info->defsec->output_section;
637 outdefsecname = bfd_get_section_name (outdefsec->owner, outdefsec);
639 /* The section where the symbol is defined is permitted. */
640 if (strcmp (outsecname, outdefsecname) == 0)
641 return;
643 for (ncr = info->ncrs->list; ncr != NULL; ncr = ncr->next)
644 if (strcmp (outsecname, ncr->name) == 0)
645 break;
647 if (ncr == NULL)
648 return;
650 /* This section is one for which cross references are prohibited.
651 Look through the relocations, and see if any of them are to
652 INFO->SYM_NAME. If INFO->SYMNAME is NULL, check for relocations
653 against the section symbol. If INFO->GLOBAL is TRUE, the
654 definition is global, check for relocations against the global
655 symbols. Otherwise check for relocations against the local and
656 section symbols. */
658 symname = info->sym_name;
659 global = info->global;
661 relsize = bfd_get_reloc_upper_bound (abfd, sec);
662 if (relsize < 0)
663 einfo (_("%B%F: could not read relocs: %E\n"), abfd);
664 if (relsize == 0)
665 return;
667 relpp = (arelent **) xmalloc (relsize);
668 relcount = bfd_canonicalize_reloc (abfd, sec, relpp, info->asymbols);
669 if (relcount < 0)
670 einfo (_("%B%F: could not read relocs: %E\n"), abfd);
672 p = relpp;
673 pend = p + relcount;
674 for (; p < pend && *p != NULL; p++)
676 arelent *q = *p;
678 if (q->sym_ptr_ptr != NULL
679 && *q->sym_ptr_ptr != NULL
680 && ((global
681 && (bfd_is_und_section (bfd_get_section (*q->sym_ptr_ptr))
682 || bfd_is_com_section (bfd_get_section (*q->sym_ptr_ptr))
683 || ((*q->sym_ptr_ptr)->flags & (BSF_GLOBAL
684 | BSF_WEAK)) != 0))
685 || (!global
686 && ((*q->sym_ptr_ptr)->flags & (BSF_LOCAL
687 | BSF_SECTION_SYM)) != 0
688 && bfd_get_section (*q->sym_ptr_ptr) == info->defsec))
689 && (symname != NULL
690 ? strcmp (bfd_asymbol_name (*q->sym_ptr_ptr), symname) == 0
691 : ((*q->sym_ptr_ptr)->flags & BSF_SECTION_SYM) != 0))
693 /* We found a reloc for the symbol. The symbol is defined
694 in OUTSECNAME. This reloc is from a section which is
695 mapped into a section from which references to OUTSECNAME
696 are prohibited. We must report an error. */
697 einfo (_("%X%C: prohibited cross reference from %s to `%T' in %s\n"),
698 abfd, sec, q->address, outsecname,
699 bfd_asymbol_name (*q->sym_ptr_ptr), outdefsecname);
703 free (relpp);