Sebastian Lackner : ntdll: Implement RtlInstallFunctionTableCallback on x86_64.
Alexandre Julliard
julliard at winehq.org
Tue Apr 8 14:02:51 CDT 2014
Module: wine
Branch: master
Commit: 4d8edf7612a62e1d2234f310b060e03e920f540c
URL: http://source.winehq.org/git/wine.git/?a=commit;h=4d8edf7612a62e1d2234f310b060e03e920f540c
Author: Sebastian Lackner <sebastian at 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*);
More information about the wine-cvs
mailing list