*** empty log message ***
[deliverable/binutils-gdb.git] / ld / ldcref.c
CommitLineData
252b5132 1/* ldcref.c -- output a cross reference table
aef6203b 2 Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
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 {
152 if (! bfd_hash_table_init (&cref_table.root, cref_hash_newfunc))
153 einfo (_("%X%P: bfd_hash_table_init of cref table failed: %E\n"));
b34976b6 154 cref_initialized = TRUE;
252b5132
RH
155 }
156
b34976b6 157 h = cref_hash_lookup (&cref_table, name, TRUE, FALSE);
252b5132
RH
158 if (h == NULL)
159 einfo (_("%X%P: cref_hash_lookup failed: %E\n"));
160
161 for (r = h->refs; r != NULL; r = r->next)
162 if (r->abfd == abfd)
163 break;
164
165 if (r == NULL)
166 {
1579bae1 167 r = xmalloc (sizeof *r);
252b5132
RH
168 r->next = h->refs;
169 h->refs = r;
170 r->abfd = abfd;
b34976b6
AM
171 r->def = FALSE;
172 r->common = FALSE;
173 r->undef = FALSE;
252b5132
RH
174 }
175
176 if (bfd_is_und_section (section))
b34976b6 177 r->undef = TRUE;
252b5132 178 else if (bfd_is_com_section (section))
b34976b6 179 r->common = TRUE;
252b5132 180 else
b34976b6 181 r->def = TRUE;
252b5132
RH
182}
183
184/* Copy the addresses of the hash table entries into an array. This
185 is called via cref_hash_traverse. We also fill in the demangled
186 name. */
187
b34976b6 188static bfd_boolean
1579bae1 189cref_fill_array (struct cref_hash_entry *h, void *data)
252b5132 190{
1579bae1 191 struct cref_hash_entry ***pph = data;
252b5132
RH
192
193 ASSERT (h->demangled == NULL);
194 h->demangled = demangle (h->root.string);
195
196 **pph = h;
197
198 ++*pph;
199
b34976b6 200 return TRUE;
252b5132
RH
201}
202
203/* Sort an array of cref hash table entries by name. */
204
205static int
1579bae1 206cref_sort_array (const void *a1, const void *a2)
252b5132 207{
1579bae1
AM
208 const struct cref_hash_entry * const *p1 = a1;
209 const struct cref_hash_entry * const *p2 = a2;
252b5132
RH
210
211 return strcmp ((*p1)->demangled, (*p2)->demangled);
212}
213
214/* Write out the cref table. */
215
216#define FILECOL (50)
217
218void
1579bae1 219output_cref (FILE *fp)
252b5132
RH
220{
221 int len;
222 struct cref_hash_entry **csyms, **csym_fill, **csym, **csym_end;
223 const char *msg;
224
225 fprintf (fp, _("\nCross Reference Table\n\n"));
226 msg = _("Symbol");
305c7206 227 fprintf (fp, "%s", msg);
252b5132
RH
228 len = strlen (msg);
229 while (len < FILECOL)
230 {
4de2d33d 231 putc (' ', fp);
252b5132
RH
232 ++len;
233 }
234 fprintf (fp, _("File\n"));
235
236 if (! cref_initialized)
237 {
238 fprintf (fp, _("No symbols\n"));
239 return;
240 }
241
1579bae1 242 csyms = xmalloc (cref_symcount * sizeof (*csyms));
252b5132
RH
243
244 csym_fill = csyms;
245 cref_hash_traverse (&cref_table, cref_fill_array, &csym_fill);
246 ASSERT ((size_t) (csym_fill - csyms) == cref_symcount);
247
248 qsort (csyms, cref_symcount, sizeof (*csyms), cref_sort_array);
249
250 csym_end = csyms + cref_symcount;
251 for (csym = csyms; csym < csym_end; csym++)
252 output_one_cref (fp, *csym);
253}
254
255/* Output one entry in the cross reference table. */
256
257static void
1579bae1 258output_one_cref (FILE *fp, struct cref_hash_entry *h)
252b5132
RH
259{
260 int len;
261 struct bfd_link_hash_entry *hl;
262 struct cref_ref *r;
263
b34976b6
AM
264 hl = bfd_link_hash_lookup (link_info.hash, h->root.string, FALSE,
265 FALSE, TRUE);
252b5132
RH
266 if (hl == NULL)
267 einfo ("%P: symbol `%T' missing from main hash table\n",
268 h->root.string);
269 else
270 {
271 /* If this symbol is defined in a dynamic object but never
272 referenced by a normal object, then don't print it. */
273 if (hl->type == bfd_link_hash_defined)
274 {
275 if (hl->u.def.section->output_section == NULL)
276 return;
277 if (hl->u.def.section->owner != NULL
278 && (hl->u.def.section->owner->flags & DYNAMIC) != 0)
279 {
280 for (r = h->refs; r != NULL; r = r->next)
281 if ((r->abfd->flags & DYNAMIC) == 0)
282 break;
283 if (r == NULL)
284 return;
285 }
286 }
287 }
288
289 fprintf (fp, "%s ", h->demangled);
290 len = strlen (h->demangled) + 1;
291
292 for (r = h->refs; r != NULL; r = r->next)
293 {
294 if (r->def)
295 {
296 while (len < FILECOL)
297 {
298 putc (' ', fp);
299 ++len;
300 }
301 lfinfo (fp, "%B\n", r->abfd);
302 len = 0;
303 }
304 }
305
306 for (r = h->refs; r != NULL; r = r->next)
307 {
308 if (! r->def)
309 {
310 while (len < FILECOL)
311 {
312 putc (' ', fp);
313 ++len;
314 }
315 lfinfo (fp, "%B\n", r->abfd);
316 len = 0;
317 }
318 }
319
320 ASSERT (len == 0);
321}
322
323/* Check for prohibited cross references. */
324
325void
1579bae1 326check_nocrossrefs (void)
252b5132
RH
327{
328 if (! cref_initialized)
329 return;
330
1579bae1 331 cref_hash_traverse (&cref_table, check_nocrossref, NULL);
e14ec88b 332
09c112da 333 lang_for_each_file (check_local_sym_xref);
e14ec88b
AM
334}
335
09c112da 336/* Check for prohibited cross references to local and section symbols. */
e14ec88b
AM
337
338static void
09c112da 339check_local_sym_xref (lang_input_statement_type *statement)
e14ec88b
AM
340{
341 bfd *abfd;
09c112da
AM
342 lang_input_statement_type *li;
343 asymbol **asymbols, **syms;
e14ec88b
AM
344
345 abfd = statement->the_bfd;
346 if (abfd == NULL)
347 return;
348
09c112da
AM
349 li = abfd->usrdata;
350 if (li != NULL && li->asymbols != NULL)
351 asymbols = li->asymbols;
352 else
e14ec88b 353 {
09c112da
AM
354 long symsize;
355 long symbol_count;
356
357 symsize = bfd_get_symtab_upper_bound (abfd);
358 if (symsize < 0)
359 einfo (_("%B%F: could not read symbols; %E\n"), abfd);
360 asymbols = xmalloc (symsize);
361 symbol_count = bfd_canonicalize_symtab (abfd, asymbols);
362 if (symbol_count < 0)
363 einfo (_("%B%F: could not read symbols: %E\n"), abfd);
364 if (li != NULL)
365 {
366 li->asymbols = asymbols;
367 li->symbol_count = symbol_count;
368 }
369 }
e14ec88b 370
09c112da
AM
371 for (syms = asymbols; *syms; ++syms)
372 {
373 asymbol *sym = *syms;
374 if (sym->flags & (BSF_GLOBAL | BSF_WARNING | BSF_INDIRECT | BSF_FILE))
375 continue;
376 if ((sym->flags & (BSF_LOCAL | BSF_SECTION_SYM)) != 0
377 && sym->section->output_section != NULL)
e14ec88b 378 {
09c112da 379 const char *outsecname, *symname;
e14ec88b
AM
380 struct lang_nocrossrefs *ncrs;
381 struct lang_nocrossref *ncr;
382
09c112da
AM
383 outsecname = sym->section->output_section->name;
384 symname = NULL;
385 if ((sym->flags & BSF_SECTION_SYM) == 0)
386 symname = sym->name;
e14ec88b
AM
387 for (ncrs = nocrossref_list; ncrs != NULL; ncrs = ncrs->next)
388 for (ncr = ncrs->list; ncr != NULL; ncr = ncr->next)
389 if (strcmp (ncr->name, outsecname) == 0)
f0e0fb23 390 check_refs (symname, FALSE, sym->section, abfd, ncrs);
e14ec88b
AM
391 }
392 }
09c112da
AM
393
394 if (li == NULL)
395 free (asymbols);
252b5132
RH
396}
397
398/* Check one symbol to see if it is a prohibited cross reference. */
399
b34976b6 400static bfd_boolean
1579bae1 401check_nocrossref (struct cref_hash_entry *h, void *ignore ATTRIBUTE_UNUSED)
252b5132
RH
402{
403 struct bfd_link_hash_entry *hl;
404 asection *defsec;
405 const char *defsecname;
406 struct lang_nocrossrefs *ncrs;
407 struct lang_nocrossref *ncr;
e14ec88b 408 struct cref_ref *ref;
252b5132 409
b34976b6
AM
410 hl = bfd_link_hash_lookup (link_info.hash, h->root.string, FALSE,
411 FALSE, TRUE);
252b5132
RH
412 if (hl == NULL)
413 {
414 einfo (_("%P: symbol `%T' missing from main hash table\n"),
415 h->root.string);
b34976b6 416 return TRUE;
252b5132
RH
417 }
418
419 if (hl->type != bfd_link_hash_defined
420 && hl->type != bfd_link_hash_defweak)
b34976b6 421 return TRUE;
252b5132
RH
422
423 defsec = hl->u.def.section->output_section;
424 if (defsec == NULL)
b34976b6 425 return TRUE;
252b5132
RH
426 defsecname = bfd_get_section_name (defsec->owner, defsec);
427
428 for (ncrs = nocrossref_list; ncrs != NULL; ncrs = ncrs->next)
429 for (ncr = ncrs->list; ncr != NULL; ncr = ncr->next)
430 if (strcmp (ncr->name, defsecname) == 0)
e14ec88b 431 for (ref = h->refs; ref != NULL; ref = ref->next)
f0e0fb23
L
432 check_refs (hl->root.string, TRUE, hl->u.def.section,
433 ref->abfd, ncrs);
252b5132 434
b34976b6 435 return TRUE;
252b5132
RH
436}
437
438/* The struct is used to pass information from check_refs to
439 check_reloc_refs through bfd_map_over_sections. */
440
89cdebba 441struct check_refs_info {
e14ec88b 442 const char *sym_name;
252b5132
RH
443 asection *defsec;
444 struct lang_nocrossrefs *ncrs;
445 asymbol **asymbols;
f0e0fb23 446 bfd_boolean global;
252b5132
RH
447};
448
449/* This function is called for each symbol defined in a section which
450 prohibits cross references. We need to look through all references
451 to this symbol, and ensure that the references are not from
452 prohibited sections. */
453
454static void
1579bae1 455check_refs (const char *name,
f0e0fb23 456 bfd_boolean global,
1579bae1
AM
457 asection *sec,
458 bfd *abfd,
459 struct lang_nocrossrefs *ncrs)
252b5132 460{
e14ec88b
AM
461 lang_input_statement_type *li;
462 asymbol **asymbols;
463 struct check_refs_info info;
252b5132 464
e14ec88b
AM
465 /* We need to look through the relocations for this BFD, to see
466 if any of the relocations which refer to this symbol are from
467 a prohibited section. Note that we need to do this even for
468 the BFD in which the symbol is defined, since even a single
469 BFD might contain a prohibited cross reference. */
470
1579bae1 471 li = abfd->usrdata;
e14ec88b
AM
472 if (li != NULL && li->asymbols != NULL)
473 asymbols = li->asymbols;
474 else
252b5132 475 {
e14ec88b
AM
476 long symsize;
477 long symbol_count;
478
479 symsize = bfd_get_symtab_upper_bound (abfd);
480 if (symsize < 0)
481 einfo (_("%B%F: could not read symbols; %E\n"), abfd);
1579bae1 482 asymbols = xmalloc (symsize);
e14ec88b
AM
483 symbol_count = bfd_canonicalize_symtab (abfd, asymbols);
484 if (symbol_count < 0)
485 einfo (_("%B%F: could not read symbols: %E\n"), abfd);
486 if (li != NULL)
252b5132 487 {
e14ec88b
AM
488 li->asymbols = asymbols;
489 li->symbol_count = symbol_count;
252b5132 490 }
252b5132 491 }
e14ec88b
AM
492
493 info.sym_name = name;
f0e0fb23 494 info.global = global;
e14ec88b
AM
495 info.defsec = sec;
496 info.ncrs = ncrs;
497 info.asymbols = asymbols;
1579bae1 498 bfd_map_over_sections (abfd, check_reloc_refs, &info);
e14ec88b
AM
499
500 if (li == NULL)
501 free (asymbols);
252b5132
RH
502}
503
e14ec88b 504/* This is called via bfd_map_over_sections. INFO->SYM_NAME is a symbol
252b5132
RH
505 defined in INFO->DEFSECNAME. If this section maps into any of the
506 sections listed in INFO->NCRS, other than INFO->DEFSECNAME, then we
507 look through the relocations. If any of the relocations are to
e14ec88b 508 INFO->SYM_NAME, then we report a prohibited cross reference error. */
252b5132
RH
509
510static void
1579bae1 511check_reloc_refs (bfd *abfd, asection *sec, void *iarg)
252b5132 512{
1579bae1 513 struct check_refs_info *info = iarg;
252b5132
RH
514 asection *outsec;
515 const char *outsecname;
516 asection *outdefsec;
517 const char *outdefsecname;
518 struct lang_nocrossref *ncr;
519 const char *symname;
f0e0fb23 520 bfd_boolean global;
252b5132
RH
521 long relsize;
522 arelent **relpp;
523 long relcount;
524 arelent **p, **pend;
525
526 outsec = sec->output_section;
527 outsecname = bfd_get_section_name (outsec->owner, outsec);
528
529 outdefsec = info->defsec->output_section;
530 outdefsecname = bfd_get_section_name (outdefsec->owner, outdefsec);
531
532 /* The section where the symbol is defined is permitted. */
533 if (strcmp (outsecname, outdefsecname) == 0)
534 return;
535
536 for (ncr = info->ncrs->list; ncr != NULL; ncr = ncr->next)
537 if (strcmp (outsecname, ncr->name) == 0)
538 break;
539
540 if (ncr == NULL)
541 return;
542
543 /* This section is one for which cross references are prohibited.
544 Look through the relocations, and see if any of them are to
e14ec88b 545 INFO->SYM_NAME. If INFO->SYMNAME is NULL, check for relocations
f0e0fb23
L
546 against the section symbol. If INFO->GLOBAL is TRUE, the
547 definition is global, check for relocations against the global
548 symbols. Otherwise check for relocations against the local and
549 section symbols. */
252b5132 550
e14ec88b 551 symname = info->sym_name;
f0e0fb23 552 global = info->global;
252b5132
RH
553
554 relsize = bfd_get_reloc_upper_bound (abfd, sec);
555 if (relsize < 0)
556 einfo (_("%B%F: could not read relocs: %E\n"), abfd);
557 if (relsize == 0)
558 return;
559
1579bae1 560 relpp = xmalloc (relsize);
252b5132
RH
561 relcount = bfd_canonicalize_reloc (abfd, sec, relpp, info->asymbols);
562 if (relcount < 0)
563 einfo (_("%B%F: could not read relocs: %E\n"), abfd);
564
565 p = relpp;
566 pend = p + relcount;
567 for (; p < pend && *p != NULL; p++)
568 {
569 arelent *q = *p;
570
571 if (q->sym_ptr_ptr != NULL
572 && *q->sym_ptr_ptr != NULL
f0e0fb23
L
573 && ((global
574 && (bfd_is_und_section (bfd_get_section (*q->sym_ptr_ptr))
575 || bfd_is_com_section (bfd_get_section (*q->sym_ptr_ptr))
576 || ((*q->sym_ptr_ptr)->flags & (BSF_GLOBAL
577 | BSF_WEAK)) != 0))
578 || (!global
579 && ((*q->sym_ptr_ptr)->flags & (BSF_LOCAL
580 | BSF_SECTION_SYM)) != 0))
e14ec88b
AM
581 && (symname != NULL
582 ? strcmp (bfd_asymbol_name (*q->sym_ptr_ptr), symname) == 0
583 : (((*q->sym_ptr_ptr)->flags & BSF_SECTION_SYM) != 0
584 && bfd_get_section (*q->sym_ptr_ptr) == info->defsec)))
252b5132
RH
585 {
586 /* We found a reloc for the symbol. The symbol is defined
1579bae1
AM
587 in OUTSECNAME. This reloc is from a section which is
588 mapped into a section from which references to OUTSECNAME
589 are prohibited. We must report an error. */
252b5132
RH
590 einfo (_("%X%C: prohibited cross reference from %s to `%T' in %s\n"),
591 abfd, sec, q->address, outsecname,
592 bfd_asymbol_name (*q->sym_ptr_ptr), outdefsecname);
593 }
594 }
595
596 free (relpp);
597}
This page took 0.324639 seconds and 4 git commands to generate.