diff options
Diffstat (limited to 'ld')
-rw-r--r-- | ld/emulparams/armelf.sh | 2 | ||||
-rw-r--r-- | ld/emulparams/armelf_linux.sh | 2 | ||||
-rw-r--r-- | ld/emulparams/armnto.sh | 2 | ||||
-rw-r--r-- | ld/emultempl/armelf.em | 7 | ||||
-rw-r--r-- | ld/ld.texinfo | 15 | ||||
-rw-r--r-- | ld/testsuite/ld-arm/arm-elf.exp | 3 | ||||
-rw-r--r-- | ld/testsuite/ld-arm/arm.ld | 1 | ||||
-rw-r--r-- | ld/testsuite/ld-arm/armv4-bx.d | 19 | ||||
-rw-r--r-- | ld/testsuite/ld-arm/armv4-bx.s | 8 |
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 |