diff options
author | Nick Clifton <nickc@redhat.com> | 2000-08-04 00:07:42 +0000 |
---|---|---|
committer | Nick Clifton <nickc@redhat.com> | 2000-08-04 00:07:42 +0000 |
commit | dcb5e6e634613f3a111c5b45be2829c1cf2116d1 (patch) | |
tree | 0863c5d6b0c181cf72251ba7727536b29f5c7aff | |
parent | 24ffec7ab81b9e4de9eb89220c32379c62cb670d (diff) | |
download | gdb-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.
-rw-r--r-- | bfd/elf32-arm.h | 21 |
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: |