Module: wine Branch: master Commit: 3c04958b8a47f56a6dfc9ac067ca88f34a4e29a2 URL: http://source.winehq.org/git/wine.git/?a=commit;h=3c04958b8a47f56a6dfc9ac067...
Author: André Hentschel nerv@dawncrow.de Date: Sat Mar 23 17:24:04 2013 +0100
ntdll: Implement RtlLookupFunctionEntry on ARM.
---
dlls/kernel32/kernel32.spec | 2 +- dlls/ntdll/ntdll.spec | 2 +- dlls/ntdll/signal_arm.c | 68 +++++++++++++++++++++++++++++++++++++++++++ include/winnt.h | 1 + 4 files changed, 71 insertions(+), 2 deletions(-)
diff --git a/dlls/kernel32/kernel32.spec b/dlls/kernel32/kernel32.spec index a07a9ff..72c1697 100644 --- a/dlls/kernel32/kernel32.spec +++ b/dlls/kernel32/kernel32.spec @@ -1034,7 +1034,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 -@ stdcall -arch=x86_64 RtlLookupFunctionEntry(long ptr ptr) ntdll.RtlLookupFunctionEntry +@ 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 @ stdcall -arch=arm -register RtlRaiseException(ptr) ntdll.RtlRaiseException diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec index d67c85e..b0cb43a 100644 --- a/dlls/ntdll/ntdll.spec +++ b/dlls/ntdll/ntdll.spec @@ -738,7 +738,7 @@ @ stdcall RtlLookupAtomInAtomTable(ptr wstr ptr) @ stub RtlLookupElementGenericTable # @ stub RtlLookupElementGenericTableAvl -@ stdcall -arch=x86_64 RtlLookupFunctionEntry(long ptr ptr) +@ stdcall -arch=arm,x86_64 RtlLookupFunctionEntry(long ptr ptr) @ stdcall RtlMakeSelfRelativeSD(ptr ptr ptr) @ stdcall RtlMapGenericMask(long ptr) # @ stub RtlMapSecurityErrorToNtStatus diff --git a/dlls/ntdll/signal_arm.c b/dlls/ntdll/signal_arm.c index f9cde38..bf144a0 100644 --- a/dlls/ntdll/signal_arm.c +++ b/dlls/ntdll/signal_arm.c @@ -47,6 +47,8 @@ # include <sys/signal.h> #endif
+#define NONAMELESSUNION +#define NONAMELESSSTRUCT #include "ntstatus.h" #define WIN32_NO_STATUS #include "windef.h" @@ -100,6 +102,15 @@ typedef int (*wine_signal_handler)(unsigned int sig);
static wine_signal_handler handlers[256];
+ +struct UNWIND_INFO +{ + WORD function_length; + WORD unknown1 : 7; + WORD count : 5; + WORD unknown2 : 4; +}; + /*********************************************************************** * dispatch_signal */ @@ -933,6 +944,63 @@ BOOLEAN CDECL RtlDeleteFunctionTable( RUNTIME_FUNCTION *table ) return TRUE; }
+/********************************************************************** + * find_function_info + */ +static RUNTIME_FUNCTION *find_function_info( ULONG_PTR pc, HMODULE module, + RUNTIME_FUNCTION *func, ULONG size ) +{ + int min = 0; + int max = size/sizeof(*func) - 1; + + while (min <= max) + { + int pos = (min + max) / 2; + DWORD begin = (func[pos].BeginAddress & ~1), end; + if (func[pos].u.s.Flag) + end = begin + func[pos].u.s.FunctionLength * 2; + else + { + struct UNWIND_INFO *info; + info = (struct UNWIND_INFO *)((char *)module + func[pos].u.UnwindData); + end = begin + info->function_length * 2; + } + + if ((char *)pc < (char *)module + begin) max = pos - 1; + else if ((char *)pc >= (char *)module + end) min = pos + 1; + else return func + pos; + } + return NULL; +} + +/********************************************************************** + * RtlLookupFunctionEntry (NTDLL.@) + */ +PRUNTIME_FUNCTION WINAPI RtlLookupFunctionEntry( ULONG_PTR pc, DWORD *base, + UNWIND_HISTORY_TABLE *table ) +{ + LDR_MODULE *module; + RUNTIME_FUNCTION *func; + ULONG size; + + /* FIXME: should use the history table to make things faster */ + + if (LdrFindEntryForAddress( (void *)pc, &module )) + { + 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; + } + func = find_function_info( pc, module->BaseAddress, func, size ); + if (func) *base = (DWORD)module->BaseAddress; + return func; +} + /*********************************************************************** * RtlUnwind (NTDLL.@) */ diff --git a/include/winnt.h b/include/winnt.h index a40ff75..79e91c0 100644 --- a/include/winnt.h +++ b/include/winnt.h @@ -1710,6 +1710,7 @@ typedef struct _CONTEXT {
BOOLEAN CDECL RtlAddFunctionTable(RUNTIME_FUNCTION*,DWORD,DWORD); BOOLEAN CDECL RtlDeleteFunctionTable(RUNTIME_FUNCTION*); +PRUNTIME_FUNCTION WINAPI RtlLookupFunctionEntry(ULONG_PTR,DWORD*,UNWIND_HISTORY_TABLE*);
#endif /* __arm__ */