This is the mail archive of the mailing list for the binutils project.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Don't sign extend the addend for R_MIPS_PC16 and R_MIPS_GNU_REL16_S2 if relocations are RELA


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?



	* 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 

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;

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]