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