diff options
author | Mikael Pettersson <[email protected]> | 2015-01-11 13:35:25 +0100 |
---|---|---|
committer | Mikael Pettersson <[email protected]> | 2015-01-11 13:35:25 +0100 |
commit | 132f27299130a5183d14122c71f9c23587e4945e (patch) | |
tree | 4ebf5f534cdf4c13373f454c77a41a8f08a52b00 /erts/emulator/hipe/hipe_arm_bifs.m4 | |
parent | aee18f309d41691019fc323bd41c5f78be49953b (diff) | |
download | otp-132f27299130a5183d14122c71f9c23587e4945e.tar.gz otp-132f27299130a5183d14122c71f9c23587e4945e.tar.bz2 otp-132f27299130a5183d14122c71f9c23587e4945e.zip |
hipe: fix ARM/Thumb interworking
HiPE on ARM is currently severely broken if the rest of the VM is
compiled to run in Thumb mode -- calling native code quickly ends
up executing code in the wrong mode and crashing the VM. This is
a problem on e.g. Ubuntu which configures its system GCC to generate
Thumb by default. It can also be triggered by overriding CC or
CFLAGS when compiling the VM.
There were three issues that caused the breakage:
1. Assembly-coded functions in hipe_arm_glue.S weren't explicitly
tagged as functions, preventing the linker from generating the
correct mode-switching call instructions for calls from C to
these functions.
Fixed by tagging those symbols as functions.
2. A few BIF wrappers were so simple that they performed tailcalls
to the C BIFs. This fails to switch mode when C is in Thumb.
Fixed by performing ordinary recursive calls when C is in Thumb.
3. The assembly-coded source files weren't explicitly tagged as ARM.
Tested with the HiPE testsuite on ARMv7, with the VM built as ARM
and as Thumb. Also manually inspected the object code for the beam
executable and checked that call sites from C to HiPE's ARM runtime
code and vice versa used the correct mode-switching instructions.
Diffstat (limited to 'erts/emulator/hipe/hipe_arm_bifs.m4')
-rw-r--r-- | erts/emulator/hipe/hipe_arm_bifs.m4 | 73 |
1 files changed, 72 insertions, 1 deletions
diff --git a/erts/emulator/hipe/hipe_arm_bifs.m4 b/erts/emulator/hipe/hipe_arm_bifs.m4 index bd8bc5ab6b..3ca9a1bcdb 100644 --- a/erts/emulator/hipe/hipe_arm_bifs.m4 +++ b/erts/emulator/hipe/hipe_arm_bifs.m4 @@ -25,6 +25,7 @@ include(`hipe/hipe_arm_asm.m4') .text .p2align 2 + .arm `#if defined(ERTS_ENABLE_LOCK_CHECK) && defined(ERTS_SMP) # define CALL_BIF(F) ldr r14, =F; str r14, [r0, #P_BIF_CALLEE]; bl hipe_debug_bif_wrapper @@ -391,7 +392,14 @@ $1: mov r0, P /* Perform a quick save;call;restore;ret sequence. */ +#ifdef __thumb__ + SAVE_CONTEXT_QUICK + bl $2 + RESTORE_CONTEXT_QUICK + NBIF_RET(0) +#else QUICK_CALL_RET($2,0) +#endif .size $1, .-$1 .type $1, %function #endif') @@ -407,7 +415,14 @@ $1: NBIF_ARG(r1,1,0) /* Perform a quick save;call;restore;ret sequence. */ +#ifdef __thumb__ + SAVE_CONTEXT_QUICK + bl $2 + RESTORE_CONTEXT_QUICK + NBIF_RET(1) +#else QUICK_CALL_RET($2,1) +#endif .size $1, .-$1 .type $1, %function #endif') @@ -424,7 +439,14 @@ $1: NBIF_ARG(r2,2,1) /* Perform a quick save;call;restore;ret sequence. */ +#ifdef __thumb__ + SAVE_CONTEXT_QUICK + bl $2 + RESTORE_CONTEXT_QUICK + NBIF_RET(2) +#else QUICK_CALL_RET($2,2) +#endif .size $1, .-$1 .type $1, %function #endif') @@ -442,7 +464,14 @@ $1: NBIF_ARG(r3,3,2) /* Perform a quick save;call;restore;ret sequence. */ +#ifdef __thumb__ + SAVE_CONTEXT_QUICK + bl $2 + RESTORE_CONTEXT_QUICK + NBIF_RET(3) +#else QUICK_CALL_RET($2,3) +#endif .size $1, .-$1 .type $1, %function #endif') @@ -466,7 +495,14 @@ $1: NBIF_ARG(r3,5,2) /* Perform a quick save;call;restore;ret sequence. */ +#ifdef __thumb__ + SAVE_CONTEXT_QUICK + bl $2 + RESTORE_CONTEXT_QUICK + NBIF_RET(5) +#else QUICK_CALL_RET($2,5) +#endif .size $1, .-$1 .type $1, %function #endif') @@ -488,9 +524,16 @@ define(noproc_primop_interface_0, #`define' HAVE_$1 .global $1 $1: - /* XXX: this case is always trivial; how to suppress the branch? */ /* Perform a quick save;call;restore;ret sequence. */ +#ifdef __thumb__ + SAVE_CONTEXT_QUICK + bl $2 + RESTORE_CONTEXT_QUICK + NBIF_RET(0) +#else + /* XXX: this case is always trivial; how to suppress the branch? */ QUICK_CALL_RET($2,0) +#endif .size $1, .-$1 .type $1, %function #endif') @@ -505,7 +548,14 @@ $1: NBIF_ARG(r0,1,0) /* Perform a quick save;call;restore;ret sequence. */ +#ifdef __thumb__ + SAVE_CONTEXT_QUICK + bl $2 + RESTORE_CONTEXT_QUICK + NBIF_RET(1) +#else QUICK_CALL_RET($2,1) +#endif .size $1, .-$1 .type $1, %function #endif') @@ -521,7 +571,14 @@ $1: NBIF_ARG(r1,2,1) /* Perform a quick save;call;restore;ret sequence. */ +#ifdef __thumb__ + SAVE_CONTEXT_QUICK + bl $2 + RESTORE_CONTEXT_QUICK + NBIF_RET(2) +#else QUICK_CALL_RET($2,2) +#endif .size $1, .-$1 .type $1, %function #endif') @@ -538,7 +595,14 @@ $1: NBIF_ARG(r2,3,2) /* Perform a quick save;call;restore;ret sequence. */ +#ifdef __thumb__ + SAVE_CONTEXT_QUICK + bl $2 + RESTORE_CONTEXT_QUICK + NBIF_RET(3) +#else QUICK_CALL_RET($2,3) +#endif .size $1, .-$1 .type $1, %function #endif') @@ -558,7 +622,14 @@ $1: str r4, [sp, #0] /* Perform a quick save;call;restore;ret sequence. */ +#ifdef __thumb__ + SAVE_CONTEXT_QUICK + bl $2 + RESTORE_CONTEXT_QUICK + NBIF_RET(5) +#else QUICK_CALL_RET($2,5) +#endif .size $1, .-$1 .type $1, %function #endif') |