Module: wine Branch: master Commit: 4d8edf7612a62e1d2234f310b060e03e920f540c URL: http://source.winehq.org/git/wine.git/?a=commit;h=4d8edf7612a62e1d2234f310b0...
Author: Sebastian Lackner sebastian@fds-team.de Date: Mon Apr 7 00:41:30 2014 +0200
ntdll: Implement RtlInstallFunctionTableCallback on x86_64.
---
dlls/ntdll/ntdll.spec | 1 + dlls/ntdll/signal_x86_64.c | 48 +++++++++++++++++++++++++++++++++++++++++++- include/winnt.h | 3 +++ 3 files changed, 51 insertions(+), 1 deletion(-)
diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec index 0dd75a2..5bac269 100644 --- a/dlls/ntdll/ntdll.spec +++ b/dlls/ntdll/ntdll.spec @@ -689,6 +689,7 @@ # @ stub RtlInitializeStackTraceDataBase @ stub RtlInsertElementGenericTable # @ stub RtlInsertElementGenericTableAvl +@ cdecl -arch=x86_64 RtlInstallFunctionTableCallback(long long long ptr ptr wstr) @ stdcall RtlInt64ToUnicodeString(int64 long ptr) @ stdcall RtlIntegerToChar(long long long ptr) @ stdcall RtlIntegerToUnicodeString(long long ptr) diff --git a/dlls/ntdll/signal_x86_64.c b/dlls/ntdll/signal_x86_64.c index 8b4c0ee..dbef828 100644 --- a/dlls/ntdll/signal_x86_64.c +++ b/dlls/ntdll/signal_x86_64.c @@ -287,6 +287,10 @@ struct dynamic_unwind_entry /* lookup table */ RUNTIME_FUNCTION *table; DWORD table_size; + + /* user defined callback */ + PGET_RUNTIME_FUNCTION_CALLBACK callback; + PVOID context; };
static struct list dynamic_unwind_list = LIST_INIT(dynamic_unwind_list); @@ -1979,7 +1983,12 @@ static RUNTIME_FUNCTION *lookup_function_info( ULONG64 pc, ULONG64 *base, LDR_MO if (pc >= entry->base && pc < entry->base + entry->size) { *base = entry->base; - func = find_function_info( pc, (HMODULE)entry->base, entry->table, entry->table_size ); + + /* use callback or lookup in function table */ + if (entry->callback) + func = entry->callback( pc, entry->context ); + else + func = find_function_info( pc, (HMODULE)entry->base, entry->table, entry->table_size ); break; } } @@ -2585,6 +2594,43 @@ BOOLEAN CDECL RtlAddFunctionTable( RUNTIME_FUNCTION *table, DWORD count, DWORD64 entry->size = table[count - 1].EndAddress; entry->table = table; entry->table_size = count * sizeof(RUNTIME_FUNCTION); + entry->callback = NULL; + entry->context = NULL; + + RtlEnterCriticalSection( &dynamic_unwind_section ); + list_add_tail( &dynamic_unwind_list, &entry->entry ); + RtlLeaveCriticalSection( &dynamic_unwind_section ); + + return TRUE; +} + + +/********************************************************************** + * RtlInstallFunctionTableCallback (NTDLL.@) + */ +BOOLEAN CDECL RtlInstallFunctionTableCallback( DWORD64 table, DWORD64 base, DWORD length, + PGET_RUNTIME_FUNCTION_CALLBACK callback, PVOID context, PCWSTR dll ) +{ + struct dynamic_unwind_entry *entry; + + TRACE( "%lx %lx %d %p %p %s\n", table, base, length, callback, context, wine_dbgstr_w(dll) ); + + /* NOTE: Windows doesn't check if the provided callback is a NULL pointer */ + + /* both low-order bits must be set */ + if ((table & 0x3) != 0x3) + return FALSE; + + entry = RtlAllocateHeap( GetProcessHeap(), 0, sizeof(*entry) ); + if (!entry) + return FALSE; + + entry->base = base; + entry->size = length; + entry->table = (RUNTIME_FUNCTION *)table; + entry->table_size = 0; + entry->callback = callback; + entry->context = context;
RtlEnterCriticalSection( &dynamic_unwind_section ); list_add_tail( &dynamic_unwind_list, &entry->entry ); diff --git a/include/winnt.h b/include/winnt.h index 93fd70a..3f33c6b 100644 --- a/include/winnt.h +++ b/include/winnt.h @@ -1193,8 +1193,11 @@ typedef struct _KNONVOLATILE_CONTEXT_POINTERS } DUMMYUNIONNAME2; } KNONVOLATILE_CONTEXT_POINTERS, *PKNONVOLATILE_CONTEXT_POINTERS;
+typedef PRUNTIME_FUNCTION (CALLBACK *PGET_RUNTIME_FUNCTION_CALLBACK)(DWORD64,PVOID); + BOOLEAN CDECL RtlAddFunctionTable(RUNTIME_FUNCTION*,DWORD,DWORD64); BOOLEAN CDECL RtlDeleteFunctionTable(RUNTIME_FUNCTION*); +BOOLEAN CDECL RtlInstallFunctionTableCallback(DWORD64,DWORD64,DWORD,PGET_RUNTIME_FUNCTION_CALLBACK,PVOID,PCWSTR); PRUNTIME_FUNCTION WINAPI RtlLookupFunctionEntry(DWORD64,DWORD64*,UNWIND_HISTORY_TABLE*); PVOID WINAPI RtlVirtualUnwind(ULONG,ULONG64,ULONG64,RUNTIME_FUNCTION*,CONTEXT*,PVOID*,ULONG64*,KNONVOLATILE_CONTEXT_POINTERS*);