aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristophe Lyon <christophe.lyon@st.com>2010-02-09 14:44:50 +0000
committerChristophe Lyon <christophe.lyon@st.com>2010-02-09 14:44:50 +0000
commit486499d044bfca617c7f3f7a0b0f6ae70ca98ef3 (patch)
treef04806ccf09966f408e30a3203b669b59254d8c9
parent1523fa24f7d51fecc82338e65a567346b9cef317 (diff)
downloadfsf-binutils-gdb-486499d044bfca617c7f3f7a0b0f6ae70ca98ef3.zip
fsf-binutils-gdb-486499d044bfca617c7f3f7a0b0f6ae70ca98ef3.tar.gz
fsf-binutils-gdb-486499d044bfca617c7f3f7a0b0f6ae70ca98ef3.tar.bz2
2010-02-08 Christophe Lyon <christophe.lyon@st.com>
gas/ * config/tc-arm.c (md_pcrel_from_section): Keep base to zero for non-local branches (BFD_RELOC_THUMB_PCREL_BRANCH23, BFD_RELOC_THUMB_PCREL_BLX, BFD_RELOC_ARM_PCREL_BLX, BFD_RELOC_ARM_PCREL_CALL) gas/testsuite/ * gas/arm/branch-reloc.s, gas/arm/branch-reloc.d, gas/arm/branch-reloc.l: New tests and expected results with all variants of call: ARM/Thumb, local/global, inter/intra-section, using BL/BLX.
-rw-r--r--gas/ChangeLog7
-rw-r--r--gas/config/tc-arm.c24
-rw-r--r--gas/testsuite/ChangeLog7
-rw-r--r--gas/testsuite/gas/arm/branch-reloc.d89
-rw-r--r--gas/testsuite/gas/arm/branch-reloc.l3
-rw-r--r--gas/testsuite/gas/arm/branch-reloc.s87
6 files changed, 209 insertions, 8 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog
index 1dbdfb3..294cc0c 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,10 @@
+2010-02-08 Christophe Lyon <christophe.lyon@st.com>
+
+ * config/tc-arm.c (md_pcrel_from_section): Keep base to zero for
+ non-local branches (BFD_RELOC_THUMB_PCREL_BRANCH23,
+ BFD_RELOC_THUMB_PCREL_BLX, BFD_RELOC_ARM_PCREL_BLX,
+ BFD_RELOC_ARM_PCREL_CALL)
+
2010-02-08 Sterling Augustine <sterling@tensilica.com>
* config/tc-xtensa.c (frag_format_size): Generalize logic to
diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c
index 7bf5416..2add801 100644
--- a/gas/config/tc-arm.c
+++ b/gas/config/tc-arm.c
@@ -19240,7 +19240,9 @@ md_pcrel_from_section (fixS * fixP, segT seg)
return base + 4;
case BFD_RELOC_THUMB_PCREL_BRANCH23:
- if (fixP->fx_addsy
+ if (fixP->fx_addsy
+ && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
+ && (!S_IS_EXTERNAL (fixP->fx_addsy))
&& ARM_IS_FUNC (fixP->fx_addsy)
&& ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t))
base = fixP->fx_where + fixP->fx_frag->fr_address;
@@ -19248,8 +19250,10 @@ md_pcrel_from_section (fixS * fixP, segT seg)
/* BLX is like branches above, but forces the low two bits of PC to
zero. */
- case BFD_RELOC_THUMB_PCREL_BLX:
- if (fixP->fx_addsy
+ case BFD_RELOC_THUMB_PCREL_BLX:
+ if (fixP->fx_addsy
+ && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
+ && (!S_IS_EXTERNAL (fixP->fx_addsy))
&& THUMB_IS_FUNC (fixP->fx_addsy)
&& ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t))
base = fixP->fx_where + fixP->fx_frag->fr_address;
@@ -19258,18 +19262,22 @@ md_pcrel_from_section (fixS * fixP, segT seg)
/* ARM mode branches are offset by +8. However, the Windows CE
loader expects the relocation not to take this into account. */
case BFD_RELOC_ARM_PCREL_BLX:
- if (fixP->fx_addsy
+ if (fixP->fx_addsy
+ && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
+ && (!S_IS_EXTERNAL (fixP->fx_addsy))
&& ARM_IS_FUNC (fixP->fx_addsy)
&& ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t))
base = fixP->fx_where + fixP->fx_frag->fr_address;
- return base + 8;
+ return base + 8;
- case BFD_RELOC_ARM_PCREL_CALL:
- if (fixP->fx_addsy
+ case BFD_RELOC_ARM_PCREL_CALL:
+ if (fixP->fx_addsy
+ && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
+ && (!S_IS_EXTERNAL (fixP->fx_addsy))
&& THUMB_IS_FUNC (fixP->fx_addsy)
&& ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t))
base = fixP->fx_where + fixP->fx_frag->fr_address;
- return base + 8;
+ return base + 8;
case BFD_RELOC_ARM_PCREL_BRANCH:
case BFD_RELOC_ARM_PCREL_JUMP:
diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog
index d875cfe..46139b7 100644
--- a/gas/testsuite/ChangeLog
+++ b/gas/testsuite/ChangeLog
@@ -1,5 +1,12 @@
2010-02-08 Christophe Lyon <christophe.lyon@st.com>
+ * gas/arm/branch-reloc.s, gas/arm/branch-reloc.d,
+ gas/arm/branch-reloc.l: New tests and expected results with all
+ variants of call: ARM/Thumb, local/global, inter/intra-section,
+ using BL/BLX.
+
+2010-02-08 Christophe Lyon <christophe.lyon@st.com>
+
* gas/arm/arm-it-auto.d: Update expected results.
* gas/arm/bl-local-v4t.d: Likewise.
* gas/arm/blx-local.d: Likewise.
diff --git a/gas/testsuite/gas/arm/branch-reloc.d b/gas/testsuite/gas/arm/branch-reloc.d
new file mode 100644
index 0000000..6ba322e
--- /dev/null
+++ b/gas/testsuite/gas/arm/branch-reloc.d
@@ -0,0 +1,89 @@
+#name: Inter-section branch relocations
+#This test is only valid on ELF based ports.
+#not-target: *-*-*coff *-*-pe *-*-wince *-*-*aout* *-*-netbsd *-*-riscix*
+#as: -march=armv5t
+#objdump: -rd
+#stderr: branch-reloc.l
+
+# Test the generation of relocation for inter-section branches
+
+.*: +file format.*arm.*
+
+
+Disassembly of section .text:
+
+00000000 <arm_glob_sym1-0x4>:
+ 0: e1a00000 nop ; \(mov r0, r0\)
+
+00000004 <arm_glob_sym1>:
+ 4: ebfffffe bl 46 <thumb_glob_sym1>
+ 4: R_ARM_CALL thumb_glob_sym1
+ 8: ebfffffe bl 100 <thumb_glob_sym2>
+ 8: R_ARM_CALL thumb_glob_sym2
+ c: fa00000c blx 44 <thumb_sym1>
+ 10: ebfffffe bl 4 <arm_glob_sym1>
+ 10: R_ARM_CALL arm_glob_sym1
+ 14: ebfffffe bl 13c <arm_glob_sym2>
+ 14: R_ARM_CALL arm_glob_sym2
+ 18: eb000007 bl 3c <arm_sym1>
+ 1c: fafffffe blx 46 <thumb_glob_sym1>
+ 1c: R_ARM_CALL thumb_glob_sym1
+ 20: fafffffe blx 100 <thumb_glob_sym2>
+ 20: R_ARM_CALL thumb_glob_sym2
+ 24: fa000006 blx 44 <thumb_sym1>
+ 28: fafffffe blx 4 <arm_glob_sym1>
+ 28: R_ARM_CALL arm_glob_sym1
+ 2c: fafffffe blx 13c <arm_glob_sym2>
+ 2c: R_ARM_CALL arm_glob_sym2
+ 30: eb000001 bl 3c <arm_sym1>
+ 34: e1a00000 nop ; \(mov r0, r0\)
+ 38: e12fff1e bx lr
+
+0000003c <arm_sym1>:
+ 3c: e1a00000 nop ; \(mov r0, r0\)
+ 40: e12fff1e bx lr
+
+00000044 <thumb_sym1>:
+ 44: 4770 bx lr
+
+00000046 <thumb_glob_sym1>:
+ 46: 4770 bx lr
+
+Disassembly of section foo:
+
+00000000 <thumb_glob_sym2-0x100>:
+ ...
+
+00000100 <thumb_glob_sym2>:
+ 100: f7ff fffe bl 4 <thumb_glob_sym2-0xfc>
+ 100: R_ARM_THM_CALL arm_glob_sym1
+ 104: f7ff fffe bl 13c <arm_glob_sym2>
+ 104: R_ARM_THM_CALL arm_glob_sym2
+ 108: f000 e816 blx 138 <arm_sym2>
+ 10c: f7ff fffe bl 46 <thumb_glob_sym2-0xba>
+ 10c: R_ARM_THM_CALL thumb_glob_sym1
+ 110: f7ff fffe bl 100 <thumb_glob_sym2>
+ 110: R_ARM_THM_CALL thumb_glob_sym2
+ 114: f000 f80e bl 134 <thumb_sym2>
+ 118: f7ff effe blx 4 <thumb_glob_sym2-0xfc>
+ 118: R_ARM_THM_CALL arm_glob_sym1
+ 11c: f7ff effe blx 13c <arm_glob_sym2>
+ 11c: R_ARM_THM_CALL arm_glob_sym2
+ 120: f000 e80a blx 138 <arm_sym2>
+ 124: f7ff effe blx 46 <thumb_glob_sym2-0xba>
+ 124: R_ARM_THM_CALL thumb_glob_sym1
+ 128: f7ff effe blx 100 <thumb_glob_sym2>
+ 128: R_ARM_THM_CALL thumb_glob_sym2
+ 12c: f000 f802 bl 134 <thumb_sym2>
+ 130: 46c0 nop ; \(mov r8, r8\)
+ 132: 4770 bx lr
+
+00000134 <thumb_sym2>:
+ 134: 46c0 nop ; \(mov r8, r8\)
+ 136: 4770 bx lr
+
+00000138 <arm_sym2>:
+ 138: e12fff1e bx lr
+
+0000013c <arm_glob_sym2>:
+ 13c: e12fff1e bx lr
diff --git a/gas/testsuite/gas/arm/branch-reloc.l b/gas/testsuite/gas/arm/branch-reloc.l
new file mode 100644
index 0000000..293cfe0
--- /dev/null
+++ b/gas/testsuite/gas/arm/branch-reloc.l
@@ -0,0 +1,3 @@
+[^:]*: Assembler messages:
+[^:]*:[0-9]*: Warning: blx to 'arm_sym1' an ARM ISA state function changed to bl
+[^:]*:[0-9]*: Warning: blx to Thumb func 'thumb_sym2' from Thumb ISA state changed to bl \ No newline at end of file
diff --git a/gas/testsuite/gas/arm/branch-reloc.s b/gas/testsuite/gas/arm/branch-reloc.s
new file mode 100644
index 0000000..b01146e
--- /dev/null
+++ b/gas/testsuite/gas/arm/branch-reloc.s
@@ -0,0 +1,87 @@
+@ Check that non-local branches with and without mode switching
+@ produce the right relocations with appropriate in-place addends.
+
+ .syntax unified
+
+ .text
+ .arm
+ .global arm_glob_sym1
+ .global arm_glob_sym2
+ .global thumb_glob_sym1
+ .global thumb_glob_sym2
+ nop
+ .type arm_glob_sym1, %function
+arm_glob_sym1:
+ bl thumb_glob_sym1
+ bl thumb_glob_sym2
+ bl thumb_sym1
+ bl arm_glob_sym1
+ bl arm_glob_sym2
+ bl arm_sym1
+ blx thumb_glob_sym1
+ blx thumb_glob_sym2
+ blx thumb_sym1
+ blx arm_glob_sym1
+ blx arm_glob_sym2
+ blx arm_sym1
+ nop
+ bx lr
+
+ .type arm_sym1, %function
+arm_sym1:
+ nop
+ bx lr
+
+ .thumb
+ .thumb_func
+ .type thumb_sym1, %function
+thumb_sym1:
+ bx lr
+
+ .type thumb_glob_sym1, %function
+ .thumb_func
+ .thumb
+thumb_glob_sym1:
+ bx lr
+
+ .section foo,"ax"
+
+@ Add some space to avoid confusing objdump output: as we are
+@ producing a relocatable file, objdump may match an address to
+@ the wrong symbol (as symbols in different sections may have the same
+@ address in the object file).
+ .space 0x100
+
+ .type thumb_glob_sym2, %function
+ .thumb_func
+ .thumb
+thumb_glob_sym2:
+ bl arm_glob_sym1
+ bl arm_glob_sym2
+ bl arm_sym2
+ bl thumb_glob_sym1
+ bl thumb_glob_sym2
+ bl thumb_sym2
+ blx arm_glob_sym1
+ blx arm_glob_sym2
+ blx arm_sym2
+ blx thumb_glob_sym1
+ blx thumb_glob_sym2
+ blx thumb_sym2
+ nop
+ bx lr
+
+ .type thumb_sym2, %function
+thumb_sym2:
+ nop
+ bx lr
+
+ .arm
+ .type arm_sym2, %function
+arm_sym2:
+ bx lr
+
+ .global arm_glob_sym2
+ .type arm_glob_sym2, %function
+arm_glob_sym2:
+ bx lr