This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[PATCH] Don't sign extend the addend for R_MIPS_PC16 and R_MIPS_GNU_REL16_S2 if relocations are RELA
- From: Andrew Bennett <Andrew dot Bennett at imgtec dot com>
- To: "binutils at sourceware dot org" <binutils at sourceware dot org>
- Date: Fri, 12 Sep 2014 14:19:35 +0000
- Subject: [PATCH] Don't sign extend the addend for R_MIPS_PC16 and R_MIPS_GNU_REL16_S2 if relocations are RELA
- Authentication-results: sourceware.org; auth=none
Hi,
The R_MIPS_PC16 and R_MIPS_GNU_REL16_S2 relocations in mips_elf_calculate_relocation
do not correctly deal with RELA. Currently the code always sign extends
the addend at bit 18, when it should only do this if the relocation is REL.
The issue was noticed while testing R6 relocations. These retain all PC relative
relocations, causing more PCHI16 relocations to be fixed up by the linker.
The issue is a corner-case. To trigger it you need an addend which exceeds the
range of the actual instruction displacement but the overall expression results
in an address within range of the branch. The addend must also have bit 18 set to
trigger the sign extension.
The patch and ChangeLog are below.
Ok to commit?
Regards,
Andrew
bfd/
* elfxx-mips.c (mips_elf_calculate_relocation): Add RELA support to
R_MIPS_PC16 and R_MIPS_GNU_REL16_S2, and check the offset is 4 byte
aligned.
diff --git a/bfd/elfxx-mips.c b/bfd/elfxx-mips.c
index ee0204d..b0f2e79 100644
--- a/bfd/elfxx-mips.c
+++ b/bfd/elfxx-mips.c
@@ -5945,7 +5945,13 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd,
case R_MIPS_PC16:
case R_MIPS_GNU_REL16_S2:
- value = symbol + _bfd_mips_elf_sign_extend (addend, 18) - p;
+ if (howto->partial_inplace)
+ addend = _bfd_mips_elf_sign_extend (addend, 18);
+
+ if ((symbol + addend) & 3)
+ return bfd_reloc_outofrange;
+
+ value = symbol + addend - p;
overflowed_p = mips_elf_overflow_p (value, 18);
value >>= howto->rightshift;
value &= howto->dst_mask;