diff options
author | Nick Clifton <nickc@redhat.com> | 2002-05-23 12:37:57 +0000 |
---|---|---|
committer | Nick Clifton <nickc@redhat.com> | 2002-05-23 12:37:57 +0000 |
commit | c62e1cc30f77e49b15d48d4d32c7f6c1e6827163 (patch) | |
tree | 7b9b45107783f709e9478e138286efc5c6682384 /bfd/elf32-arm.h | |
parent | 6ff96af674ed8b5872e90def470405f90f8b4aac (diff) | |
download | gdb-c62e1cc30f77e49b15d48d4d32c7f6c1e6827163.zip gdb-c62e1cc30f77e49b15d48d4d32c7f6c1e6827163.tar.gz gdb-c62e1cc30f77e49b15d48d4d32c7f6c1e6827163.tar.bz2 |
For the Thumb BLX reloc round the relocation up rather than down.
Diffstat (limited to 'bfd/elf32-arm.h')
-rw-r--r-- | bfd/elf32-arm.h | 21 |
1 files changed, 9 insertions, 12 deletions
diff --git a/bfd/elf32-arm.h b/bfd/elf32-arm.h index 91ea63b..8b9bf07 100644 --- a/bfd/elf32-arm.h +++ b/bfd/elf32-arm.h @@ -1471,22 +1471,19 @@ elf32_arm_final_link_relocate (howto, input_bfd, output_bfd, if (signed_check > reloc_signed_max || signed_check < reloc_signed_min) overflow = true; - /* Put RELOCATION back into the insn. */ - upper_insn = (upper_insn & ~(bfd_vma) 0x7ff) | ((relocation >> 12) & 0x7ff); - lower_insn = (lower_insn & ~(bfd_vma) 0x7ff) | ((relocation >> 1) & 0x7ff); - #ifndef OLD_ARM_ABI 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; + /* For a BLX instruction, make sure that the relocation is rounded up + to a word boundary. This follows the semantics of the instruction + which specifies that bit 1 of the target address will come from bit + 1 of the base address. */ + relocation = (relocation + 2) & ~ 3; #endif + /* Put RELOCATION back into the insn. */ + upper_insn = (upper_insn & ~(bfd_vma) 0x7ff) | ((relocation >> 12) & 0x7ff); + lower_insn = (lower_insn & ~(bfd_vma) 0x7ff) | ((relocation >> 1) & 0x7ff); + /* 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); |