This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
Fix for ARM BLX relocation.
- To: binutils at sourceware dot cygnus dot com
- Subject: Fix for ARM BLX relocation.
- From: Nick Clifton <nickc at cygnus dot com>
- Date: Thu, 3 Aug 2000 17:06:12 -0700
Hi Guys,
It was pointed out to me that the ARM BLX instruction is not being
relocated properly when the destination address is aligned to a half
word boundary. The patch below fixes this, and I will be checking
it into sourceware shortly.
Cheers
Nick
2000-08-03 Nick Clifton <nickc@cygnus.com>
* elf32-arm.h (elf32_arm_final_link_relocate): If the destination
of a BLX instruction is aligned on a half word boundary, set the H
bit.
Index: bfd/elf32-arm.h
===================================================================
RCS file: /cvs/src//src/bfd/elf32-arm.h,v
retrieving revision 1.32
diff -w -p -r1.32 elf32-arm.h
*** elf32-arm.h 2000/07/20 03:21:59 1.32
--- elf32-arm.h 2000/08/04 00:04:53
*************** elf32_arm_final_link_relocate (howto, in
*** 1259,1278 ****
}
}
/* 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))
|| 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));
break;
--- 1259,1287 ----
}
}
+ /* 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)
{
if ( signed_addend > ((bfd_signed_vma) (howto->dst_mask >> 1))
|| signed_addend < - ((bfd_signed_vma) ((howto->dst_mask + 1) >> 1)))
return bfd_reloc_overflow;
}
+ #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;