This is the mail archive of the
binutils@sourceware.cygnus.com
mailing list for the binutils project.
Re: arm-elf-as truncates branch offsets w/o warning
- To: grante at visi dot com
- Subject: Re: arm-elf-as truncates branch offsets w/o warning
- From: Nick Clifton <nickc at cygnus dot com>
- Date: Thu, 16 Mar 2000 17:09:27 -0800
- CC: scottb at netwinder dot org, binutils at sourceware dot cygnus dot com
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\)
+