Sebastian Lackner : ntdll: Unify exception function lookup on x86_64.
Alexandre Julliard
julliard at winehq.org
Tue Apr 8 14:02:50 CDT 2014
Module: wine
Branch: master
Commit: a71d1e389f7fffb66b93de3a9a9bbb568337623a
URL: http://source.winehq.org/git/wine.git/?a=commit;h=a71d1e389f7fffb66b93de3a9a9bbb568337623a
Author: Sebastian Lackner <sebastian at fds-team.de>
Date: Fri Apr 4 10:11:56 2014 +0200
ntdll: Unify exception function lookup on x86_64.
---
dlls/ntdll/signal_x86_64.c | 100 ++++++++++++++++++++------------------------
1 file changed, 46 insertions(+), 54 deletions(-)
diff --git a/dlls/ntdll/signal_x86_64.c b/dlls/ntdll/signal_x86_64.c
index b28cb99..0e72092 100644
--- a/dlls/ntdll/signal_x86_64.c
+++ b/dlls/ntdll/signal_x86_64.c
@@ -1921,6 +1921,30 @@ 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 );
+ }
+ }
+ else
+ *module = NULL;
+
+ return func;
+}
/**********************************************************************
* call_handler
@@ -2002,7 +2026,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;
@@ -2016,31 +2039,17 @@ static NTSTATUS call_stack_handlers( EXCEPTION_RECORD *rec, CONTEXT *orig_contex
/* FIXME: should use the history table to make things faster */
- module = NULL;
dispatch.ImageBase = 0;
/* 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 */
@@ -2064,6 +2073,7 @@ static NTSTATUS call_stack_handlers( EXCEPTION_RECORD *rec, CONTEXT *orig_contex
goto unwind_done;
}
}
+ else WARN( "exception data not found in %s\n", debugstr_w(module->BaseDllName.Buffer) );
/* no exception information, treat as a leaf function */
@@ -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;
@@ -2956,32 +2961,18 @@ void WINAPI RtlUnwindEx( PVOID end_frame, PVOID target_ip, EXCEPTION_RECORD *rec
{
/* FIXME: should use the history table to make things faster */
- module = NULL;
dispatch.ImageBase = 0;
dispatch.ScopeIndex = 0; /* FIXME */
/* 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 */
@@ -3005,6 +2996,7 @@ void WINAPI RtlUnwindEx( PVOID end_frame, PVOID target_ip, EXCEPTION_RECORD *rec
goto unwind_done;
}
}
+ else WARN( "exception data not found in %s\n", debugstr_w(module->BaseDllName.Buffer) );
/* no exception information, treat as a leaf function */
More information about the wine-cvs
mailing list