mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2025-02-17 13:10:12 +08:00
bfd/
* elflink.c (resolve_symbol): Handle symbols in SEC_MERGE sections. Don't test symbol st_shndx. Don't bother with bfd_link_hash_common symbols. Print longs rather than ints in debug messages. (eval_symbol): Replace "sym" and "advanced" params with "symp". Replace "addr" and "section_offset" params with "dot". Don't cast bfd_vma values to signed, cast them to bfd_signed_vma. (bfd_elf_perform_complex_relocation): Delete "output_bfd", "info", "local_syms" and "local_sections" params. Add "relocation". Delete code calculating relocation value. (evaluate_complex_relocation_symbols): Delete function. Fold into.. (elf_link_input_bfd): ..existing code examining relocs. * elf-bfd.h (bfd_elf_perform_complex_relocation): Update prototype. * elf32-mep.c (mep_elf_check_relocs): Delete function. (mep_elf_gc_sweep_hook, mep_elf_gc_mark_hook): Likewise. (mep_elf_object_p): Don't set elf_bad_symtab. (elf_backend_check_relocs): Don't define. (elf_backend_gc_mark_hook, elf_backend_gc_sweep_hook): Likewise. (elf_backend_can_gc_sections, USE_RELA): Likwise. (mep_elf_relocate_section): Move bfd_elf_perform_complex_relocation call after we have calculated reloc value. Delete local sym debug code. Use RELOC_FOR_GLOBAL_SYMBOL. Delete addend adjusting code.. (elf_backend_rela_normal): ..instead define this. ld/testsuite/ * ld-selective/sel-dump.exp: Add am33, m88k, mep to xfails. * ld-selective/selective.exp: Don't run for same target list we xfail sel-dump.
This commit is contained in:
parent
c9ccd0dfa0
commit
0f02bbd9f8
@ -1,3 +1,30 @@
|
||||
2007-09-29 Alan Modra <amodra@bigpond.net.au>
|
||||
|
||||
* elflink.c (resolve_symbol): Handle symbols in SEC_MERGE
|
||||
sections. Don't test symbol st_shndx. Don't bother with
|
||||
bfd_link_hash_common symbols. Print longs rather than ints
|
||||
in debug messages.
|
||||
(eval_symbol): Replace "sym" and "advanced" params with "symp".
|
||||
Replace "addr" and "section_offset" params with "dot". Don't
|
||||
cast bfd_vma values to signed, cast them to bfd_signed_vma.
|
||||
(bfd_elf_perform_complex_relocation): Delete "output_bfd", "info",
|
||||
"local_syms" and "local_sections" params. Add "relocation".
|
||||
Delete code calculating relocation value.
|
||||
(evaluate_complex_relocation_symbols): Delete function. Fold into..
|
||||
(elf_link_input_bfd): ..existing code examining relocs.
|
||||
* elf-bfd.h (bfd_elf_perform_complex_relocation): Update prototype.
|
||||
* elf32-mep.c (mep_elf_check_relocs): Delete function.
|
||||
(mep_elf_gc_sweep_hook, mep_elf_gc_mark_hook): Likewise.
|
||||
(mep_elf_object_p): Don't set elf_bad_symtab.
|
||||
(elf_backend_check_relocs): Don't define.
|
||||
(elf_backend_gc_mark_hook, elf_backend_gc_sweep_hook): Likewise.
|
||||
(elf_backend_can_gc_sections, USE_RELA): Likwise.
|
||||
(mep_elf_relocate_section): Move bfd_elf_perform_complex_relocation
|
||||
call after we have calculated reloc value. Delete local sym
|
||||
debug code. Use RELOC_FOR_GLOBAL_SYMBOL. Delete addend
|
||||
adjusting code..
|
||||
(elf_backend_rela_normal): ..instead define this.
|
||||
|
||||
2007-09-28 Alan Modra <amodra@bigpond.net.au>
|
||||
|
||||
* elf-m10300.c (mn10300_elf_check_relocs): Delete dead code.
|
||||
|
@ -1814,14 +1814,7 @@ extern bfd_boolean bfd_elf_match_symbols_in_sections
|
||||
(asection *, asection *, struct bfd_link_info *);
|
||||
|
||||
extern void bfd_elf_perform_complex_relocation
|
||||
(bfd * output_bfd ATTRIBUTE_UNUSED,
|
||||
struct bfd_link_info * info,
|
||||
bfd * input_bfd,
|
||||
asection * input_section,
|
||||
bfd_byte * contents,
|
||||
Elf_Internal_Rela * rel,
|
||||
Elf_Internal_Sym * local_syms,
|
||||
asection ** local_sections);
|
||||
(bfd *, asection *, bfd_byte *, Elf_Internal_Rela *, bfd_vma);
|
||||
|
||||
extern bfd_boolean _bfd_elf_setup_sections
|
||||
(bfd *);
|
||||
|
189
bfd/elf32-mep.c
189
bfd/elf32-mep.c
@ -402,48 +402,6 @@ mep_info_to_howto_rela
|
||||
r_type = ELF32_R_TYPE (dst->r_info);
|
||||
cache_ptr->howto = & mep_elf_howto_table [r_type];
|
||||
}
|
||||
|
||||
/* Look through the relocs for a section during the first phase.
|
||||
Since we don't do .gots or .plts, we just need to consider the
|
||||
virtual table relocs for gc. */
|
||||
|
||||
static bfd_boolean
|
||||
mep_elf_check_relocs
|
||||
(bfd * abfd,
|
||||
struct bfd_link_info * info,
|
||||
asection * sec,
|
||||
const Elf_Internal_Rela * relocs)
|
||||
{
|
||||
Elf_Internal_Shdr * symtab_hdr;
|
||||
struct elf_link_hash_entry ** sym_hashes;
|
||||
struct elf_link_hash_entry ** sym_hashes_end;
|
||||
const Elf_Internal_Rela * rel;
|
||||
const Elf_Internal_Rela * rel_end;
|
||||
|
||||
if (info->relocatable)
|
||||
return TRUE;
|
||||
|
||||
symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
|
||||
sym_hashes = elf_sym_hashes (abfd);
|
||||
sym_hashes_end = sym_hashes + symtab_hdr->sh_size / sizeof (Elf32_External_Sym);
|
||||
if (!elf_bad_symtab (abfd))
|
||||
sym_hashes_end -= symtab_hdr->sh_info;
|
||||
|
||||
rel_end = relocs + sec->reloc_count;
|
||||
for (rel = relocs; rel < rel_end; rel++)
|
||||
{
|
||||
struct elf_link_hash_entry *h;
|
||||
unsigned long r_symndx;
|
||||
|
||||
r_symndx = ELF32_R_SYM (rel->r_info);
|
||||
if (r_symndx < symtab_hdr->sh_info)
|
||||
h = NULL;
|
||||
else
|
||||
h = sym_hashes[r_symndx - symtab_hdr->sh_info];
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/* Relocate a MEP ELF section.
|
||||
There is some attempt to make this function usable for many architectures,
|
||||
@ -513,18 +471,7 @@ mep_elf_relocate_section
|
||||
int r_type;
|
||||
|
||||
r_type = ELF32_R_TYPE (rel->r_info);
|
||||
|
||||
r_symndx = ELF32_R_SYM (rel->r_info);
|
||||
|
||||
/* Is this a complex relocation? */
|
||||
if (!info->relocatable && ELF32_R_TYPE (rel->r_info) == R_RELC)
|
||||
{
|
||||
bfd_elf_perform_complex_relocation (output_bfd, info,
|
||||
input_bfd, input_section, contents,
|
||||
rel, local_syms, local_sections);
|
||||
continue;
|
||||
}
|
||||
|
||||
howto = mep_elf_howto_table + ELF32_R_TYPE (rel->r_info);
|
||||
h = NULL;
|
||||
sym = NULL;
|
||||
@ -539,56 +486,17 @@ mep_elf_relocate_section
|
||||
name = bfd_elf_string_from_elf_section
|
||||
(input_bfd, symtab_hdr->sh_link, sym->st_name);
|
||||
name = (name == NULL) ? bfd_section_name (input_bfd, sec) : name;
|
||||
#if 0
|
||||
fprintf (stderr, "local: sec: %s, sym: %s (%d), value: %x + %x + %x addend %x\n",
|
||||
sec->name, name, sym->st_name,
|
||||
sec->output_section->vma, sec->output_offset,
|
||||
sym->st_value, rel->r_addend);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
relocation = 0;
|
||||
h = sym_hashes [r_symndx];
|
||||
bfd_boolean warned, unresolved_reloc;
|
||||
|
||||
while (h->root.type == bfd_link_hash_indirect
|
||||
|| h->root.type == bfd_link_hash_warning)
|
||||
h = (struct elf_link_hash_entry *) h->root.u.i.link;
|
||||
RELOC_FOR_GLOBAL_SYMBOL(info, input_bfd, input_section, rel,
|
||||
r_symndx, symtab_hdr, sym_hashes,
|
||||
h, sec, relocation,
|
||||
unresolved_reloc, warned);
|
||||
|
||||
name = h->root.root.string;
|
||||
|
||||
if (h->root.type == bfd_link_hash_defined
|
||||
|| h->root.type == bfd_link_hash_defweak)
|
||||
{
|
||||
sec = h->root.u.def.section;
|
||||
relocation = (h->root.u.def.value
|
||||
+ sec->output_section->vma
|
||||
+ sec->output_offset);
|
||||
#if 0
|
||||
fprintf (stderr,
|
||||
"defined: sec: %s, name: %s, value: %x + %x + %x gives: %x\n",
|
||||
sec->name, name, h->root.u.def.value,
|
||||
sec->output_section->vma, sec->output_offset, relocation);
|
||||
#endif
|
||||
}
|
||||
else if (h->root.type == bfd_link_hash_undefweak)
|
||||
{
|
||||
#if 0
|
||||
fprintf (stderr, "undefined: sec: %s, name: %s\n",
|
||||
sec->name, name);
|
||||
#endif
|
||||
}
|
||||
else if (!info->relocatable)
|
||||
{
|
||||
if (! ((*info->callbacks->undefined_symbol)
|
||||
(info, h->root.root.string, input_bfd,
|
||||
input_section, rel->r_offset,
|
||||
(!info->shared && info->unresolved_syms_in_objects == RM_GENERATE_ERROR))))
|
||||
return FALSE;
|
||||
#if 0
|
||||
fprintf (stderr, "unknown: name: %s\n", name);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if (sec != NULL && elf_discarded_section (sec))
|
||||
@ -603,18 +511,15 @@ mep_elf_relocate_section
|
||||
}
|
||||
|
||||
if (info->relocatable)
|
||||
{
|
||||
/* This is a relocatable link. We don't have to change
|
||||
anything, unless the reloc is against a section symbol,
|
||||
in which case we have to adjust according to where the
|
||||
section symbol winds up in the output section. */
|
||||
if (sym != NULL && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
|
||||
rel->r_addend += sec->output_offset;
|
||||
continue;
|
||||
}
|
||||
continue;
|
||||
|
||||
switch (r_type)
|
||||
{
|
||||
case R_RELC:
|
||||
bfd_elf_perform_complex_relocation (input_bfd, input_section,
|
||||
contents, rel, relocation);
|
||||
continue;
|
||||
|
||||
default:
|
||||
r = mep_final_link_relocate (howto, input_bfd, input_section,
|
||||
contents, rel, relocation);
|
||||
@ -675,63 +580,6 @@ mep_elf_relocate_section
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/* Update the got entry reference counts for the section being
|
||||
removed. */
|
||||
|
||||
static bfd_boolean
|
||||
mep_elf_gc_sweep_hook
|
||||
(bfd * abfd ATTRIBUTE_UNUSED,
|
||||
struct bfd_link_info * info ATTRIBUTE_UNUSED,
|
||||
asection * sec ATTRIBUTE_UNUSED,
|
||||
const Elf_Internal_Rela * relocs ATTRIBUTE_UNUSED)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Return the section that should be marked against GC for a given
|
||||
relocation. */
|
||||
|
||||
static asection *
|
||||
mep_elf_gc_mark_hook
|
||||
(asection * sec,
|
||||
struct bfd_link_info * info ATTRIBUTE_UNUSED,
|
||||
Elf_Internal_Rela * rel,
|
||||
struct elf_link_hash_entry * h,
|
||||
Elf_Internal_Sym * sym)
|
||||
{
|
||||
if (h != NULL)
|
||||
{
|
||||
switch (ELF32_R_TYPE (rel->r_info))
|
||||
{
|
||||
default:
|
||||
switch (h->root.type)
|
||||
{
|
||||
case bfd_link_hash_defined:
|
||||
case bfd_link_hash_defweak:
|
||||
return h->root.u.def.section;
|
||||
|
||||
case bfd_link_hash_common:
|
||||
return h->root.u.c.p->section;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!(elf_bad_symtab (sec->owner)
|
||||
&& ELF_ST_BIND (sym->st_info) != STB_LOCAL)
|
||||
&& ! ((sym->st_shndx <= 0 || sym->st_shndx >= SHN_LORESERVE)
|
||||
&& sym->st_shndx != SHN_COMMON))
|
||||
return bfd_section_from_elf_index (sec->owner, sym->st_shndx);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/* Function to set the ELF flag bits. */
|
||||
|
||||
@ -899,11 +747,6 @@ elf32_mep_machine (bfd * abfd)
|
||||
static bfd_boolean
|
||||
mep_elf_object_p (bfd * abfd)
|
||||
{
|
||||
/* Irix 5 and 6 is broken. Object file symbol tables are not always
|
||||
sorted correctly such that local symbols preceed global symbols,
|
||||
and the sh_info field in the symbol table is not always right. */
|
||||
/* This is needed for the RELC support code. */
|
||||
elf_bad_symtab (abfd) = TRUE;
|
||||
bfd_default_set_arch_mach (abfd, bfd_arch_mep, elf32_mep_machine (abfd));
|
||||
return TRUE;
|
||||
}
|
||||
@ -940,23 +783,17 @@ mep_elf_fake_sections (bfd * abfd ATTRIBUTE_UNUSED,
|
||||
#define elf_info_to_howto_rel NULL
|
||||
#define elf_info_to_howto mep_info_to_howto_rela
|
||||
#define elf_backend_relocate_section mep_elf_relocate_section
|
||||
#define elf_backend_gc_mark_hook mep_elf_gc_mark_hook
|
||||
#define elf_backend_gc_sweep_hook mep_elf_gc_sweep_hook
|
||||
#define elf_backend_check_relocs mep_elf_check_relocs
|
||||
#define elf_backend_object_p mep_elf_object_p
|
||||
#define elf_backend_section_flags mep_elf_section_flags
|
||||
#define elf_backend_fake_sections mep_elf_fake_sections
|
||||
|
||||
#define elf_backend_can_gc_sections 1
|
||||
|
||||
#define bfd_elf32_bfd_reloc_type_lookup mep_reloc_type_lookup
|
||||
#define bfd_elf32_bfd_reloc_name_lookup mep_reloc_name_lookup
|
||||
#define bfd_elf32_bfd_reloc_name_lookup mep_reloc_name_lookup
|
||||
#define bfd_elf32_bfd_set_private_flags mep_elf_set_private_flags
|
||||
#define bfd_elf32_bfd_copy_private_bfd_data mep_elf_copy_private_bfd_data
|
||||
#define bfd_elf32_bfd_merge_private_bfd_data mep_elf_merge_private_bfd_data
|
||||
#define bfd_elf32_bfd_print_private_bfd_data mep_elf_print_private_bfd_data
|
||||
|
||||
/* We use only the RELA entries. */
|
||||
#define USE_RELA
|
||||
#define elf_backend_rela_normal 1
|
||||
|
||||
#include "elf32-target.h"
|
||||
|
452
bfd/elflink.c
452
bfd/elflink.c
@ -7281,7 +7281,6 @@ resolve_symbol (const char * name,
|
||||
struct bfd_link_hash_entry * global_entry;
|
||||
const char * candidate = NULL;
|
||||
Elf_Internal_Shdr * symtab_hdr;
|
||||
asection * sec = NULL;
|
||||
size_t i;
|
||||
|
||||
symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
|
||||
@ -7289,7 +7288,6 @@ resolve_symbol (const char * name,
|
||||
for (i = 0; i < locsymcount; ++ i)
|
||||
{
|
||||
sym = isymbuf + i;
|
||||
sec = finfo->sections [i];
|
||||
|
||||
if (ELF_ST_BIND (sym->st_info) != STB_LOCAL)
|
||||
continue;
|
||||
@ -7298,26 +7296,18 @@ resolve_symbol (const char * name,
|
||||
symtab_hdr->sh_link,
|
||||
sym->st_name);
|
||||
#ifdef DEBUG
|
||||
printf ("Comparing string: '%s' vs. '%s' = 0x%x\n",
|
||||
name, candidate, (unsigned int)sym->st_value);
|
||||
printf ("Comparing string: '%s' vs. '%s' = 0x%lx\n",
|
||||
name, candidate, (unsigned long) sym->st_value);
|
||||
#endif
|
||||
if (candidate && strcmp (candidate, name) == 0)
|
||||
{
|
||||
* result = sym->st_value;
|
||||
asection *sec = finfo->sections [i];
|
||||
|
||||
if (sym->st_shndx > SHN_UNDEF &&
|
||||
sym->st_shndx < SHN_LORESERVE)
|
||||
{
|
||||
*result = _bfd_elf_rel_local_sym (input_bfd, sym, &sec, 0);
|
||||
*result += sec->output_offset + sec->output_section->vma;
|
||||
#ifdef DEBUG
|
||||
printf ("adjusting for sec '%s' @ 0x%x + 0x%x\n",
|
||||
sec->output_section->name,
|
||||
(unsigned int)sec->output_section->vma,
|
||||
(unsigned int)sec->output_offset);
|
||||
#endif
|
||||
* result += sec->output_offset + sec->output_section->vma;
|
||||
}
|
||||
#ifdef DEBUG
|
||||
printf ("Found symbol with effective value %8.8x\n", (unsigned int)* result);
|
||||
printf ("Found symbol with value %8.8lx\n",
|
||||
(unsigned long) *result);
|
||||
#endif
|
||||
return TRUE;
|
||||
}
|
||||
@ -7335,24 +7325,12 @@ resolve_symbol (const char * name,
|
||||
+ global_entry->u.def.section->output_section->vma
|
||||
+ global_entry->u.def.section->output_offset;
|
||||
#ifdef DEBUG
|
||||
printf ("Found GLOBAL symbol '%s' with value %8.8x\n",
|
||||
global_entry->root.string, (unsigned int)*result);
|
||||
printf ("Found GLOBAL symbol '%s' with value %8.8lx\n",
|
||||
global_entry->root.string, (unsigned long) *result);
|
||||
#endif
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (global_entry->type == bfd_link_hash_common)
|
||||
{
|
||||
*result = global_entry->u.def.value +
|
||||
bfd_com_section_ptr->output_section->vma +
|
||||
bfd_com_section_ptr->output_offset;
|
||||
#ifdef DEBUG
|
||||
printf ("Found COMMON symbol '%s' with value %8.8x\n",
|
||||
global_entry->root.string, (unsigned int)*result);
|
||||
#endif
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -7402,12 +7380,10 @@ undefined_reference (const char * reftype,
|
||||
|
||||
static bfd_boolean
|
||||
eval_symbol (bfd_vma * result,
|
||||
char * sym,
|
||||
char ** advanced,
|
||||
const char ** symp,
|
||||
bfd * input_bfd,
|
||||
struct elf_final_link_info * finfo,
|
||||
bfd_vma addr,
|
||||
bfd_vma section_offset,
|
||||
bfd_vma dot,
|
||||
Elf_Internal_Sym * isymbuf,
|
||||
size_t locsymcount,
|
||||
int signed_p)
|
||||
@ -7418,6 +7394,7 @@ eval_symbol (bfd_vma * result,
|
||||
bfd_vma b;
|
||||
const int bufsz = 4096;
|
||||
char symbuf [bufsz];
|
||||
const char *sym = *symp;
|
||||
const char * symend;
|
||||
bfd_boolean symbol_is_section = FALSE;
|
||||
|
||||
@ -7433,21 +7410,21 @@ eval_symbol (bfd_vma * result,
|
||||
switch (* sym)
|
||||
{
|
||||
case '.':
|
||||
* result = addr + section_offset;
|
||||
* advanced = sym + 1;
|
||||
*result = dot;
|
||||
*symp = sym + 1;
|
||||
return TRUE;
|
||||
|
||||
case '#':
|
||||
++ sym;
|
||||
* result = strtoul (sym, advanced, 16);
|
||||
++sym;
|
||||
*result = strtoul (sym, (char **) symp, 16);
|
||||
return TRUE;
|
||||
|
||||
case 'S':
|
||||
symbol_is_section = TRUE;
|
||||
case 's':
|
||||
++ sym;
|
||||
symlen = strtol (sym, &sym, 10);
|
||||
++ sym; /* Skip the trailing ':'. */
|
||||
++sym;
|
||||
symlen = strtol (sym, (char **) symp, 10);
|
||||
sym = *symp + 1; /* Skip the trailing ':'. */
|
||||
|
||||
if ((symend < sym) || ((symlen + 1) > bufsz))
|
||||
{
|
||||
@ -7457,7 +7434,7 @@ eval_symbol (bfd_vma * result,
|
||||
|
||||
memcpy (symbuf, sym, symlen);
|
||||
symbuf [symlen] = '\0';
|
||||
* advanced = sym + symlen;
|
||||
*symp = sym + symlen;
|
||||
|
||||
/* Is it always possible, with complex symbols, that gas "mis-guessed"
|
||||
the symbol as a section, or vice-versa. so we're pretty liberal in our
|
||||
@ -7496,15 +7473,14 @@ eval_symbol (bfd_vma * result,
|
||||
sym += strlen (#op); \
|
||||
if (* sym == ':') \
|
||||
++ sym; \
|
||||
if (!eval_symbol (&a, sym, &sym, input_bfd, finfo, addr, \
|
||||
section_offset, isymbuf, locsymcount, \
|
||||
signed_p)) \
|
||||
*symp = sym; \
|
||||
if (!eval_symbol (&a, symp, input_bfd, finfo, dot, \
|
||||
isymbuf, locsymcount, signed_p)) \
|
||||
return FALSE; \
|
||||
if (signed_p) \
|
||||
* result = op ((signed)a); \
|
||||
*result = op ((bfd_signed_vma) a); \
|
||||
else \
|
||||
* result = op a; \
|
||||
* advanced = sym; \
|
||||
return TRUE; \
|
||||
}
|
||||
|
||||
@ -7514,20 +7490,18 @@ eval_symbol (bfd_vma * result,
|
||||
sym += strlen (#op); \
|
||||
if (* sym == ':') \
|
||||
++ sym; \
|
||||
if (!eval_symbol (&a, sym, &sym, input_bfd, finfo, addr, \
|
||||
section_offset, isymbuf, locsymcount, \
|
||||
signed_p)) \
|
||||
*symp = sym; \
|
||||
if (!eval_symbol (&a, symp, input_bfd, finfo, dot, \
|
||||
isymbuf, locsymcount, signed_p)) \
|
||||
return FALSE; \
|
||||
++ sym; \
|
||||
if (!eval_symbol (&b, sym, &sym, input_bfd, finfo, addr, \
|
||||
section_offset, isymbuf, locsymcount, \
|
||||
signed_p)) \
|
||||
++*symp; \
|
||||
if (!eval_symbol (&b, symp, input_bfd, finfo, dot, \
|
||||
isymbuf, locsymcount, signed_p)) \
|
||||
return FALSE; \
|
||||
if (signed_p) \
|
||||
* result = ((signed) a) op ((signed) b); \
|
||||
*result = ((bfd_signed_vma) a) op ((bfd_signed_vma) b); \
|
||||
else \
|
||||
* result = a op b; \
|
||||
* advanced = sym; \
|
||||
return TRUE; \
|
||||
}
|
||||
|
||||
@ -7561,141 +7535,6 @@ eval_symbol (bfd_vma * result,
|
||||
}
|
||||
}
|
||||
|
||||
/* Entry point to evaluator, called from elf_link_input_bfd. */
|
||||
|
||||
static bfd_boolean
|
||||
evaluate_complex_relocation_symbols (bfd *input_bfd,
|
||||
struct elf_final_link_info *finfo,
|
||||
Elf_Internal_Sym *isymbuf,
|
||||
size_t locsymcount)
|
||||
{
|
||||
const struct elf_backend_data * bed;
|
||||
Elf_Internal_Shdr * symtab_hdr;
|
||||
struct elf_link_hash_entry ** sym_hashes;
|
||||
asection * reloc_sec;
|
||||
bfd_boolean result = TRUE;
|
||||
|
||||
/* For each section, we're going to check and see if it has any
|
||||
complex relocations, and we're going to evaluate any of them
|
||||
we can. */
|
||||
|
||||
if (finfo->info->relocatable)
|
||||
return TRUE;
|
||||
|
||||
symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
|
||||
sym_hashes = elf_sym_hashes (input_bfd);
|
||||
bed = get_elf_backend_data (input_bfd);
|
||||
|
||||
for (reloc_sec = input_bfd->sections; reloc_sec; reloc_sec = reloc_sec->next)
|
||||
{
|
||||
Elf_Internal_Rela * internal_relocs;
|
||||
unsigned long i;
|
||||
|
||||
/* This section was omitted from the link. */
|
||||
if (! reloc_sec->linker_mark)
|
||||
continue;
|
||||
|
||||
/* Only process sections containing relocs. */
|
||||
if ((reloc_sec->flags & SEC_RELOC) == 0)
|
||||
continue;
|
||||
|
||||
if (reloc_sec->reloc_count == 0)
|
||||
continue;
|
||||
|
||||
/* Read in the relocs for this section. */
|
||||
internal_relocs
|
||||
= _bfd_elf_link_read_relocs (input_bfd, reloc_sec, NULL,
|
||||
(Elf_Internal_Rela *) NULL,
|
||||
FALSE);
|
||||
if (internal_relocs == NULL)
|
||||
continue;
|
||||
|
||||
for (i = reloc_sec->reloc_count; i--;)
|
||||
{
|
||||
Elf_Internal_Rela * rel;
|
||||
char * sym_name;
|
||||
bfd_vma index;
|
||||
Elf_Internal_Sym * sym;
|
||||
bfd_vma result;
|
||||
bfd_vma section_offset;
|
||||
bfd_vma addr;
|
||||
int signed_p = 0;
|
||||
|
||||
rel = internal_relocs + i;
|
||||
section_offset = reloc_sec->output_section->vma
|
||||
+ reloc_sec->output_offset;
|
||||
addr = rel->r_offset;
|
||||
|
||||
index = ELF32_R_SYM (rel->r_info);
|
||||
if (bed->s->arch_size == 64)
|
||||
index >>= 24;
|
||||
|
||||
if (index == STN_UNDEF)
|
||||
continue;
|
||||
|
||||
if (index < locsymcount)
|
||||
{
|
||||
/* The symbol is local. */
|
||||
sym = isymbuf + index;
|
||||
|
||||
/* We're only processing STT_RELC or STT_SRELC type symbols. */
|
||||
if ((ELF_ST_TYPE (sym->st_info) != STT_RELC) &&
|
||||
(ELF_ST_TYPE (sym->st_info) != STT_SRELC))
|
||||
continue;
|
||||
|
||||
sym_name = bfd_elf_string_from_elf_section
|
||||
(input_bfd, symtab_hdr->sh_link, sym->st_name);
|
||||
|
||||
signed_p = (ELF_ST_TYPE (sym->st_info) == STT_SRELC);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The symbol is global. */
|
||||
struct elf_link_hash_entry * h;
|
||||
|
||||
if (elf_bad_symtab (input_bfd))
|
||||
continue;
|
||||
|
||||
h = sym_hashes [index - locsymcount];
|
||||
while ( h->root.type == bfd_link_hash_indirect
|
||||
|| h->root.type == bfd_link_hash_warning)
|
||||
h = (struct elf_link_hash_entry *) h->root.u.i.link;
|
||||
|
||||
if (h->type != STT_RELC && h->type != STT_SRELC)
|
||||
continue;
|
||||
|
||||
signed_p = (h->type == STT_SRELC);
|
||||
sym_name = (char *) h->root.root.string;
|
||||
}
|
||||
#ifdef DEBUG
|
||||
printf ("Encountered a complex symbol!");
|
||||
printf (" (input_bfd %s, section %s, reloc %ld\n",
|
||||
input_bfd->filename, reloc_sec->name, i);
|
||||
printf (" symbol: idx %8.8lx, name %s\n",
|
||||
index, sym_name);
|
||||
printf (" reloc : info %8.8lx, addr %8.8lx\n",
|
||||
rel->r_info, addr);
|
||||
printf (" Evaluating '%s' ...\n ", sym_name);
|
||||
#endif
|
||||
if (eval_symbol (& result, sym_name, & sym_name, input_bfd,
|
||||
finfo, addr, section_offset, isymbuf, locsymcount,
|
||||
signed_p))
|
||||
/* Symbol evaluated OK. Update to absolute value. */
|
||||
set_symbol_value (input_bfd, isymbuf, locsymcount, index, result);
|
||||
|
||||
else
|
||||
result = FALSE;
|
||||
}
|
||||
|
||||
if (internal_relocs != elf_section_data (reloc_sec)->relocs)
|
||||
free (internal_relocs);
|
||||
}
|
||||
|
||||
/* If nothing went wrong, then we adjusted
|
||||
everything we wanted to adjust. */
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
put_value (bfd_vma size,
|
||||
unsigned long chunksz,
|
||||
@ -7791,84 +7630,20 @@ decode_complex_addend
|
||||
}
|
||||
|
||||
void
|
||||
bfd_elf_perform_complex_relocation
|
||||
(bfd * output_bfd ATTRIBUTE_UNUSED,
|
||||
struct bfd_link_info * info,
|
||||
bfd * input_bfd,
|
||||
asection * input_section,
|
||||
bfd_byte * contents,
|
||||
Elf_Internal_Rela * rel,
|
||||
Elf_Internal_Sym * local_syms,
|
||||
asection ** local_sections)
|
||||
bfd_elf_perform_complex_relocation (bfd *input_bfd,
|
||||
asection *input_section,
|
||||
bfd_byte *contents,
|
||||
Elf_Internal_Rela *rel,
|
||||
bfd_vma relocation)
|
||||
{
|
||||
const struct elf_backend_data * bed;
|
||||
Elf_Internal_Shdr * symtab_hdr;
|
||||
asection * sec;
|
||||
bfd_vma relocation = 0, shift, x;
|
||||
bfd_vma r_symndx;
|
||||
bfd_vma mask;
|
||||
unsigned long start, oplen, len, wordsz,
|
||||
chunksz, lsb0_p, signed_p, trunc_p;
|
||||
bfd_vma shift, x, mask;
|
||||
unsigned long start, oplen, len, wordsz, chunksz, lsb0_p, signed_p, trunc_p;
|
||||
|
||||
/* Perform this reloc, since it is complex.
|
||||
(this is not to say that it necessarily refers to a complex
|
||||
symbol; merely that it is a self-describing CGEN based reloc.
|
||||
i.e. the addend has the complete reloc information (bit start, end,
|
||||
word size, etc) encoded within it.). */
|
||||
r_symndx = ELF32_R_SYM (rel->r_info);
|
||||
bed = get_elf_backend_data (input_bfd);
|
||||
if (bed->s->arch_size == 64)
|
||||
r_symndx >>= 24;
|
||||
|
||||
#ifdef DEBUG
|
||||
printf ("Performing complex relocation %ld...\n", r_symndx);
|
||||
#endif
|
||||
|
||||
symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
|
||||
if (r_symndx < symtab_hdr->sh_info)
|
||||
{
|
||||
/* The symbol is local. */
|
||||
Elf_Internal_Sym * sym;
|
||||
|
||||
sym = local_syms + r_symndx;
|
||||
sec = local_sections [r_symndx];
|
||||
relocation = sym->st_value;
|
||||
if (sym->st_shndx > SHN_UNDEF &&
|
||||
sym->st_shndx < SHN_LORESERVE)
|
||||
relocation += (sec->output_offset +
|
||||
sec->output_section->vma);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The symbol is global. */
|
||||
struct elf_link_hash_entry **sym_hashes;
|
||||
struct elf_link_hash_entry * h;
|
||||
|
||||
sym_hashes = elf_sym_hashes (input_bfd);
|
||||
h = sym_hashes [r_symndx];
|
||||
|
||||
while (h->root.type == bfd_link_hash_indirect
|
||||
|| h->root.type == bfd_link_hash_warning)
|
||||
h = (struct elf_link_hash_entry *) h->root.u.i.link;
|
||||
|
||||
if (h->root.type == bfd_link_hash_defined
|
||||
|| h->root.type == bfd_link_hash_defweak)
|
||||
{
|
||||
sec = h->root.u.def.section;
|
||||
relocation = h->root.u.def.value;
|
||||
|
||||
if (! bfd_is_abs_section (sec))
|
||||
relocation += (sec->output_section->vma
|
||||
+ sec->output_offset);
|
||||
}
|
||||
if (h->root.type == bfd_link_hash_undefined
|
||||
&& !((*info->callbacks->undefined_symbol)
|
||||
(info, h->root.root.string, input_bfd,
|
||||
input_section, rel->r_offset,
|
||||
info->unresolved_syms_in_objects == RM_GENERATE_ERROR
|
||||
|| ELF_ST_VISIBILITY (h->other))))
|
||||
return;
|
||||
}
|
||||
|
||||
decode_complex_addend (& start, & oplen, & len, & wordsz,
|
||||
& chunksz, & lsb0_p, & signed_p,
|
||||
@ -9213,10 +8988,6 @@ elf_link_input_bfd (struct elf_final_link_info *finfo, bfd *input_bfd)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (! evaluate_complex_relocation_symbols (input_bfd, finfo, isymbuf,
|
||||
locsymcount))
|
||||
return FALSE;
|
||||
|
||||
/* Relocate the contents of each section. */
|
||||
sym_hashes = elf_sym_hashes (input_bfd);
|
||||
for (o = input_bfd->sections; o != NULL; o = o->next)
|
||||
@ -9258,8 +9029,10 @@ elf_link_input_bfd (struct elf_final_link_info *finfo, bfd *input_bfd)
|
||||
if ((o->flags & SEC_RELOC) != 0)
|
||||
{
|
||||
Elf_Internal_Rela *internal_relocs;
|
||||
Elf_Internal_Rela *rel, *relend;
|
||||
bfd_vma r_type_mask;
|
||||
int r_sym_shift;
|
||||
int action_discarded;
|
||||
int ret;
|
||||
|
||||
/* Get the swapped relocs. */
|
||||
@ -9281,76 +9054,107 @@ elf_link_input_bfd (struct elf_final_link_info *finfo, bfd *input_bfd)
|
||||
r_sym_shift = 32;
|
||||
}
|
||||
|
||||
/* Run through the relocs looking for any against symbols
|
||||
from discarded sections and section symbols from
|
||||
removed link-once sections. Complain about relocs
|
||||
against discarded sections. Zero relocs against removed
|
||||
link-once sections. */
|
||||
action_discarded = -1;
|
||||
if (!elf_section_ignore_discarded_relocs (o))
|
||||
action_discarded = (*bed->action_discarded) (o);
|
||||
|
||||
/* Run through the relocs evaluating complex reloc symbols and
|
||||
looking for relocs against symbols from discarded sections
|
||||
or section symbols from removed link-once sections.
|
||||
Complain about relocs against discarded sections. Zero
|
||||
relocs against removed link-once sections. */
|
||||
|
||||
rel = internal_relocs;
|
||||
relend = rel + o->reloc_count * bed->s->int_rels_per_ext_rel;
|
||||
for ( ; rel < relend; rel++)
|
||||
{
|
||||
Elf_Internal_Rela *rel, *relend;
|
||||
unsigned int action = (*bed->action_discarded) (o);
|
||||
unsigned long r_symndx = rel->r_info >> r_sym_shift;
|
||||
unsigned int s_type;
|
||||
asection **ps, *sec;
|
||||
struct elf_link_hash_entry *h = NULL;
|
||||
const char *sym_name;
|
||||
|
||||
rel = internal_relocs;
|
||||
relend = rel + o->reloc_count * bed->s->int_rels_per_ext_rel;
|
||||
for ( ; rel < relend; rel++)
|
||||
if (r_symndx == STN_UNDEF)
|
||||
continue;
|
||||
|
||||
if (r_symndx >= locsymcount
|
||||
|| (elf_bad_symtab (input_bfd)
|
||||
&& finfo->sections[r_symndx] == NULL))
|
||||
{
|
||||
unsigned long r_symndx = rel->r_info >> r_sym_shift;
|
||||
asection **ps, *sec;
|
||||
struct elf_link_hash_entry *h = NULL;
|
||||
const char *sym_name;
|
||||
h = sym_hashes[r_symndx - extsymoff];
|
||||
|
||||
if (r_symndx == STN_UNDEF)
|
||||
continue;
|
||||
|
||||
if (r_symndx >= locsymcount
|
||||
|| (elf_bad_symtab (input_bfd)
|
||||
&& finfo->sections[r_symndx] == NULL))
|
||||
/* Badly formatted input files can contain relocs that
|
||||
reference non-existant symbols. Check here so that
|
||||
we do not seg fault. */
|
||||
if (h == NULL)
|
||||
{
|
||||
h = sym_hashes[r_symndx - extsymoff];
|
||||
char buffer [32];
|
||||
|
||||
/* Badly formatted input files can contain relocs that
|
||||
reference non-existant symbols. Check here so that
|
||||
we do not seg fault. */
|
||||
if (h == NULL)
|
||||
{
|
||||
char buffer [32];
|
||||
|
||||
sprintf_vma (buffer, rel->r_info);
|
||||
(*_bfd_error_handler)
|
||||
(_("error: %B contains a reloc (0x%s) for section %A "
|
||||
"that references a non-existent global symbol"),
|
||||
input_bfd, o, buffer);
|
||||
bfd_set_error (bfd_error_bad_value);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
while (h->root.type == bfd_link_hash_indirect
|
||||
|| h->root.type == bfd_link_hash_warning)
|
||||
h = (struct elf_link_hash_entry *) h->root.u.i.link;
|
||||
|
||||
if (h->root.type != bfd_link_hash_defined
|
||||
&& h->root.type != bfd_link_hash_defweak)
|
||||
continue;
|
||||
|
||||
ps = &h->root.u.def.section;
|
||||
sym_name = h->root.root.string;
|
||||
}
|
||||
else
|
||||
{
|
||||
Elf_Internal_Sym *sym = isymbuf + r_symndx;
|
||||
ps = &finfo->sections[r_symndx];
|
||||
sym_name = bfd_elf_sym_name (input_bfd,
|
||||
symtab_hdr,
|
||||
sym, *ps);
|
||||
sprintf_vma (buffer, rel->r_info);
|
||||
(*_bfd_error_handler)
|
||||
(_("error: %B contains a reloc (0x%s) for section %A "
|
||||
"that references a non-existent global symbol"),
|
||||
input_bfd, o, buffer);
|
||||
bfd_set_error (bfd_error_bad_value);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
while (h->root.type == bfd_link_hash_indirect
|
||||
|| h->root.type == bfd_link_hash_warning)
|
||||
h = (struct elf_link_hash_entry *) h->root.u.i.link;
|
||||
|
||||
s_type = h->type;
|
||||
|
||||
ps = NULL;
|
||||
if (h->root.type == bfd_link_hash_defined
|
||||
|| h->root.type == bfd_link_hash_defweak)
|
||||
ps = &h->root.u.def.section;
|
||||
|
||||
sym_name = h->root.root.string;
|
||||
}
|
||||
else
|
||||
{
|
||||
Elf_Internal_Sym *sym = isymbuf + r_symndx;
|
||||
|
||||
s_type = ELF_ST_TYPE (sym->st_info);
|
||||
ps = &finfo->sections[r_symndx];
|
||||
sym_name = bfd_elf_sym_name (input_bfd, symtab_hdr,
|
||||
sym, *ps);
|
||||
}
|
||||
|
||||
if (s_type == STT_RELC || s_type == STT_SRELC)
|
||||
{
|
||||
bfd_vma val;
|
||||
bfd_vma dot = (rel->r_offset
|
||||
+ o->output_offset + o->output_section->vma);
|
||||
#ifdef DEBUG
|
||||
printf ("Encountered a complex symbol!");
|
||||
printf (" (input_bfd %s, section %s, reloc %ld\n",
|
||||
input_bfd->filename, o->name, rel - internal_relocs);
|
||||
printf (" symbol: idx %8.8lx, name %s\n",
|
||||
r_symndx, sym_name);
|
||||
printf (" reloc : info %8.8lx, addr %8.8lx\n",
|
||||
(unsigned long) rel->r_info,
|
||||
(unsigned long) rel->r_offset);
|
||||
#endif
|
||||
if (!eval_symbol (&val, &sym_name, input_bfd, finfo, dot,
|
||||
isymbuf, locsymcount, s_type == STT_SRELC))
|
||||
return FALSE;
|
||||
|
||||
/* Symbol evaluated OK. Update to absolute value. */
|
||||
set_symbol_value (input_bfd, isymbuf, locsymcount,
|
||||
r_symndx, val);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (action_discarded != -1 && ps != NULL)
|
||||
{
|
||||
/* Complain if the definition comes from a
|
||||
discarded section. */
|
||||
if ((sec = *ps) != NULL && elf_discarded_section (sec))
|
||||
{
|
||||
BFD_ASSERT (r_symndx != 0);
|
||||
if (action & COMPLAIN)
|
||||
if (action_discarded & COMPLAIN)
|
||||
(*finfo->info->callbacks->einfo)
|
||||
(_("%X`%s' referenced in section `%A' of %B: "
|
||||
"defined in discarded section `%A' of %B\n"),
|
||||
@ -9362,7 +9166,7 @@ elf_link_input_bfd (struct elf_final_link_info *finfo, bfd *input_bfd)
|
||||
FIXME: This is quite broken. Modifying the
|
||||
symbol here means we will be changing all later
|
||||
uses of the symbol, not just in this section. */
|
||||
if (action & PRETEND)
|
||||
if (action_discarded & PRETEND)
|
||||
{
|
||||
asection *kept;
|
||||
|
||||
|
@ -1,3 +1,9 @@
|
||||
2007-09-29 Alan Modra <amodra@bigpond.net.au>
|
||||
|
||||
* ld-selective/sel-dump.exp: Add am33, m88k, mep to xfails.
|
||||
* ld-selective/selective.exp: Don't run for same target list
|
||||
we xfail sel-dump.
|
||||
|
||||
2007-09-29 Mike Frysinger <vapier@gentoo.org>
|
||||
|
||||
* ld-alpha/tlsbin.rd: Use [0-9]+ to match section header count and
|
||||
|
@ -28,8 +28,8 @@ set test_list [lsort [glob -nocomplain $srcdir/$subdir/*.d]]
|
||||
for { set i 0 } { $i < [llength $test_list] } { incr i } {
|
||||
# We need to strip the ".d", but can leave the dirname.
|
||||
verbose [file rootname [lindex $test_list $i]]
|
||||
setup_xfail "alpha*-*" "arc*-*" "d30v*-*" "dlx*-*" "hppa64-*-*"
|
||||
setup_xfail "i370*-*" "i860*-*" "i960*-*" "ia64*-*" "mn10200-*"
|
||||
setup_xfail "or32-*" "pj-*"
|
||||
setup_xfail "alpha*-*" "am33*-*" "arc*-*" "d30v*-*" "dlx*-*"
|
||||
setup_xfail "hppa*64-*-*" "i370*-*" "i860*-*" "i960*-*" "ia64*-*"
|
||||
setup_xfail "m88*-*" "mn10200-*" "mep-*" "or32-*" "pj-*"
|
||||
run_dump_test [file rootname [lindex $test_list $i]]
|
||||
}
|
||||
|
@ -27,8 +27,15 @@ if ![is_elf_format] {
|
||||
return
|
||||
}
|
||||
|
||||
# Alpha and IA64 do not support selective linking
|
||||
if {[istarget "alpha*-*-*"] || [istarget "ia64-*-*"]} {
|
||||
# These targets do not support selective linking
|
||||
if {[istarget "alpha*-*-*"] || [istarget "am33*-*-*"] ||
|
||||
[istarget "arc-*-*"] || [istarget "d30v-*-*"] ||
|
||||
[istarget "dlx-*-*"] || [istarget "hppa*64*-*-*"] ||
|
||||
[istarget "i370-*-*"] || [istarget "i860-*-*"] ||
|
||||
[istarget "i960-*-*"] || [istarget "ia64-*-*"] ||
|
||||
[istarget "m88*-*-*"] || [istarget "mn10200-*-*"] ||
|
||||
[istarget "mep-*-*"] || [istarget "or32-*-*"] ||
|
||||
[istarget "pj*-*-*"]} {
|
||||
return
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user