From 54cd0e9187da7b592054dc6cbcf7beed9e1c937c Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Mon, 18 Jan 2021 11:43:55 +0100 Subject: [PATCH] ntdll: Make inline asm compatible with Thumb-2. Signed-off-by: Alexandre Julliard --- dlls/ntdll/relay.c | 5 +++-- dlls/ntdll/signal_arm.c | 16 ++++++++++++++-- dlls/ntdll/unix/signal_arm.c | 17 ++++++++++------- include/wine/asm.h | 4 +++- 4 files changed, 30 insertions(+), 12 deletions(-) diff --git a/dlls/ntdll/relay.c b/dlls/ntdll/relay.c index ee7d9951c59..be2dc833377 100644 --- a/dlls/ntdll/relay.c +++ b/dlls/ntdll/relay.c @@ -545,7 +545,6 @@ DECLSPEC_HIDDEN void WINAPI relay_trace_exit( struct relay_descr *descr, unsigne extern LONGLONG WINAPI relay_call( struct relay_descr *descr, unsigned int idx, const DWORD *stack ); __ASM_GLOBAL_FUNC( relay_call, - ".arm\n\t" "push {r4-r8,lr}\n\t" "sub sp, #16\n\t" "mov r6, r2\n\t" @@ -559,8 +558,9 @@ __ASM_GLOBAL_FUNC( relay_call, "lsl r3, r1, #2\n\t" "subs r3, #16\n\t" /* first 4 args are in registers */ "ble 2f\n\t" + "add r3, #7\n\t" + "and r3, #~7\n" "sub sp, r3\n\t" - "and sp, #~7\n" "add r2, r6, #16\n\t" /* skip r0-r3 */ "1:\tsubs r3, r3, #4\n\t" "ldr r0, [r2, r3]\n\t" @@ -570,6 +570,7 @@ __ASM_GLOBAL_FUNC( relay_call, #ifndef __SOFTFP__ "tst r1, #0x80000000\n\t" "ldm r6, {r0-r3}\n\t" + "it ne\n\t" "vldmdbne r6!, {s0-s15}\n\t" #else "ldm r6, {r0-r3}\n\t" diff --git a/dlls/ntdll/signal_arm.c b/dlls/ntdll/signal_arm.c index 512462b7066..0461183460d 100644 --- a/dlls/ntdll/signal_arm.c +++ b/dlls/ntdll/signal_arm.c @@ -61,8 +61,8 @@ __ASM_GLOBAL_FUNC( __chkstk, "lsl r4, r4, #2\n\t" * RtlCaptureContext (NTDLL.@) */ __ASM_STDCALL_FUNC( RtlCaptureContext, 4, - ".arm\n\t" - "stmib r0, {r0-r12}\n\t" /* context->R0..R12 */ + "str r0, [r0, #0x4]\n\t" /* context->R0 */ + "str r1, [r0, #0x8]\n\t" /* context->R1 */ "mov r1, #0x0200000\n\t" /* CONTEXT_ARM */ "add r1, r1, #0x3\n\t" /* CONTEXT_FULL */ "str r1, [r0]\n\t" /* context->ContextFlags */ @@ -70,7 +70,13 @@ __ASM_STDCALL_FUNC( RtlCaptureContext, 4, "str LR, [r0, #0x3c]\n\t" /* context->Lr */ "str LR, [r0, #0x40]\n\t" /* context->Pc */ "mrs r1, CPSR\n\t" + "tst lr, #1\n\t" /* Thumb? */ + "ite ne\n\t" + "orrne r1, r1, #0x20\n\t" + "biceq r1, r1, #0x20\n\t" "str r1, [r0, #0x44]\n\t" /* context->Cpsr */ + "add r0, #0x0c\n\t" + "stm r0, {r2-r12}\n\t" /* context->R2..R12 */ "bx lr" ) @@ -257,6 +263,12 @@ __ASM_STDCALL_FUNC( RtlRaiseException, 4, "ldr r0, [sp, #0x1a0]\n\t" /* rec */ "ldr r1, [sp, #0x1a4]\n\t" "str r1, [sp, #0x40]\n\t" /* context->Pc */ + "ldr r2, [sp, #0x44]\n\t" /* context->Cpsr */ + "tst r1, #1\n\t" /* Thumb? */ + "ite ne\n\t" + "orrne r2, r2, #0x20\n\t" + "biceq r2, r2, #0x20\n\t" + "str r2, [sp, #0x44]\n\t" /* context->Cpsr */ "str r1, [r0, #12]\n\t" /* rec->ExceptionAddress */ "add r1, sp, #0x1a8\n\t" "str r1, [sp, #0x38]\n\t" /* context->Sp */ diff --git a/dlls/ntdll/unix/signal_arm.c b/dlls/ntdll/unix/signal_arm.c index 487c8501cc7..6fa37b81415 100644 --- a/dlls/ntdll/unix/signal_arm.c +++ b/dlls/ntdll/unix/signal_arm.c @@ -316,17 +316,18 @@ static void restore_context( const CONTEXT *context, ucontext_t *sigcontext ) */ void DECLSPEC_HIDDEN set_cpu_context( const CONTEXT *context ); __ASM_GLOBAL_FUNC( set_cpu_context, - ".arm\n\t" "ldr r2, [r0, #0x44]\n\t" /* context->Cpsr */ "tst r2, #0x20\n\t" /* thumb? */ "ldr r1, [r0, #0x40]\n\t" /* context->Pc */ + "ite ne\n\t" "orrne r1, r1, #1\n\t" /* Adjust PC according to thumb */ "biceq r1, r1, #1\n\t" /* Adjust PC according to arm */ "msr CPSR_f, r2\n\t" "ldr lr, [r0, #0x3c]\n\t" /* context->Lr */ "ldr sp, [r0, #0x38]\n\t" /* context->Sp */ "push {r1}\n\t" - "ldmib r0, {r0-r12}\n\t" /* context->R0..R12 */ + "add r0, #0x4\n\t" + "ldm r0, {r0-r12}\n\t" /* context->R0..R12 */ "pop {pc}" ) @@ -611,7 +612,8 @@ __ASM_GLOBAL_FUNC( call_user_apc_dispatcher, "mov sp, r0\n\t" "b 2f\n" "1:\tldr r0, [r10]\n\t" - "sub sp, r0, #0x1a0\n\t" + "sub r0, #0x1a0\n\t" + "mov sp, r0\n\t" "mov r0, #3\n\t" "movt r0, #32\n\t" "str r0, [sp]\n\t" /* context.ContextFlags = CONTEXT_FULL */ @@ -658,7 +660,8 @@ __ASM_GLOBAL_FUNC( call_user_exception_dispatcher, "ldm r3, {r5-r11}\n\t" "ldr r4, [r3, #32]\n\t" "ldr lr, [r3, #36]\n\t" - "add sp, r3, #40\n\t" + "add r3, #40\n\t" + "mov sp, r3\n\t" "bx r2" ) @@ -1031,7 +1034,6 @@ PCONTEXT DECLSPEC_HIDDEN get_initial_context( LPTHREAD_START_ROUTINE entry, void * signal_start_thread */ __ASM_GLOBAL_FUNC( signal_start_thread, - ".arm\n\t" "push {r4-r12,lr}\n\t" "mov r5, r3\n\t" /* thunk */ /* store exit frame */ @@ -1039,7 +1041,8 @@ __ASM_GLOBAL_FUNC( signal_start_thread, "str sp, [r3, #0x1d4]\n\t" /* arm_thread_data()->exit_frame */ /* switch to thread stack */ "ldr r4, [r3, #4]\n\t" /* teb->Tib.StackBase */ - "sub sp, r4, #0x1000\n\t" + "sub r4, #0x1000\n\t" + "mov sp, r4\n\t" /* attach dlls */ "bl " __ASM_NAME("get_initial_context") "\n\t" "mov lr, #0\n\t" @@ -1048,11 +1051,11 @@ __ASM_GLOBAL_FUNC( signal_start_thread, extern void DECLSPEC_NORETURN call_thread_exit_func( int status, void (*func)(int), TEB *teb ); __ASM_GLOBAL_FUNC( call_thread_exit_func, - ".arm\n\t" "ldr r3, [r2, #0x1d4]\n\t" /* arm_thread_data()->exit_frame */ "mov ip, #0\n\t" "str ip, [r2, #0x1d4]\n\t" "cmp r3, ip\n\t" + "it ne\n\t" "movne sp, r3\n\t" "blx r1" ) diff --git a/include/wine/asm.h b/include/wine/asm.h index 236b35cf8fe..b9dae95dc6d 100644 --- a/include/wine/asm.h +++ b/include/wine/asm.h @@ -59,7 +59,9 @@ # define __ASM_FUNC_TYPE(name) ".def " name "\n\t.scl 2\n\t.type 32\n\t.endef" #elif defined(__APPLE__) # define __ASM_FUNC_TYPE(name) "" -#elif defined(__arm__) || defined(__arm64__) +#elif defined(__arm__) && defined(__thumb__) +# define __ASM_FUNC_TYPE(name) ".type " name ",%function\n\t.thumb_func" +#elif defined(__arm__) || defined(__aarch64__) # define __ASM_FUNC_TYPE(name) ".type " name ",%function" #else # define __ASM_FUNC_TYPE(name) ".type " name ",@function"