aboutsummaryrefslogtreecommitdiff
path: root/bfd/elf32-arm.h
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>2000-08-04 00:07:42 +0000
committerNick Clifton <nickc@redhat.com>2000-08-04 00:07:42 +0000
commitdcb5e6e634613f3a111c5b45be2829c1cf2116d1 (patch)
tree0863c5d6b0c181cf72251ba7727536b29f5c7aff /bfd/elf32-arm.h
parent24ffec7ab81b9e4de9eb89220c32379c62cb670d (diff)
downloadgdb-dcb5e6e634613f3a111c5b45be2829c1cf2116d1.zip
gdb-dcb5e6e634613f3a111c5b45be2829c1cf2116d1.tar.gz
gdb-dcb5e6e634613f3a111c5b45be2829c1cf2116d1.tar.bz2
If the destination of a BLX instruction is aligned on a half word boundary,
set the H bit.
Diffstat (limited to 'bfd/elf32-arm.h')
-rw-r--r--bfd/elf32-arm.h21
1 files changed, 15 insertions, 6 deletions
diff --git a/bfd/elf32-arm.h b/bfd/elf32-arm.h
index 6b748ef..51d62f8 100644
--- a/bfd/elf32-arm.h
+++ b/bfd/elf32-arm.h
@@ -1259,22 +1259,31 @@ elf32_arm_final_link_relocate (howto, input_bfd, output_bfd,
}
}
+ /* Perform a signed range check. */
+ signed_addend = value;
+ signed_addend >>= howto->rightshift;
+
/* It is not an error for an undefined weak reference to be
out of range. Any program that branches to such a symbol
is going to crash anyway, so there is no point worrying
about getting the destination exactly right. */
if (! h || h->root.type != bfd_link_hash_undefweak)
{
- /* Perform a signed range check. */
- signed_addend = value;
- signed_addend >>= howto->rightshift;
- if (signed_addend > ((bfd_signed_vma)(howto->dst_mask >> 1))
+ if ( signed_addend > ((bfd_signed_vma) (howto->dst_mask >> 1))
|| signed_addend < - ((bfd_signed_vma) ((howto->dst_mask + 1) >> 1)))
return bfd_reloc_overflow;
}
- value = (signed_addend & howto->dst_mask)
- | (bfd_get_32 (input_bfd, hit_data) & (~ howto->dst_mask));
+#ifndef OLD_ARM_ABI
+ /* If necessary set the H bit in the BLX instruction. */
+ if (r_type == R_ARM_XPC25 && ((value & 2) == 2))
+ value = (signed_addend & howto->dst_mask)
+ | (bfd_get_32 (input_bfd, hit_data) & (~ howto->dst_mask))
+ | (1 << 24);
+ else
+#endif
+ value = (signed_addend & howto->dst_mask)
+ | (bfd_get_32 (input_bfd, hit_data) & (~ howto->dst_mask));
break;
case R_ARM_ABS32: