aboutsummaryrefslogtreecommitdiff
path: root/bfd/elf32-ppc.c
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2017-02-23 12:20:42 +1030
committerAlan Modra <amodra@gmail.com>2017-02-23 12:33:51 +1030
commit5499c7c71cc403a1deff90b79ab41d17efc5c4cc (patch)
tree741cd69ec800b5e24bcae98532a6aeb50de13150 /bfd/elf32-ppc.c
parentd8260425e6a8ef78cf47324f6f68d7978ac701ba (diff)
Correct VLE 16D and SDAREL relocations
PR 20744 bfd/ * elf32-ppc.c (ppc_elf_howto_raw): Correct dst_mask on all VLE 16D relocations. (ppc_elf_vle_split16): Correct field mask and shift for 16D relocs. (ppc_elf_relocate_section): Correct calculation for VLE SDAREL relocs. ld/ * testsuite/ld-powerpc/vle-reloc-2.s: Use r6 for last insn of each group. * testsuite/ld-powerpc/vle-reloc-2.d: Update for above change and sdarel reloc fix.
Diffstat (limited to 'bfd/elf32-ppc.c')
-rw-r--r--bfd/elf32-ppc.c41
1 files changed, 14 insertions, 27 deletions
diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c
index d82193560e..e71757eab0 100644
--- a/bfd/elf32-ppc.c
+++ b/bfd/elf32-ppc.c
@@ -1471,7 +1471,7 @@ static reloc_howto_type ppc_elf_howto_raw[] = {
"R_PPC_VLE_LO16D", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
- 0x1f007ff, /* dst_mask */
+ 0x3e007ff, /* dst_mask */
FALSE), /* pcrel_offset */
/* Bits 16-31 split16a format. */
@@ -1501,7 +1501,7 @@ static reloc_howto_type ppc_elf_howto_raw[] = {
"R_PPC_VLE_HI16D", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
- 0x1f007ff, /* dst_mask */
+ 0x3e007ff, /* dst_mask */
FALSE), /* pcrel_offset */
/* Bits 16-31 (High Adjusted) in split16a format. */
@@ -1531,7 +1531,7 @@ static reloc_howto_type ppc_elf_howto_raw[] = {
"R_PPC_VLE_HA16D", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
- 0x1f007ff, /* dst_mask */
+ 0x3e007ff, /* dst_mask */
FALSE), /* pcrel_offset */
/* This reloc is like R_PPC_EMB_SDA21 but only applies to e_add16i
@@ -1593,7 +1593,7 @@ static reloc_howto_type ppc_elf_howto_raw[] = {
"R_PPC_VLE_SDAREL_LO16D", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
- 0x1f007ff, /* dst_mask */
+ 0x3e007ff, /* dst_mask */
FALSE), /* pcrel_offset */
/* Bits 16-31 relative to _SDA_BASE_ in split16a format. */
@@ -1623,7 +1623,7 @@ static reloc_howto_type ppc_elf_howto_raw[] = {
"R_PPC_VLE_SDAREL_HI16D", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
- 0x1f007ff, /* dst_mask */
+ 0x3e007ff, /* dst_mask */
FALSE), /* pcrel_offset */
/* Bits 16-31 (HA) relative to _SDA_BASE split16a format. */
@@ -1653,7 +1653,7 @@ static reloc_howto_type ppc_elf_howto_raw[] = {
"R_PPC_VLE_SDAREL_HA16D", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
- 0x1f007ff, /* dst_mask */
+ 0x3e007ff, /* dst_mask */
FALSE), /* pcrel_offset */
HOWTO (R_PPC_IRELATIVE, /* type */
@@ -4942,8 +4942,8 @@ ppc_elf_vle_split16 (bfd *input_bfd,
}
}
top5 = value & 0xf800;
- top5 = top5 << (split16_format == split16a_type ? 5 : 9);
- insn &= (split16_format == split16a_type ? ~0x1f07ff : ~0x1f007ff);
+ top5 = top5 << (split16_format == split16a_type ? 5 : 10);
+ insn &= (split16_format == split16a_type ? ~0x1f07ff : ~0x3e007ff);
insn |= top5;
insn |= value & 0x7ff;
bfd_put_32 (input_bfd, insn, loc);
@@ -9388,7 +9388,6 @@ ppc_elf_relocate_section (bfd *output_bfd,
{
bfd_vma value;
const char *name;
- //int reg;
struct elf_link_hash_entry *sda = NULL;
if (sec == NULL || sec->output_section == NULL)
@@ -9400,16 +9399,10 @@ ppc_elf_relocate_section (bfd *output_bfd,
name = bfd_get_section_name (output_bfd, sec->output_section);
if (strcmp (name, ".sdata") == 0
|| strcmp (name, ".sbss") == 0)
- {
- //reg = 13;
- sda = htab->sdata[0].sym;
- }
+ sda = htab->sdata[0].sym;
else if (strcmp (name, ".sdata2") == 0
|| strcmp (name, ".sbss2") == 0)
- {
- //reg = 2;
- sda = htab->sdata[1].sym;
- }
+ sda = htab->sdata[1].sym;
else
{
_bfd_error_handler
@@ -9426,18 +9419,12 @@ ppc_elf_relocate_section (bfd *output_bfd,
goto copy_reloc;
}
- if (sda != NULL)
+ if (sda == NULL || !is_static_defined (sda))
{
- if (!is_static_defined (sda))
- {
- unresolved_reloc = TRUE;
- break;
- }
+ unresolved_reloc = TRUE;
+ break;
}
-
- value = (sda->root.u.def.section->output_section->vma
- + sda->root.u.def.section->output_offset
- + addend);
+ value = relocation + addend - SYM_VAL (sda);
if (r_type == R_PPC_VLE_SDAREL_LO16A)
ppc_elf_vle_split16 (input_bfd, input_section, rel->r_offset,