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