* ld.h (check_nocrossrefs): Declare.
[binutils-gdb.git] / ld / ldcref.c
1 /* ldcref.c -- output a cross reference table
2 Copyright (C) 1996 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 /*ARGSUSED*/
149 void
150 add_cref (name, abfd, section, value)
151 const char *name;
152 bfd *abfd;
153 asection *section;
154 bfd_vma value;
155 {
156 struct cref_hash_entry *h;
157 struct cref_ref *r;
158
159 if (! cref_initialized)
160 {
161 if (! bfd_hash_table_init (&cref_table.root, cref_hash_newfunc))
162 einfo ("%X%P: bfd_hash_table_init of cref table failed: %E\n");
163 cref_initialized = true;
164 }
165
166 h = cref_hash_lookup (&cref_table, name, true, false);
167 if (h == NULL)
168 einfo ("%X%P: cref_hash_lookup failed: %E\n");
169
170 for (r = h->refs; r != NULL; r = r->next)
171 if (r->abfd == abfd)
172 break;
173
174 if (r == NULL)
175 {
176 r = (struct cref_ref *) xmalloc (sizeof *r);
177 r->next = h->refs;
178 h->refs = r;
179 r->abfd = abfd;
180 r->def = false;
181 r->common = false;
182 r->undef = false;
183 }
184
185 if (bfd_is_und_section (section))
186 r->undef = true;
187 else if (bfd_is_com_section (section))
188 r->common = true;
189 else
190 r->def = true;
191 }
192
193 /* Copy the addresses of the hash table entries into an array. This
194 is called via cref_hash_traverse. We also fill in the demangled
195 name. */
196
197 static boolean
198 cref_fill_array (h, data)
199 struct cref_hash_entry *h;
200 PTR data;
201 {
202 struct cref_hash_entry ***pph = (struct cref_hash_entry ***) data;
203
204 ASSERT (h->demangled == NULL);
205 h->demangled = demangle (h->root.string);
206
207 **pph = h;
208
209 ++*pph;
210
211 return true;
212 }
213
214 /* Sort an array of cref hash table entries by name. */
215
216 static int
217 cref_sort_array (a1, a2)
218 const PTR a1;
219 const PTR a2;
220 {
221 const struct cref_hash_entry **p1 = (const struct cref_hash_entry **) a1;
222 const struct cref_hash_entry **p2 = (const struct cref_hash_entry **) a2;
223
224 return strcmp ((*p1)->demangled, (*p2)->demangled);
225 }
226
227 /* Write out the cref table. */
228
229 #define FILECOL (50)
230
231 void
232 output_cref (fp)
233 FILE *fp;
234 {
235 int len;
236 struct cref_hash_entry **csyms, **csym_fill, **csym, **csym_end;
237
238 fprintf (fp, "\nCross Reference Table\n\n");
239 fprintf (fp, "Symbol");
240 len = sizeof "Symbol" - 1;
241 while (len < FILECOL)
242 {
243 putc (' ' , fp);
244 ++len;
245 }
246 fprintf (fp, "File\n");
247
248 if (! cref_initialized)
249 {
250 fprintf (fp, "No symbols\n");
251 return;
252 }
253
254 csyms = ((struct cref_hash_entry **)
255 xmalloc (cref_symcount * sizeof (*csyms)));
256
257 csym_fill = csyms;
258 cref_hash_traverse (&cref_table, cref_fill_array, &csym_fill);
259 ASSERT (csym_fill - csyms == cref_symcount);
260
261 qsort (csyms, cref_symcount, sizeof (*csyms), cref_sort_array);
262
263 csym_end = csyms + cref_symcount;
264 for (csym = csyms; csym < csym_end; csym++)
265 output_one_cref (fp, *csym);
266 }
267
268 /* Output one entry in the cross reference table. */
269
270 static void
271 output_one_cref (fp, h)
272 FILE *fp;
273 struct cref_hash_entry *h;
274 {
275 int len;
276 struct bfd_link_hash_entry *hl;
277 struct cref_ref *r;
278
279 hl = bfd_link_hash_lookup (link_info.hash, h->root.string, false,
280 false, true);
281 if (hl == NULL)
282 einfo ("%P: symbol `%T' missing from main hash table\n",
283 h->root.string);
284 else
285 {
286 /* If this symbol is defined in a dynamic object but never
287 referenced by a normal object, then don't print it. */
288 if (hl->type == bfd_link_hash_defined)
289 {
290 if (hl->u.def.section->output_section == NULL)
291 return;
292 if (hl->u.def.section->owner != NULL
293 && (hl->u.def.section->owner->flags & DYNAMIC) != 0)
294 {
295 for (r = h->refs; r != NULL; r = r->next)
296 if ((r->abfd->flags & DYNAMIC) == 0)
297 break;
298 if (r == NULL)
299 return;
300 }
301 }
302 }
303
304 fprintf (fp, "%s ", h->demangled);
305 len = strlen (h->demangled) + 1;
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 finfo (fp, "%B\n", r->abfd);
317 len = 0;
318 }
319 }
320
321 for (r = h->refs; r != NULL; r = r->next)
322 {
323 if (! r->def)
324 {
325 while (len < FILECOL)
326 {
327 putc (' ', fp);
328 ++len;
329 }
330 finfo (fp, "%B\n", r->abfd);
331 len = 0;
332 }
333 }
334
335 ASSERT (len == 0);
336 }
337
338 /* Check for prohibited cross references. */
339
340 void
341 check_nocrossrefs ()
342 {
343 if (! cref_initialized)
344 return;
345
346 cref_hash_traverse (&cref_table, check_nocrossref, (PTR) NULL);
347 }
348
349 /* Check one symbol to see if it is a prohibited cross reference. */
350
351 /*ARGSUSED*/
352 static boolean
353 check_nocrossref (h, ignore)
354 struct cref_hash_entry *h;
355 PTR ignore;
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 defsecname = bfd_get_section_name (defsec->owner, defsec);
378
379 for (ncrs = nocrossref_list; ncrs != NULL; ncrs = ncrs->next)
380 for (ncr = ncrs->list; ncr != NULL; ncr = ncr->next)
381 if (strcmp (ncr->name, defsecname) == 0)
382 check_refs (h, hl, ncrs);
383
384 return true;
385 }
386
387 /* The struct is used to pass information from check_refs to
388 check_reloc_refs through bfd_map_over_sections. */
389
390 struct check_refs_info
391 {
392 struct cref_hash_entry *h;
393 asection *defsec;
394 struct lang_nocrossrefs *ncrs;
395 asymbol **asymbols;
396 boolean same;
397 };
398
399 /* This function is called for each symbol defined in a section which
400 prohibits cross references. We need to look through all references
401 to this symbol, and ensure that the references are not from
402 prohibited sections. */
403
404 static void
405 check_refs (h, hl, ncrs)
406 struct cref_hash_entry *h;
407 struct bfd_link_hash_entry *hl;
408 struct lang_nocrossrefs *ncrs;
409 {
410 struct cref_ref *ref;
411
412 for (ref = h->refs; ref != NULL; ref = ref->next)
413 {
414 lang_input_statement_type *li;
415 asymbol **asymbols;
416 struct check_refs_info info;
417
418 /* We need to look through the relocations for this BFD, to see
419 if any of the relocations which refer to this symbol are from
420 a prohibited section. Note that we need to do this even for
421 the BFD in which the symbol is defined, since even a single
422 BFD might contain a prohibited cross reference; for this
423 case, we set the SAME field in INFO, which will cause
424 CHECK_RELOCS_REFS to check for relocations against the
425 section as well as against the symbol. */
426
427 li = (lang_input_statement_type *) ref->abfd->usrdata;
428 if (li != NULL && li->asymbols != NULL)
429 asymbols = li->asymbols;
430 else
431 {
432 long symsize;
433 long symbol_count;
434
435 symsize = bfd_get_symtab_upper_bound (ref->abfd);
436 if (symsize < 0)
437 einfo ("%B%F: could not read symbols; %E\n", ref->abfd);
438 asymbols = (asymbol **) xmalloc (symsize);
439 symbol_count = bfd_canonicalize_symtab (ref->abfd, asymbols);
440 if (symbol_count < 0)
441 einfo ("%B%F: could not read symbols: %E\n", ref->abfd);
442 if (li != NULL)
443 {
444 li->asymbols = asymbols;
445 li->symbol_count = symbol_count;
446 }
447 }
448
449 info.h = h;
450 info.defsec = hl->u.def.section;
451 info.ncrs = ncrs;
452 info.asymbols = asymbols;
453 if (ref->abfd == hl->u.def.section->owner)
454 info.same = true;
455 else
456 info.same = false;
457 bfd_map_over_sections (ref->abfd, check_reloc_refs, (PTR) &info);
458
459 if (li == NULL)
460 free (asymbols);
461 }
462 }
463
464 /* This is called via bfd_map_over_sections. INFO->H is a symbol
465 defined in INFO->DEFSECNAME. If this section maps into any of the
466 sections listed in INFO->NCRS, other than INFO->DEFSECNAME, then we
467 look through the relocations. If any of the relocations are to
468 INFO->H, then we report a prohibited cross reference error. */
469
470 static void
471 check_reloc_refs (abfd, sec, iarg)
472 bfd *abfd;
473 asection *sec;
474 PTR iarg;
475 {
476 struct check_refs_info *info = (struct check_refs_info *) iarg;
477 asection *outsec;
478 const char *outsecname;
479 asection *outdefsec;
480 const char *outdefsecname;
481 struct lang_nocrossref *ncr;
482 const char *symname;
483 long relsize;
484 arelent **relpp;
485 long relcount;
486 arelent **p, **pend;
487
488 outsec = sec->output_section;
489 outsecname = bfd_get_section_name (outsec->owner, outsec);
490
491 outdefsec = info->defsec->output_section;
492 outdefsecname = bfd_get_section_name (outdefsec->owner, outdefsec);
493
494 /* The section where the symbol is defined is permitted. */
495 if (strcmp (outsecname, outdefsecname) == 0)
496 return;
497
498 for (ncr = info->ncrs->list; ncr != NULL; ncr = ncr->next)
499 if (strcmp (outsecname, ncr->name) == 0)
500 break;
501
502 if (ncr == NULL)
503 return;
504
505 /* This section is one for which cross references are prohibited.
506 Look through the relocations, and see if any of them are to
507 INFO->H. */
508
509 symname = info->h->root.string;
510
511 relsize = bfd_get_reloc_upper_bound (abfd, sec);
512 if (relsize < 0)
513 einfo ("%B%F: could not read relocs: %E\n", abfd);
514 if (relsize == 0)
515 return;
516
517 relpp = (arelent **) xmalloc (relsize);
518 relcount = bfd_canonicalize_reloc (abfd, sec, relpp, info->asymbols);
519 if (relcount < 0)
520 einfo ("%B%F: could not read relocs: %E\n", abfd);
521
522 p = relpp;
523 pend = p + relcount;
524 for (; p < pend && *p != NULL; p++)
525 {
526 arelent *q = *p;
527
528 if (q->sym_ptr_ptr != NULL
529 && *q->sym_ptr_ptr != NULL
530 && (strcmp (bfd_asymbol_name (*q->sym_ptr_ptr), symname) == 0
531 || (info->same
532 && *q->sym_ptr_ptr == info->defsec->symbol)))
533 {
534 /* We found a reloc for the symbol. The symbol is defined
535 in OUTSECNAME. This reloc is from a section which is
536 mapped into a section from which references to OUTSECNAME
537 are prohibited. We must report an error. */
538 einfo ("%X%C: prohibited cross reference from %s to `%T' in %s\n",
539 abfd, sec, q->address, outsecname,
540 bfd_asymbol_name (*q->sym_ptr_ptr), outdefsecname);
541 }
542 }
543
544 free (relpp);
545 }