diff options
Diffstat (limited to 'bfd/elf32-arm.h')
-rw-r--r-- | bfd/elf32-arm.h | 11 |
1 files changed, 11 insertions, 0 deletions
diff --git a/bfd/elf32-arm.h b/bfd/elf32-arm.h index 6b56797..b64df9a 100644 --- a/bfd/elf32-arm.h +++ b/bfd/elf32-arm.h @@ -1434,6 +1434,17 @@ elf32_arm_final_link_relocate (howto, input_bfd, output_bfd, upper_insn = (upper_insn & ~(bfd_vma) 0x7ff) | ((relocation >> 12) & 0x7ff); lower_insn = (lower_insn & ~(bfd_vma) 0x7ff) | ((relocation >> 1) & 0x7ff); + if (r_type == R_ARM_THM_XPC22 + && ((lower_insn & 0x1800) == 0x0800)) + /* Remove bit zero of the adjusted offset. Bit zero can only be + set if the upper insn is at a half-word boundary, since the + destination address, an ARM instruction, must always be on a + word boundary. The semantics of the BLX (1) instruction, however, + are that bit zero in the offset must always be zero, and the + corresponding bit one in the target address will be set from bit + one of the source address. */ + lower_insn &= ~1; + /* Put the relocated value back in the object file: */ bfd_put_16 (input_bfd, upper_insn, hit_data); bfd_put_16 (input_bfd, lower_insn, hit_data + 2); |