mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-24 10:35:12 +08:00
PR ld/10406
* elf32-ppc.c (ppc_elf_howto_raw): Make R_PPC_EMB_SDAI16 and R_PPC_EMB_SDA2I16 complain_overflow_signed. (create_sdata_sym): Pass info rather than htab. Update all callers. Ensure symbols are hidden. (ppc_elf_check_relocs): Allow SDAREL16 when shared. (ppc_elf_size_dynamic_sections): When shared, equate _SDA_BASE_ to _GLOBAL_OFFSET_TABLE_. (elf_finish_pointer_linker_section): Don't assume that sdata base symbol is always at 0x8000 offset. Don't subtract the addend here. (is_static_defined): New function. (ppc_elf_relocate_section): Verify symbol base used in SDA relocs is statically defined. Clear addend for EMB_SDAI16 and EMB_SDA2I16 relocs. Downgrade error on unexpected section for EMB_SDA2REL reloc symbols to a warning.
This commit is contained in:
parent
2f0205e893
commit
bd6c6e2b80
@ -1,3 +1,21 @@
|
||||
2009-09-18 Alan Modra <amodra@bigpond.net.au>
|
||||
|
||||
PR ld/10406
|
||||
* elf32-ppc.c (ppc_elf_howto_raw): Make R_PPC_EMB_SDAI16 and
|
||||
R_PPC_EMB_SDA2I16 complain_overflow_signed.
|
||||
(create_sdata_sym): Pass info rather than htab.
|
||||
Update all callers. Ensure symbols are hidden.
|
||||
(ppc_elf_check_relocs): Allow SDAREL16 when shared.
|
||||
(ppc_elf_size_dynamic_sections): When shared, equate _SDA_BASE_ to
|
||||
_GLOBAL_OFFSET_TABLE_.
|
||||
(elf_finish_pointer_linker_section): Don't assume that sdata base
|
||||
symbol is always at 0x8000 offset. Don't subtract the addend here.
|
||||
(is_static_defined): New function.
|
||||
(ppc_elf_relocate_section): Verify symbol base used in SDA relocs
|
||||
is statically defined. Clear addend for EMB_SDAI16 and EMB_SDA2I16
|
||||
relocs. Downgrade error on unexpected section for EMB_SDA2REL
|
||||
reloc symbols to a warning.
|
||||
|
||||
2009-09-18 Nick Clifton <nickc@redhat.com>
|
||||
|
||||
* po/es.po: Updated Spanish translation.
|
||||
|
102
bfd/elf32-ppc.c
102
bfd/elf32-ppc.c
@ -1300,7 +1300,7 @@ static reloc_howto_type ppc_elf_howto_raw[] = {
|
||||
16, /* bitsize */
|
||||
FALSE, /* pc_relative */
|
||||
0, /* bitpos */
|
||||
complain_overflow_bitfield, /* complain_on_overflow */
|
||||
complain_overflow_signed, /* complain_on_overflow */
|
||||
bfd_elf_generic_reloc, /* special_function */
|
||||
"R_PPC_EMB_SDAI16", /* name */
|
||||
FALSE, /* partial_inplace */
|
||||
@ -1317,7 +1317,7 @@ static reloc_howto_type ppc_elf_howto_raw[] = {
|
||||
16, /* bitsize */
|
||||
FALSE, /* pc_relative */
|
||||
0, /* bitpos */
|
||||
complain_overflow_bitfield, /* complain_on_overflow */
|
||||
complain_overflow_signed, /* complain_on_overflow */
|
||||
bfd_elf_generic_reloc, /* special_function */
|
||||
"R_PPC_EMB_SDA2I16", /* name */
|
||||
FALSE, /* partial_inplace */
|
||||
@ -3129,9 +3129,10 @@ ppc_elf_add_symbol_hook (bfd *abfd,
|
||||
}
|
||||
|
||||
static bfd_boolean
|
||||
create_sdata_sym (struct ppc_elf_link_hash_table *htab,
|
||||
elf_linker_section_t *lsect)
|
||||
create_sdata_sym (struct bfd_link_info *info, elf_linker_section_t *lsect)
|
||||
{
|
||||
struct ppc_elf_link_hash_table *htab = ppc_elf_hash_table (info);
|
||||
|
||||
lsect->sym = elf_link_hash_lookup (&htab->elf, lsect->sym_name,
|
||||
TRUE, FALSE, TRUE);
|
||||
if (lsect->sym == NULL)
|
||||
@ -3139,6 +3140,7 @@ create_sdata_sym (struct ppc_elf_link_hash_table *htab,
|
||||
if (lsect->sym->root.type == bfd_link_hash_new)
|
||||
lsect->sym->non_elf = 0;
|
||||
lsect->sym->ref_regular = 1;
|
||||
_bfd_elf_link_hash_hide_symbol (info, lsect->sym, TRUE);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -3168,7 +3170,7 @@ ppc_elf_create_linker_section (bfd *abfd,
|
||||
return FALSE;
|
||||
lsect->section = s;
|
||||
|
||||
return create_sdata_sym (htab, lsect);
|
||||
return create_sdata_sym (info, lsect);
|
||||
}
|
||||
|
||||
/* Find a linker generated pointer with a given addend and type. */
|
||||
@ -3633,13 +3635,8 @@ ppc_elf_check_relocs (bfd *abfd,
|
||||
break;
|
||||
|
||||
case R_PPC_SDAREL16:
|
||||
if (info->shared)
|
||||
{
|
||||
bad_shared_reloc (abfd, r_type);
|
||||
return FALSE;
|
||||
}
|
||||
if (htab->sdata[0].sym == NULL
|
||||
&& !create_sdata_sym (htab, &htab->sdata[0]))
|
||||
&& !create_sdata_sym (info, &htab->sdata[0]))
|
||||
return FALSE;
|
||||
if (h != NULL)
|
||||
{
|
||||
@ -3655,7 +3652,7 @@ ppc_elf_check_relocs (bfd *abfd,
|
||||
return FALSE;
|
||||
}
|
||||
if (htab->sdata[1].sym == NULL
|
||||
&& !create_sdata_sym (htab, &htab->sdata[1]))
|
||||
&& !create_sdata_sym (info, &htab->sdata[1]))
|
||||
return FALSE;
|
||||
if (h != NULL)
|
||||
{
|
||||
@ -3672,10 +3669,10 @@ ppc_elf_check_relocs (bfd *abfd,
|
||||
return FALSE;
|
||||
}
|
||||
if (htab->sdata[0].sym == NULL
|
||||
&& !create_sdata_sym (htab, &htab->sdata[0]))
|
||||
&& !create_sdata_sym (info, &htab->sdata[0]))
|
||||
return FALSE;
|
||||
if (htab->sdata[1].sym == NULL
|
||||
&& !create_sdata_sym (htab, &htab->sdata[1]))
|
||||
&& !create_sdata_sym (info, &htab->sdata[1]))
|
||||
return FALSE;
|
||||
if (h != NULL)
|
||||
{
|
||||
@ -5660,6 +5657,18 @@ ppc_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
|
||||
|
||||
htab->elf.hgot->root.u.def.value = g_o_t;
|
||||
}
|
||||
if (info->shared)
|
||||
{
|
||||
struct elf_link_hash_entry *sda = htab->sdata[0].sym;
|
||||
if (sda != NULL
|
||||
&& !(sda->root.type == bfd_link_hash_defined
|
||||
|| sda->root.type == bfd_link_hash_defweak))
|
||||
{
|
||||
sda->root.type = bfd_link_hash_defined;
|
||||
sda->root.u.def.section = htab->elf.hgot->root.u.def.section;
|
||||
sda->root.u.def.value = htab->elf.hgot->root.u.def.value;
|
||||
}
|
||||
}
|
||||
|
||||
if (htab->glink != NULL
|
||||
&& htab->glink->size != 0
|
||||
@ -6446,9 +6455,10 @@ elf_finish_pointer_linker_section (bfd *input_bfd,
|
||||
linker_section_ptr->offset += 1;
|
||||
}
|
||||
|
||||
relocation = (lsect->section->output_offset
|
||||
relocation = (lsect->section->output_section->vma
|
||||
+ lsect->section->output_offset
|
||||
+ linker_section_ptr->offset - 1
|
||||
- 0x8000);
|
||||
- SYM_VAL (lsect->sym));
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf (stderr,
|
||||
@ -6456,9 +6466,7 @@ elf_finish_pointer_linker_section (bfd *input_bfd,
|
||||
lsect->name, (long) relocation, (long) relocation);
|
||||
#endif
|
||||
|
||||
/* Subtract out the addend, because it will get added back in by the normal
|
||||
processing. */
|
||||
return relocation - linker_section_ptr->addend;
|
||||
return relocation;
|
||||
}
|
||||
|
||||
#define PPC_LO(v) ((v) & 0xffff)
|
||||
@ -6528,6 +6536,17 @@ write_glink_stub (struct plt_entry *ent, asection *plt_sec,
|
||||
}
|
||||
}
|
||||
|
||||
/* Return true if symbol is defined statically. */
|
||||
|
||||
static bfd_boolean
|
||||
is_static_defined (struct elf_link_hash_entry *h)
|
||||
{
|
||||
return ((h->root.type == bfd_link_hash_defined
|
||||
|| h->root.type == bfd_link_hash_defweak)
|
||||
&& h->root.u.def.section != NULL
|
||||
&& h->root.u.def.section->output_section != NULL);
|
||||
}
|
||||
|
||||
/* The RELOCATE_SECTION function is called by the ELF backend linker
|
||||
to handle the relocations for a section.
|
||||
|
||||
@ -7629,17 +7648,29 @@ ppc_elf_relocate_section (bfd *output_bfd,
|
||||
/* Indirect .sdata relocation. */
|
||||
case R_PPC_EMB_SDAI16:
|
||||
BFD_ASSERT (htab->sdata[0].section != NULL);
|
||||
if (!is_static_defined (htab->sdata[0].sym))
|
||||
{
|
||||
unresolved_reloc = TRUE;
|
||||
break;
|
||||
}
|
||||
relocation
|
||||
= elf_finish_pointer_linker_section (input_bfd, &htab->sdata[0],
|
||||
h, relocation, rel);
|
||||
addend = 0;
|
||||
break;
|
||||
|
||||
/* Indirect .sdata2 relocation. */
|
||||
case R_PPC_EMB_SDA2I16:
|
||||
BFD_ASSERT (htab->sdata[1].section != NULL);
|
||||
if (!is_static_defined (htab->sdata[1].sym))
|
||||
{
|
||||
unresolved_reloc = TRUE;
|
||||
break;
|
||||
}
|
||||
relocation
|
||||
= elf_finish_pointer_linker_section (input_bfd, &htab->sdata[1],
|
||||
h, relocation, rel);
|
||||
addend = 0;
|
||||
break;
|
||||
|
||||
/* Handle the TOC16 reloc. We want to use the offset within the .got
|
||||
@ -7692,12 +7723,16 @@ ppc_elf_relocate_section (bfd *output_bfd,
|
||||
case R_PPC_SDAREL16:
|
||||
{
|
||||
const char *name;
|
||||
struct elf_link_hash_entry *sda = htab->sdata[0].sym;
|
||||
|
||||
if (sec == NULL || sec->output_section == NULL)
|
||||
if (sec == NULL
|
||||
|| sec->output_section == NULL
|
||||
|| !is_static_defined (sda))
|
||||
{
|
||||
unresolved_reloc = TRUE;
|
||||
break;
|
||||
}
|
||||
addend -= SYM_VAL (sda);
|
||||
|
||||
name = bfd_get_section_name (abfd, sec->output_section);
|
||||
if (! ((CONST_STRNEQ (name, ".sdata")
|
||||
@ -7713,7 +7748,6 @@ ppc_elf_relocate_section (bfd *output_bfd,
|
||||
howto->name,
|
||||
name);
|
||||
}
|
||||
addend -= SYM_VAL (htab->sdata[0].sym);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -7721,12 +7755,16 @@ ppc_elf_relocate_section (bfd *output_bfd,
|
||||
case R_PPC_EMB_SDA2REL:
|
||||
{
|
||||
const char *name;
|
||||
struct elf_link_hash_entry *sda = htab->sdata[1].sym;
|
||||
|
||||
if (sec == NULL || sec->output_section == NULL)
|
||||
if (sec == NULL
|
||||
|| sec->output_section == NULL
|
||||
|| !is_static_defined (sda))
|
||||
{
|
||||
unresolved_reloc = TRUE;
|
||||
break;
|
||||
}
|
||||
addend -= SYM_VAL (sda);
|
||||
|
||||
name = bfd_get_section_name (abfd, sec->output_section);
|
||||
if (! (CONST_STRNEQ (name, ".sdata2")
|
||||
@ -7739,12 +7777,7 @@ ppc_elf_relocate_section (bfd *output_bfd,
|
||||
sym_name,
|
||||
howto->name,
|
||||
name);
|
||||
|
||||
bfd_set_error (bfd_error_bad_value);
|
||||
ret = FALSE;
|
||||
continue;
|
||||
}
|
||||
addend -= SYM_VAL (htab->sdata[1].sym);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -7754,6 +7787,7 @@ ppc_elf_relocate_section (bfd *output_bfd,
|
||||
{
|
||||
const char *name;
|
||||
int reg;
|
||||
struct elf_link_hash_entry *sda = NULL;
|
||||
|
||||
if (sec == NULL || sec->output_section == NULL)
|
||||
{
|
||||
@ -7768,13 +7802,13 @@ ppc_elf_relocate_section (bfd *output_bfd,
|
||||
&& (name[5] == 0 || name[5] == '.'))))
|
||||
{
|
||||
reg = 13;
|
||||
addend -= SYM_VAL (htab->sdata[0].sym);
|
||||
sda = htab->sdata[0].sym;
|
||||
}
|
||||
else if (CONST_STRNEQ (name, ".sdata2")
|
||||
|| CONST_STRNEQ (name, ".sbss2"))
|
||||
{
|
||||
reg = 2;
|
||||
addend -= SYM_VAL (htab->sdata[1].sym);
|
||||
sda = htab->sdata[1].sym;
|
||||
}
|
||||
else if (strcmp (name, ".PPC.EMB.sdata0") == 0
|
||||
|| strcmp (name, ".PPC.EMB.sbss0") == 0)
|
||||
@ -7796,6 +7830,16 @@ ppc_elf_relocate_section (bfd *output_bfd,
|
||||
continue;
|
||||
}
|
||||
|
||||
if (sda != NULL)
|
||||
{
|
||||
if (!is_static_defined (sda))
|
||||
{
|
||||
unresolved_reloc = TRUE;
|
||||
break;
|
||||
}
|
||||
addend -= SYM_VAL (sda);
|
||||
}
|
||||
|
||||
if (r_type == R_PPC_EMB_SDA21)
|
||||
{ /* fill in register field */
|
||||
insn = bfd_get_32 (output_bfd, contents + rel->r_offset);
|
||||
|
Loading…
Reference in New Issue
Block a user