[PATCH] Don't sign extend the addend for R_MIPS_PC16 and R_MIPS_GNU_REL16_S2 if relocations are RELA
Andrew Bennett
Andrew.Bennett@imgtec.com
Fri Sep 12 14:19:00 GMT 2014
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;
More information about the Binutils
mailing list