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