This is the mail archive of the binutils@sourceware.cygnus.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]

Re: arm-elf-as truncates branch offsets w/o warning


Hi Grant,

: Sure:
: ------------------------------testit2.s------------------------------
:      .text
:      .org 0x05000000
:      b    label1
:      nop
:      nop
:      nop
: label1:
:      nop
: --------------------------------------------------------------------

Great - thanks.  I have now been able to track the cause of the
assembler's failure to handle this code correctly.  It turns out that
the assembler was performing an absolute relocation rather than a PC
relative relocation.  If you try to assemble the following code you
will also get a bad binary:

     .text
     .org 0x100
     b label1
     nop
label1:
     nop

I have developed a patch to fix this, and also to catch the case when
the branch really is out of range, like this:

     .text
     b label1
     .org 0x5000000
label1:
     nop

As an added bonus I have also added a test case to the gas ARM
testsuite to catch this problem, should it arise again.

I will be checking this patch in shortly.

Cheers
	Nick


2000-03-16  Nick Clifton  <nickc@cygnus.com>

	* config/tc-arm.c (md_apply_fix3, BFD_RELOC_ARM_PCREL_BRANCH): For
	OBJ_ELF, force addend to be PC relative.
	Check addend to make sure that it is in range.

Index: config/tc-arm.c
===================================================================
RCS file: /cvs/src//src/gas/config/tc-arm.c,v
retrieving revision 1.33
diff -p -r1.33 tc-arm.c
*** tc-arm.c	2000/02/24 19:46:27	1.33
--- tc-arm.c	2000/03/17 00:41:44
*************** md_apply_fix3 (fixP, val, seg)
*** 5562,5571 ****
  
  #ifdef OBJ_ELF
        if (! target_oabi)
!         value = fixP->fx_offset;
  #endif
!       value  = (value >> 2) & 0x00ffffff;
!       value  = (value + (newval & 0x00ffffff)) & 0x00ffffff;
        newval = value | (newval & 0xff000000);
        md_number_to_chars (buf, newval, INSN_SIZE);
        break;
--- 5562,5581 ----
  
  #ifdef OBJ_ELF
        if (! target_oabi)
! 	{
! 	  value = fixP->fx_offset;
! 	  value -= fixP->fx_frag->fr_address;
! 	}
  #endif
!       value >>= 2;
! /* Sign-extend a 24-bit number.  */
! #define SEXT24(x)	((((x) & 0xffffff) ^ (~ 0x7fffff)) + 0x800000)
!       value += SEXT24 (newval);
!       
!       if (value & 0xff000000UL)
!         as_bad_where (fixP->fx_file, fixP->fx_line,
! 		      _("out of range branch"));
! 	
        newval = value | (newval & 0xff000000);
        md_number_to_chars (buf, newval, INSN_SIZE);
        break;


2000-03-16  Nick Clifton  <nickc@cygnus.com>

	* gas/arm/arm.exp: Run branch.s test.
	Run tests if target is strongarm.

	* gas/arm/branch.s: New test.  Make sure that assembler can handle
	same-section branch relocations properly.

	* gas/arm/branch.d: New file.  Expected output from assembling
	branch.s.

Index: testsuite/gas/arm/arm.exp
===================================================================
RCS file: /cvs/src//src/gas/testsuite/gas/arm/arm.exp,v
retrieving revision 1.1.1.1
diff -p -r1.1.1.1 arm.exp
*** arm.exp	1999/05/03 07:28:48	1.1.1.1
--- arm.exp	2000/03/17 01:08:12
***************
*** 1,7 ****
  #
  # Some ARM tests
  #
! if [istarget arm-*-*] then {
      run_dump_test "inst"
  
      gas_test "arm3.s" "" $stdoptlist "Arm 3 instructions"
--- 1,7 ----
  #
  # Some ARM tests
  #
! if [istarget *arm-*-*] then {
      run_dump_test "inst"
  
      gas_test "arm3.s" "" $stdoptlist "Arm 3 instructions"
*************** if [istarget arm-*-*] then {
*** 21,26 ****
--- 21,28 ----
      gas_test "immed.s" "" $stdoptlist "immediate expressions"
  
      gas_test "float.s" "" $stdoptlist "Core floating point instructions"
+     
+     run_dump_test "branch"
  }
  
  # Not all arm targets are bi-endian, so only run this test on ones

Index: testsuite/gas/arm/branch.s
===================================================================
RCS file: branch.s
diff -N branch.s
*** /dev/null	Tue May  5 13:32:27 1998
--- branch.s	Thu Mar 16 17:08:12 2000
***************
*** 0 ****
--- 1,16 ----
+      .text
+ bar:
+ 	b label2
+ 	nop
+ 	nop
+ label2:	
+ 	nop	
+ 	
+ 	.org 0x100
+ baz:
+ 	b label3
+ 	nop
+ 	nop
+ label3:	
+ 	nop	
+ 			

Index: testsuite/gas/arm/branch.d
===================================================================
RCS file: branch.d
diff -N branch.d
*** /dev/null	Tue May  5 13:32:27 1998
--- branch.d	Thu Mar 16 17:08:12 2000
***************
*** 0 ****
--- 1,25 ----
+ #objdump: -d
+ #name: Branch relocations
+ #as: -marm7t -EL
+ 
+ .*:     file format .*arm.*
+ 
+ Disassembly of section .text:
+ 
+ 00000000 <bar>:
+ .*0:	ea000001 	b	c <label2>
+ .*4:	e1a00000 	nop			\(mov r0,r0\)
+ .*8:	e1a00000 	nop			\(mov r0,r0\)
+ 
+ 0000000c <label2>:
+ .*c:	e1a00000 	nop			\(mov r0,r0\)
+ 	...
+ 
+ 00000100 <baz>:
+ .*100:	ea000001 	b	10c <label3>
+ .*104:	e1a00000 	nop			\(mov r0,r0\)
+ .*108:	e1a00000 	nop			\(mov r0,r0\)
+ 
+ 0000010c <label3>:
+ .*10c:	e1a00000 	nop			\(mov r0,r0\)
+ 

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