[binutils-gdb] PR24697, R_PPC_EMB_SDA21 relocation
Alan Modra
amodra@sourceware.org
Wed Jun 19 04:38:00 GMT 2019
https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=6f5601c4d0ad43254244f1b624900cdd5afd02ba
commit 6f5601c4d0ad43254244f1b624900cdd5afd02ba
Author: Alan Modra <amodra@gmail.com>
Date: Wed Jun 19 13:55:59 2019 +0930
PR24697, R_PPC_EMB_SDA21 relocation
PR 24697
* elf32-ppc.c (ppc_elf_relocate_section): Don't read insn for
R_PPC_EMB_RELSDA. Mask low bit of R_PPC_EMB_SDA21 r_offset.
Diff:
---
bfd/ChangeLog | 6 ++++++
bfd/elf32-ppc.c | 22 +++++++++++++++-------
2 files changed, 21 insertions(+), 7 deletions(-)
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index ea049b1..f40f6ed 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,5 +1,11 @@
2019-06-19 Alan Modra <amodra@gmail.com>
+ PR 24697
+ * elf32-ppc.c (ppc_elf_relocate_section): Don't read insn for
+ R_PPC_EMB_RELSDA. Mask low bit of R_PPC_EMB_SDA21 r_offset.
+
+2019-06-19 Alan Modra <amodra@gmail.com>
+
* elf64-ppc.c (ppc64_elf_inline_plt): Correct st_other test for
functions that require r2 valid to use local entry.
(ppc64_elf_size_stubs, ppc64_elf_relocate_section): Likewise.
diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c
index e73539a..df813d3 100644
--- a/bfd/elf32-ppc.c
+++ b/bfd/elf32-ppc.c
@@ -8654,6 +8654,19 @@ ppc_elf_relocate_section (bfd *output_bfd,
addend -= SYM_VAL (sda);
}
+ if (r_type == R_PPC_EMB_RELSDA)
+ break;
+
+ /* The PowerPC Embedded Application Binary Interface
+ version 1.0 insanely chose to specify R_PPC_EMB_SDA21
+ operating on a 24-bit field at r_offset. GNU as and
+ GNU ld have always assumed R_PPC_EMB_SDA21 operates on
+ a 32-bit bit insn at r_offset. Cope with object file
+ producers that possibly comply with the EABI in
+ generating an odd r_offset for big-endian objects. */
+ if (r_type == R_PPC_EMB_SDA21)
+ rel->r_offset &= ~1;
+
insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
if (reg == 0
&& (r_type == R_PPC_VLE_SDA21
@@ -8681,13 +8694,8 @@ ppc_elf_relocate_section (bfd *output_bfd,
goto overflow;
goto copy_reloc;
}
- else if (r_type == R_PPC_EMB_SDA21
- || r_type == R_PPC_VLE_SDA21
- || r_type == R_PPC_VLE_SDA21_LO)
- {
- /* Fill in register field. */
- insn = (insn & ~RA_REGISTER_MASK) | (reg << RA_REGISTER_SHIFT);
- }
+ /* Fill in register field. */
+ insn = (insn & ~RA_REGISTER_MASK) | (reg << RA_REGISTER_SHIFT);
bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
}
break;
More information about the Binutils-cvs
mailing list