ntdll: Implement RtlLookupFunctionEntry on ARM.

This commit is contained in:
André Hentschel 2013-03-23 17:24:04 +01:00 committed by Alexandre Julliard
parent df7f4fb720
commit 3c04958b8a
4 changed files with 71 additions and 2 deletions

View File

@ -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

View File

@ -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

View File

@ -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.@)
*/

View File

@ -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__ */