This is the mail archive of the binutils@sources.redhat.com mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Fix for ARM BLX relocation.


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;

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]