mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2024-09-13 09:17:20 -07:00
Removed dynamic unwind patches (accepted upstream).
This commit is contained in:
parent
48bbae3fb7
commit
f9eebd5599
1
debian/changelog
vendored
1
debian/changelog
vendored
@ -1,5 +1,6 @@
|
||||
wine-compholio (1.7.16-1) UNRELEASED; urgency=low
|
||||
* Split Arial replacement into two patches.
|
||||
* Remove dynamic unwind patches (accepted upstream).
|
||||
* Update the linguistic casing patches to print a FIXME that the flags are not fully supported.
|
||||
-- Erich E. Hoover <erich.e.hoover@gmail.com> Sat, 05 Apr 2014 17:38:41 -0600
|
||||
|
||||
|
@ -1,189 +0,0 @@
|
||||
From 565726f893787072a12329af854e072c5d325906 Mon Sep 17 00:00:00 2001
|
||||
From: Sebastian Lackner <sebastian@fds-team.de>
|
||||
Date: Fri, 4 Apr 2014 10:11:56 +0200
|
||||
Subject: ntdll: Unify exception function lookup on x86_64.
|
||||
|
||||
---
|
||||
dlls/ntdll/signal_x86_64.c | 102 +++++++++++++++++++++-----------------------
|
||||
1 file changed, 48 insertions(+), 54 deletions(-)
|
||||
|
||||
diff --git a/dlls/ntdll/signal_x86_64.c b/dlls/ntdll/signal_x86_64.c
|
||||
index b28cb99..57afe16 100644
|
||||
--- a/dlls/ntdll/signal_x86_64.c
|
||||
+++ b/dlls/ntdll/signal_x86_64.c
|
||||
@@ -1921,6 +1921,28 @@ static RUNTIME_FUNCTION *find_function_info( ULONG64 pc, HMODULE module,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
+/**********************************************************************
|
||||
+ * lookup_function_info
|
||||
+ */
|
||||
+static RUNTIME_FUNCTION *lookup_function_info( ULONG64 pc, ULONG64 *base, LDR_MODULE **module )
|
||||
+{
|
||||
+ RUNTIME_FUNCTION *func = NULL;
|
||||
+ ULONG size;
|
||||
+
|
||||
+ /* PE module or wine module */
|
||||
+ if (!LdrFindEntryForAddress( (void *)pc, module ))
|
||||
+ {
|
||||
+ *base = (ULONG64)(*module)->BaseAddress;
|
||||
+ if ((func = RtlImageDirectoryEntryToData( (*module)->BaseAddress, TRUE,
|
||||
+ IMAGE_DIRECTORY_ENTRY_EXCEPTION, &size )))
|
||||
+ {
|
||||
+ /* lookup in function table */
|
||||
+ func = find_function_info( pc, (*module)->BaseAddress, func, size );
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return func;
|
||||
+}
|
||||
|
||||
/**********************************************************************
|
||||
* call_handler
|
||||
@@ -2002,7 +2024,6 @@ static NTSTATUS call_stack_handlers( EXCEPTION_RECORD *rec, CONTEXT *orig_contex
|
||||
DISPATCHER_CONTEXT dispatch;
|
||||
CONTEXT context, new_context;
|
||||
LDR_MODULE *module;
|
||||
- DWORD size;
|
||||
NTSTATUS status;
|
||||
|
||||
context = *orig_context;
|
||||
@@ -2021,31 +2042,18 @@ static NTSTATUS call_stack_handlers( EXCEPTION_RECORD *rec, CONTEXT *orig_contex
|
||||
|
||||
/* first look for PE exception information */
|
||||
|
||||
- if (!LdrFindEntryForAddress( (void *)context.Rip, &module ))
|
||||
+ if ((dispatch.FunctionEntry = lookup_function_info( context.Rip, &dispatch.ImageBase, &module )))
|
||||
{
|
||||
- RUNTIME_FUNCTION *dir;
|
||||
-
|
||||
- dispatch.ImageBase = (ULONG64)module->BaseAddress;
|
||||
- if ((dir = RtlImageDirectoryEntryToData( module->BaseAddress, TRUE,
|
||||
- IMAGE_DIRECTORY_ENTRY_EXCEPTION, &size )))
|
||||
- {
|
||||
- if ((dispatch.FunctionEntry = find_function_info( context.Rip, module->BaseAddress,
|
||||
- dir, size )))
|
||||
- {
|
||||
- dispatch.LanguageHandler = RtlVirtualUnwind( UNW_FLAG_EHANDLER, dispatch.ImageBase,
|
||||
- context.Rip, dispatch.FunctionEntry,
|
||||
- &new_context, &dispatch.HandlerData,
|
||||
- &dispatch.EstablisherFrame, NULL );
|
||||
- goto unwind_done;
|
||||
- }
|
||||
- }
|
||||
- else if (!(module->Flags & LDR_WINE_INTERNAL))
|
||||
- WARN( "exception data not found in %s\n", debugstr_w(module->BaseDllName.Buffer) );
|
||||
+ dispatch.LanguageHandler = RtlVirtualUnwind( UNW_FLAG_EHANDLER, dispatch.ImageBase,
|
||||
+ context.Rip, dispatch.FunctionEntry,
|
||||
+ &new_context, &dispatch.HandlerData,
|
||||
+ &dispatch.EstablisherFrame, NULL );
|
||||
+ goto unwind_done;
|
||||
}
|
||||
|
||||
/* then look for host system exception information */
|
||||
|
||||
- if (!module || (module->Flags & LDR_WINE_INTERNAL))
|
||||
+ else if (!module || (module->Flags & LDR_WINE_INTERNAL))
|
||||
{
|
||||
struct dwarf_eh_bases bases;
|
||||
const struct dwarf_fde *fde = _Unwind_Find_FDE( (void *)(context.Rip - 1), &bases );
|
||||
@@ -2065,6 +2073,8 @@ static NTSTATUS call_stack_handlers( EXCEPTION_RECORD *rec, CONTEXT *orig_contex
|
||||
}
|
||||
}
|
||||
|
||||
+ else WARN( "exception data not found in %s\n", debugstr_w(module->BaseDllName.Buffer) );
|
||||
+
|
||||
/* no exception information, treat as a leaf function */
|
||||
|
||||
new_context.Rip = *(ULONG64 *)context.Rsp;
|
||||
@@ -2540,23 +2550,18 @@ PRUNTIME_FUNCTION WINAPI RtlLookupFunctionEntry( ULONG64 pc, ULONG64 *base, UNWI
|
||||
{
|
||||
LDR_MODULE *module;
|
||||
RUNTIME_FUNCTION *func;
|
||||
- ULONG size;
|
||||
|
||||
/* FIXME: should use the history table to make things faster */
|
||||
|
||||
- if (LdrFindEntryForAddress( (void *)pc, &module ))
|
||||
+ func = lookup_function_info( pc, base, &module );
|
||||
+ if (!func)
|
||||
{
|
||||
- WARN( "module not found for %lx\n", pc );
|
||||
- return NULL;
|
||||
- }
|
||||
- if (!(func = RtlImageDirectoryEntryToData( module->BaseAddress, TRUE,
|
||||
- IMAGE_DIRECTORY_ENTRY_EXCEPTION, &size )))
|
||||
- {
|
||||
- WARN( "no exception table found in module %p pc %lx\n", module->BaseAddress, pc );
|
||||
- return NULL;
|
||||
+ if (module)
|
||||
+ WARN( "no exception table found in module %p pc %lx\n", module->BaseAddress, pc );
|
||||
+ else
|
||||
+ WARN( "module not found for %lx\n", pc );
|
||||
}
|
||||
- func = find_function_info( pc, module->BaseAddress, func, size );
|
||||
- if (func) *base = (ULONG64)module->BaseAddress;
|
||||
+
|
||||
return func;
|
||||
}
|
||||
|
||||
@@ -2916,7 +2921,7 @@ void WINAPI RtlUnwindEx( PVOID end_frame, PVOID target_ip, EXCEPTION_RECORD *rec
|
||||
CONTEXT new_context;
|
||||
LDR_MODULE *module;
|
||||
NTSTATUS status;
|
||||
- DWORD i, size;
|
||||
+ DWORD i;
|
||||
|
||||
RtlCaptureContext( context );
|
||||
new_context = *context;
|
||||
@@ -2962,31 +2967,18 @@ void WINAPI RtlUnwindEx( PVOID end_frame, PVOID target_ip, EXCEPTION_RECORD *rec
|
||||
|
||||
/* first look for PE exception information */
|
||||
|
||||
- if (!LdrFindEntryForAddress( (void *)context->Rip, &module ))
|
||||
+ if ((dispatch.FunctionEntry = lookup_function_info( context->Rip, &dispatch.ImageBase, &module )))
|
||||
{
|
||||
- RUNTIME_FUNCTION *dir;
|
||||
-
|
||||
- dispatch.ImageBase = (ULONG64)module->BaseAddress;
|
||||
- if ((dir = RtlImageDirectoryEntryToData( module->BaseAddress, TRUE,
|
||||
- IMAGE_DIRECTORY_ENTRY_EXCEPTION, &size )))
|
||||
- {
|
||||
- if ((dispatch.FunctionEntry = find_function_info( context->Rip, module->BaseAddress,
|
||||
- dir, size )))
|
||||
- {
|
||||
- dispatch.LanguageHandler = RtlVirtualUnwind( UNW_FLAG_UHANDLER, dispatch.ImageBase,
|
||||
- context->Rip, dispatch.FunctionEntry,
|
||||
- &new_context, &dispatch.HandlerData,
|
||||
- &dispatch.EstablisherFrame, NULL );
|
||||
- goto unwind_done;
|
||||
- }
|
||||
- }
|
||||
- else if (!(module->Flags & LDR_WINE_INTERNAL))
|
||||
- WARN( "exception data not found in %s\n", debugstr_w(module->BaseDllName.Buffer) );
|
||||
+ dispatch.LanguageHandler = RtlVirtualUnwind( UNW_FLAG_UHANDLER, dispatch.ImageBase,
|
||||
+ context->Rip, dispatch.FunctionEntry,
|
||||
+ &new_context, &dispatch.HandlerData,
|
||||
+ &dispatch.EstablisherFrame, NULL );
|
||||
+ goto unwind_done;
|
||||
}
|
||||
|
||||
/* then look for host system exception information */
|
||||
|
||||
- if (!module || (module->Flags & LDR_WINE_INTERNAL))
|
||||
+ else if (!module || (module->Flags & LDR_WINE_INTERNAL))
|
||||
{
|
||||
struct dwarf_eh_bases bases;
|
||||
const struct dwarf_fde *fde = _Unwind_Find_FDE( (void *)(context->Rip - 1), &bases );
|
||||
@@ -3006,6 +2998,8 @@ void WINAPI RtlUnwindEx( PVOID end_frame, PVOID target_ip, EXCEPTION_RECORD *rec
|
||||
}
|
||||
}
|
||||
|
||||
+ else WARN( "exception data not found in %s\n", debugstr_w(module->BaseDllName.Buffer) );
|
||||
+
|
||||
/* no exception information, treat as a leaf function */
|
||||
|
||||
new_context.Rip = *(ULONG64 *)context->Rsp;
|
||||
--
|
||||
1.7.9.5
|
||||
|
@ -1,216 +0,0 @@
|
||||
From efcbb9869c71a40f88ff0c4516f0d65419394104 Mon Sep 17 00:00:00 2001
|
||||
From: Sebastian Lackner <sebastian@fds-team.de>
|
||||
Date: Fri, 4 Apr 2014 19:32:33 +0200
|
||||
Subject: ntdll: Implement dynamic unwind table functions.
|
||||
|
||||
---
|
||||
dlls/ntdll/ntdll.spec | 1 +
|
||||
dlls/ntdll/signal_x86_64.c | 128 +++++++++++++++++++++++++++++++++++++++++++-
|
||||
include/winnt.h | 3 ++
|
||||
3 files changed, 130 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec
|
||||
index 0dd75a2..7a3c3f1 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 ptr)
|
||||
@ 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 57afe16..c8e1a16 100644
|
||||
--- a/dlls/ntdll/signal_x86_64.c
|
||||
+++ b/dlls/ntdll/signal_x86_64.c
|
||||
@@ -56,6 +56,7 @@
|
||||
#include "winternl.h"
|
||||
#include "wine/library.h"
|
||||
#include "wine/exception.h"
|
||||
+#include "wine/list.h"
|
||||
#include "ntdll_misc.h"
|
||||
#include "wine/debug.h"
|
||||
|
||||
@@ -271,6 +272,34 @@ typedef int (*wine_signal_handler)(unsigned int sig);
|
||||
|
||||
static wine_signal_handler handlers[256];
|
||||
|
||||
+/***********************************************************************
|
||||
+ * Dynamic unwind table
|
||||
+ */
|
||||
+
|
||||
+struct dynamic_unwind_entry
|
||||
+{
|
||||
+ struct list entry;
|
||||
+
|
||||
+ DWORD64 base;
|
||||
+ DWORD size;
|
||||
+
|
||||
+ RUNTIME_FUNCTION *table;
|
||||
+ DWORD table_size;
|
||||
+
|
||||
+ PGET_RUNTIME_FUNCTION_CALLBACK callback;
|
||||
+ PVOID context;
|
||||
+};
|
||||
+
|
||||
+static struct list dynamic_unwind_list = LIST_INIT(dynamic_unwind_list);
|
||||
+
|
||||
+static RTL_CRITICAL_SECTION dynamic_unwind_section;
|
||||
+static RTL_CRITICAL_SECTION_DEBUG dynamic_unwind_debug =
|
||||
+{
|
||||
+ 0, 0, &dynamic_unwind_section,
|
||||
+ { &dynamic_unwind_debug.ProcessLocksList, &dynamic_unwind_debug.ProcessLocksList },
|
||||
+ 0, 0, { (DWORD_PTR)(__FILE__ ": dynamic_unwind_section") }
|
||||
+};
|
||||
+static RTL_CRITICAL_SECTION dynamic_unwind_section = { &dynamic_unwind_debug, -1, 0, 0, 0, 0 };
|
||||
|
||||
/***********************************************************************
|
||||
* Definitions for Win32 unwind tables
|
||||
@@ -1927,6 +1956,7 @@ static RUNTIME_FUNCTION *find_function_info( ULONG64 pc, HMODULE module,
|
||||
static RUNTIME_FUNCTION *lookup_function_info( ULONG64 pc, ULONG64 *base, LDR_MODULE **module )
|
||||
{
|
||||
RUNTIME_FUNCTION *func = NULL;
|
||||
+ struct dynamic_unwind_entry *entry;
|
||||
ULONG size;
|
||||
|
||||
/* PE module or wine module */
|
||||
@@ -1940,6 +1970,25 @@ static RUNTIME_FUNCTION *lookup_function_info( ULONG64 pc, ULONG64 *base, LDR_MO
|
||||
func = find_function_info( pc, (*module)->BaseAddress, func, size );
|
||||
}
|
||||
}
|
||||
+ else
|
||||
+ {
|
||||
+ RtlEnterCriticalSection( &dynamic_unwind_section );
|
||||
+ LIST_FOR_EACH_ENTRY( entry, &dynamic_unwind_list, struct dynamic_unwind_entry, entry )
|
||||
+ {
|
||||
+ if (pc >= entry->base && pc < entry->base + entry->size)
|
||||
+ {
|
||||
+ *base = entry->base;
|
||||
+
|
||||
+ /* lookup in function table or call callback in signal handler stack */
|
||||
+ if (entry->callback)
|
||||
+ func = entry->callback( pc, entry->context );
|
||||
+ else
|
||||
+ func = find_function_info( pc, (HMODULE)entry->base, entry->table, entry->table_size );
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ RtlLeaveCriticalSection( &dynamic_unwind_section );
|
||||
+ }
|
||||
|
||||
return func;
|
||||
}
|
||||
@@ -2528,7 +2577,29 @@ void signal_init_process(void)
|
||||
*/
|
||||
BOOLEAN CDECL RtlAddFunctionTable( RUNTIME_FUNCTION *table, DWORD count, DWORD64 addr )
|
||||
{
|
||||
- FIXME( "%p %u %lx: stub\n", table, count, addr );
|
||||
+ struct dynamic_unwind_entry *entry;
|
||||
+ DWORD size;
|
||||
+
|
||||
+ TRACE( "%p %u %lx\n", table, count, addr );
|
||||
+
|
||||
+ /* NOTE: Windows doesn't check if table is aligned or a NULL pointer */
|
||||
+
|
||||
+ size = table[count - 1].EndAddress;
|
||||
+ entry = RtlAllocateHeap( GetProcessHeap(), 0, sizeof(*entry) );
|
||||
+ if (!entry)
|
||||
+ return FALSE;
|
||||
+
|
||||
+ entry->base = addr;
|
||||
+ entry->size = size;
|
||||
+ entry->table = table;
|
||||
+ entry->table_size = count * sizeof(RUNTIME_FUNCTION);
|
||||
+ entry->callback = NULL; /* unused */
|
||||
+ entry->context = NULL; /* unused */
|
||||
+
|
||||
+ RtlEnterCriticalSection( &dynamic_unwind_section );
|
||||
+ list_add_tail( &dynamic_unwind_list, &entry->entry );
|
||||
+ RtlLeaveCriticalSection( &dynamic_unwind_section );
|
||||
+
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -2538,7 +2609,60 @@ BOOLEAN CDECL RtlAddFunctionTable( RUNTIME_FUNCTION *table, DWORD count, DWORD64
|
||||
*/
|
||||
BOOLEAN CDECL RtlDeleteFunctionTable( RUNTIME_FUNCTION *table )
|
||||
{
|
||||
- FIXME( "%p: stub\n", table );
|
||||
+ struct dynamic_unwind_entry *entry, *old_entry = NULL;
|
||||
+
|
||||
+ TRACE( "%p\n", table );
|
||||
+
|
||||
+ RtlEnterCriticalSection( &dynamic_unwind_section );
|
||||
+ LIST_FOR_EACH_ENTRY( entry, &dynamic_unwind_list, struct dynamic_unwind_entry, entry )
|
||||
+ {
|
||||
+ if (entry->table == table)
|
||||
+ {
|
||||
+ old_entry = entry;
|
||||
+ list_remove( &entry->entry );
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ RtlLeaveCriticalSection( &dynamic_unwind_section );
|
||||
+
|
||||
+ if (old_entry)
|
||||
+ RtlFreeHeap( GetProcessHeap(), 0, old_entry );
|
||||
+
|
||||
+ return (old_entry != NULL);
|
||||
+}
|
||||
+
|
||||
+
|
||||
+/**********************************************************************
|
||||
+ * 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; /* unused */
|
||||
+ entry->callback = callback;
|
||||
+ entry->context = context;
|
||||
+
|
||||
+ RtlEnterCriticalSection( &dynamic_unwind_section );
|
||||
+ list_add_tail( &dynamic_unwind_list, &entry->entry );
|
||||
+ RtlLeaveCriticalSection( &dynamic_unwind_section );
|
||||
+
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
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*);
|
||||
|
||||
--
|
||||
1.7.9.5
|
||||
|
@ -1,181 +0,0 @@
|
||||
From f9bc66f164f6d556e383585d761ed7bf9b5187e1 Mon Sep 17 00:00:00 2001
|
||||
From: Sebastian Lackner <sebastian@fds-team.de>
|
||||
Date: Sat, 5 Apr 2014 01:04:25 +0200
|
||||
Subject: ntdll/tests: Add tests for dynamic unwind table.
|
||||
|
||||
---
|
||||
dlls/ntdll/tests/exception.c | 137 ++++++++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 137 insertions(+)
|
||||
|
||||
diff --git a/dlls/ntdll/tests/exception.c b/dlls/ntdll/tests/exception.c
|
||||
index b4cbaf5..9658aa5 100644
|
||||
--- a/dlls/ntdll/tests/exception.c
|
||||
+++ b/dlls/ntdll/tests/exception.c
|
||||
@@ -49,6 +49,12 @@ static NTSTATUS (WINAPI *pNtReadVirtualMemory)(HANDLE, const void*, void*, SIZE
|
||||
static NTSTATUS (WINAPI *pNtTerminateProcess)(HANDLE handle, LONG exit_code);
|
||||
static NTSTATUS (WINAPI *pNtQueryInformationProcess)(HANDLE, PROCESSINFOCLASS, PVOID, ULONG, PULONG);
|
||||
static NTSTATUS (WINAPI *pNtSetInformationProcess)(HANDLE, PROCESSINFOCLASS, PVOID, ULONG);
|
||||
+#if defined(__x86_64__)
|
||||
+static BOOLEAN (WINAPI *pRtlAddFunctionTable)(RUNTIME_FUNCTION*, DWORD, DWORD64);
|
||||
+static BOOLEAN (WINAPI *pRtlDeleteFunctionTable)(RUNTIME_FUNCTION*);
|
||||
+static BOOLEAN (WINAPI *pRtlInstallFunctionTableCallback)(DWORD64, DWORD64, DWORD, PGET_RUNTIME_FUNCTION_CALLBACK, PVOID, PCWSTR);
|
||||
+static PRUNTIME_FUNCTION (WINAPI *pRtlLookupFunctionEntry)(ULONG64, ULONG64*, UNWIND_HISTORY_TABLE*);
|
||||
+#endif
|
||||
static BOOL (WINAPI *pIsWow64Process)(HANDLE, PBOOL);
|
||||
|
||||
#ifdef __i386__
|
||||
@@ -1447,6 +1453,122 @@ static void test_virtual_unwind(void)
|
||||
call_virtual_unwind( i, &tests[i] );
|
||||
}
|
||||
|
||||
+static RUNTIME_FUNCTION* CALLBACK function_table_callback( DWORD64 pc, PVOID context )
|
||||
+{
|
||||
+ static const int code_offset = 1024;
|
||||
+ static RUNTIME_FUNCTION runtime_func;
|
||||
+ (*(DWORD *)context)++;
|
||||
+
|
||||
+ runtime_func.BeginAddress = code_offset;
|
||||
+ runtime_func.EndAddress = code_offset + 16;
|
||||
+ runtime_func.UnwindData = 0;
|
||||
+ return &runtime_func;
|
||||
+}
|
||||
+
|
||||
+static void test_dynamic_unwind(void)
|
||||
+{
|
||||
+ static const int code_offset = 1024;
|
||||
+ char buf[sizeof(RUNTIME_FUNCTION) + 4];
|
||||
+ RUNTIME_FUNCTION *runtime_func, *func;
|
||||
+ ULONG_PTR table, base;
|
||||
+ DWORD count;
|
||||
+
|
||||
+ /* Aligned RUNTIME_FUNCTION pointer */
|
||||
+ runtime_func = (RUNTIME_FUNCTION *)buf;
|
||||
+ runtime_func->BeginAddress = code_offset;
|
||||
+ runtime_func->EndAddress = code_offset + 16;
|
||||
+ runtime_func->UnwindData = 0;
|
||||
+ ok( pRtlAddFunctionTable( runtime_func, 1, (ULONG_PTR)code_mem ),
|
||||
+ "RtlAddFunctionTable failed for runtime_func = %p (aligned)\n", runtime_func );
|
||||
+
|
||||
+ /* Pointer outside of the area */
|
||||
+ base = 0xdeadbeef;
|
||||
+ func = pRtlLookupFunctionEntry( (ULONG_PTR)code_mem + code_offset + 16, &base, NULL );
|
||||
+ ok( func == NULL,
|
||||
+ "RtlLookupFunctionEntry returned unexpected function, expected: NULL, got: %p\n", func );
|
||||
+ ok( base == 0xdeadbeef,
|
||||
+ "RtlLookupFunctionEntry modified base address, expected: 0xdeadbeef, got: %lx\n", base );
|
||||
+
|
||||
+ /* Pointer inside of a function */
|
||||
+ base = 0xdeadbeef;
|
||||
+ func = pRtlLookupFunctionEntry( (ULONG_PTR)code_mem + code_offset + 8, &base, NULL );
|
||||
+ ok( func == runtime_func,
|
||||
+ "RtlLookupFunctionEntry didn't return expected function, expected: %p, got: %p\n", runtime_func, func );
|
||||
+ ok( base == (ULONG_PTR)code_mem,
|
||||
+ "RtlLookupFunctionEntry returned invalid base, expected: %lx, got: %lx\n", (ULONG_PTR)code_mem, base );
|
||||
+
|
||||
+ /* Ensure that deleting is also successful */
|
||||
+ ok( pRtlDeleteFunctionTable( runtime_func ),
|
||||
+ "RtlDeleteFunctionTable failed for runtime_func = %p (aligned)\n", runtime_func );
|
||||
+ ok( !pRtlDeleteFunctionTable( runtime_func ),
|
||||
+ "RtlDeleteFunctionTable returned success for nonexistent table runtime_func = %p\n", runtime_func );
|
||||
+
|
||||
+ /* Unaligned RUNTIME_FUNCTION pointer */
|
||||
+ runtime_func = (RUNTIME_FUNCTION *)((ULONG_PTR)buf | 0x3);
|
||||
+ runtime_func->BeginAddress = code_offset;
|
||||
+ runtime_func->EndAddress = code_offset + 16;
|
||||
+ runtime_func->UnwindData = 0;
|
||||
+ ok( pRtlAddFunctionTable( runtime_func, 1, (ULONG_PTR)code_mem ),
|
||||
+ "RtlAddFunctionTable failed for runtime_func = %p (unaligned)\n", runtime_func );
|
||||
+ ok( pRtlDeleteFunctionTable( runtime_func ),
|
||||
+ "RtlDeleteFunctionTable failed for runtime_func = %p (unaligned)\n", runtime_func );
|
||||
+
|
||||
+ /* Attempt to insert the same entry twice */
|
||||
+ runtime_func = (RUNTIME_FUNCTION *)buf;
|
||||
+ runtime_func->BeginAddress = code_offset;
|
||||
+ runtime_func->EndAddress = code_offset + 16;
|
||||
+ runtime_func->UnwindData = 0;
|
||||
+ ok( pRtlAddFunctionTable( runtime_func, 1, (ULONG_PTR)code_mem ),
|
||||
+ "RtlAddFunctionTable failed for runtime_func = %p (first attempt)\n", runtime_func );
|
||||
+ ok( pRtlAddFunctionTable( runtime_func, 1, (ULONG_PTR)code_mem ),
|
||||
+ "RtlAddFunctionTable failed for runtime_func = %p (second attempt)\n", runtime_func );
|
||||
+ ok( pRtlDeleteFunctionTable( runtime_func ),
|
||||
+ "RtlDeleteFunctionTable failed for runtime_func = %p (first attempt)\n", runtime_func );
|
||||
+ ok( pRtlDeleteFunctionTable( runtime_func ),
|
||||
+ "RtlDeleteFunctionTable failed for runtime_func = %p (second attempt)\n", runtime_func );
|
||||
+ ok( !pRtlDeleteFunctionTable( runtime_func ),
|
||||
+ "RtlDeleteFunctionTable returned success for nonexistent table runtime_func = %p\n", runtime_func );
|
||||
+
|
||||
+ /* Table without both low bits set */
|
||||
+ table = (ULONG_PTR)code_mem;
|
||||
+ ok( !pRtlInstallFunctionTableCallback( table, (ULONG_PTR)code_mem, code_offset + 16, &function_table_callback, (PVOID*)&count, NULL ),
|
||||
+ "RtlInstallFunctionTableCallback returned success for table = %lx\n", table );
|
||||
+
|
||||
+ /* Table with both low bits set */
|
||||
+ table = (ULONG_PTR)code_mem | 0x3;
|
||||
+ ok( pRtlInstallFunctionTableCallback( table, (ULONG_PTR)code_mem, code_offset + 16, &function_table_callback, (PVOID*)&count, NULL ),
|
||||
+ "RtlInstallFunctionTableCallback failed for table = %lx\n", table );
|
||||
+
|
||||
+ /* Pointer outside of the area */
|
||||
+ count = 0;
|
||||
+ base = 0xdeadbeef;
|
||||
+ func = pRtlLookupFunctionEntry( (ULONG_PTR)code_mem + code_offset + 16, &base, NULL );
|
||||
+ ok( func == NULL,
|
||||
+ "RtlLookupFunctionEntry returned unexpected function, expected: NULL, got: %p\n", func );
|
||||
+ ok( base == 0xdeadbeef,
|
||||
+ "RtlLookupFunctionEntry modified base address, expected: 0xdeadbeef, got: %lx\n", base );
|
||||
+ ok( !count,
|
||||
+ "RtlLookupFunctionEntry issued %d unexpected calls to function_table_callback\n", count );
|
||||
+
|
||||
+ /* Pointer inside of a function */
|
||||
+ count = 0;
|
||||
+ base = 0xdeadbeef;
|
||||
+ func = pRtlLookupFunctionEntry( (ULONG_PTR)code_mem + code_offset + 8, &base, NULL );
|
||||
+ ok( func != NULL && func->BeginAddress == code_offset && func->EndAddress == code_offset + 16,
|
||||
+ "RtlLookupFunctionEntry didn't return expected function, got: %p\n", func );
|
||||
+ ok( base == (ULONG_PTR)code_mem,
|
||||
+ "RtlLookupFunctionEntry returned invalid base, expected: %lx, got: %lx\n", (ULONG_PTR)code_mem, base );
|
||||
+ ok( count == 1,
|
||||
+ "RtlLookupFunctionEntry issued %d calls to function_table_callback, expected: 1\n", count );
|
||||
+
|
||||
+ /* Clean up again */
|
||||
+ ok( pRtlDeleteFunctionTable( (PRUNTIME_FUNCTION)table ),
|
||||
+ "RtlDeleteFunctionTable failed for table = %p\n", (PVOID)table );
|
||||
+ ok( !pRtlDeleteFunctionTable( (PRUNTIME_FUNCTION)table ),
|
||||
+ "RtlDeleteFunctionTable returned success for nonexistent table = %p\n", (PVOID)table );
|
||||
+
|
||||
+}
|
||||
+
|
||||
#endif /* __x86_64__ */
|
||||
|
||||
START_TEST(exception)
|
||||
@@ -1473,6 +1595,16 @@ START_TEST(exception)
|
||||
"NtQueryInformationProcess" );
|
||||
pNtSetInformationProcess = (void*)GetProcAddress( hntdll,
|
||||
"NtSetInformationProcess" );
|
||||
+#if defined(__x86_64__)
|
||||
+ pRtlAddFunctionTable = (void *)GetProcAddress( hntdll,
|
||||
+ "RtlAddFunctionTable" );
|
||||
+ pRtlDeleteFunctionTable = (void *)GetProcAddress( hntdll,
|
||||
+ "RtlDeleteFunctionTable" );
|
||||
+ pRtlInstallFunctionTableCallback = (void *)GetProcAddress( hntdll,
|
||||
+ "RtlInstallFunctionTableCallback" );
|
||||
+ pRtlLookupFunctionEntry = (void *)GetProcAddress( hntdll,
|
||||
+ "RtlLookupFunctionEntry" );
|
||||
+#endif
|
||||
pIsWow64Process = (void *)GetProcAddress(GetModuleHandleA("kernel32.dll"), "IsWow64Process");
|
||||
|
||||
#ifdef __i386__
|
||||
@@ -1537,6 +1669,11 @@ START_TEST(exception)
|
||||
|
||||
test_virtual_unwind();
|
||||
|
||||
+ if (pRtlAddFunctionTable && pRtlDeleteFunctionTable && pRtlInstallFunctionTableCallback && pRtlLookupFunctionEntry)
|
||||
+ test_dynamic_unwind();
|
||||
+ else
|
||||
+ skip( "Rtl{Add,Delete}FunctionTable or RtlInstallFunctionTableCallback or RtlLookupFunctionEntry not found\n" );
|
||||
+
|
||||
#endif
|
||||
|
||||
VirtualFree(code_mem, 0, MEM_FREE);
|
||||
--
|
||||
1.7.9.5
|
||||
|
@ -1,24 +0,0 @@
|
||||
From 71d9e2ae7a81a8ab030933a10984cad5c5a8c7c1 Mon Sep 17 00:00:00 2001
|
||||
From: Sebastian Lackner <sebastian@fds-team.de>
|
||||
Date: Sat, 5 Apr 2014 02:01:38 +0200
|
||||
Subject: kernel32: Forward RtlInstallFunctionTableCallback to ntdll
|
||||
|
||||
---
|
||||
dlls/kernel32/kernel32.spec | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/dlls/kernel32/kernel32.spec b/dlls/kernel32/kernel32.spec
|
||||
index f3e5c67..a6c6b29 100644
|
||||
--- a/dlls/kernel32/kernel32.spec
|
||||
+++ b/dlls/kernel32/kernel32.spec
|
||||
@@ -1042,6 +1042,7 @@
|
||||
@ stdcall -arch=x86_64 RtlCompareMemory(ptr ptr long) ntdll.RtlCompareMemory
|
||||
@ cdecl -arch=arm,x86_64 RtlDeleteFunctionTable(ptr) ntdll.RtlDeleteFunctionTable
|
||||
@ stdcall RtlFillMemory(ptr long long) ntdll.RtlFillMemory
|
||||
+@ cdecl -arch=x86_64 RtlInstallFunctionTableCallback(long long long ptr ptr ptr) ntdll.RtlInstallFunctionTableCallback
|
||||
@ stdcall -arch=arm,x86_64 RtlLookupFunctionEntry(long ptr ptr) ntdll.RtlLookupFunctionEntry
|
||||
@ stdcall RtlMoveMemory(ptr ptr long) ntdll.RtlMoveMemory
|
||||
@ stdcall -arch=x86_64,arm RtlPcToFileHeader(ptr ptr) ntdll.RtlPcToFileHeader
|
||||
--
|
||||
1.7.9.5
|
||||
|
@ -1,3 +0,0 @@
|
||||
Revision: 4
|
||||
Author: Sebastian Lackner
|
||||
Title: Add implementation for dynamic unwind tables/callbacks on x86_64.
|
@ -37,7 +37,7 @@ diff --git a/libs/wine/config.c b/libs/wine/config.c
|
||||
index a273502..5fa0cd5 100644
|
||||
--- a/libs/wine/config.c
|
||||
+++ b/libs/wine/config.c
|
||||
@@ -478,6 +478,38 @@ const char *wine_get_version(void)
|
||||
@@ -478,6 +478,37 @@ const char *wine_get_version(void)
|
||||
return PACKAGE_VERSION;
|
||||
}
|
||||
|
||||
@ -57,7 +57,6 @@ index a273502..5fa0cd5 100644
|
||||
+ { "4cd13e94-7f2d-11e3-b5eb-0090f5c75ad5:1", "Erich E. Hoover", "Support for junction points/reparse points." },
|
||||
+ { "5fb1f5c8-7f17-11e3-9b62-0090f5c75ad5:1", "Erich E. Hoover", "Implement TransmitFile." },
|
||||
+ { "3d7c4774-9e7f-11e3-9cfc-0090f5c75ad5:1", "Erich E. Hoover", "Implement missing fonts expected by Silverlight." },
|
||||
+ { "bbbf7d25-cca0-4630-9a83-0dec5e53ecb8:4", "Sebastian Lackner", "Add implementation for dynamic unwind tables/callbacks on x86_64." },
|
||||
+ { "0b21d7ac-0387-4493-aa38-fbafe3e749f5:1", "Michael Müller", "Decrease minimum SetTimer interval from 15 to 5 ms." },
|
||||
+ { "19835498-8d90-4673-867e-2376af4d7c76:1", "Sebastian Lackner", "Allow to set wined3d strictDrawOrdering via environment variable." },
|
||||
+ { "59bd38b7-bbdc-4cfd-9ccd-1c72c4ed84c0:1", "Sebastian Lackner", "Implement X11DRV_FLUSH_GDI_DISPLAY ExtEscape command." },
|
||||
|
Loading…
Reference in New Issue
Block a user