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