2005-10-05 H.J. Lu <hongjiu.lu@intel.com>
[platform/upstream/binutils.git] / ld / ldcref.c
1 /* ldcref.c -- output a cross reference table
2    Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
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         einfo (_("%X%P: bfd_hash_table_init of cref table failed: %E\n"));
154       cref_initialized = TRUE;
155     }
156
157   h = cref_hash_lookup (&cref_table, name, TRUE, FALSE);
158   if (h == NULL)
159     einfo (_("%X%P: cref_hash_lookup failed: %E\n"));
160
161   for (r = h->refs; r != NULL; r = r->next)
162     if (r->abfd == abfd)
163       break;
164
165   if (r == NULL)
166     {
167       r = xmalloc (sizeof *r);
168       r->next = h->refs;
169       h->refs = r;
170       r->abfd = abfd;
171       r->def = FALSE;
172       r->common = FALSE;
173       r->undef = FALSE;
174     }
175
176   if (bfd_is_und_section (section))
177     r->undef = TRUE;
178   else if (bfd_is_com_section (section))
179     r->common = TRUE;
180   else
181     r->def = TRUE;
182 }
183
184 /* Copy the addresses of the hash table entries into an array.  This
185    is called via cref_hash_traverse.  We also fill in the demangled
186    name.  */
187
188 static bfd_boolean
189 cref_fill_array (struct cref_hash_entry *h, void *data)
190 {
191   struct cref_hash_entry ***pph = data;
192
193   ASSERT (h->demangled == NULL);
194   h->demangled = demangle (h->root.string);
195
196   **pph = h;
197
198   ++*pph;
199
200   return TRUE;
201 }
202
203 /* Sort an array of cref hash table entries by name.  */
204
205 static int
206 cref_sort_array (const void *a1, const void *a2)
207 {
208   const struct cref_hash_entry * const *p1 = a1;
209   const struct cref_hash_entry * const *p2 = a2;
210
211   return strcmp ((*p1)->demangled, (*p2)->demangled);
212 }
213
214 /* Write out the cref table.  */
215
216 #define FILECOL (50)
217
218 void
219 output_cref (FILE *fp)
220 {
221   int len;
222   struct cref_hash_entry **csyms, **csym_fill, **csym, **csym_end;
223   const char *msg;
224
225   fprintf (fp, _("\nCross Reference Table\n\n"));
226   msg = _("Symbol");
227   fprintf (fp, "%s", msg);
228   len = strlen (msg);
229   while (len < FILECOL)
230     {
231       putc (' ', fp);
232       ++len;
233     }
234   fprintf (fp, _("File\n"));
235
236   if (! cref_initialized)
237     {
238       fprintf (fp, _("No symbols\n"));
239       return;
240     }
241
242   csyms = xmalloc (cref_symcount * sizeof (*csyms));
243
244   csym_fill = csyms;
245   cref_hash_traverse (&cref_table, cref_fill_array, &csym_fill);
246   ASSERT ((size_t) (csym_fill - csyms) == cref_symcount);
247
248   qsort (csyms, cref_symcount, sizeof (*csyms), cref_sort_array);
249
250   csym_end = csyms + cref_symcount;
251   for (csym = csyms; csym < csym_end; csym++)
252     output_one_cref (fp, *csym);
253 }
254
255 /* Output one entry in the cross reference table.  */
256
257 static void
258 output_one_cref (FILE *fp, struct cref_hash_entry *h)
259 {
260   int len;
261   struct bfd_link_hash_entry *hl;
262   struct cref_ref *r;
263
264   hl = bfd_link_hash_lookup (link_info.hash, h->root.string, FALSE,
265                              FALSE, TRUE);
266   if (hl == NULL)
267     einfo ("%P: symbol `%T' missing from main hash table\n",
268            h->root.string);
269   else
270     {
271       /* If this symbol is defined in a dynamic object but never
272          referenced by a normal object, then don't print it.  */
273       if (hl->type == bfd_link_hash_defined)
274         {
275           if (hl->u.def.section->output_section == NULL)
276             return;
277           if (hl->u.def.section->owner != NULL
278               && (hl->u.def.section->owner->flags & DYNAMIC) != 0)
279             {
280               for (r = h->refs; r != NULL; r = r->next)
281                 if ((r->abfd->flags & DYNAMIC) == 0)
282                   break;
283               if (r == NULL)
284                 return;
285             }
286         }
287     }
288
289   fprintf (fp, "%s ", h->demangled);
290   len = strlen (h->demangled) + 1;
291
292   for (r = h->refs; r != NULL; r = r->next)
293     {
294       if (r->def)
295         {
296           while (len < FILECOL)
297             {
298               putc (' ', fp);
299               ++len;
300             }
301           lfinfo (fp, "%B\n", r->abfd);
302           len = 0;
303         }
304     }
305
306   for (r = h->refs; r != NULL; r = r->next)
307     {
308       if (! r->def)
309         {
310           while (len < FILECOL)
311             {
312               putc (' ', fp);
313               ++len;
314             }
315           lfinfo (fp, "%B\n", r->abfd);
316           len = 0;
317         }
318     }
319
320   ASSERT (len == 0);
321 }
322
323 /* Check for prohibited cross references.  */
324
325 void
326 check_nocrossrefs (void)
327 {
328   if (! cref_initialized)
329     return;
330
331   cref_hash_traverse (&cref_table, check_nocrossref, NULL);
332
333   lang_for_each_file (check_local_sym_xref);
334 }
335
336 /* Check for prohibited cross references to local and section symbols.  */
337
338 static void
339 check_local_sym_xref (lang_input_statement_type *statement)
340 {
341   bfd *abfd;
342   lang_input_statement_type *li;
343   asymbol **asymbols, **syms;
344
345   abfd = statement->the_bfd;
346   if (abfd == NULL)
347     return;
348
349   li = abfd->usrdata;
350   if (li != NULL && li->asymbols != NULL)
351     asymbols = li->asymbols;
352   else
353     {
354       long symsize;
355       long symbol_count;
356
357       symsize = bfd_get_symtab_upper_bound (abfd);
358       if (symsize < 0)
359         einfo (_("%B%F: could not read symbols; %E\n"), abfd);
360       asymbols = xmalloc (symsize);
361       symbol_count = bfd_canonicalize_symtab (abfd, asymbols);
362       if (symbol_count < 0)
363         einfo (_("%B%F: could not read symbols: %E\n"), abfd);
364       if (li != NULL)
365         {
366           li->asymbols = asymbols;
367           li->symbol_count = symbol_count;
368         }
369     }
370
371   for (syms = asymbols; *syms; ++syms)
372     {
373       asymbol *sym = *syms;
374       if (sym->flags & (BSF_GLOBAL | BSF_WARNING | BSF_INDIRECT | BSF_FILE))
375         continue;
376       if ((sym->flags & (BSF_LOCAL | BSF_SECTION_SYM)) != 0
377           && sym->section->output_section != NULL)
378         {
379           const char *outsecname, *symname;
380           struct lang_nocrossrefs *ncrs;
381           struct lang_nocrossref *ncr;
382
383           outsecname = sym->section->output_section->name;
384           symname = NULL;
385           if ((sym->flags & BSF_SECTION_SYM) == 0)
386             symname = sym->name;
387           for (ncrs = nocrossref_list; ncrs != NULL; ncrs = ncrs->next)
388             for (ncr = ncrs->list; ncr != NULL; ncr = ncr->next)
389               if (strcmp (ncr->name, outsecname) == 0)
390                 check_refs (symname, FALSE, sym->section, abfd, ncrs);
391         }
392     }
393
394   if (li == NULL)
395     free (asymbols);
396 }
397
398 /* Check one symbol to see if it is a prohibited cross reference.  */
399
400 static bfd_boolean
401 check_nocrossref (struct cref_hash_entry *h, void *ignore ATTRIBUTE_UNUSED)
402 {
403   struct bfd_link_hash_entry *hl;
404   asection *defsec;
405   const char *defsecname;
406   struct lang_nocrossrefs *ncrs;
407   struct lang_nocrossref *ncr;
408   struct cref_ref *ref;
409
410   hl = bfd_link_hash_lookup (link_info.hash, h->root.string, FALSE,
411                              FALSE, TRUE);
412   if (hl == NULL)
413     {
414       einfo (_("%P: symbol `%T' missing from main hash table\n"),
415              h->root.string);
416       return TRUE;
417     }
418
419   if (hl->type != bfd_link_hash_defined
420       && hl->type != bfd_link_hash_defweak)
421     return TRUE;
422
423   defsec = hl->u.def.section->output_section;
424   if (defsec == NULL)
425     return TRUE;
426   defsecname = bfd_get_section_name (defsec->owner, defsec);
427
428   for (ncrs = nocrossref_list; ncrs != NULL; ncrs = ncrs->next)
429     for (ncr = ncrs->list; ncr != NULL; ncr = ncr->next)
430       if (strcmp (ncr->name, defsecname) == 0)
431         for (ref = h->refs; ref != NULL; ref = ref->next)
432           check_refs (hl->root.string, TRUE, hl->u.def.section,
433                       ref->abfd, ncrs);
434
435   return TRUE;
436 }
437
438 /* The struct is used to pass information from check_refs to
439    check_reloc_refs through bfd_map_over_sections.  */
440
441 struct check_refs_info {
442   const char *sym_name;
443   asection *defsec;
444   struct lang_nocrossrefs *ncrs;
445   asymbol **asymbols;
446   bfd_boolean global;
447 };
448
449 /* This function is called for each symbol defined in a section which
450    prohibits cross references.  We need to look through all references
451    to this symbol, and ensure that the references are not from
452    prohibited sections.  */
453
454 static void
455 check_refs (const char *name,
456             bfd_boolean global,
457             asection *sec,
458             bfd *abfd,
459             struct lang_nocrossrefs *ncrs)
460 {
461   lang_input_statement_type *li;
462   asymbol **asymbols;
463   struct check_refs_info info;
464
465   /* We need to look through the relocations for this BFD, to see
466      if any of the relocations which refer to this symbol are from
467      a prohibited section.  Note that we need to do this even for
468      the BFD in which the symbol is defined, since even a single
469      BFD might contain a prohibited cross reference.  */
470
471   li = abfd->usrdata;
472   if (li != NULL && li->asymbols != NULL)
473     asymbols = li->asymbols;
474   else
475     {
476       long symsize;
477       long symbol_count;
478
479       symsize = bfd_get_symtab_upper_bound (abfd);
480       if (symsize < 0)
481         einfo (_("%B%F: could not read symbols; %E\n"), abfd);
482       asymbols = xmalloc (symsize);
483       symbol_count = bfd_canonicalize_symtab (abfd, asymbols);
484       if (symbol_count < 0)
485         einfo (_("%B%F: could not read symbols: %E\n"), abfd);
486       if (li != NULL)
487         {
488           li->asymbols = asymbols;
489           li->symbol_count = symbol_count;
490         }
491     }
492
493   info.sym_name = name;
494   info.global = global;
495   info.defsec = sec;
496   info.ncrs = ncrs;
497   info.asymbols = asymbols;
498   bfd_map_over_sections (abfd, check_reloc_refs, &info);
499
500   if (li == NULL)
501     free (asymbols);
502 }
503
504 /* This is called via bfd_map_over_sections.  INFO->SYM_NAME is a symbol
505    defined in INFO->DEFSECNAME.  If this section maps into any of the
506    sections listed in INFO->NCRS, other than INFO->DEFSECNAME, then we
507    look through the relocations.  If any of the relocations are to
508    INFO->SYM_NAME, then we report a prohibited cross reference error.  */
509
510 static void
511 check_reloc_refs (bfd *abfd, asection *sec, void *iarg)
512 {
513   struct check_refs_info *info = iarg;
514   asection *outsec;
515   const char *outsecname;
516   asection *outdefsec;
517   const char *outdefsecname;
518   struct lang_nocrossref *ncr;
519   const char *symname;
520   bfd_boolean global;
521   long relsize;
522   arelent **relpp;
523   long relcount;
524   arelent **p, **pend;
525
526   outsec = sec->output_section;
527   outsecname = bfd_get_section_name (outsec->owner, outsec);
528
529   outdefsec = info->defsec->output_section;
530   outdefsecname = bfd_get_section_name (outdefsec->owner, outdefsec);
531
532   /* The section where the symbol is defined is permitted.  */
533   if (strcmp (outsecname, outdefsecname) == 0)
534     return;
535
536   for (ncr = info->ncrs->list; ncr != NULL; ncr = ncr->next)
537     if (strcmp (outsecname, ncr->name) == 0)
538       break;
539
540   if (ncr == NULL)
541     return;
542
543   /* This section is one for which cross references are prohibited.
544      Look through the relocations, and see if any of them are to
545      INFO->SYM_NAME.  If INFO->SYMNAME is NULL, check for relocations
546      against the section symbol.  If INFO->GLOBAL is TRUE, the
547      definition is global, check for relocations against the global
548      symbols.  Otherwise check for relocations against the local and
549      section symbols.  */
550
551   symname = info->sym_name;
552   global = info->global;
553
554   relsize = bfd_get_reloc_upper_bound (abfd, sec);
555   if (relsize < 0)
556     einfo (_("%B%F: could not read relocs: %E\n"), abfd);
557   if (relsize == 0)
558     return;
559
560   relpp = xmalloc (relsize);
561   relcount = bfd_canonicalize_reloc (abfd, sec, relpp, info->asymbols);
562   if (relcount < 0)
563     einfo (_("%B%F: could not read relocs: %E\n"), abfd);
564
565   p = relpp;
566   pend = p + relcount;
567   for (; p < pend && *p != NULL; p++)
568     {
569       arelent *q = *p;
570
571       if (q->sym_ptr_ptr != NULL
572           && *q->sym_ptr_ptr != NULL
573           && ((global
574                && (bfd_is_und_section (bfd_get_section (*q->sym_ptr_ptr))
575                    || bfd_is_com_section (bfd_get_section (*q->sym_ptr_ptr))
576                    || ((*q->sym_ptr_ptr)->flags & (BSF_GLOBAL
577                                                    | BSF_WEAK)) != 0))
578               || (!global
579                   && ((*q->sym_ptr_ptr)->flags & (BSF_LOCAL
580                                                   | BSF_SECTION_SYM)) != 0))
581           && (symname != NULL
582               ? strcmp (bfd_asymbol_name (*q->sym_ptr_ptr), symname) == 0
583               : (((*q->sym_ptr_ptr)->flags & BSF_SECTION_SYM) != 0
584                  && bfd_get_section (*q->sym_ptr_ptr) == info->defsec)))
585         {
586           /* We found a reloc for the symbol.  The symbol is defined
587              in OUTSECNAME.  This reloc is from a section which is
588              mapped into a section from which references to OUTSECNAME
589              are prohibited.  We must report an error.  */
590           einfo (_("%X%C: prohibited cross reference from %s to `%T' in %s\n"),
591                  abfd, sec, q->address, outsecname,
592                  bfd_asymbol_name (*q->sym_ptr_ptr), outdefsecname);
593         }
594     }
595
596   free (relpp);
597 }