4ebb8cddf441e241a7ed5bd2f2d18778209d3847
[deliverable/binutils-gdb.git] / ld / ldcref.c
1 /* ldcref.c -- output a cross reference table
2 Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2006,
3 2007 Free Software Foundation, Inc.
4 Written by Ian Lance Taylor <ian@cygnus.com>
5
6 This file is part of the GNU Binutils.
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 3 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,
21 MA 02110-1301, USA. */
22
23
24 /* This file holds routines that manage the cross reference table.
25 The table is used to generate cross reference reports. It is also
26 used to implement the NOCROSSREFS command in the linker script. */
27
28 #include "sysdep.h"
29 #include "bfd.h"
30 #include "bfdlink.h"
31 #include "libiberty.h"
32 #include "demangle.h"
33 #include "objalloc.h"
34
35 #include "ld.h"
36 #include "ldmain.h"
37 #include "ldmisc.h"
38 #include "ldexp.h"
39 #include "ldlang.h"
40
41 /* We keep an instance of this structure for each reference to a
42 symbol from a given object. */
43
44 struct cref_ref {
45 /* The next reference. */
46 struct cref_ref *next;
47 /* The object. */
48 bfd *abfd;
49 /* True if the symbol is defined. */
50 unsigned int def : 1;
51 /* True if the symbol is common. */
52 unsigned int common : 1;
53 /* True if the symbol is undefined. */
54 unsigned int undef : 1;
55 };
56
57 /* We keep a hash table of symbols. Each entry looks like this. */
58
59 struct cref_hash_entry {
60 struct bfd_hash_entry root;
61 /* The demangled name. */
62 const char *demangled;
63 /* References to and definitions of this symbol. */
64 struct cref_ref *refs;
65 };
66
67 /* This is what the hash table looks like. */
68
69 struct cref_hash_table {
70 struct bfd_hash_table root;
71 };
72
73 /* Forward declarations. */
74
75 static void output_one_cref (FILE *, struct cref_hash_entry *);
76 static void check_local_sym_xref (lang_input_statement_type *);
77 static bfd_boolean check_nocrossref (struct cref_hash_entry *, void *);
78 static void check_refs (const char *, bfd_boolean, asection *, bfd *,
79 struct lang_nocrossrefs *);
80 static void check_reloc_refs (bfd *, asection *, void *);
81
82 /* Look up an entry in the cref hash table. */
83
84 #define cref_hash_lookup(table, string, create, copy) \
85 ((struct cref_hash_entry *) \
86 bfd_hash_lookup (&(table)->root, (string), (create), (copy)))
87
88 /* Traverse the cref hash table. */
89
90 #define cref_hash_traverse(table, func, info) \
91 (bfd_hash_traverse \
92 (&(table)->root, \
93 (bfd_boolean (*) (struct bfd_hash_entry *, void *)) (func), \
94 (info)))
95
96 /* The cref hash table. */
97
98 static struct cref_hash_table cref_table;
99
100 /* Whether the cref hash table has been initialized. */
101
102 static bfd_boolean cref_initialized;
103
104 /* The number of symbols seen so far. */
105
106 static size_t cref_symcount;
107
108 /* Used to take a snapshot of the cref hash table when starting to
109 add syms from an as-needed library. */
110 static struct bfd_hash_entry **old_table;
111 static unsigned int old_size;
112 static unsigned int old_count;
113 static void *old_tab;
114 static void *alloc_mark;
115 static size_t tabsize, entsize, refsize;
116 static size_t old_symcount;
117
118 /* Create an entry in a cref hash table. */
119
120 static struct bfd_hash_entry *
121 cref_hash_newfunc (struct bfd_hash_entry *entry,
122 struct bfd_hash_table *table,
123 const char *string)
124 {
125 struct cref_hash_entry *ret = (struct cref_hash_entry *) entry;
126
127 /* Allocate the structure if it has not already been allocated by a
128 subclass. */
129 if (ret == NULL)
130 ret = ((struct cref_hash_entry *)
131 bfd_hash_allocate (table, sizeof (struct cref_hash_entry)));
132 if (ret == NULL)
133 return NULL;
134
135 /* Call the allocation method of the superclass. */
136 ret = ((struct cref_hash_entry *)
137 bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string));
138 if (ret != NULL)
139 {
140 /* Set local fields. */
141 ret->demangled = NULL;
142 ret->refs = NULL;
143
144 /* Keep a count of the number of entries created in the hash
145 table. */
146 ++cref_symcount;
147 }
148
149 return &ret->root;
150 }
151
152 /* Add a symbol to the cref hash table. This is called for every
153 global symbol that is seen during the link. */
154
155 void
156 add_cref (const char *name,
157 bfd *abfd,
158 asection *section,
159 bfd_vma value ATTRIBUTE_UNUSED)
160 {
161 struct cref_hash_entry *h;
162 struct cref_ref *r;
163
164 if (! cref_initialized)
165 {
166 if (!bfd_hash_table_init (&cref_table.root, cref_hash_newfunc,
167 sizeof (struct cref_hash_entry)))
168 einfo (_("%X%P: bfd_hash_table_init of cref table failed: %E\n"));
169 cref_initialized = TRUE;
170 }
171
172 h = cref_hash_lookup (&cref_table, name, TRUE, FALSE);
173 if (h == NULL)
174 einfo (_("%X%P: cref_hash_lookup failed: %E\n"));
175
176 for (r = h->refs; r != NULL; r = r->next)
177 if (r->abfd == abfd)
178 break;
179
180 if (r == NULL)
181 {
182 r = bfd_hash_allocate (&cref_table.root, sizeof *r);
183 if (r == NULL)
184 einfo (_("%X%P: cref alloc failed: %E\n"));
185 r->next = h->refs;
186 h->refs = r;
187 r->abfd = abfd;
188 r->def = FALSE;
189 r->common = FALSE;
190 r->undef = FALSE;
191 }
192
193 if (bfd_is_und_section (section))
194 r->undef = TRUE;
195 else if (bfd_is_com_section (section))
196 r->common = TRUE;
197 else
198 r->def = TRUE;
199 }
200
201 /* Called before loading an as-needed library to take a snapshot of
202 the cref hash table, and after we have loaded or found that the
203 library was not needed. */
204
205 bfd_boolean
206 handle_asneeded_cref (bfd *abfd ATTRIBUTE_UNUSED,
207 enum notice_asneeded_action act)
208 {
209 unsigned int i;
210
211 if (!cref_initialized)
212 return TRUE;
213
214 if (act == notice_as_needed)
215 {
216 char *old_ent, *old_ref;
217
218 for (i = 0; i < cref_table.root.size; i++)
219 {
220 struct bfd_hash_entry *p;
221 struct cref_hash_entry *c;
222 struct cref_ref *r;
223
224 for (p = cref_table.root.table[i]; p != NULL; p = p->next)
225 {
226 entsize += cref_table.root.entsize;
227 c = (struct cref_hash_entry *) p;
228 for (r = c->refs; r != NULL; r = r->next)
229 refsize += sizeof (struct cref_hash_entry);
230 }
231 }
232
233 tabsize = cref_table.root.size * sizeof (struct bfd_hash_entry *);
234 old_tab = xmalloc (tabsize + entsize + refsize);
235
236 alloc_mark = bfd_hash_allocate (&cref_table.root, 1);
237 if (alloc_mark == NULL)
238 return FALSE;
239
240 memcpy (old_tab, cref_table.root.table, tabsize);
241 old_ent = (char *) old_tab + tabsize;
242 old_ref = (char *) old_ent + entsize;
243 old_table = cref_table.root.table;
244 old_size = cref_table.root.size;
245 old_count = cref_table.root.count;
246 old_symcount = cref_symcount;
247
248 for (i = 0; i < cref_table.root.size; i++)
249 {
250 struct bfd_hash_entry *p;
251 struct cref_hash_entry *c;
252 struct cref_ref *r;
253
254 for (p = cref_table.root.table[i]; p != NULL; p = p->next)
255 {
256 memcpy (old_ent, p, cref_table.root.entsize);
257 old_ent = (char *) old_ent + cref_table.root.entsize;
258 c = (struct cref_hash_entry *) p;
259 for (r = c->refs; r != NULL; r = r->next)
260 {
261 memcpy (old_ref, r, sizeof (struct cref_hash_entry));
262 old_ref = (char *) old_ref + sizeof (struct cref_hash_entry);
263 }
264 }
265 }
266 return TRUE;
267 }
268
269 if (act == notice_not_needed)
270 {
271 char *old_ent, *old_ref;
272
273 if (old_tab == NULL)
274 {
275 /* The only way old_tab can be NULL is if the cref hash table
276 had not been initialised when notice_as_needed. */
277 bfd_hash_table_free (&cref_table.root);
278 cref_initialized = FALSE;
279 return TRUE;
280 }
281
282 old_ent = (char *) old_tab + tabsize;
283 old_ref = (char *) old_ent + entsize;
284 cref_table.root.table = old_table;
285 cref_table.root.size = old_size;
286 cref_table.root.count = old_count;
287 memcpy (cref_table.root.table, old_tab, tabsize);
288 cref_symcount = old_symcount;
289
290 for (i = 0; i < cref_table.root.size; i++)
291 {
292 struct bfd_hash_entry *p;
293 struct cref_hash_entry *c;
294 struct cref_ref *r;
295
296 for (p = cref_table.root.table[i]; p != NULL; p = p->next)
297 {
298 memcpy (p, old_ent, cref_table.root.entsize);
299 old_ent = (char *) old_ent + cref_table.root.entsize;
300 c = (struct cref_hash_entry *) p;
301 for (r = c->refs; r != NULL; r = r->next)
302 {
303 memcpy (r, old_ref, sizeof (struct cref_hash_entry));
304 old_ref = (char *) old_ref + sizeof (struct cref_hash_entry);
305 }
306 }
307 }
308
309 objalloc_free_block ((struct objalloc *) cref_table.root.memory,
310 alloc_mark);
311 }
312 else if (act != notice_needed)
313 return FALSE;
314
315 free (old_tab);
316 old_tab = NULL;
317 return TRUE;
318 }
319
320 /* Copy the addresses of the hash table entries into an array. This
321 is called via cref_hash_traverse. We also fill in the demangled
322 name. */
323
324 static bfd_boolean
325 cref_fill_array (struct cref_hash_entry *h, void *data)
326 {
327 struct cref_hash_entry ***pph = data;
328
329 ASSERT (h->demangled == NULL);
330 h->demangled = bfd_demangle (output_bfd, h->root.string,
331 DMGL_ANSI | DMGL_PARAMS);
332 if (h->demangled == NULL)
333 h->demangled = h->root.string;
334
335 **pph = h;
336
337 ++*pph;
338
339 return TRUE;
340 }
341
342 /* Sort an array of cref hash table entries by name. */
343
344 static int
345 cref_sort_array (const void *a1, const void *a2)
346 {
347 const struct cref_hash_entry * const *p1 = a1;
348 const struct cref_hash_entry * const *p2 = a2;
349
350 return strcmp ((*p1)->demangled, (*p2)->demangled);
351 }
352
353 /* Write out the cref table. */
354
355 #define FILECOL (50)
356
357 void
358 output_cref (FILE *fp)
359 {
360 int len;
361 struct cref_hash_entry **csyms, **csym_fill, **csym, **csym_end;
362 const char *msg;
363
364 fprintf (fp, _("\nCross Reference Table\n\n"));
365 msg = _("Symbol");
366 fprintf (fp, "%s", msg);
367 len = strlen (msg);
368 while (len < FILECOL)
369 {
370 putc (' ', fp);
371 ++len;
372 }
373 fprintf (fp, _("File\n"));
374
375 if (! cref_initialized)
376 {
377 fprintf (fp, _("No symbols\n"));
378 return;
379 }
380
381 csyms = xmalloc (cref_symcount * sizeof (*csyms));
382
383 csym_fill = csyms;
384 cref_hash_traverse (&cref_table, cref_fill_array, &csym_fill);
385 ASSERT ((size_t) (csym_fill - csyms) == cref_symcount);
386
387 qsort (csyms, cref_symcount, sizeof (*csyms), cref_sort_array);
388
389 csym_end = csyms + cref_symcount;
390 for (csym = csyms; csym < csym_end; csym++)
391 output_one_cref (fp, *csym);
392 }
393
394 /* Output one entry in the cross reference table. */
395
396 static void
397 output_one_cref (FILE *fp, struct cref_hash_entry *h)
398 {
399 int len;
400 struct bfd_link_hash_entry *hl;
401 struct cref_ref *r;
402
403 hl = bfd_link_hash_lookup (link_info.hash, h->root.string, FALSE,
404 FALSE, TRUE);
405 if (hl == NULL)
406 einfo ("%P: symbol `%T' missing from main hash table\n",
407 h->root.string);
408 else
409 {
410 /* If this symbol is defined in a dynamic object but never
411 referenced by a normal object, then don't print it. */
412 if (hl->type == bfd_link_hash_defined)
413 {
414 if (hl->u.def.section->output_section == NULL)
415 return;
416 if (hl->u.def.section->owner != NULL
417 && (hl->u.def.section->owner->flags & DYNAMIC) != 0)
418 {
419 for (r = h->refs; r != NULL; r = r->next)
420 if ((r->abfd->flags & DYNAMIC) == 0)
421 break;
422 if (r == NULL)
423 return;
424 }
425 }
426 }
427
428 fprintf (fp, "%s ", h->demangled);
429 len = strlen (h->demangled) + 1;
430
431 for (r = h->refs; r != NULL; r = r->next)
432 {
433 if (r->def)
434 {
435 while (len < FILECOL)
436 {
437 putc (' ', fp);
438 ++len;
439 }
440 lfinfo (fp, "%B\n", r->abfd);
441 len = 0;
442 }
443 }
444
445 for (r = h->refs; r != NULL; r = r->next)
446 {
447 if (! r->def)
448 {
449 while (len < FILECOL)
450 {
451 putc (' ', fp);
452 ++len;
453 }
454 lfinfo (fp, "%B\n", r->abfd);
455 len = 0;
456 }
457 }
458
459 ASSERT (len == 0);
460 }
461
462 /* Check for prohibited cross references. */
463
464 void
465 check_nocrossrefs (void)
466 {
467 if (! cref_initialized)
468 return;
469
470 cref_hash_traverse (&cref_table, check_nocrossref, NULL);
471
472 lang_for_each_file (check_local_sym_xref);
473 }
474
475 /* Check for prohibited cross references to local and section symbols. */
476
477 static void
478 check_local_sym_xref (lang_input_statement_type *statement)
479 {
480 bfd *abfd;
481 lang_input_statement_type *li;
482 asymbol **asymbols, **syms;
483
484 abfd = statement->the_bfd;
485 if (abfd == NULL)
486 return;
487
488 li = abfd->usrdata;
489 if (li != NULL && li->asymbols != NULL)
490 asymbols = li->asymbols;
491 else
492 {
493 long symsize;
494 long symbol_count;
495
496 symsize = bfd_get_symtab_upper_bound (abfd);
497 if (symsize < 0)
498 einfo (_("%B%F: could not read symbols; %E\n"), abfd);
499 asymbols = xmalloc (symsize);
500 symbol_count = bfd_canonicalize_symtab (abfd, asymbols);
501 if (symbol_count < 0)
502 einfo (_("%B%F: could not read symbols: %E\n"), abfd);
503 if (li != NULL)
504 {
505 li->asymbols = asymbols;
506 li->symbol_count = symbol_count;
507 }
508 }
509
510 for (syms = asymbols; *syms; ++syms)
511 {
512 asymbol *sym = *syms;
513 if (sym->flags & (BSF_GLOBAL | BSF_WARNING | BSF_INDIRECT | BSF_FILE))
514 continue;
515 if ((sym->flags & (BSF_LOCAL | BSF_SECTION_SYM)) != 0
516 && sym->section->output_section != NULL)
517 {
518 const char *outsecname, *symname;
519 struct lang_nocrossrefs *ncrs;
520 struct lang_nocrossref *ncr;
521
522 outsecname = sym->section->output_section->name;
523 symname = NULL;
524 if ((sym->flags & BSF_SECTION_SYM) == 0)
525 symname = sym->name;
526 for (ncrs = nocrossref_list; ncrs != NULL; ncrs = ncrs->next)
527 for (ncr = ncrs->list; ncr != NULL; ncr = ncr->next)
528 if (strcmp (ncr->name, outsecname) == 0)
529 check_refs (symname, FALSE, sym->section, abfd, ncrs);
530 }
531 }
532
533 if (li == NULL)
534 free (asymbols);
535 }
536
537 /* Check one symbol to see if it is a prohibited cross reference. */
538
539 static bfd_boolean
540 check_nocrossref (struct cref_hash_entry *h, void *ignore ATTRIBUTE_UNUSED)
541 {
542 struct bfd_link_hash_entry *hl;
543 asection *defsec;
544 const char *defsecname;
545 struct lang_nocrossrefs *ncrs;
546 struct lang_nocrossref *ncr;
547 struct cref_ref *ref;
548
549 hl = bfd_link_hash_lookup (link_info.hash, h->root.string, FALSE,
550 FALSE, TRUE);
551 if (hl == NULL)
552 {
553 einfo (_("%P: symbol `%T' missing from main hash table\n"),
554 h->root.string);
555 return TRUE;
556 }
557
558 if (hl->type != bfd_link_hash_defined
559 && hl->type != bfd_link_hash_defweak)
560 return TRUE;
561
562 defsec = hl->u.def.section->output_section;
563 if (defsec == NULL)
564 return TRUE;
565 defsecname = bfd_get_section_name (defsec->owner, defsec);
566
567 for (ncrs = nocrossref_list; ncrs != NULL; ncrs = ncrs->next)
568 for (ncr = ncrs->list; ncr != NULL; ncr = ncr->next)
569 if (strcmp (ncr->name, defsecname) == 0)
570 for (ref = h->refs; ref != NULL; ref = ref->next)
571 check_refs (hl->root.string, TRUE, hl->u.def.section,
572 ref->abfd, ncrs);
573
574 return TRUE;
575 }
576
577 /* The struct is used to pass information from check_refs to
578 check_reloc_refs through bfd_map_over_sections. */
579
580 struct check_refs_info {
581 const char *sym_name;
582 asection *defsec;
583 struct lang_nocrossrefs *ncrs;
584 asymbol **asymbols;
585 bfd_boolean global;
586 };
587
588 /* This function is called for each symbol defined in a section which
589 prohibits cross references. We need to look through all references
590 to this symbol, and ensure that the references are not from
591 prohibited sections. */
592
593 static void
594 check_refs (const char *name,
595 bfd_boolean global,
596 asection *sec,
597 bfd *abfd,
598 struct lang_nocrossrefs *ncrs)
599 {
600 lang_input_statement_type *li;
601 asymbol **asymbols;
602 struct check_refs_info info;
603
604 /* We need to look through the relocations for this BFD, to see
605 if any of the relocations which refer to this symbol are from
606 a prohibited section. Note that we need to do this even for
607 the BFD in which the symbol is defined, since even a single
608 BFD might contain a prohibited cross reference. */
609
610 li = abfd->usrdata;
611 if (li != NULL && li->asymbols != NULL)
612 asymbols = li->asymbols;
613 else
614 {
615 long symsize;
616 long symbol_count;
617
618 symsize = bfd_get_symtab_upper_bound (abfd);
619 if (symsize < 0)
620 einfo (_("%B%F: could not read symbols; %E\n"), abfd);
621 asymbols = xmalloc (symsize);
622 symbol_count = bfd_canonicalize_symtab (abfd, asymbols);
623 if (symbol_count < 0)
624 einfo (_("%B%F: could not read symbols: %E\n"), abfd);
625 if (li != NULL)
626 {
627 li->asymbols = asymbols;
628 li->symbol_count = symbol_count;
629 }
630 }
631
632 info.sym_name = name;
633 info.global = global;
634 info.defsec = sec;
635 info.ncrs = ncrs;
636 info.asymbols = asymbols;
637 bfd_map_over_sections (abfd, check_reloc_refs, &info);
638
639 if (li == NULL)
640 free (asymbols);
641 }
642
643 /* This is called via bfd_map_over_sections. INFO->SYM_NAME is a symbol
644 defined in INFO->DEFSECNAME. If this section maps into any of the
645 sections listed in INFO->NCRS, other than INFO->DEFSECNAME, then we
646 look through the relocations. If any of the relocations are to
647 INFO->SYM_NAME, then we report a prohibited cross reference error. */
648
649 static void
650 check_reloc_refs (bfd *abfd, asection *sec, void *iarg)
651 {
652 struct check_refs_info *info = iarg;
653 asection *outsec;
654 const char *outsecname;
655 asection *outdefsec;
656 const char *outdefsecname;
657 struct lang_nocrossref *ncr;
658 const char *symname;
659 bfd_boolean global;
660 long relsize;
661 arelent **relpp;
662 long relcount;
663 arelent **p, **pend;
664
665 outsec = sec->output_section;
666 outsecname = bfd_get_section_name (outsec->owner, outsec);
667
668 outdefsec = info->defsec->output_section;
669 outdefsecname = bfd_get_section_name (outdefsec->owner, outdefsec);
670
671 /* The section where the symbol is defined is permitted. */
672 if (strcmp (outsecname, outdefsecname) == 0)
673 return;
674
675 for (ncr = info->ncrs->list; ncr != NULL; ncr = ncr->next)
676 if (strcmp (outsecname, ncr->name) == 0)
677 break;
678
679 if (ncr == NULL)
680 return;
681
682 /* This section is one for which cross references are prohibited.
683 Look through the relocations, and see if any of them are to
684 INFO->SYM_NAME. If INFO->SYMNAME is NULL, check for relocations
685 against the section symbol. If INFO->GLOBAL is TRUE, the
686 definition is global, check for relocations against the global
687 symbols. Otherwise check for relocations against the local and
688 section symbols. */
689
690 symname = info->sym_name;
691 global = info->global;
692
693 relsize = bfd_get_reloc_upper_bound (abfd, sec);
694 if (relsize < 0)
695 einfo (_("%B%F: could not read relocs: %E\n"), abfd);
696 if (relsize == 0)
697 return;
698
699 relpp = xmalloc (relsize);
700 relcount = bfd_canonicalize_reloc (abfd, sec, relpp, info->asymbols);
701 if (relcount < 0)
702 einfo (_("%B%F: could not read relocs: %E\n"), abfd);
703
704 p = relpp;
705 pend = p + relcount;
706 for (; p < pend && *p != NULL; p++)
707 {
708 arelent *q = *p;
709
710 if (q->sym_ptr_ptr != NULL
711 && *q->sym_ptr_ptr != NULL
712 && ((global
713 && (bfd_is_und_section (bfd_get_section (*q->sym_ptr_ptr))
714 || bfd_is_com_section (bfd_get_section (*q->sym_ptr_ptr))
715 || ((*q->sym_ptr_ptr)->flags & (BSF_GLOBAL
716 | BSF_WEAK)) != 0))
717 || (!global
718 && ((*q->sym_ptr_ptr)->flags & (BSF_LOCAL
719 | BSF_SECTION_SYM)) != 0
720 && bfd_get_section (*q->sym_ptr_ptr) == info->defsec))
721 && (symname != NULL
722 ? strcmp (bfd_asymbol_name (*q->sym_ptr_ptr), symname) == 0
723 : ((*q->sym_ptr_ptr)->flags & BSF_SECTION_SYM) != 0))
724 {
725 /* We found a reloc for the symbol. The symbol is defined
726 in OUTSECNAME. This reloc is from a section which is
727 mapped into a section from which references to OUTSECNAME
728 are prohibited. We must report an error. */
729 einfo (_("%X%C: prohibited cross reference from %s to `%T' in %s\n"),
730 abfd, sec, q->address, outsecname,
731 bfd_asymbol_name (*q->sym_ptr_ptr), outdefsecname);
732 }
733 }
734
735 free (relpp);
736 }
This page took 0.046773 seconds and 4 git commands to generate.