Fixtypos in ChangeLogs, fix copyright dates in files
[external/binutils.git] / ld / ldcref.c
1 /* ldcref.c -- output a cross reference table
2    Copyright 1996, 1997, 1998, 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   /* 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 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 boolean check_nocrossref PARAMS ((struct cref_hash_entry *, PTR));
76 static void check_refs
77   PARAMS ((struct cref_hash_entry *, struct bfd_link_hash_entry *,
78            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     (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 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 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
347 /* Check one symbol to see if it is a prohibited cross reference.  */
348
349 static boolean
350 check_nocrossref (h, ignore)
351      struct cref_hash_entry *h;
352      PTR ignore ATTRIBUTE_UNUSED;
353 {
354   struct bfd_link_hash_entry *hl;
355   asection *defsec;
356   const char *defsecname;
357   struct lang_nocrossrefs *ncrs;
358   struct lang_nocrossref *ncr;
359
360   hl = bfd_link_hash_lookup (link_info.hash, h->root.string, false,
361                              false, true);
362   if (hl == NULL)
363     {
364       einfo (_("%P: symbol `%T' missing from main hash table\n"),
365              h->root.string);
366       return true;
367     }
368
369   if (hl->type != bfd_link_hash_defined
370       && hl->type != bfd_link_hash_defweak)
371     return true;
372
373   defsec = hl->u.def.section->output_section;
374   if (defsec == NULL)
375     return true;
376   defsecname = bfd_get_section_name (defsec->owner, defsec);
377
378   for (ncrs = nocrossref_list; ncrs != NULL; ncrs = ncrs->next)
379     for (ncr = ncrs->list; ncr != NULL; ncr = ncr->next)
380       if (strcmp (ncr->name, defsecname) == 0)
381         check_refs (h, hl, ncrs);
382
383   return true;
384 }
385
386 /* The struct is used to pass information from check_refs to
387    check_reloc_refs through bfd_map_over_sections.  */
388
389 struct check_refs_info {
390   struct cref_hash_entry *h;
391   asection *defsec;
392   struct lang_nocrossrefs *ncrs;
393   asymbol **asymbols;
394   boolean same;
395 };
396
397 /* This function is called for each symbol defined in a section which
398    prohibits cross references.  We need to look through all references
399    to this symbol, and ensure that the references are not from
400    prohibited sections.  */
401
402 static void
403 check_refs (h, hl, ncrs)
404      struct cref_hash_entry *h;
405      struct bfd_link_hash_entry *hl;
406      struct lang_nocrossrefs *ncrs;
407 {
408   struct cref_ref *ref;
409
410   for (ref = h->refs; ref != NULL; ref = ref->next)
411     {
412       lang_input_statement_type *li;
413       asymbol **asymbols;
414       struct check_refs_info info;
415
416       /* We need to look through the relocations for this BFD, to see
417          if any of the relocations which refer to this symbol are from
418          a prohibited section.  Note that we need to do this even for
419          the BFD in which the symbol is defined, since even a single
420          BFD might contain a prohibited cross reference; for this
421          case, we set the SAME field in INFO, which will cause
422          CHECK_RELOCS_REFS to check for relocations against the
423          section as well as against the symbol.  */
424
425       li = (lang_input_statement_type *) ref->abfd->usrdata;
426       if (li != NULL && li->asymbols != NULL)
427         asymbols = li->asymbols;
428       else
429         {
430           long symsize;
431           long symbol_count;
432
433           symsize = bfd_get_symtab_upper_bound (ref->abfd);
434           if (symsize < 0)
435             einfo (_("%B%F: could not read symbols; %E\n"), ref->abfd);
436           asymbols = (asymbol **) xmalloc (symsize);
437           symbol_count = bfd_canonicalize_symtab (ref->abfd, asymbols);
438           if (symbol_count < 0)
439             einfo (_("%B%F: could not read symbols: %E\n"), ref->abfd);
440           if (li != NULL)
441             {
442               li->asymbols = asymbols;
443               li->symbol_count = symbol_count;
444             }
445         }
446
447       info.h = h;
448       info.defsec = hl->u.def.section;
449       info.ncrs = ncrs;
450       info.asymbols = asymbols;
451       if (ref->abfd == hl->u.def.section->owner)
452         info.same = true;
453       else
454         info.same = false;
455       bfd_map_over_sections (ref->abfd, check_reloc_refs, (PTR) &info);
456
457       if (li == NULL)
458         free (asymbols);
459     }
460 }
461
462 /* This is called via bfd_map_over_sections.  INFO->H is a symbol
463    defined in INFO->DEFSECNAME.  If this section maps into any of the
464    sections listed in INFO->NCRS, other than INFO->DEFSECNAME, then we
465    look through the relocations.  If any of the relocations are to
466    INFO->H, then we report a prohibited cross reference error.  */
467
468 static void
469 check_reloc_refs (abfd, sec, iarg)
470      bfd *abfd;
471      asection *sec;
472      PTR iarg;
473 {
474   struct check_refs_info *info = (struct check_refs_info *) iarg;
475   asection *outsec;
476   const char *outsecname;
477   asection *outdefsec;
478   const char *outdefsecname;
479   struct lang_nocrossref *ncr;
480   const char *symname;
481   long relsize;
482   arelent **relpp;
483   long relcount;
484   arelent **p, **pend;
485
486   outsec = sec->output_section;
487   outsecname = bfd_get_section_name (outsec->owner, outsec);
488
489   outdefsec = info->defsec->output_section;
490   outdefsecname = bfd_get_section_name (outdefsec->owner, outdefsec);
491
492   /* The section where the symbol is defined is permitted.  */
493   if (strcmp (outsecname, outdefsecname) == 0)
494     return;
495
496   for (ncr = info->ncrs->list; ncr != NULL; ncr = ncr->next)
497     if (strcmp (outsecname, ncr->name) == 0)
498       break;
499
500   if (ncr == NULL)
501     return;
502
503   /* This section is one for which cross references are prohibited.
504      Look through the relocations, and see if any of them are to
505      INFO->H.  */
506
507   symname = info->h->root.string;
508
509   relsize = bfd_get_reloc_upper_bound (abfd, sec);
510   if (relsize < 0)
511     einfo (_("%B%F: could not read relocs: %E\n"), abfd);
512   if (relsize == 0)
513     return;
514
515   relpp = (arelent **) xmalloc (relsize);
516   relcount = bfd_canonicalize_reloc (abfd, sec, relpp, info->asymbols);
517   if (relcount < 0)
518     einfo (_("%B%F: could not read relocs: %E\n"), abfd);
519
520   p = relpp;
521   pend = p + relcount;
522   for (; p < pend && *p != NULL; p++)
523     {
524       arelent *q = *p;
525
526       if (q->sym_ptr_ptr != NULL
527           && *q->sym_ptr_ptr != NULL
528           && (strcmp (bfd_asymbol_name (*q->sym_ptr_ptr), symname) == 0
529               || (info->same
530                   && bfd_get_section (*q->sym_ptr_ptr) == info->defsec)))
531         {
532           /* We found a reloc for the symbol.  The symbol is defined
533              in OUTSECNAME.  This reloc is from a section which is
534              mapped into a section from which references to OUTSECNAME
535              are prohibited.  We must report an error.  */
536           einfo (_("%X%C: prohibited cross reference from %s to `%T' in %s\n"),
537                  abfd, sec, q->address, outsecname,
538                  bfd_asymbol_name (*q->sym_ptr_ptr), outdefsecname);
539         }
540     }
541
542   free (relpp);
543 }