xref: /openbsd/gnu/usr.bin/binutils-2.17/ld/ldcref.c (revision 09467b48)
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>
5 
6 This file is part of GLD, the Gnu Linker.
7 
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.
12 
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.
17 
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.  */
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 "bfd.h"
27 #include "sysdep.h"
28 #include "bfdlink.h"
29 #include "libiberty.h"
30 
31 #include "ld.h"
32 #include "ldmain.h"
33 #include "ldmisc.h"
34 #include "ldexp.h"
35 #include "ldlang.h"
36 
37 /* We keep an instance of this structure for each reference to a
38    symbol from a given object.  */
39 
40 struct cref_ref {
41   /* The next reference.  */
42   struct cref_ref *next;
43   /* The object.  */
44   bfd *abfd;
45   /* True if the symbol is defined.  */
46   unsigned int def : 1;
47   /* True if the symbol is common.  */
48   unsigned int common : 1;
49   /* True if the symbol is undefined.  */
50   unsigned int undef : 1;
51 };
52 
53 /* We keep a hash table of symbols.  Each entry looks like this.  */
54 
55 struct cref_hash_entry {
56   struct bfd_hash_entry root;
57   /* The demangled name.  */
58   char *demangled;
59   /* References to and definitions of this symbol.  */
60   struct cref_ref *refs;
61 };
62 
63 /* This is what the hash table looks like.  */
64 
65 struct cref_hash_table {
66   struct bfd_hash_table root;
67 };
68 
69 /* Forward declarations.  */
70 
71 static void output_one_cref (FILE *, struct cref_hash_entry *);
72 static void check_local_sym_xref (lang_input_statement_type *);
73 static bfd_boolean check_nocrossref (struct cref_hash_entry *, void *);
74 static void check_refs (const char *, bfd_boolean, asection *, bfd *,
75 			struct lang_nocrossrefs *);
76 static void check_reloc_refs (bfd *, asection *, void *);
77 
78 /* Look up an entry in the cref hash table.  */
79 
80 #define cref_hash_lookup(table, string, create, copy)		\
81   ((struct cref_hash_entry *)					\
82    bfd_hash_lookup (&(table)->root, (string), (create), (copy)))
83 
84 /* Traverse the cref hash table.  */
85 
86 #define cref_hash_traverse(table, func, info)				\
87   (bfd_hash_traverse							\
88    (&(table)->root,							\
89     (bfd_boolean (*) (struct bfd_hash_entry *, void *)) (func),		\
90     (info)))
91 
92 /* The cref hash table.  */
93 
94 static struct cref_hash_table cref_table;
95 
96 /* Whether the cref hash table has been initialized.  */
97 
98 static bfd_boolean cref_initialized;
99 
100 /* The number of symbols seen so far.  */
101 
102 static size_t cref_symcount;
103 
104 /* Create an entry in a cref hash table.  */
105 
106 static struct bfd_hash_entry *
107 cref_hash_newfunc (struct bfd_hash_entry *entry,
108 		   struct bfd_hash_table *table,
109 		   const char *string)
110 {
111   struct cref_hash_entry *ret = (struct cref_hash_entry *) entry;
112 
113   /* Allocate the structure if it has not already been allocated by a
114      subclass.  */
115   if (ret == NULL)
116     ret = ((struct cref_hash_entry *)
117 	   bfd_hash_allocate (table, sizeof (struct cref_hash_entry)));
118   if (ret == NULL)
119     return NULL;
120 
121   /* Call the allocation method of the superclass.  */
122   ret = ((struct cref_hash_entry *)
123 	 bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string));
124   if (ret != NULL)
125     {
126       /* Set local fields.  */
127       ret->demangled = NULL;
128       ret->refs = NULL;
129 
130       /* Keep a count of the number of entries created in the hash
131 	 table.  */
132       ++cref_symcount;
133     }
134 
135   return &ret->root;
136 }
137 
138 /* Add a symbol to the cref hash table.  This is called for every
139    global symbol that is seen during the link.  */
140 
141 void
142 add_cref (const char *name,
143 	  bfd *abfd,
144 	  asection *section,
145 	  bfd_vma value ATTRIBUTE_UNUSED)
146 {
147   struct cref_hash_entry *h;
148   struct cref_ref *r;
149 
150   if (! cref_initialized)
151     {
152       if (!bfd_hash_table_init (&cref_table.root, cref_hash_newfunc,
153 				sizeof (struct cref_hash_entry)))
154 	einfo (_("%X%P: bfd_hash_table_init of cref table failed: %E\n"));
155       cref_initialized = TRUE;
156     }
157 
158   h = cref_hash_lookup (&cref_table, name, TRUE, FALSE);
159   if (h == NULL)
160     einfo (_("%X%P: cref_hash_lookup failed: %E\n"));
161 
162   for (r = h->refs; r != NULL; r = r->next)
163     if (r->abfd == abfd)
164       break;
165 
166   if (r == NULL)
167     {
168       r = xmalloc (sizeof *r);
169       r->next = h->refs;
170       h->refs = r;
171       r->abfd = abfd;
172       r->def = FALSE;
173       r->common = FALSE;
174       r->undef = FALSE;
175     }
176 
177   if (bfd_is_und_section (section))
178     r->undef = TRUE;
179   else if (bfd_is_com_section (section))
180     r->common = TRUE;
181   else
182     r->def = TRUE;
183 }
184 
185 /* Copy the addresses of the hash table entries into an array.  This
186    is called via cref_hash_traverse.  We also fill in the demangled
187    name.  */
188 
189 static bfd_boolean
190 cref_fill_array (struct cref_hash_entry *h, void *data)
191 {
192   struct cref_hash_entry ***pph = data;
193 
194   ASSERT (h->demangled == NULL);
195   h->demangled = demangle (h->root.string);
196 
197   **pph = h;
198 
199   ++*pph;
200 
201   return TRUE;
202 }
203 
204 /* Sort an array of cref hash table entries by name.  */
205 
206 static int
207 cref_sort_array (const void *a1, const void *a2)
208 {
209   const struct cref_hash_entry * const *p1 = a1;
210   const struct cref_hash_entry * const *p2 = a2;
211 
212   return strcmp ((*p1)->demangled, (*p2)->demangled);
213 }
214 
215 /* Write out the cref table.  */
216 
217 #define FILECOL (50)
218 
219 void
220 output_cref (FILE *fp)
221 {
222   int len;
223   struct cref_hash_entry **csyms, **csym_fill, **csym, **csym_end;
224   const char *msg;
225 
226   fprintf (fp, _("\nCross Reference Table\n\n"));
227   msg = _("Symbol");
228   fprintf (fp, "%s", msg);
229   len = strlen (msg);
230   while (len < FILECOL)
231     {
232       putc (' ', fp);
233       ++len;
234     }
235   fprintf (fp, _("File\n"));
236 
237   if (! cref_initialized)
238     {
239       fprintf (fp, _("No symbols\n"));
240       return;
241     }
242 
243   csyms = xmalloc (cref_symcount * sizeof (*csyms));
244 
245   csym_fill = csyms;
246   cref_hash_traverse (&cref_table, cref_fill_array, &csym_fill);
247   ASSERT ((size_t) (csym_fill - csyms) == cref_symcount);
248 
249   qsort (csyms, cref_symcount, sizeof (*csyms), cref_sort_array);
250 
251   csym_end = csyms + cref_symcount;
252   for (csym = csyms; csym < csym_end; csym++)
253     output_one_cref (fp, *csym);
254 }
255 
256 /* Output one entry in the cross reference table.  */
257 
258 static void
259 output_one_cref (FILE *fp, struct cref_hash_entry *h)
260 {
261   int len;
262   struct bfd_link_hash_entry *hl;
263   struct cref_ref *r;
264 
265   hl = bfd_link_hash_lookup (link_info.hash, h->root.string, FALSE,
266 			     FALSE, TRUE);
267   if (hl == NULL)
268     einfo ("%P: symbol `%T' missing from main hash table\n",
269 	   h->root.string);
270   else
271     {
272       /* If this symbol is defined in a dynamic object but never
273 	 referenced by a normal object, then don't print it.  */
274       if (hl->type == bfd_link_hash_defined)
275 	{
276 	  if (hl->u.def.section->output_section == NULL)
277 	    return;
278 	  if (hl->u.def.section->owner != NULL
279 	      && (hl->u.def.section->owner->flags & DYNAMIC) != 0)
280 	    {
281 	      for (r = h->refs; r != NULL; r = r->next)
282 		if ((r->abfd->flags & DYNAMIC) == 0)
283 		  break;
284 	      if (r == NULL)
285 		return;
286 	    }
287 	}
288     }
289 
290   fprintf (fp, "%s ", h->demangled);
291   len = strlen (h->demangled) + 1;
292 
293   for (r = h->refs; r != NULL; r = r->next)
294     {
295       if (r->def)
296 	{
297 	  while (len < FILECOL)
298 	    {
299 	      putc (' ', fp);
300 	      ++len;
301 	    }
302 	  lfinfo (fp, "%B\n", r->abfd);
303 	  len = 0;
304 	}
305     }
306 
307   for (r = h->refs; r != NULL; r = r->next)
308     {
309       if (! r->def)
310 	{
311 	  while (len < FILECOL)
312 	    {
313 	      putc (' ', fp);
314 	      ++len;
315 	    }
316 	  lfinfo (fp, "%B\n", r->abfd);
317 	  len = 0;
318 	}
319     }
320 
321   ASSERT (len == 0);
322 }
323 
324 /* Check for prohibited cross references.  */
325 
326 void
327 check_nocrossrefs (void)
328 {
329   if (! cref_initialized)
330     return;
331 
332   cref_hash_traverse (&cref_table, check_nocrossref, NULL);
333 
334   lang_for_each_file (check_local_sym_xref);
335 }
336 
337 /* Check for prohibited cross references to local and section symbols.  */
338 
339 static void
340 check_local_sym_xref (lang_input_statement_type *statement)
341 {
342   bfd *abfd;
343   lang_input_statement_type *li;
344   asymbol **asymbols, **syms;
345 
346   abfd = statement->the_bfd;
347   if (abfd == NULL)
348     return;
349 
350   li = abfd->usrdata;
351   if (li != NULL && li->asymbols != NULL)
352     asymbols = li->asymbols;
353   else
354     {
355       long symsize;
356       long symbol_count;
357 
358       symsize = bfd_get_symtab_upper_bound (abfd);
359       if (symsize < 0)
360 	einfo (_("%B%F: could not read symbols; %E\n"), abfd);
361       asymbols = xmalloc (symsize);
362       symbol_count = bfd_canonicalize_symtab (abfd, asymbols);
363       if (symbol_count < 0)
364 	einfo (_("%B%F: could not read symbols: %E\n"), abfd);
365       if (li != NULL)
366 	{
367 	  li->asymbols = asymbols;
368 	  li->symbol_count = symbol_count;
369 	}
370     }
371 
372   for (syms = asymbols; *syms; ++syms)
373     {
374       asymbol *sym = *syms;
375       if (sym->flags & (BSF_GLOBAL | BSF_WARNING | BSF_INDIRECT | BSF_FILE))
376 	continue;
377       if ((sym->flags & (BSF_LOCAL | BSF_SECTION_SYM)) != 0
378 	  && sym->section->output_section != NULL)
379 	{
380 	  const char *outsecname, *symname;
381 	  struct lang_nocrossrefs *ncrs;
382 	  struct lang_nocrossref *ncr;
383 
384 	  outsecname = sym->section->output_section->name;
385 	  symname = NULL;
386 	  if ((sym->flags & BSF_SECTION_SYM) == 0)
387 	    symname = sym->name;
388 	  for (ncrs = nocrossref_list; ncrs != NULL; ncrs = ncrs->next)
389 	    for (ncr = ncrs->list; ncr != NULL; ncr = ncr->next)
390 	      if (strcmp (ncr->name, outsecname) == 0)
391 		check_refs (symname, FALSE, sym->section, abfd, ncrs);
392 	}
393     }
394 
395   if (li == NULL)
396     free (asymbols);
397 }
398 
399 /* Check one symbol to see if it is a prohibited cross reference.  */
400 
401 static bfd_boolean
402 check_nocrossref (struct cref_hash_entry *h, void *ignore ATTRIBUTE_UNUSED)
403 {
404   struct bfd_link_hash_entry *hl;
405   asection *defsec;
406   const char *defsecname;
407   struct lang_nocrossrefs *ncrs;
408   struct lang_nocrossref *ncr;
409   struct cref_ref *ref;
410 
411   hl = bfd_link_hash_lookup (link_info.hash, h->root.string, FALSE,
412 			     FALSE, TRUE);
413   if (hl == NULL)
414     {
415       einfo (_("%P: symbol `%T' missing from main hash table\n"),
416 	     h->root.string);
417       return TRUE;
418     }
419 
420   if (hl->type != bfd_link_hash_defined
421       && hl->type != bfd_link_hash_defweak)
422     return TRUE;
423 
424   defsec = hl->u.def.section->output_section;
425   if (defsec == NULL)
426     return TRUE;
427   defsecname = bfd_get_section_name (defsec->owner, defsec);
428 
429   for (ncrs = nocrossref_list; ncrs != NULL; ncrs = ncrs->next)
430     for (ncr = ncrs->list; ncr != NULL; ncr = ncr->next)
431       if (strcmp (ncr->name, defsecname) == 0)
432 	for (ref = h->refs; ref != NULL; ref = ref->next)
433 	  check_refs (hl->root.string, TRUE, hl->u.def.section,
434 		      ref->abfd, ncrs);
435 
436   return TRUE;
437 }
438 
439 /* The struct is used to pass information from check_refs to
440    check_reloc_refs through bfd_map_over_sections.  */
441 
442 struct check_refs_info {
443   const char *sym_name;
444   asection *defsec;
445   struct lang_nocrossrefs *ncrs;
446   asymbol **asymbols;
447   bfd_boolean global;
448 };
449 
450 /* This function is called for each symbol defined in a section which
451    prohibits cross references.  We need to look through all references
452    to this symbol, and ensure that the references are not from
453    prohibited sections.  */
454 
455 static void
456 check_refs (const char *name,
457 	    bfd_boolean global,
458 	    asection *sec,
459 	    bfd *abfd,
460 	    struct lang_nocrossrefs *ncrs)
461 {
462   lang_input_statement_type *li;
463   asymbol **asymbols;
464   struct check_refs_info info;
465 
466   /* We need to look through the relocations for this BFD, to see
467      if any of the relocations which refer to this symbol are from
468      a prohibited section.  Note that we need to do this even for
469      the BFD in which the symbol is defined, since even a single
470      BFD might contain a prohibited cross reference.  */
471 
472   li = abfd->usrdata;
473   if (li != NULL && li->asymbols != NULL)
474     asymbols = li->asymbols;
475   else
476     {
477       long symsize;
478       long symbol_count;
479 
480       symsize = bfd_get_symtab_upper_bound (abfd);
481       if (symsize < 0)
482 	einfo (_("%B%F: could not read symbols; %E\n"), abfd);
483       asymbols = xmalloc (symsize);
484       symbol_count = bfd_canonicalize_symtab (abfd, asymbols);
485       if (symbol_count < 0)
486 	einfo (_("%B%F: could not read symbols: %E\n"), abfd);
487       if (li != NULL)
488 	{
489 	  li->asymbols = asymbols;
490 	  li->symbol_count = symbol_count;
491 	}
492     }
493 
494   info.sym_name = name;
495   info.global = global;
496   info.defsec = sec;
497   info.ncrs = ncrs;
498   info.asymbols = asymbols;
499   bfd_map_over_sections (abfd, check_reloc_refs, &info);
500 
501   if (li == NULL)
502     free (asymbols);
503 }
504 
505 /* This is called via bfd_map_over_sections.  INFO->SYM_NAME is a symbol
506    defined in INFO->DEFSECNAME.  If this section maps into any of the
507    sections listed in INFO->NCRS, other than INFO->DEFSECNAME, then we
508    look through the relocations.  If any of the relocations are to
509    INFO->SYM_NAME, then we report a prohibited cross reference error.  */
510 
511 static void
512 check_reloc_refs (bfd *abfd, asection *sec, void *iarg)
513 {
514   struct check_refs_info *info = iarg;
515   asection *outsec;
516   const char *outsecname;
517   asection *outdefsec;
518   const char *outdefsecname;
519   struct lang_nocrossref *ncr;
520   const char *symname;
521   bfd_boolean global;
522   long relsize;
523   arelent **relpp;
524   long relcount;
525   arelent **p, **pend;
526 
527   outsec = sec->output_section;
528   outsecname = bfd_get_section_name (outsec->owner, outsec);
529 
530   outdefsec = info->defsec->output_section;
531   outdefsecname = bfd_get_section_name (outdefsec->owner, outdefsec);
532 
533   /* The section where the symbol is defined is permitted.  */
534   if (strcmp (outsecname, outdefsecname) == 0)
535     return;
536 
537   for (ncr = info->ncrs->list; ncr != NULL; ncr = ncr->next)
538     if (strcmp (outsecname, ncr->name) == 0)
539       break;
540 
541   if (ncr == NULL)
542     return;
543 
544   /* This section is one for which cross references are prohibited.
545      Look through the relocations, and see if any of them are to
546      INFO->SYM_NAME.  If INFO->SYMNAME is NULL, check for relocations
547      against the section symbol.  If INFO->GLOBAL is TRUE, the
548      definition is global, check for relocations against the global
549      symbols.  Otherwise check for relocations against the local and
550      section symbols.  */
551 
552   symname = info->sym_name;
553   global = info->global;
554 
555   relsize = bfd_get_reloc_upper_bound (abfd, sec);
556   if (relsize < 0)
557     einfo (_("%B%F: could not read relocs: %E\n"), abfd);
558   if (relsize == 0)
559     return;
560 
561   relpp = xmalloc (relsize);
562   relcount = bfd_canonicalize_reloc (abfd, sec, relpp, info->asymbols);
563   if (relcount < 0)
564     einfo (_("%B%F: could not read relocs: %E\n"), abfd);
565 
566   p = relpp;
567   pend = p + relcount;
568   for (; p < pend && *p != NULL; p++)
569     {
570       arelent *q = *p;
571 
572       if (q->sym_ptr_ptr != NULL
573 	  && *q->sym_ptr_ptr != NULL
574 	  && ((global
575 	       && (bfd_is_und_section (bfd_get_section (*q->sym_ptr_ptr))
576 		   || bfd_is_com_section (bfd_get_section (*q->sym_ptr_ptr))
577 		   || ((*q->sym_ptr_ptr)->flags & (BSF_GLOBAL
578 						   | BSF_WEAK)) != 0))
579 	      || (!global
580 		  && ((*q->sym_ptr_ptr)->flags & (BSF_LOCAL
581 						  | BSF_SECTION_SYM)) != 0))
582 	  && (symname != NULL
583 	      ? strcmp (bfd_asymbol_name (*q->sym_ptr_ptr), symname) == 0
584 	      : (((*q->sym_ptr_ptr)->flags & BSF_SECTION_SYM) != 0
585 		 && bfd_get_section (*q->sym_ptr_ptr) == info->defsec)))
586 	{
587 	  /* We found a reloc for the symbol.  The symbol is defined
588 	     in OUTSECNAME.  This reloc is from a section which is
589 	     mapped into a section from which references to OUTSECNAME
590 	     are prohibited.  We must report an error.  */
591 	  einfo (_("%X%C: prohibited cross reference from %s to `%T' in %s\n"),
592 		 abfd, sec, q->address, outsecname,
593 		 bfd_asymbol_name (*q->sym_ptr_ptr), outdefsecname);
594 	}
595     }
596 
597   free (relpp);
598 }
599