aboutsummaryrefslogtreecommitdiff
path: root/ld
diff options
context:
space:
mode:
Diffstat (limited to 'ld')
-rw-r--r--ld/emulparams/armelf.sh2
-rw-r--r--ld/emulparams/armelf_linux.sh2
-rw-r--r--ld/emulparams/armnto.sh2
-rw-r--r--ld/emultempl/armelf.em7
-rw-r--r--ld/ld.texinfo15
-rw-r--r--ld/testsuite/ld-arm/arm-elf.exp3
-rw-r--r--ld/testsuite/ld-arm/arm.ld1
-rw-r--r--ld/testsuite/ld-arm/armv4-bx.d19
-rw-r--r--ld/testsuite/ld-arm/armv4-bx.s8
9 files changed, 56 insertions, 3 deletions
diff --git a/ld/emulparams/armelf.sh b/ld/emulparams/armelf.sh
index ba9fdbe..a3c317f 100644
--- a/ld/emulparams/armelf.sh
+++ b/ld/emulparams/armelf.sh
@@ -6,7 +6,7 @@ LITTLE_OUTPUT_FORMAT="elf32-littlearm"
TEXT_START_ADDR=0x8000
TEMPLATE_NAME=elf32
EXTRA_EM_FILE=armelf
-OTHER_TEXT_SECTIONS='*(.glue_7t) *(.glue_7) *(.vfp11_veneer)'
+OTHER_TEXT_SECTIONS='*(.glue_7t) *(.glue_7) *(.vfp11_veneer) *(.v4_bx)'
OTHER_BSS_SYMBOLS='__bss_start__ = .;'
OTHER_BSS_END_SYMBOLS='_bss_end__ = . ; __bss_end__ = . ;'
OTHER_END_SYMBOLS='__end__ = . ;'
diff --git a/ld/emulparams/armelf_linux.sh b/ld/emulparams/armelf_linux.sh
index e7f301f..338d2eb 100644
--- a/ld/emulparams/armelf_linux.sh
+++ b/ld/emulparams/armelf_linux.sh
@@ -11,7 +11,7 @@ GENERATE_SHLIB_SCRIPT=yes
GENERATE_PIE_SCRIPT=yes
DATA_START_SYMBOLS='__data_start = . ;';
-OTHER_TEXT_SECTIONS='*(.glue_7t) *(.glue_7) *(.vfp11_veneer)'
+OTHER_TEXT_SECTIONS='*(.glue_7t) *(.glue_7) *(.vfp11_veneer) *(.v4_bx)'
OTHER_BSS_SYMBOLS='__bss_start__ = .;'
OTHER_BSS_END_SYMBOLS='_bss_end__ = . ; __bss_end__ = . ;'
OTHER_END_SYMBOLS='__end__ = . ;'
diff --git a/ld/emulparams/armnto.sh b/ld/emulparams/armnto.sh
index ae0b4be..f89f14f 100644
--- a/ld/emulparams/armnto.sh
+++ b/ld/emulparams/armnto.sh
@@ -6,7 +6,7 @@ LITTLE_OUTPUT_FORMAT="elf32-littlearm"
TEXT_START_ADDR=0x00100000
TEMPLATE_NAME=elf32
EXTRA_EM_FILE=armelf
-OTHER_TEXT_SECTIONS='*(.glue_7t) *(.glue_7) *(.vfp11_veneer)'
+OTHER_TEXT_SECTIONS='*(.glue_7t) *(.glue_7) *(.vfp11_veneer) *(.v4_bx)'
OTHER_BSS_SYMBOLS='__bss_start__ = .;'
OTHER_BSS_END_SYMBOLS='_bss_end__ = . ; __bss_end__ = . ;'
OTHER_END_SYMBOLS='__end__ = . ;'
diff --git a/ld/emultempl/armelf.em b/ld/emultempl/armelf.em
index 7d0320d..29e9902 100644
--- a/ld/emultempl/armelf.em
+++ b/ld/emultempl/armelf.em
@@ -264,6 +264,7 @@ PARSE_AND_LIST_PROLOGUE='
#define OPTION_VFP11_DENORM_FIX 308
#define OPTION_NO_ENUM_SIZE_WARNING 309
#define OPTION_PIC_VENEER 310
+#define OPTION_FIX_V4BX_INTERWORKING 311
'
PARSE_AND_LIST_SHORTOPTS=p
@@ -276,6 +277,7 @@ PARSE_AND_LIST_LONGOPTS='
{ "target1-abs", no_argument, NULL, OPTION_TARGET1_ABS},
{ "target2", required_argument, NULL, OPTION_TARGET2},
{ "fix-v4bx", no_argument, NULL, OPTION_FIX_V4BX},
+ { "fix-v4bx-interworking", no_argument, NULL, OPTION_FIX_V4BX_INTERWORKING},
{ "use-blx", no_argument, NULL, OPTION_USE_BLX},
{ "vfp11-denorm-fix", required_argument, NULL, OPTION_VFP11_DENORM_FIX},
{ "no-enum-size-warning", no_argument, NULL, OPTION_NO_ENUM_SIZE_WARNING},
@@ -289,6 +291,7 @@ PARSE_AND_LIST_OPTIONS='
fprintf (file, _(" --target1=abs Interpret R_ARM_TARGET1 as R_ARM_ABS32\n"));
fprintf (file, _(" --target2=<type> Specify definition of R_ARM_TARGET2\n"));
fprintf (file, _(" --fix-v4bx Rewrite BX rn as MOV pc, rn for ARMv4\n"));
+ fprintf (file, _(" --fix-v4bx-interworking Rewrite BX rn branch to ARMv4 interworking veneer\n"));
fprintf (file, _(" --use-blx Enable use of BLX instructions\n"));
fprintf (file, _(" --vfp11-denorm-fix Specify how to fix VFP11 denorm erratum\n"));
fprintf (file, _(" --no-enum-size-warning Don'\''t warn about objects with incompatible"
@@ -325,6 +328,10 @@ PARSE_AND_LIST_ARGS_CASES='
fix_v4bx = 1;
break;
+ case OPTION_FIX_V4BX_INTERWORKING:
+ fix_v4bx = 2;
+ break;
+
case OPTION_USE_BLX:
use_blx = 1;
break;
diff --git a/ld/ld.texinfo b/ld/ld.texinfo
index 00081da..cda834a 100644
--- a/ld/ld.texinfo
+++ b/ld/ld.texinfo
@@ -5584,6 +5584,21 @@ linker, which causes v4t @code{BX rM} instructions to be rewritten as
In the former case, the switch should not be used, and @samp{R_ARM_V4BX}
relocations are ignored.
+@cindex FIX_V4BX_INTERWORKING
+@kindex --fix-v4bx-interworking
+Replace @code{BX rM} instructions identified by @samp{R_ARM_V4BX}
+relocations with a branch to the following veneer:
+
+@smallexample
+TST rM, #1
+MOVEQ PC, rM
+BX Rn
+@end smallexample
+
+This allows generation of libraries/applications that work on ARMv4 cores
+and are still interworking safe. Note that the above veneer clobbers the
+condition flags, so may cause incorrect progrm behavior in rare cases.
+
@cindex USE_BLX
@kindex --use-blx
The @samp{--use-blx} switch enables the linker to use ARM/Thumb
diff --git a/ld/testsuite/ld-arm/arm-elf.exp b/ld/testsuite/ld-arm/arm-elf.exp
index 8897968..3f2b69c 100644
--- a/ld/testsuite/ld-arm/arm-elf.exp
+++ b/ld/testsuite/ld-arm/arm-elf.exp
@@ -173,6 +173,9 @@ set armelftests {
{"callweak" "-static -T arm.ld" "" {callweak.s}
{{objdump -dr callweak.d}}
"callweak"}
+ {"ARMv4 interworking" "-static -T arm.ld --fix-v4bx-interworking" "--fix-v4bx -meabi=4" {armv4-bx.s}
+ {{objdump -d armv4-bx.d}}
+ "armv4-bx"}
}
run_ld_link_tests $armelftests
diff --git a/ld/testsuite/ld-arm/arm.ld b/ld/testsuite/ld-arm/arm.ld
index c9e01e6..cb73fb3 100644
--- a/ld/testsuite/ld-arm/arm.ld
+++ b/ld/testsuite/ld-arm/arm.ld
@@ -11,6 +11,7 @@ SECTIONS
*(.text)
*(.after)
*(.glue_7)
+ *(.v4_bx)
} =0
. = 0x9000;
.got : { *(.got) *(.got.plt)}
diff --git a/ld/testsuite/ld-arm/armv4-bx.d b/ld/testsuite/ld-arm/armv4-bx.d
new file mode 100644
index 0000000..095b387
--- /dev/null
+++ b/ld/testsuite/ld-arm/armv4-bx.d
@@ -0,0 +1,19 @@
+
+.*: .*file format elf32-(big|little)arm
+
+Disassembly of section \.text:
+
+00008000 <_start>:
+ 8000: ea000001 b 800c \<__bx_r14\>
+ 8004: ea000003 b 8018 \<__bx_r0\>
+ 8008: 0a000002 beq 8018 \<__bx_r0\>
+
+0000800c <__bx_r14>:
+ 800c: e31e0001 tst lr, #1 ; 0x1
+ 8010: 01a0f00e moveq pc, lr
+ 8014: e12fff1e bx lr
+
+00008018 <__bx_r0>:
+ 8018: e3100001 tst r0, #1 ; 0x1
+ 801c: 01a0f000 moveq pc, r0
+ 8020: e12fff10 bx r0
diff --git a/ld/testsuite/ld-arm/armv4-bx.s b/ld/testsuite/ld-arm/armv4-bx.s
new file mode 100644
index 0000000..ef86357
--- /dev/null
+++ b/ld/testsuite/ld-arm/armv4-bx.s
@@ -0,0 +1,8 @@
+.text
+.arch armv4
+.global _start
+.type _start, %function
+_start:
+bx lr
+bx r0
+bxeq r0