aboutsummaryrefslogtreecommitdiff
path: root/bfd/elf32-arm.h
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>2001-03-06 22:33:47 +0000
committerNick Clifton <nickc@redhat.com>2001-03-06 22:33:47 +0000
commit4f3c3dbb370a8c0c8b66710c5d0c2854c1bab4f5 (patch)
tree2042b5c453e962b76adfdd2eb4b67bd6899cfb55 /bfd/elf32-arm.h
parentf8f3c6cc3747d01156af27c7cc74a4628755f4d0 (diff)
downloadgdb-4f3c3dbb370a8c0c8b66710c5d0c2854c1bab4f5.zip
gdb-4f3c3dbb370a8c0c8b66710c5d0c2854c1bab4f5.tar.gz
gdb-4f3c3dbb370a8c0c8b66710c5d0c2854c1bab4f5.tar.bz2
Fix BLX(1) for Thumb
Diffstat (limited to 'bfd/elf32-arm.h')
-rw-r--r--bfd/elf32-arm.h11
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);