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