From f127448d00b9f4c4869c737c8c38038ed15fc4f8 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Mon, 11 Mar 2024 16:52:36 +0100 Subject: [PATCH] ntdll: Implement RtlWalkFrameChain on x86-64. --- dlls/ntdll/signal_x86_64.c | 30 ++++++++++++++++++++++++++++++ include/rtlsupportapi.h | 1 + 2 files changed, 31 insertions(+) diff --git a/dlls/ntdll/signal_x86_64.c b/dlls/ntdll/signal_x86_64.c index 8b1de07ccc9..1e928cad2c9 100644 --- a/dlls/ntdll/signal_x86_64.c +++ b/dlls/ntdll/signal_x86_64.c @@ -958,6 +958,36 @@ __ASM_GLOBAL_FUNC( RtlRaiseException, "call " __ASM_NAME("RtlRaiseStatus") /* does not return */ ); +/************************************************************************* + * RtlWalkFrameChain (NTDLL.@) + */ +ULONG WINAPI RtlWalkFrameChain( void **buffer, ULONG count, ULONG flags ) +{ + UNWIND_HISTORY_TABLE table; + RUNTIME_FUNCTION *func; + PEXCEPTION_ROUTINE handler; + ULONG_PTR frame, base; + CONTEXT context; + void *data; + ULONG i, skip = flags >> 8, num_entries = 0; + + RtlCaptureContext( &context ); + + for (i = 0; i < count; i++) + { + func = RtlLookupFunctionEntry( context.Rip, &base, &table ); + if (RtlVirtualUnwind2( UNW_FLAG_NHANDLER, base, context.Rip, func, &context, NULL, + &data, &frame, NULL, NULL, NULL, &handler, 0 )) + break; + if (!context.Rip) break; + if (!frame || !is_valid_frame( frame )) break; + if (context.Rsp == (ULONG_PTR)NtCurrentTeb()->Tib.StackBase) break; + if (i >= skip) buffer[num_entries++] = (void *)context.Rip; + } + return num_entries; +} + + static inline ULONG hash_pointers( void **ptrs, ULONG count ) { /* Based on MurmurHash2, which is in the public domain */ diff --git a/include/rtlsupportapi.h b/include/rtlsupportapi.h index 32f0099c0b6..becb6179a56 100644 --- a/include/rtlsupportapi.h +++ b/include/rtlsupportapi.h @@ -28,6 +28,7 @@ NTSYSAPI void WINAPI RtlRaiseException(EXCEPTION_RECORD*); NTSYSAPI void CDECL RtlRestoreContext(CONTEXT*,EXCEPTION_RECORD*); NTSYSAPI void WINAPI RtlUnwind(void*,void*,EXCEPTION_RECORD*,void*); NTSYSAPI void* WINAPI RtlPcToFileHeader(void*,void**); +NTSYSAPI ULONG WINAPI RtlWalkFrameChain(void**,ULONG,ULONG); #ifndef __i386__