From: "Rémi Bernon" Subject: [PATCH 2/4] ntdll: Keep track of syscall frame unix return addresses. Message-Id: <20220207190544.1342125-2-rbernon@codeweavers.com> Date: Mon, 7 Feb 2022 20:05:42 +0100 In-Reply-To: <20220207190544.1342125-1-rbernon@codeweavers.com> References: <20220207190544.1342125-1-rbernon@codeweavers.com> For pthread_exit unwinding purposes, as libunwind needs to retrieve %rip and we don't want to let it unwind the PE frames, we need to keep track of a unix-only return address chain. Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52213 Signed-off-by: Rémi Bernon --- dlls/ntdll/unix/signal_i386.c | 7 +++++-- dlls/ntdll/unix/signal_x86_64.c | 5 ++++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/dlls/ntdll/unix/signal_i386.c b/dlls/ntdll/unix/signal_i386.c index 0e3b1daf51a..d98a3b1d4bb 100644 --- a/dlls/ntdll/unix/signal_i386.c +++ b/dlls/ntdll/unix/signal_i386.c @@ -463,9 +463,10 @@ struct syscall_frame * 32-bit mode, but some processors fault if they're not in writable memory. */ DECLSPEC_ALIGN(64) XSTATE xstate; /* 240 */ + DWORD unwind_eip; /* 380 */ }; -C_ASSERT( sizeof(struct syscall_frame) == 0x380 ); +C_ASSERT( sizeof(struct syscall_frame) == 0x3c0 ); struct x86_thread_data { @@ -2432,7 +2433,7 @@ __ASM_GLOBAL_FUNC( signal_start_thread, "movl 0x1f8(%ecx),%eax\n\t" /* x86_thread_data()->syscall_frame */ "orl %eax,%eax\n\t" "jnz 1f\n\t" - "leal -0x380(%esp),%eax\n\t" /* sizeof(struct syscall_frame) */ + "leal -0x3c0(%esp),%eax\n\t" /* sizeof(struct syscall_frame) */ "andl $~63,%eax\n\t" "movl %eax,0x1f8(%ecx)\n" /* x86_thread_data()->syscall_frame */ "1:\tmovl %eax,%esp\n\t" @@ -2591,6 +2592,8 @@ __ASM_GLOBAL_FUNC( __wine_syscall_dispatcher, "6:\tmovl $0xc000000d,%eax\n\t" /* STATUS_INVALID_PARAMETER */ "jmp 5b\n" __ASM_NAME("__wine_syscall_dispatcher_return") ":\n\t" + "movl 0(%esp),%eax\n\t" + "movl %eax,0x380(%esp)\n\t" /* frame->unwind_eip */ "movl 8(%esp),%eax\n\t" "movl 4(%esp),%esp\n\t" "jmp 5b" ) diff --git a/dlls/ntdll/unix/signal_x86_64.c b/dlls/ntdll/unix/signal_x86_64.c index da89b958665..f8cddd15569 100644 --- a/dlls/ntdll/unix/signal_x86_64.c +++ b/dlls/ntdll/unix/signal_x86_64.c @@ -349,7 +349,8 @@ struct syscall_frame struct syscall_frame *prev_frame; /* 00a0 */ SYSTEM_SERVICE_TABLE *syscall_table; /* 00a8 */ DWORD syscall_flags; /* 00b0 */ - DWORD align[3]; /* 00b4 */ + DWORD align; /* 00b4 */ + ULONG64 unwind_rip; /* 00b8 */ XMM_SAVE_AREA32 xsave; /* 00c0 */ DECLSPEC_ALIGN(64) XSTATE xstate; /* 02c0 */ }; @@ -3278,6 +3279,8 @@ __ASM_GLOBAL_FUNC( __wine_syscall_dispatcher, "5:\tmovl $0xc000000d,%edx\n\t" /* STATUS_INVALID_PARAMETER */ "movq %rsp,%rcx\n" __ASM_NAME("__wine_syscall_dispatcher_return") ":\n\t" + "movq 0(%rsp),%r14\n\t" + "movq %r14,0xb8(%rcx)\n\t" /* frame->unwind_rip */ "movl 0xb0(%rcx),%r14d\n\t" /* frame->syscall_flags */ "movq %rdx,%rax\n\t" "jmp 2b" ) -- 2.34.1