forked from OSchip/llvm-project
[lldb] Reduce the stack alignment requirements for the Windows x86_64 ABI
This fixes https://github.com/llvm/llvm-project/issues/56095. Differential Revision: https://reviews.llvm.org/D129455
This commit is contained in:
parent
2bd8e74b94
commit
66cdd6548a
|
@ -40,10 +40,15 @@ public:
|
|||
|
||||
bool RegisterIsVolatile(const lldb_private::RegisterInfo *reg_info) override;
|
||||
|
||||
// In Windows_x86_64 ABI, stack will always be maintained 16-byte aligned
|
||||
// In Windows_x86_64 ABI requires that the stack will be maintained 16-byte
|
||||
// aligned.
|
||||
// When ntdll invokes callbacks such as KiUserExceptionDispatcher or
|
||||
// KiUserCallbackDispatcher, those functions won't have a properly 16-byte
|
||||
// aligned stack - but tolerate unwinding through them by relaxing the
|
||||
// requirement to 8 bytes.
|
||||
bool CallFrameAddressIsValid(lldb::addr_t cfa) override {
|
||||
if (cfa & (16ull - 1ull))
|
||||
return false; // Not 16 byte aligned
|
||||
if (cfa & (8ull - 1ull))
|
||||
return false; // Not 8 byte aligned
|
||||
if (cfa == 0)
|
||||
return false; // Zero is not a valid stack address
|
||||
return true;
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
.globl call_func
|
||||
.def call_func; .scl 2; .type 32; .endef
|
||||
.seh_proc call_func
|
||||
call_func:
|
||||
subq $32, %rsp
|
||||
.seh_stackalloc 32
|
||||
.seh_endprologue
|
||||
call realign_stack
|
||||
addq $32, %rsp
|
||||
ret
|
||||
.seh_endproc
|
||||
|
||||
.globl realign_stack
|
||||
.def realign_stack; .scl 2; .type 32; .endef
|
||||
.seh_proc realign_stack
|
||||
realign_stack:
|
||||
subq $32, %rsp
|
||||
.seh_stackalloc 32
|
||||
.seh_endprologue
|
||||
movq %rcx, %rax
|
||||
movl %edx, %ecx
|
||||
call *%rax
|
||||
addq $32, %rsp
|
||||
ret
|
||||
.seh_endproc
|
|
@ -0,0 +1,8 @@
|
|||
extern "C" void call_func(void (*ptr)(int a), int a);
|
||||
|
||||
extern "C" void func(int arg) { }
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
call_func(func, 42);
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
# Test unwinding through stack frames that aren't aligned to 16 bytes.
|
||||
# (In real world code, this happens when unwinding through
|
||||
# KiUserExceptionDispatcher and KiUserCallbackDispatcher in ntdll.dll.)
|
||||
|
||||
# REQUIRES: target-x86_64, native, system-windows
|
||||
|
||||
# RUN: %build %p/Inputs/windows-unaligned-x86_64.cpp %p/Inputs/windows-unaligned-x86_64-asm.s -o %t
|
||||
# RUN: %lldb %t -s %s -o exit | FileCheck %s
|
||||
|
||||
# Future TODO: If %build could compile the source file in C mode, the symbol
|
||||
# name handling would be easier across msvc and mingw build configurations.
|
||||
# (In mingw mode, the extern C symbol "func" is printed as "::func" while
|
||||
# it's plain "func" in msvc mode. Without the extern C, it's "func(..." in
|
||||
# mingw mode, but "void __cdecl func(..." in msvc mode.)
|
||||
|
||||
breakpoint set -n func
|
||||
# CHECK: Breakpoint 1: where = {{.*}}`{{(::)?}}func
|
||||
|
||||
process launch
|
||||
# CHECK: stop reason = breakpoint 1.1
|
||||
|
||||
thread backtrace
|
||||
# CHECK: frame #0: {{.*}}`{{(::)?}}func
|
||||
# CHECK: frame #1: {{.*}}`realign_stack
|
||||
# CHECK: frame #2: {{.*}}`call_func
|
||||
# CHECK: frame #3: {{.*}}`main
|
Loading…
Reference in New Issue