1 /* ldcref.c -- output a cross reference table 2 Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2006 3 Free Software Foundation, Inc. 4 Written by Ian Lance Taylor <ian@cygnus.com> 5 6 This file is part of GLD, the Gnu Linker. 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 2 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, MA 02110-1301, USA. */ 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 40 struct cref_ref { 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 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 65 struct cref_hash_table { 66 struct bfd_hash_table root; 67 }; 68 69 /* Forward declarations. */ 70 71 static void output_one_cref (FILE *, struct cref_hash_entry *); 72 static void check_local_sym_xref (lang_input_statement_type *); 73 static bfd_boolean check_nocrossref (struct cref_hash_entry *, void *); 74 static void check_refs (const char *, bfd_boolean, asection *, bfd *, 75 struct lang_nocrossrefs *); 76 static void check_reloc_refs (bfd *, asection *, void *); 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, \ 89 (bfd_boolean (*) (struct bfd_hash_entry *, void *)) (func), \ 90 (info))) 91 92 /* The cref hash table. */ 93 94 static struct cref_hash_table cref_table; 95 96 /* Whether the cref hash table has been initialized. */ 97 98 static bfd_boolean cref_initialized; 99 100 /* The number of symbols seen so far. */ 101 102 static size_t cref_symcount; 103 104 /* Create an entry in a cref hash table. */ 105 106 static struct bfd_hash_entry * 107 cref_hash_newfunc (struct bfd_hash_entry *entry, 108 struct bfd_hash_table *table, 109 const char *string) 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) 119 return NULL; 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 131 table. */ 132 ++cref_symcount; 133 } 134 135 return &ret->root; 136 } 137 138 /* Add a symbol to the cref hash table. This is called for every 139 global symbol that is seen during the link. */ 140 141 void 142 add_cref (const char *name, 143 bfd *abfd, 144 asection *section, 145 bfd_vma value ATTRIBUTE_UNUSED) 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 sizeof (struct cref_hash_entry))) 154 einfo (_("%X%P: bfd_hash_table_init of cref table failed: %E\n")); 155 cref_initialized = TRUE; 156 } 157 158 h = cref_hash_lookup (&cref_table, name, TRUE, FALSE); 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 { 168 r = xmalloc (sizeof *r); 169 r->next = h->refs; 170 h->refs = r; 171 r->abfd = abfd; 172 r->def = FALSE; 173 r->common = FALSE; 174 r->undef = FALSE; 175 } 176 177 if (bfd_is_und_section (section)) 178 r->undef = TRUE; 179 else if (bfd_is_com_section (section)) 180 r->common = TRUE; 181 else 182 r->def = TRUE; 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 189 static bfd_boolean 190 cref_fill_array (struct cref_hash_entry *h, void *data) 191 { 192 struct cref_hash_entry ***pph = data; 193 194 ASSERT (h->demangled == NULL); 195 h->demangled = demangle (h->root.string); 196 197 **pph = h; 198 199 ++*pph; 200 201 return TRUE; 202 } 203 204 /* Sort an array of cref hash table entries by name. */ 205 206 static int 207 cref_sort_array (const void *a1, const void *a2) 208 { 209 const struct cref_hash_entry * const *p1 = a1; 210 const struct cref_hash_entry * const *p2 = a2; 211 212 return strcmp ((*p1)->demangled, (*p2)->demangled); 213 } 214 215 /* Write out the cref table. */ 216 217 #define FILECOL (50) 218 219 void 220 output_cref (FILE *fp) 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"); 228 fprintf (fp, "%s", msg); 229 len = strlen (msg); 230 while (len < FILECOL) 231 { 232 putc (' ', fp); 233 ++len; 234 } 235 fprintf (fp, _("File\n")); 236 237 if (! cref_initialized) 238 { 239 fprintf (fp, _("No symbols\n")); 240 return; 241 } 242 243 csyms = xmalloc (cref_symcount * sizeof (*csyms)); 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 258 static void 259 output_one_cref (FILE *fp, struct cref_hash_entry *h) 260 { 261 int len; 262 struct bfd_link_hash_entry *hl; 263 struct cref_ref *r; 264 265 hl = bfd_link_hash_lookup (link_info.hash, h->root.string, FALSE, 266 FALSE, TRUE); 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 326 void 327 check_nocrossrefs (void) 328 { 329 if (! cref_initialized) 330 return; 331 332 cref_hash_traverse (&cref_table, check_nocrossref, NULL); 333 334 lang_for_each_file (check_local_sym_xref); 335 } 336 337 /* Check for prohibited cross references to local and section symbols. */ 338 339 static void 340 check_local_sym_xref (lang_input_statement_type *statement) 341 { 342 bfd *abfd; 343 lang_input_statement_type *li; 344 asymbol **asymbols, **syms; 345 346 abfd = statement->the_bfd; 347 if (abfd == NULL) 348 return; 349 350 li = abfd->usrdata; 351 if (li != NULL && li->asymbols != NULL) 352 asymbols = li->asymbols; 353 else 354 { 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 } 371 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) 379 { 380 const char *outsecname, *symname; 381 struct lang_nocrossrefs *ncrs; 382 struct lang_nocrossref *ncr; 383 384 outsecname = sym->section->output_section->name; 385 symname = NULL; 386 if ((sym->flags & BSF_SECTION_SYM) == 0) 387 symname = sym->name; 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) 391 check_refs (symname, FALSE, sym->section, abfd, ncrs); 392 } 393 } 394 395 if (li == NULL) 396 free (asymbols); 397 } 398 399 /* Check one symbol to see if it is a prohibited cross reference. */ 400 401 static bfd_boolean 402 check_nocrossref (struct cref_hash_entry *h, void *ignore ATTRIBUTE_UNUSED) 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; 409 struct cref_ref *ref; 410 411 hl = bfd_link_hash_lookup (link_info.hash, h->root.string, FALSE, 412 FALSE, TRUE); 413 if (hl == NULL) 414 { 415 einfo (_("%P: symbol `%T' missing from main hash table\n"), 416 h->root.string); 417 return TRUE; 418 } 419 420 if (hl->type != bfd_link_hash_defined 421 && hl->type != bfd_link_hash_defweak) 422 return TRUE; 423 424 defsec = hl->u.def.section->output_section; 425 if (defsec == NULL) 426 return TRUE; 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) 432 for (ref = h->refs; ref != NULL; ref = ref->next) 433 check_refs (hl->root.string, TRUE, hl->u.def.section, 434 ref->abfd, ncrs); 435 436 return TRUE; 437 } 438 439 /* The struct is used to pass information from check_refs to 440 check_reloc_refs through bfd_map_over_sections. */ 441 442 struct check_refs_info { 443 const char *sym_name; 444 asection *defsec; 445 struct lang_nocrossrefs *ncrs; 446 asymbol **asymbols; 447 bfd_boolean global; 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 455 static void 456 check_refs (const char *name, 457 bfd_boolean global, 458 asection *sec, 459 bfd *abfd, 460 struct lang_nocrossrefs *ncrs) 461 { 462 lang_input_statement_type *li; 463 asymbol **asymbols; 464 struct check_refs_info info; 465 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 472 li = abfd->usrdata; 473 if (li != NULL && li->asymbols != NULL) 474 asymbols = li->asymbols; 475 else 476 { 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); 483 asymbols = xmalloc (symsize); 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) 488 { 489 li->asymbols = asymbols; 490 li->symbol_count = symbol_count; 491 } 492 } 493 494 info.sym_name = name; 495 info.global = global; 496 info.defsec = sec; 497 info.ncrs = ncrs; 498 info.asymbols = asymbols; 499 bfd_map_over_sections (abfd, check_reloc_refs, &info); 500 501 if (li == NULL) 502 free (asymbols); 503 } 504 505 /* This is called via bfd_map_over_sections. INFO->SYM_NAME is a symbol 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 509 INFO->SYM_NAME, then we report a prohibited cross reference error. */ 510 511 static void 512 check_reloc_refs (bfd *abfd, asection *sec, void *iarg) 513 { 514 struct check_refs_info *info = iarg; 515 asection *outsec; 516 const char *outsecname; 517 asection *outdefsec; 518 const char *outdefsecname; 519 struct lang_nocrossref *ncr; 520 const char *symname; 521 bfd_boolean global; 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 546 INFO->SYM_NAME. If INFO->SYMNAME is NULL, check for relocations 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. */ 551 552 symname = info->sym_name; 553 global = info->global; 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 561 relpp = xmalloc (relsize); 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 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)) 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))) 586 { 587 /* We found a reloc for the symbol. The symbol is defined 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. */ 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 } 599