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>
5
6This file is part of GLD, the Gnu Linker.
7
8This program is free software; you can redistribute it and/or modify
9it under the terms of the GNU General Public License as published by
10the Free Software Foundation; either version 2 of the License, or
11(at your option) any later version.
12
13This program is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19along with this program; if not, write to the Free Software
20Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
21
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.  */
25
26#include "sysdep.h"
27#include "bfd.h"
28#include "bfdlink.h"
29#include "libiberty.h"
30#include "demangle.h"
31#include "objalloc.h"
32
33#include "ld.h"
34#include "ldmain.h"
35#include "ldmisc.h"
36#include "ldexp.h"
37#include "ldlang.h"
38
39/* We keep an instance of this structure for each reference to a
40   symbol from a given object.  */
41
42struct cref_ref {
43  /* The next reference.  */
44  struct cref_ref *next;
45  /* The object.  */
46  bfd *abfd;
47  /* True if the symbol is defined.  */
48  unsigned int def : 1;
49  /* True if the symbol is common.  */
50  unsigned int common : 1;
51  /* True if the symbol is undefined.  */
52  unsigned int undef : 1;
53};
54
55/* We keep a hash table of symbols.  Each entry looks like this.  */
56
57struct 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;
63};
64
65/* This is what the hash table looks like.  */
66
67struct cref_hash_table {
68  struct bfd_hash_table root;
69};
70
71/* Forward declarations.  */
72
73static void output_one_cref (FILE *, struct cref_hash_entry *);
74static void check_local_sym_xref (lang_input_statement_type *);
75static bfd_boolean check_nocrossref (struct cref_hash_entry *, void *);
76static void check_refs (const char *, bfd_boolean, asection *, bfd *,
77			struct lang_nocrossrefs *);
78static void check_reloc_refs (bfd *, asection *, void *);
79
80/* Look up an entry in the cref hash table.  */
81
82#define cref_hash_lookup(table, string, create, copy)		\
83  ((struct cref_hash_entry *)					\
84   bfd_hash_lookup (&(table)->root, (string), (create), (copy)))
85
86/* Traverse the cref hash table.  */
87
88#define cref_hash_traverse(table, func, info)				\
89  (bfd_hash_traverse							\
90   (&(table)->root,							\
91    (bfd_boolean (*) (struct bfd_hash_entry *, void *)) (func),		\
92    (info)))
93
94/* The cref hash table.  */
95
96static struct cref_hash_table cref_table;
97
98/* Whether the cref hash table has been initialized.  */
99
100static bfd_boolean cref_initialized;
101
102/* The number of symbols seen so far.  */
103
104static size_t cref_symcount;
105
106/* Used to take a snapshot of the cref hash table when starting to
107   add syms from an as-needed library.  */
108static struct bfd_hash_entry **old_table;
109static unsigned int old_size;
110static unsigned int old_count;
111static void *old_tab;
112static void *alloc_mark;
113static size_t tabsize, entsize, refsize;
114static size_t old_symcount;
115
116/* Create an entry in a cref hash table.  */
117
118static struct bfd_hash_entry *
119cref_hash_newfunc (struct bfd_hash_entry *entry,
120		   struct bfd_hash_table *table,
121		   const char *string)
122{
123  struct cref_hash_entry *ret = (struct cref_hash_entry *) entry;
124
125  /* Allocate the structure if it has not already been allocated by a
126     subclass.  */
127  if (ret == NULL)
128    ret = ((struct cref_hash_entry *)
129	   bfd_hash_allocate (table, sizeof (struct cref_hash_entry)));
130  if (ret == NULL)
131    return NULL;
132
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));
136  if (ret != NULL)
137    {
138      /* Set local fields.  */
139      ret->demangled = NULL;
140      ret->refs = NULL;
141
142      /* Keep a count of the number of entries created in the hash
143	 table.  */
144      ++cref_symcount;
145    }
146
147  return &ret->root;
148}
149
150/* Add a symbol to the cref hash table.  This is called for every
151   global symbol that is seen during the link.  */
152
153void
154add_cref (const char *name,
155	  bfd *abfd,
156	  asection *section,
157	  bfd_vma value ATTRIBUTE_UNUSED)
158{
159  struct cref_hash_entry *h;
160  struct cref_ref *r;
161
162  if (! cref_initialized)
163    {
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;
168    }
169
170  h = cref_hash_lookup (&cref_table, name, TRUE, FALSE);
171  if (h == NULL)
172    einfo (_("%X%P: cref_hash_lookup failed: %E\n"));
173
174  for (r = h->refs; r != NULL; r = r->next)
175    if (r->abfd == abfd)
176      break;
177
178  if (r == NULL)
179    {
180      r = bfd_hash_allocate (&cref_table.root, sizeof *r);
181      if (r == NULL)
182	einfo (_("%X%P: cref alloc failed: %E\n"));
183      r->next = h->refs;
184      h->refs = r;
185      r->abfd = abfd;
186      r->def = FALSE;
187      r->common = FALSE;
188      r->undef = FALSE;
189    }
190
191  if (bfd_is_und_section (section))
192    r->undef = TRUE;
193  else if (bfd_is_com_section (section))
194    r->common = TRUE;
195  else
196    r->def = TRUE;
197}
198
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.  */
202
203bfd_boolean
204handle_asneeded_cref (bfd *abfd ATTRIBUTE_UNUSED,
205		      enum notice_asneeded_action act)
206{
207  unsigned int i;
208
209  if (!cref_initialized)
210    return TRUE;
211
212  if (act == notice_as_needed)
213    {
214      char *old_ent, *old_ref;
215
216      for (i = 0; i < cref_table.root.size; i++)
217	{
218	  struct bfd_hash_entry *p;
219	  struct cref_hash_entry *c;
220	  struct cref_ref *r;
221
222	  for (p = cref_table.root.table[i]; p != NULL; p = p->next)
223	    {
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);
228	    }
229	}
230
231      tabsize = cref_table.root.size * sizeof (struct bfd_hash_entry *);
232      old_tab = xmalloc (tabsize + entsize + refsize);
233
234      alloc_mark = bfd_hash_allocate (&cref_table.root, 1);
235      if (alloc_mark == NULL)
236	return FALSE;
237
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;
245
246      for (i = 0; i < cref_table.root.size; i++)
247	{
248	  struct bfd_hash_entry *p;
249	  struct cref_hash_entry *c;
250	  struct cref_ref *r;
251
252	  for (p = cref_table.root.table[i]; p != NULL; p = p->next)
253	    {
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)
258		{
259		  memcpy (old_ref, r, sizeof (struct cref_hash_entry));
260		  old_ref = (char *) old_ref + sizeof (struct cref_hash_entry);
261		}
262	    }
263	}
264      return TRUE;
265    }
266
267  if (act == notice_not_needed)
268    {
269      char *old_ent, *old_ref;
270
271      if (old_tab == NULL)
272	{
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;
277	  return TRUE;
278	}
279
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;
287
288      for (i = 0; i < cref_table.root.size; i++)
289	{
290	  struct bfd_hash_entry *p;
291	  struct cref_hash_entry *c;
292	  struct cref_ref *r;
293
294	  for (p = cref_table.root.table[i]; p != NULL; p = p->next)
295	    {
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)
300		{
301		  memcpy (r, old_ref, sizeof (struct cref_hash_entry));
302		  old_ref = (char *) old_ref + sizeof (struct cref_hash_entry);
303		}
304	    }
305	}
306
307      objalloc_free_block ((struct objalloc *) cref_table.root.memory,
308			   alloc_mark);
309    }
310  else if (act != notice_needed)
311    return FALSE;
312
313  free (old_tab);
314  old_tab = NULL;
315  return TRUE;
316}
317
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
320   name.  */
321
322static bfd_boolean
323cref_fill_array (struct cref_hash_entry *h, void *data)
324{
325  struct cref_hash_entry ***pph = data;
326
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;
332
333  **pph = h;
334
335  ++*pph;
336
337  return TRUE;
338}
339
340/* Sort an array of cref hash table entries by name.  */
341
342static int
343cref_sort_array (const void *a1, const void *a2)
344{
345  const struct cref_hash_entry * const *p1 = a1;
346  const struct cref_hash_entry * const *p2 = a2;
347
348  return strcmp ((*p1)->demangled, (*p2)->demangled);
349}
350
351/* Write out the cref table.  */
352
353#define FILECOL (50)
354
355void
356output_cref (FILE *fp)
357{
358  int len;
359  struct cref_hash_entry **csyms, **csym_fill, **csym, **csym_end;
360  const char *msg;
361
362  fprintf (fp, _("\nCross Reference Table\n\n"));
363  msg = _("Symbol");
364  fprintf (fp, "%s", msg);
365  len = strlen (msg);
366  while (len < FILECOL)
367    {
368      putc (' ', fp);
369      ++len;
370    }
371  fprintf (fp, _("File\n"));
372
373  if (! cref_initialized)
374    {
375      fprintf (fp, _("No symbols\n"));
376      return;
377    }
378
379  csyms = xmalloc (cref_symcount * sizeof (*csyms));
380
381  csym_fill = csyms;
382  cref_hash_traverse (&cref_table, cref_fill_array, &csym_fill);
383  ASSERT ((size_t) (csym_fill - csyms) == cref_symcount);
384
385  qsort (csyms, cref_symcount, sizeof (*csyms), cref_sort_array);
386
387  csym_end = csyms + cref_symcount;
388  for (csym = csyms; csym < csym_end; csym++)
389    output_one_cref (fp, *csym);
390}
391
392/* Output one entry in the cross reference table.  */
393
394static void
395output_one_cref (FILE *fp, struct cref_hash_entry *h)
396{
397  int len;
398  struct bfd_link_hash_entry *hl;
399  struct cref_ref *r;
400
401  hl = bfd_link_hash_lookup (link_info.hash, h->root.string, FALSE,
402			     FALSE, TRUE);
403  if (hl == NULL)
404    einfo ("%P: symbol `%T' missing from main hash table\n",
405	   h->root.string);
406  else
407    {
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)
411	{
412	  if (hl->u.def.section->output_section == NULL)
413	    return;
414	  if (hl->u.def.section->owner != NULL
415	      && (hl->u.def.section->owner->flags & DYNAMIC) != 0)
416	    {
417	      for (r = h->refs; r != NULL; r = r->next)
418		if ((r->abfd->flags & DYNAMIC) == 0)
419		  break;
420	      if (r == NULL)
421		return;
422	    }
423	}
424    }
425
426  fprintf (fp, "%s ", h->demangled);
427  len = strlen (h->demangled) + 1;
428
429  for (r = h->refs; r != NULL; r = r->next)
430    {
431      if (r->def)
432	{
433	  while (len < FILECOL)
434	    {
435	      putc (' ', fp);
436	      ++len;
437	    }
438	  lfinfo (fp, "%B\n", r->abfd);
439	  len = 0;
440	}
441    }
442
443  for (r = h->refs; r != NULL; r = r->next)
444    {
445      if (! r->def)
446	{
447	  while (len < FILECOL)
448	    {
449	      putc (' ', fp);
450	      ++len;
451	    }
452	  lfinfo (fp, "%B\n", r->abfd);
453	  len = 0;
454	}
455    }
456
457  ASSERT (len == 0);
458}
459
460/* Check for prohibited cross references.  */
461
462void
463check_nocrossrefs (void)
464{
465  if (! cref_initialized)
466    return;
467
468  cref_hash_traverse (&cref_table, check_nocrossref, NULL);
469
470  lang_for_each_file (check_local_sym_xref);
471}
472
473/* Check for prohibited cross references to local and section symbols.  */
474
475static void
476check_local_sym_xref (lang_input_statement_type *statement)
477{
478  bfd *abfd;
479  lang_input_statement_type *li;
480  asymbol **asymbols, **syms;
481
482  abfd = statement->the_bfd;
483  if (abfd == NULL)
484    return;
485
486  li = abfd->usrdata;
487  if (li != NULL && li->asymbols != NULL)
488    asymbols = li->asymbols;
489  else
490    {
491      long symsize;
492      long symbol_count;
493
494      symsize = bfd_get_symtab_upper_bound (abfd);
495      if (symsize < 0)
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);
501      if (li != NULL)
502	{
503	  li->asymbols = asymbols;
504	  li->symbol_count = symbol_count;
505	}
506    }
507
508  for (syms = asymbols; *syms; ++syms)
509    {
510      asymbol *sym = *syms;
511      if (sym->flags & (BSF_GLOBAL | BSF_WARNING | BSF_INDIRECT | BSF_FILE))
512	continue;
513      if ((sym->flags & (BSF_LOCAL | BSF_SECTION_SYM)) != 0
514	  && sym->section->output_section != NULL)
515	{
516	  const char *outsecname, *symname;
517	  struct lang_nocrossrefs *ncrs;
518	  struct lang_nocrossref *ncr;
519
520	  outsecname = sym->section->output_section->name;
521	  symname = NULL;
522	  if ((sym->flags & BSF_SECTION_SYM) == 0)
523	    symname = sym->name;
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);
528	}
529    }
530
531  if (li == NULL)
532    free (asymbols);
533}
534
535/* Check one symbol to see if it is a prohibited cross reference.  */
536
537static bfd_boolean
538check_nocrossref (struct cref_hash_entry *h, void *ignore ATTRIBUTE_UNUSED)
539{
540  struct bfd_link_hash_entry *hl;
541  asection *defsec;
542  const char *defsecname;
543  struct lang_nocrossrefs *ncrs;
544  struct lang_nocrossref *ncr;
545  struct cref_ref *ref;
546
547  hl = bfd_link_hash_lookup (link_info.hash, h->root.string, FALSE,
548			     FALSE, TRUE);
549  if (hl == NULL)
550    {
551      einfo (_("%P: symbol `%T' missing from main hash table\n"),
552	     h->root.string);
553      return TRUE;
554    }
555
556  if (hl->type != bfd_link_hash_defined
557      && hl->type != bfd_link_hash_defweak)
558    return TRUE;
559
560  defsec = hl->u.def.section->output_section;
561  if (defsec == NULL)
562    return TRUE;
563  defsecname = bfd_get_section_name (defsec->owner, defsec);
564
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,
570		      ref->abfd, ncrs);
571
572  return TRUE;
573}
574
575/* The struct is used to pass information from check_refs to
576   check_reloc_refs through bfd_map_over_sections.  */
577
578struct check_refs_info {
579  const char *sym_name;
580  asection *defsec;
581  struct lang_nocrossrefs *ncrs;
582  asymbol **asymbols;
583  bfd_boolean global;
584};
585
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.  */
590
591static void
592check_refs (const char *name,
593	    bfd_boolean global,
594	    asection *sec,
595	    bfd *abfd,
596	    struct lang_nocrossrefs *ncrs)
597{
598  lang_input_statement_type *li;
599  asymbol **asymbols;
600  struct check_refs_info info;
601
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.  */
607
608  li = abfd->usrdata;
609  if (li != NULL && li->asymbols != NULL)
610    asymbols = li->asymbols;
611  else
612    {
613      long symsize;
614      long symbol_count;
615
616      symsize = bfd_get_symtab_upper_bound (abfd);
617      if (symsize < 0)
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);
623      if (li != NULL)
624	{
625	  li->asymbols = asymbols;
626	  li->symbol_count = symbol_count;
627	}
628    }
629
630  info.sym_name = name;
631  info.global = global;
632  info.defsec = sec;
633  info.ncrs = ncrs;
634  info.asymbols = asymbols;
635  bfd_map_over_sections (abfd, check_reloc_refs, &info);
636
637  if (li == NULL)
638    free (asymbols);
639}
640
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.  */
646
647static void
648check_reloc_refs (bfd *abfd, asection *sec, void *iarg)
649{
650  struct check_refs_info *info = iarg;
651  asection *outsec;
652  const char *outsecname;
653  asection *outdefsec;
654  const char *outdefsecname;
655  struct lang_nocrossref *ncr;
656  const char *symname;
657  bfd_boolean global;
658  long relsize;
659  arelent **relpp;
660  long relcount;
661  arelent **p, **pend;
662
663  outsec = sec->output_section;
664  outsecname = bfd_get_section_name (outsec->owner, outsec);
665
666  outdefsec = info->defsec->output_section;
667  outdefsecname = bfd_get_section_name (outdefsec->owner, outdefsec);
668
669  /* The section where the symbol is defined is permitted.  */
670  if (strcmp (outsecname, outdefsecname) == 0)
671    return;
672
673  for (ncr = info->ncrs->list; ncr != NULL; ncr = ncr->next)
674    if (strcmp (outsecname, ncr->name) == 0)
675      break;
676
677  if (ncr == NULL)
678    return;
679
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
686     section symbols.  */
687
688  symname = info->sym_name;
689  global = info->global;
690
691  relsize = bfd_get_reloc_upper_bound (abfd, sec);
692  if (relsize < 0)
693    einfo (_("%B%F: could not read relocs: %E\n"), abfd);
694  if (relsize == 0)
695    return;
696
697  relpp = xmalloc (relsize);
698  relcount = bfd_canonicalize_reloc (abfd, sec, relpp, info->asymbols);
699  if (relcount < 0)
700    einfo (_("%B%F: could not read relocs: %E\n"), abfd);
701
702  p = relpp;
703  pend = p + relcount;
704  for (; p < pend && *p != NULL; p++)
705    {
706      arelent *q = *p;
707
708      if (q->sym_ptr_ptr != NULL
709	  && *q->sym_ptr_ptr != NULL
710	  && ((global
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
714						   | BSF_WEAK)) != 0))
715	      || (!global
716		  && ((*q->sym_ptr_ptr)->flags & (BSF_LOCAL
717						  | BSF_SECTION_SYM)) != 0
718		  && bfd_get_section (*q->sym_ptr_ptr) == info->defsec))
719	  && (symname != NULL
720	      ? strcmp (bfd_asymbol_name (*q->sym_ptr_ptr), symname) == 0
721	      : ((*q->sym_ptr_ptr)->flags & BSF_SECTION_SYM) != 0))
722	{
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);
730	}
731    }
732
733  free (relpp);
734}
735