From 847db3c1d3f5444808814cbea8f2920b16a96fcb Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Wed, 25 Aug 2021 15:15:01 +0200 Subject: [PATCH] ntdll: Store the syscall table in the syscall frame on all platforms. Signed-off-by: Alexandre Julliard --- dlls/ntdll/unix/loader.c | 6 ++ dlls/ntdll/unix/signal_arm.c | 10 ++- dlls/ntdll/unix/signal_arm64.c | 14 ++-- dlls/ntdll/unix/signal_i386.c | 51 +++++++------ dlls/ntdll/unix/signal_x86_64.c | 7 +- include/wine/unixlib.h | 2 + include/winternl.h | 8 ++ tools/winebuild/import.c | 131 ++++++++++++++------------------ 8 files changed, 122 insertions(+), 107 deletions(-) diff --git a/dlls/ntdll/unix/loader.c b/dlls/ntdll/unix/loader.c index 8a5314a1117..bdd54314540 100644 --- a/dlls/ntdll/unix/loader.c +++ b/dlls/ntdll/unix/loader.c @@ -115,6 +115,11 @@ SYSTEM_DLL_INIT_BLOCK *pLdrSystemDllInitBlock = NULL; static NTSTATUS (CDECL *p__wine_set_unix_funcs)( int version, const struct unix_funcs *funcs ); +extern SYSTEM_SERVICE_TABLE __wine_syscall_table DECLSPEC_HIDDEN; + +SYSTEM_SERVICE_TABLE KeServiceDescriptorTable[4]; + + #ifdef __GNUC__ static void fatal_error( const char *err, ... ) __attribute__((noreturn, format(printf,1,2))); #endif @@ -1939,6 +1944,7 @@ static void start_main_thread(void) NtCreateKeyedEvent( &keyed_event, GENERIC_READ | GENERIC_WRITE, NULL, 0 ); load_ntdll(); if (main_image_info.Machine != current_machine) load_wow64_ntdll( main_image_info.Machine ); + KeServiceDescriptorTable[0] = __wine_syscall_table; status = p__wine_set_unix_funcs( NTDLL_UNIXLIB_VERSION, &unix_funcs ); if (status == STATUS_REVISION_MISMATCH) { diff --git a/dlls/ntdll/unix/signal_arm.c b/dlls/ntdll/unix/signal_arm.c index 8fa10da3a01..de0f7deb150 100644 --- a/dlls/ntdll/unix/signal_arm.c +++ b/dlls/ntdll/unix/signal_arm.c @@ -192,10 +192,12 @@ struct syscall_frame DWORD restore_flags; /* 044 */ DWORD fpscr; /* 048 */ struct syscall_frame *prev_frame; /* 04c */ - ULONGLONG d[32]; /* 050 */ + SYSTEM_SERVICE_TABLE *syscall_table; /* 050 */ + DWORD align[3]; /* 054 */ + ULONGLONG d[32]; /* 060 */ }; -C_ASSERT( sizeof( struct syscall_frame ) == 0x150); +C_ASSERT( sizeof( struct syscall_frame ) == 0x160); struct arm_thread_data { @@ -607,6 +609,7 @@ NTSTATUS WINAPI KeUserModeCallback( ULONG id, const void *args, ULONG len, void callback_frame.frame.sp = (ULONG_PTR)args_data; callback_frame.frame.pc = (ULONG_PTR)pKiUserCallbackDispatcher; callback_frame.frame.restore_flags = CONTEXT_INTEGER; + callback_frame.frame.syscall_table = frame->syscall_table; callback_frame.frame.prev_frame = frame; arm_thread_data()->syscall_frame = &callback_frame.frame; @@ -993,6 +996,7 @@ void DECLSPEC_HIDDEN call_init_thunk( LPTHREAD_START_ROUTINE entry, void *arg, B frame->r0 = (DWORD)ctx; frame->prev_frame = NULL; frame->restore_flags |= CONTEXT_INTEGER; + frame->syscall_table = KeServiceDescriptorTable; pthread_sigmask( SIG_UNBLOCK, &server_block_set, NULL ); __wine_syscall_dispatcher_return( frame, 0 ); @@ -1009,7 +1013,7 @@ __ASM_GLOBAL_FUNC( signal_start_thread, /* set syscall frame */ "ldr r6, [r3, #0x1d8]\n\t" /* arm_thread_data()->syscall_frame */ "cbnz r6, 1f\n\t" - "sub r6, sp, #0x150\n\t" /* sizeof(struct syscall_frame) */ + "sub r6, sp, #0x160\n\t" /* sizeof(struct syscall_frame) */ "str r6, [r3, #0x1d8]\n\t" /* arm_thread_data()->syscall_frame */ "1:\tmov sp, r6\n\t" "bl " __ASM_NAME("call_init_thunk") ) diff --git a/dlls/ntdll/unix/signal_arm64.c b/dlls/ntdll/unix/signal_arm64.c index b0c427b9fd0..2fcc1bb5739 100644 --- a/dlls/ntdll/unix/signal_arm64.c +++ b/dlls/ntdll/unix/signal_arm64.c @@ -142,12 +142,14 @@ struct syscall_frame ULONG cpsr; /* 108 */ ULONG restore_flags; /* 10c */ struct syscall_frame *prev_frame; /* 110 */ - ULONG fpcr; /* 118 */ - ULONG fpsr; /* 11c */ - NEON128 v[32]; /* 120 */ + SYSTEM_SERVICE_TABLE *syscall_table; /* 118 */ + ULONG64 align; /* 120 */ + ULONG fpcr; /* 128 */ + ULONG fpsr; /* 12c */ + NEON128 v[32]; /* 130 */ }; -C_ASSERT( sizeof( struct syscall_frame ) == 0x320 ); +C_ASSERT( sizeof( struct syscall_frame ) == 0x330 ); struct arm64_thread_data { @@ -756,6 +758,7 @@ NTSTATUS WINAPI KeUserModeCallback( ULONG id, const void *args, ULONG len, void callback_frame.frame.sp = (ULONG_PTR)args_data; callback_frame.frame.pc = (ULONG_PTR)pKiUserCallbackDispatcher; callback_frame.frame.restore_flags = CONTEXT_INTEGER; + callback_frame.frame.syscall_table = frame->syscall_table; callback_frame.frame.prev_frame = frame; arm64_thread_data()->syscall_frame = &callback_frame.frame; @@ -1186,6 +1189,7 @@ void DECLSPEC_HIDDEN call_init_thunk( LPTHREAD_START_ROUTINE entry, void *arg, B frame->x[18] = (ULONG64)teb; frame->prev_frame = NULL; frame->restore_flags |= CONTEXT_INTEGER; + frame->syscall_table = KeServiceDescriptorTable; pthread_sigmask( SIG_UNBLOCK, &server_block_set, NULL ); __wine_syscall_dispatcher_return( frame, 0 ); @@ -1203,7 +1207,7 @@ __ASM_GLOBAL_FUNC( signal_start_thread, /* set syscall frame */ "ldr x8, [x3, #0x2f8]\n\t" /* arm64_thread_data()->syscall_frame */ "cbnz x8, 1f\n\t" - "sub x8, sp, #0x320\n\t" /* sizeof(struct syscall_frame) */ + "sub x8, sp, #0x330\n\t" /* sizeof(struct syscall_frame) */ "str x8, [x3, #0x2f8]\n\t" /* arm64_thread_data()->syscall_frame */ "1:\tmov sp, x8\n\t" "bl " __ASM_NAME("call_init_thunk") ) diff --git a/dlls/ntdll/unix/signal_i386.c b/dlls/ntdll/unix/signal_i386.c index 04645a9c4a6..5638975e337 100644 --- a/dlls/ntdll/unix/signal_i386.c +++ b/dlls/ntdll/unix/signal_i386.c @@ -463,26 +463,27 @@ enum i386_trap_code struct syscall_frame { - DWORD restore_flags; /* 000 */ - DWORD eflags; /* 004 */ - DWORD eip; /* 008 */ - DWORD esp; /* 00c */ - WORD cs; /* 010 */ - WORD ss; /* 012 */ - WORD ds; /* 014 */ - WORD es; /* 016 */ - WORD fs; /* 018 */ - WORD gs; /* 01a */ - DWORD eax; /* 01c */ - DWORD ebx; /* 020 */ - DWORD ecx; /* 024 */ - DWORD edx; /* 028 */ - DWORD edi; /* 02c */ - DWORD esi; /* 030 */ - DWORD ebp; /* 034 */ - DWORD syscall_flags; /* 038 */ - struct syscall_frame *prev_frame; /* 03c */ - union /* 040 */ + WORD syscall_flags; /* 000 */ + WORD restore_flags; /* 002 */ + DWORD eflags; /* 004 */ + DWORD eip; /* 008 */ + DWORD esp; /* 00c */ + WORD cs; /* 010 */ + WORD ss; /* 012 */ + WORD ds; /* 014 */ + WORD es; /* 016 */ + WORD fs; /* 018 */ + WORD gs; /* 01a */ + DWORD eax; /* 01c */ + DWORD ebx; /* 020 */ + DWORD ecx; /* 024 */ + DWORD edx; /* 028 */ + DWORD edi; /* 02c */ + DWORD esi; /* 030 */ + DWORD ebp; /* 034 */ + SYSTEM_SERVICE_TABLE *syscall_table; /* 038 */ + struct syscall_frame *prev_frame; /* 03c */ + union /* 040 */ { XSAVE_FORMAT xsave; FLOATING_SAVE_AREA fsave; @@ -490,7 +491,7 @@ struct syscall_frame /* Leave space for the whole set of YMM registers. They're not used in * 32-bit mode, but some processors fault if they're not in writable memory. */ - DECLSPEC_ALIGN(64) XSTATE xstate; /* 240 */ + DECLSPEC_ALIGN(64) XSTATE xstate; /* 240 */ }; C_ASSERT( sizeof(struct syscall_frame) == 0x380 ); @@ -873,7 +874,7 @@ NTSTATUS signal_set_full_context( CONTEXT *context ) NTSTATUS status = NtSetContextThread( GetCurrentThread(), context ); if (!status && (context->ContextFlags & CONTEXT_INTEGER) == CONTEXT_INTEGER) - x86_thread_data()->syscall_frame->restore_flags |= CONTEXT_INTEGER; + x86_thread_data()->syscall_frame->restore_flags |= LOWORD(CONTEXT_INTEGER); return status; } @@ -1617,6 +1618,7 @@ NTSTATUS WINAPI KeUserModeCallback( ULONG id, const void *args, ULONG len, void callback_frame.frame.eip = (ULONG_PTR)pKiUserCallbackDispatcher; callback_frame.frame.eflags = 0x202; callback_frame.frame.syscall_flags = frame->syscall_flags; + callback_frame.frame.syscall_table = frame->syscall_table; callback_frame.frame.prev_frame = frame; x86_thread_data()->syscall_frame = &callback_frame.frame; @@ -1779,7 +1781,7 @@ static BOOL handle_syscall_trap( ucontext_t *sigcontext ) frame->eip = *(ULONG *)ESP_sig( sigcontext ); frame->eflags = EFL_sig(sigcontext); - frame->restore_flags = CONTEXT_CONTROL; + frame->restore_flags = LOWORD(CONTEXT_CONTROL); EIP_sig( sigcontext ) = (ULONG)__wine_syscall_dispatcher_prolog_end; ECX_sig( sigcontext ) = (ULONG)frame; @@ -2420,7 +2422,8 @@ void DECLSPEC_HIDDEN call_init_thunk( LPTHREAD_START_ROUTINE entry, void *arg, B frame->eip = (DWORD)pLdrInitializeThunk; frame->prev_frame = NULL; frame->syscall_flags = syscall_flags; - frame->restore_flags |= CONTEXT_INTEGER; + frame->syscall_table = KeServiceDescriptorTable; + frame->restore_flags |= LOWORD(CONTEXT_INTEGER); pthread_sigmask( SIG_UNBLOCK, &server_block_set, NULL ); __wine_syscall_dispatcher_return( frame, 0 ); diff --git a/dlls/ntdll/unix/signal_x86_64.c b/dlls/ntdll/unix/signal_x86_64.c index cc2238f62c4..eab9932f52f 100644 --- a/dlls/ntdll/unix/signal_x86_64.c +++ b/dlls/ntdll/unix/signal_x86_64.c @@ -327,8 +327,9 @@ struct syscall_frame DWORD restore_flags; /* 0094 */ ULONG64 rbp; /* 0098 */ struct syscall_frame *prev_frame; /* 00a0 */ - DWORD syscall_flags; /* 00a8 */ - DWORD align[5]; /* 00ac */ + SYSTEM_SERVICE_TABLE *syscall_table; /* 00a8 */ + DWORD syscall_flags; /* 00b0 */ + DWORD align[3]; /* 00b4 */ XMM_SAVE_AREA32 xsave; /* 00c0 */ DECLSPEC_ALIGN(64) XSTATE xstate; /* 02c0 */ }; @@ -2318,6 +2319,7 @@ NTSTATUS WINAPI KeUserModeCallback( ULONG id, const void *args, ULONG len, void callback_frame.frame.restore_flags = CONTEXT_CONTROL | CONTEXT_INTEGER; callback_frame.frame.prev_frame = frame; callback_frame.frame.syscall_flags = frame->syscall_flags; + callback_frame.frame.syscall_table = frame->syscall_table; amd64_thread_data()->syscall_frame = &callback_frame.frame; __wine_syscall_dispatcher_return( &callback_frame.frame, 0 ); @@ -3043,6 +3045,7 @@ void DECLSPEC_HIDDEN call_init_thunk( LPTHREAD_START_ROUTINE entry, void *arg, B frame->prev_frame = NULL; frame->restore_flags |= CONTEXT_INTEGER; frame->syscall_flags = syscall_flags; + frame->syscall_table = KeServiceDescriptorTable; pthread_sigmask( SIG_UNBLOCK, &server_block_set, NULL ); __wine_syscall_dispatcher_return( frame, 0 ); diff --git a/include/wine/unixlib.h b/include/wine/unixlib.h index 7997a924eac..1f5308cb434 100644 --- a/include/wine/unixlib.h +++ b/include/wine/unixlib.h @@ -26,6 +26,8 @@ typedef UINT64 unixlib_handle_t; extern NTSTATUS WINAPI __wine_unix_call( unixlib_handle_t handle, unsigned int code, void *args ); +extern SYSTEM_SERVICE_TABLE KeServiceDescriptorTable[4]; + /* some useful helpers from ntdll */ extern DWORD ntdll_umbstowcs( const char *src, DWORD srclen, WCHAR *dst, DWORD dstlen ); extern int ntdll_wcstoumbs( const WCHAR *src, DWORD srclen, char *dst, DWORD dstlen, BOOL strict ); diff --git a/include/winternl.h b/include/winternl.h index bc70121ac28..ec2c95e99bc 100644 --- a/include/winternl.h +++ b/include/winternl.h @@ -3761,6 +3761,14 @@ typedef struct } SYSTEM_DLL_INIT_BLOCK; #endif +typedef struct +{ + ULONG_PTR *ServiceTable; + ULONG_PTR *CounterTable; + ULONG_PTR ServiceLimit; + BYTE *ArgumentTable; +} SYSTEM_SERVICE_TABLE; + /*********************************************************************** * Function declarations */ diff --git a/tools/winebuild/import.c b/tools/winebuild/import.c index 4b1e0b18b46..0228952d3b3 100644 --- a/tools/winebuild/import.c +++ b/tools/winebuild/import.c @@ -1434,7 +1434,7 @@ static void output_syscall_dispatcher(void) { case CPU_x86: output( "\tmovl %%fs:0x1f8,%%ecx\n" ); /* x86_thread_data()->syscall_frame */ - output( "\tmovl $0,0x00(%%ecx)\n" ); /* frame->restore_flags */ + output( "\tmovw $0,0x02(%%ecx)\n" ); /* frame->restore_flags */ output( "\tpopl 0x08(%%ecx)\n" ); /* frame->eip */ output( "\tpushfl\n" ); output( "\tpopl 0x04(%%ecx)\n" ); /* frame->eflags */ @@ -1453,29 +1453,23 @@ static void output_syscall_dispatcher(void) output( "\tmovl %%ebp,0x34(%%ecx)\n" ); output( "\tleal 0x34(%%ecx),%%ebp\n" ); output( "\tleal 4(%%esp),%%esi\n" ); /* first argument */ - output( "\tmovl %%eax,%%edx\n" ); - output( "\tshrl $8,%%edx\n" ); - output( "\tandl $0x30,%%edx\n" ); /* syscall table number */ - if (UsePIC) - { - output( "\tcall %s\n", asm_name("__wine_spec_get_pc_thunk_eax") ); - output( "1:\tleal %s-1b(%%eax,%%edx),%%ebx\n", asm_name("KeServiceDescriptorTable") ); - needs_get_pc_thunk = 1; - } - else output( "\tleal %s(%%edx),%%ebx\n", asm_name("KeServiceDescriptorTable") ); - output( "\ttestl $3,0x38(%%ecx)\n" ); /* SYSCALL_HAVE_XSAVE | SYSCALL_HAVE_XSAVEC */ + output( "\tmovl %%eax,%%ebx\n" ); + output( "\tshrl $8,%%ebx\n" ); + output( "\tandl $0x30,%%ebx\n" ); /* syscall table number */ + output( "\taddl 0x38(%%ecx),%%ebx\n" ); /* frame->syscall_table */ + output( "\ttestl $3,(%%ecx)\n" ); /* frame->syscall_flags & (SYSCALL_HAVE_XSAVE | SYSCALL_HAVE_XSAVEC) */ output( "\tjz 2f\n" ); output( "\tmovl $7,%%eax\n" ); output( "\txorl %%edx,%%edx\n" ); for (i = 0; i < 6; i++) output( "\tmovl %%edx,0x%x(%%ecx)\n", 0x240 + i * 4 ); - output( "\ttestl $2,0x38(%%ecx)\n" ); /* SYSCALL_HAVE_XSAVEC */ + output( "\ttestl $2,(%%ecx)\n" ); /* frame->syscall_flags & SYSCALL_HAVE_XSAVEC */ output( "\tjz 1f\n" ); for (i = 6; i < 16; i++) output( "\tmovl %%edx,0x%x(%%ecx)\n", 0x240 + i * 4 ); output( "\txsavec 0x40(%%ecx)\n" ); output( "\tjmp 4f\n" ); output( "1:\txsave 0x40(%%ecx)\n" ); output( "\tjmp 4f\n" ); - output( "2:\ttestl $4,0x38(%%ecx)\n" ); /* SYSCALL_HAVE_FXSAVE */ + output( "2:\ttestl $4,(%%ecx)\n" ); /* frame->syscall_flags & SYSCALL_HAVE_FXSAVE */ output( "\tjz 3f\n" ); output( "\tfxsave 0x40(%%ecx)\n" ); output( "\tjmp 4f\n" ); @@ -1497,10 +1491,10 @@ static void output_syscall_dispatcher(void) output( "\trep; movsl\n" ); output( "\tcall *(%%eax,%%edx,4)\n" ); output( "\tleal -0x34(%%ebp),%%esp\n" ); - output( "5:\tmovl (%%esp),%%ecx\n" ); /* frame->restore_flags */ - output( "\ttestl $0x68,%%ecx\n" ); /* CONTEXT_FLOATING_POINT | CONTEXT_EXTENDED_REGISTERS | CONTEXT_XSAVE */ + output( "5:\tmovl 0(%%esp),%%ecx\n" ); /* frame->syscall_flags + (frame->restore_flags << 16) */ + output( "\ttestl $0x68 << 16,%%ecx\n" ); /* CONTEXT_FLOATING_POINT | CONTEXT_EXTENDED_REGISTERS | CONTEXT_XSAVE */ output( "\tjz 3f\n" ); - output( "\ttestl $3,0x38(%%esp)\n" ); /* SYSCALL_HAVE_XSAVE | SYSCALL_HAVE_XSAVEC */ + output( "\ttestl $3,%%ecx\n" ); /* SYSCALL_HAVE_XSAVE | SYSCALL_HAVE_XSAVEC */ output( "\tjz 1f\n" ); output( "\tmovl %%eax,%%esi\n" ); output( "\tmovl $7,%%eax\n" ); @@ -1508,7 +1502,7 @@ static void output_syscall_dispatcher(void) output( "\txrstor 0x40(%%esp)\n" ); output( "\tmovl %%esi,%%eax\n" ); output( "\tjmp 3f\n" ); - output( "1:\ttestl $4,0x38(%%esp)\n" ); /* SYSCALL_HAVE_FXSAVE */ + output( "1:\ttestl $4,%%ecx\n" ); /* SYSCALL_HAVE_FXSAVE */ output( "\tjz 2f\n" ); output( "\tfxrstor 0x40(%%esp)\n" ); output( "\tjmp 3f\n" ); @@ -1517,13 +1511,13 @@ static void output_syscall_dispatcher(void) output( "3:\tmovl 0x2c(%%esp),%%edi\n" ); output( "\tmovl 0x30(%%esp),%%esi\n" ); output( "\tmovl 0x34(%%esp),%%ebp\n" ); - output( "\ttestl $0x7,%%ecx\n" ); /* CONTEXT_CONTROL | CONTEXT_SEGMENTS | CONTEXT_INTEGER */ + output( "\ttestl $0x7 << 16,%%ecx\n" ); /* CONTEXT_CONTROL | CONTEXT_SEGMENTS | CONTEXT_INTEGER */ output( "\tjnz 1f\n" ); output( "\tmovl 0x20(%%esp),%%ebx\n" ); output( "\tmovl 0x08(%%esp),%%ecx\n" ); /* frame->eip */ output( "\tmovl 0x0c(%%esp),%%esp\n" ); /* frame->esp */ output( "\tjmpl *%%ecx\n" ); - output( "1:\ttestl $0x2,%%ecx\n" ); /* CONTEXT_INTEGER */ + output( "1:\ttestl $0x2 << 16,%%ecx\n" ); /* CONTEXT_INTEGER */ output( "\tjz 1f\n" ); output( "\tmovl 0x1c(%%esp),%%eax\n" ); output( "\tmovl 0x24(%%esp),%%ecx\n" ); @@ -1576,7 +1570,7 @@ static void output_syscall_dispatcher(void) /* Legends of Runeterra hooks the first system call return instruction, and * depends on us returning to it. Adjust the return address accordingly. */ output( "\tsubq $0xb,0x70(%%rcx)\n" ); - output( "\tmovl 0xa8(%%rcx),%%r14d\n" ); /* frame->syscall_flags */ + output( "\tmovl 0xb0(%%rcx),%%r14d\n" ); /* frame->syscall_flags */ output( "\ttestl $3,%%r14d\n" ); /* SYSCALL_HAVE_XSAVE | SYSCALL_HAVE_XSAVEC */ output( "\tjz 2f\n" ); output( "\tmovl $7,%%eax\n" ); @@ -1619,7 +1613,7 @@ static void output_syscall_dispatcher(void) output( "\tmovl %%eax,%%ebx\n" ); output( "\tshrl $8,%%ebx\n" ); output( "\tandl $0x30,%%ebx\n" ); /* syscall table number */ - output( "\tleaq %s(%%rip),%%rcx\n", asm_name("KeServiceDescriptorTable") ); + output( "\tmovq 0xa8(%%rcx),%%rcx\n" ); /* frame->syscall_table */ output( "\tleaq (%%rcx,%%rbx,2),%%rbx\n" ); output( "\tandl $0xfff,%%eax\n" ); /* syscall number */ output( "\tcmpq 16(%%rbx),%%rax\n" ); /* table->ServiceLimit */ @@ -1685,7 +1679,7 @@ static void output_syscall_dispatcher(void) output( "5:\tmovl $0x%x,%%edx\n", invalid_param ); output( "\tmovq %%rsp,%%rcx\n" ); output( "%s\n", asm_globl("__wine_syscall_dispatcher_return") ); - output( "\tmovl 0xa8(%%rcx),%%r14d\n" ); /* frame->syscall_flags */ + output( "\tmovl 0xb0(%%rcx),%%r14d\n" ); /* frame->syscall_flags */ output( "\tmovq %%rdx,%%rax\n" ); output( "\tjmp 2b\n" ); break; @@ -1705,14 +1699,13 @@ static void output_syscall_dispatcher(void) { output( "\tvmrs r0, fpscr\n" ); output( "\tstr r0, [r1, #0x48]\n" ); - output( "\tadd r0, r1, #0x50\n" ); + output( "\tadd r0, r1, #0x60\n" ); output( "\tvstm r0, {d0-d15}\n" ); } output( "\tmov r6, sp\n" ); output( "\tmov sp, r1\n" ); output( "\tmov r8, r1\n" ); - output( "\tldr r5, 6f\n"); - if (UsePIC) output( "1:\tadd r5, pc\n"); + output( "\tldr r5, [r1, #0x50]\n"); /* frame->syscall_table */ output( "\tubfx r4, ip, #12, #2\n" ); /* syscall table number */ output( "\tbfc ip, #12, #20\n" ); /* syscall number */ output( "\tadd r4, r5, r4, lsl #4\n" ); @@ -1742,7 +1735,7 @@ static void output_syscall_dispatcher(void) output( "\tbeq 3f\n" ); output( "\tldr r4, [r8, #0x48]\n" ); output( "\tvmsr fpscr, r4\n" ); - output( "\tadd r4, r8, #0x50\n" ); + output( "\tadd r4, r8, #0x60\n" ); output( "\tvldm r4, {d0-d15}\n" ); output( "3:\n" ); } @@ -1760,10 +1753,6 @@ static void output_syscall_dispatcher(void) output( "\tmov r8, r0\n" ); output( "\tmov r0, r1\n" ); output( "\tb 4b\n" ); - if (UsePIC) - output( "6:\t.long %s-1b-%u\n", asm_name("KeServiceDescriptorTable"), thumb_mode ? 4 : 8 ); - else - output( "6:\t.long %s\n", asm_name("KeServiceDescriptorTable") ); break; case CPU_ARM64: /* FIXME: use x18 directly instead */ @@ -1794,30 +1783,29 @@ static void output_syscall_dispatcher(void) output( "\tmrs x9, NZCV\n" ); output( "\tstp x30, x9, [x10, #0x100]\n" ); output( "\tmrs x9, FPCR\n" ); - output( "\tstr w9, [x10, #0x118]\n" ); + output( "\tstr w9, [x10, #0x128]\n" ); output( "\tmrs x9, FPSR\n" ); - output( "\tstr w9, [x10, #0x11c]\n" ); - output( "\tstp q0, q1, [x10, #0x120]\n" ); - output( "\tstp q2, q3, [x10, #0x140]\n" ); - output( "\tstp q4, q5, [x10, #0x160]\n" ); - output( "\tstp q6, q7, [x10, #0x180]\n" ); - output( "\tstp q8, q9, [x10, #0x1a0]\n" ); - output( "\tstp q10, q11, [x10, #0x1c0]\n" ); - output( "\tstp q12, q13, [x10, #0x1e0]\n" ); - output( "\tstp q14, q15, [x10, #0x200]\n" ); - output( "\tstp q16, q17, [x10, #0x220]\n" ); - output( "\tstp q18, q19, [x10, #0x240]\n" ); - output( "\tstp q20, q21, [x10, #0x260]\n" ); - output( "\tstp q22, q23, [x10, #0x280]\n" ); - output( "\tstp q24, q25, [x10, #0x2a0]\n" ); - output( "\tstp q26, q27, [x10, #0x2c0]\n" ); - output( "\tstp q28, q29, [x10, #0x2e0]\n" ); - output( "\tstp q30, q31, [x10, #0x300]\n" ); + output( "\tstr w9, [x10, #0x12c]\n" ); + output( "\tstp q0, q1, [x10, #0x130]\n" ); + output( "\tstp q2, q3, [x10, #0x150]\n" ); + output( "\tstp q4, q5, [x10, #0x170]\n" ); + output( "\tstp q6, q7, [x10, #0x190]\n" ); + output( "\tstp q8, q9, [x10, #0x1b0]\n" ); + output( "\tstp q10, q11, [x10, #0x1d0]\n" ); + output( "\tstp q12, q13, [x10, #0x1f0]\n" ); + output( "\tstp q14, q15, [x10, #0x210]\n" ); + output( "\tstp q16, q17, [x10, #0x230]\n" ); + output( "\tstp q18, q19, [x10, #0x250]\n" ); + output( "\tstp q20, q21, [x10, #0x270]\n" ); + output( "\tstp q22, q23, [x10, #0x290]\n" ); + output( "\tstp q24, q25, [x10, #0x2b0]\n" ); + output( "\tstp q26, q27, [x10, #0x2d0]\n" ); + output( "\tstp q28, q29, [x10, #0x2f0]\n" ); + output( "\tstp q30, q31, [x10, #0x310]\n" ); output( "\tmov sp, x10\n" ); output( "\tand x20, x8, #0xfff\n" ); /* syscall number */ output( "\tubfx x21, x8, #12, #2\n" ); /* syscall table number */ - output( "\tadrp x16, %s\n", arm64_page(asm_name("KeServiceDescriptorTable")) ); - output( "\tadd x16, x16, #%s\n", arm64_pageoff(asm_name("KeServiceDescriptorTable")) ); + output( "\tldr x16, [x10, #0x118]\n" );/* frame->syscall_table */ output( "\tadd x21, x16, x21, lsl #5\n" ); output( "\tldr x16, [x21, #16]\n" ); /* table->ServiceLimit */ output( "\tcmp x20, x16\n" ); @@ -1846,25 +1834,25 @@ static void output_syscall_dispatcher(void) output( "\tldp x28, x29, [sp, #0xe0]\n" ); output( "\tldr w16, [sp, #0x10c]\n" ); /* frame->restore_flags */ output( "\ttbz x16, #2, 1f\n" ); /* CONTEXT_FLOATING_POINT */ - output( "\tldp q0, q1, [sp, #0x120]\n" ); - output( "\tldp q2, q3, [sp, #0x140]\n" ); - output( "\tldp q4, q5, [sp, #0x160]\n" ); - output( "\tldp q6, q7, [sp, #0x180]\n" ); - output( "\tldp q8, q9, [sp, #0x1a0]\n" ); - output( "\tldp q10, q11, [sp, #0x1c0]\n" ); - output( "\tldp q12, q13, [sp, #0x1e0]\n" ); - output( "\tldp q14, q15, [sp, #0x200]\n" ); - output( "\tldp q16, q17, [sp, #0x220]\n" ); - output( "\tldp q18, q19, [sp, #0x240]\n" ); - output( "\tldp q20, q21, [sp, #0x260]\n" ); - output( "\tldp q22, q23, [sp, #0x280]\n" ); - output( "\tldp q24, q25, [sp, #0x2a0]\n" ); - output( "\tldp q26, q27, [sp, #0x2c0]\n" ); - output( "\tldp q28, q29, [sp, #0x2e0]\n" ); - output( "\tldp q30, q31, [sp, #0x300]\n" ); - output( "\tldr w9, [sp, #0x118]\n" ); + output( "\tldp q0, q1, [sp, #0x130]\n" ); + output( "\tldp q2, q3, [sp, #0x150]\n" ); + output( "\tldp q4, q5, [sp, #0x170]\n" ); + output( "\tldp q6, q7, [sp, #0x190]\n" ); + output( "\tldp q8, q9, [sp, #0x1b0]\n" ); + output( "\tldp q10, q11, [sp, #0x1d0]\n" ); + output( "\tldp q12, q13, [sp, #0x1f0]\n" ); + output( "\tldp q14, q15, [sp, #0x210]\n" ); + output( "\tldp q16, q17, [sp, #0x230]\n" ); + output( "\tldp q18, q19, [sp, #0x250]\n" ); + output( "\tldp q20, q21, [sp, #0x270]\n" ); + output( "\tldp q22, q23, [sp, #0x290]\n" ); + output( "\tldp q24, q25, [sp, #0x2b0]\n" ); + output( "\tldp q26, q27, [sp, #0x2d0]\n" ); + output( "\tldp q28, q29, [sp, #0x2f0]\n" ); + output( "\tldp q30, q31, [sp, #0x310]\n" ); + output( "\tldr w9, [sp, #0x128]\n" ); output( "\tmsr FPCR, x9\n" ); - output( "\tldr w9, [sp, #0x11c]\n" ); + output( "\tldr w9, [sp, #0x12c]\n" ); output( "\tmsr FPSR, x9\n" ); output( "1:\ttbz x16, #1, 1f\n" ); /* CONTEXT_INTEGER */ output( "\tldp x0, x1, [sp, #0x00]\n" ); @@ -1921,11 +1909,8 @@ void output_syscalls( DLLSPEC *spec ) output( "\t.data\n" ); output( "\t.align %d\n", get_alignment( get_ptr_size() ) ); - output( "%s\n", asm_globl("KeServiceDescriptorTable") ); + output( "%s\n", asm_globl("__wine_syscall_table") ); output( "\t%s .Lsyscall_table, 0, %u, .Lsyscall_args\n", get_asm_ptr_keyword(), count ); - output( "\t%s 0, 0, 0, 0\n", get_asm_ptr_keyword() ); - output( "\t%s 0, 0, 0, 0\n", get_asm_ptr_keyword() ); - output( "\t%s 0, 0, 0, 0\n", get_asm_ptr_keyword() ); output( ".Lsyscall_table:\n" ); for (i = 0; i < count; i++) output( "\t%s %s\n", get_asm_ptr_keyword(), asm_name( get_link_name( syscalls[i] )));