From 3c04958b8a47f56a6dfc9ac067ca88f34a4e29a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Hentschel?= Date: Sat, 23 Mar 2013 17:24:04 +0100 Subject: [PATCH] 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 a07a9ff1d21..72c1697097e 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 d67c85e48d7..b0cb43a8e92 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 f9cde3864f6..bf144a08346 100644 --- a/dlls/ntdll/signal_arm.c +++ b/dlls/ntdll/signal_arm.c @@ -47,6 +47,8 @@ # include #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 a40ff752749..79e91c084f8 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__ */