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