OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [binutils-2.18.50/] [ld/] [ldcref.c] - Blame information for rev 826

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.