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