aboutsummaryrefslogtreecommitdiff
path: root/bfd
diff options
context:
space:
mode:
Diffstat (limited to 'bfd')
-rw-r--r--bfd/ChangeLog5
-rw-r--r--bfd/elfxx-mips.c6
2 files changed, 10 insertions, 1 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 4882260..f52e75d 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,8 @@
+2017-08-30 Maciej W. Rozycki <macro@imgtec.com>
+
+ * elfxx-mips.c (mips_elf_perform_relocation): Correct microMIPS
+ branch offset interpretation.
+
2017-08-30 H.J. Lu <hongjiu.lu@intel.com>
PR binutils/22032
diff --git a/bfd/elfxx-mips.c b/bfd/elfxx-mips.c
index fddf68c..6a4d3e1 100644
--- a/bfd/elfxx-mips.c
+++ b/bfd/elfxx-mips.c
@@ -6414,6 +6414,7 @@ mips_elf_perform_relocation (struct bfd_link_info *info,
bfd_boolean ok = FALSE;
bfd_vma opcode = x >> 16;
bfd_vma jalx_opcode = 0;
+ bfd_vma sign_bit = 0;
bfd_vma addr;
bfd_vma dest;
@@ -6421,12 +6422,14 @@ mips_elf_perform_relocation (struct bfd_link_info *info,
{
ok = opcode == 0x4060;
jalx_opcode = 0x3c;
+ sign_bit = 0x10000;
value <<= 1;
}
else if (r_type == R_MIPS_PC16 || r_type == R_MIPS_GNU_REL16_S2)
{
ok = opcode == 0x411;
jalx_opcode = 0x1d;
+ sign_bit = 0x20000;
value <<= 2;
}
@@ -6436,7 +6439,8 @@ mips_elf_perform_relocation (struct bfd_link_info *info,
+ input_section->output_offset
+ relocation->r_offset
+ 4);
- dest = addr + (((value & 0x3ffff) ^ 0x20000) - 0x20000);
+ dest = (addr
+ + (((value & ((sign_bit << 1) - 1)) ^ sign_bit) - sign_bit));
if ((addr >> 28) << 28 != (dest >> 28) << 28)
{