[2/2] ntdll: Implement RtlLookupFunctionEntry on ARM
André Hentschel
nerv at dawncrow.de
Sat Mar 23 11:24:04 CDT 2013
---
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__ */
--
1.8.0
--
Best Regards, André Hentschel
More information about the wine-patches
mailing list