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