mirror of
git://source.winehq.org/git/wine.git
synced 2024-10-31 01:57:23 +00:00
ntdll: Implement RtlLookupFunctionTable.
This commit is contained in:
parent
165830c317
commit
de492f9a34
8 changed files with 120 additions and 9 deletions
|
@ -640,16 +640,10 @@ RUNTIME_FUNCTION *lookup_function_info( ULONG_PTR pc, ULONG_PTR *base, LDR_DATA_
|
|||
ULONG size;
|
||||
|
||||
/* PE module or wine module */
|
||||
if (!LdrFindEntryForAddress( (void *)pc, module ))
|
||||
if ((func = RtlLookupFunctionTable( pc, base, &size )))
|
||||
{
|
||||
*base = (ULONG_PTR)(*module)->DllBase;
|
||||
if ((func = RtlImageDirectoryEntryToData( (*module)->DllBase, TRUE,
|
||||
IMAGE_DIRECTORY_ENTRY_EXCEPTION, &size )))
|
||||
{
|
||||
/* lookup in function table */
|
||||
func = find_function_info( pc, (ULONG_PTR)(*module)->DllBase, func, size/sizeof(*func) );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
*module = NULL;
|
||||
|
|
|
@ -878,6 +878,7 @@
|
|||
@ stdcall RtlLookupElementGenericTable(ptr ptr)
|
||||
# @ stub RtlLookupElementGenericTableAvl
|
||||
@ stdcall -arch=!i386 RtlLookupFunctionEntry(long ptr ptr)
|
||||
@ stdcall -arch=!i386 RtlLookupFunctionTable(long ptr ptr)
|
||||
@ stdcall RtlMakeSelfRelativeSD(ptr ptr ptr)
|
||||
@ stdcall RtlMapGenericMask(ptr ptr)
|
||||
# @ stub RtlMapSecurityErrorToNtStatus
|
||||
|
|
|
@ -1191,6 +1191,19 @@ PVOID WINAPI RtlVirtualUnwind( ULONG type, ULONG_PTR base, ULONG_PTR pc,
|
|||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* RtlLookupFunctionTable (NTDLL.@)
|
||||
*/
|
||||
PRUNTIME_FUNCTION WINAPI RtlLookupFunctionTable( ULONG_PTR pc, ULONG_PTR *base, ULONG *len )
|
||||
{
|
||||
LDR_DATA_TABLE_ENTRY *module;
|
||||
|
||||
if (LdrFindEntryForAddress( (void *)pc, &module )) return NULL;
|
||||
*base = (ULONG_PTR)module->DllBase;
|
||||
return RtlImageDirectoryEntryToData( module->DllBase, TRUE, IMAGE_DIRECTORY_ENTRY_EXCEPTION, len );
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* call_consolidate_callback
|
||||
*
|
||||
|
|
|
@ -1070,6 +1070,20 @@ PVOID WINAPI RtlVirtualUnwind( ULONG type, ULONG_PTR base, ULONG_PTR pc,
|
|||
return handler;
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* RtlLookupFunctionTable (NTDLL.@)
|
||||
*/
|
||||
PRUNTIME_FUNCTION WINAPI RtlLookupFunctionTable( ULONG_PTR pc, ULONG_PTR *base, ULONG *len )
|
||||
{
|
||||
LDR_DATA_TABLE_ENTRY *module;
|
||||
|
||||
if (LdrFindEntryForAddress( (void *)pc, &module )) return NULL;
|
||||
*base = (ULONG_PTR)module->DllBase;
|
||||
return RtlImageDirectoryEntryToData( module->DllBase, TRUE, IMAGE_DIRECTORY_ENTRY_EXCEPTION, len );
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* call_consolidate_callback
|
||||
*
|
||||
|
|
|
@ -1782,6 +1782,35 @@ PVOID WINAPI RtlVirtualUnwind( ULONG type, ULONG64 base, ULONG64 pc,
|
|||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* RtlLookupFunctionTable (NTDLL.@)
|
||||
*/
|
||||
PRUNTIME_FUNCTION WINAPI RtlLookupFunctionTable( ULONG_PTR pc, ULONG_PTR *base, ULONG *len )
|
||||
{
|
||||
LDR_DATA_TABLE_ENTRY *module;
|
||||
|
||||
if (LdrFindEntryForAddress( (void *)pc, &module )) return NULL;
|
||||
*base = (ULONG_PTR)module->DllBase;
|
||||
|
||||
if (RtlIsEcCode( (void *)pc ))
|
||||
{
|
||||
IMAGE_LOAD_CONFIG_DIRECTORY *cfg;
|
||||
IMAGE_ARM64EC_METADATA *metadata;
|
||||
ULONG size;
|
||||
|
||||
if (!(cfg = RtlImageDirectoryEntryToData( module->DllBase, TRUE,
|
||||
IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG, &size )))
|
||||
return NULL;
|
||||
size = min( size, cfg->Size );
|
||||
if (size <= offsetof( IMAGE_LOAD_CONFIG_DIRECTORY, CHPEMetadataPointer )) return NULL;
|
||||
metadata = (IMAGE_ARM64EC_METADATA *)cfg->CHPEMetadataPointer;
|
||||
*len = metadata->ExtraRFETableSize;
|
||||
return (RUNTIME_FUNCTION *)(*base + metadata->ExtraRFETable);
|
||||
}
|
||||
return RtlImageDirectoryEntryToData( module->DllBase, TRUE, IMAGE_DIRECTORY_ENTRY_EXCEPTION, len );
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
* RtlUnwindEx (NTDLL.@)
|
||||
*/
|
||||
|
|
|
@ -1029,6 +1029,20 @@ PVOID WINAPI RtlVirtualUnwind( ULONG type, ULONG64 base, ULONG64 pc,
|
|||
return (char *)base + handler_data->handler;
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* RtlLookupFunctionTable (NTDLL.@)
|
||||
*/
|
||||
PRUNTIME_FUNCTION WINAPI RtlLookupFunctionTable( ULONG_PTR pc, ULONG_PTR *base, ULONG *len )
|
||||
{
|
||||
LDR_DATA_TABLE_ENTRY *module;
|
||||
|
||||
if (LdrFindEntryForAddress( (void *)pc, &module )) return NULL;
|
||||
*base = (ULONG_PTR)module->DllBase;
|
||||
return RtlImageDirectoryEntryToData( module->DllBase, TRUE, IMAGE_DIRECTORY_ENTRY_EXCEPTION, len );
|
||||
}
|
||||
|
||||
|
||||
struct unwind_exception_frame
|
||||
{
|
||||
EXCEPTION_REGISTRATION_RECORD frame;
|
||||
|
|
|
@ -187,6 +187,7 @@ typedef struct _UNWIND_INFO
|
|||
|
||||
static BOOLEAN (CDECL *pRtlInstallFunctionTableCallback)(DWORD64, DWORD64, DWORD, PGET_RUNTIME_FUNCTION_CALLBACK, PVOID, PCWSTR);
|
||||
static PRUNTIME_FUNCTION (WINAPI *pRtlLookupFunctionEntry)(ULONG64, ULONG64*, UNWIND_HISTORY_TABLE*);
|
||||
static PRUNTIME_FUNCTION (WINAPI *pRtlLookupFunctionTable)(ULONG64, ULONG64*, ULONG*);
|
||||
static DWORD (WINAPI *pRtlAddGrowableFunctionTable)(void**, RUNTIME_FUNCTION*, DWORD, DWORD, ULONG_PTR, ULONG_PTR);
|
||||
static void (WINAPI *pRtlGrowFunctionTable)(void*, DWORD);
|
||||
static void (WINAPI *pRtlDeleteGrowableFunctionTable)(void*);
|
||||
|
@ -196,6 +197,7 @@ static VOID (CDECL *pRtlRestoreContext)(CONTEXT*, EXCEPTION_RECORD*);
|
|||
static NTSTATUS (WINAPI *pRtlWow64GetThreadContext)(HANDLE, WOW64_CONTEXT *);
|
||||
static NTSTATUS (WINAPI *pRtlWow64SetThreadContext)(HANDLE, const WOW64_CONTEXT *);
|
||||
static NTSTATUS (WINAPI *pRtlWow64GetCpuAreaInfo)(WOW64_CPURESERVED*,ULONG,WOW64_CPU_AREA_INFO*);
|
||||
static NTSTATUS (WINAPI *pRtlGetNativeSystemInformation)(SYSTEM_INFORMATION_CLASS,void*,ULONG,ULONG*);
|
||||
static int (CDECL *p_setjmp)(_JUMP_BUFFER*);
|
||||
#endif
|
||||
|
||||
|
@ -2793,11 +2795,13 @@ static void test_dynamic_unwind(void)
|
|||
{
|
||||
static const int code_offset = 1024;
|
||||
char buf[2 * sizeof(RUNTIME_FUNCTION) + 4];
|
||||
SYSTEM_CPU_INFORMATION info;
|
||||
RUNTIME_FUNCTION *runtime_func, *func;
|
||||
ULONG_PTR table, base;
|
||||
void *growable_table;
|
||||
void *growable_table, *ptr;
|
||||
NTSTATUS status;
|
||||
DWORD count;
|
||||
ULONG len, len2;
|
||||
|
||||
if (!pRtlInstallFunctionTableCallback || !pRtlLookupFunctionEntry)
|
||||
{
|
||||
|
@ -2976,7 +2980,46 @@ static void test_dynamic_unwind(void)
|
|||
ok( base == (ULONG_PTR)code_mem,
|
||||
"RtlLookupFunctionEntry returned invalid base, expected: %Ix, got: %Ix\n", (ULONG_PTR)code_mem, base );
|
||||
|
||||
base = 0xdeadbeef;
|
||||
func = pRtlLookupFunctionTable( (ULONG_PTR)code_mem + code_offset + 8, &base, &len );
|
||||
ok( func == NULL, "RtlLookupFunctionTable wrong table, got: %p\n", func );
|
||||
ok( base == 0xdeadbeef, "RtlLookupFunctionTable wrong base, got: %Ix\n", base );
|
||||
|
||||
base = 0xdeadbeef;
|
||||
func = pRtlLookupFunctionTable( (ULONG_PTR)pRtlLookupFunctionEntry, &base, &len );
|
||||
ok( base == (ULONG_PTR)GetModuleHandleA("ntdll.dll"),
|
||||
"RtlLookupFunctionTable wrong base, got: %Ix / %p\n", base, GetModuleHandleA("ntdll.dll") );
|
||||
ptr = RtlImageDirectoryEntryToData( (void *)base, TRUE, IMAGE_DIRECTORY_ENTRY_EXCEPTION, &len2 );
|
||||
ok( func == ptr, "RtlLookupFunctionTable wrong table, got: %p / %p\n", func, ptr );
|
||||
ok( len == len2, "RtlLookupFunctionTable wrong len, got: %lu / %lu\n", len, len2 );
|
||||
|
||||
pRtlDeleteGrowableFunctionTable( growable_table );
|
||||
|
||||
if (pRtlGetNativeSystemInformation &&
|
||||
!pRtlGetNativeSystemInformation( SystemCpuInformation, &info, sizeof(info), &len ) &&
|
||||
info.ProcessorArchitecture == PROCESSOR_ARCHITECTURE_ARM64)
|
||||
{
|
||||
static const BYTE fast_forward[] = { 0x48, 0x8b, 0xc4, 0x48, 0x89, 0x58, 0x20, 0x55, 0x5d, 0xe9 };
|
||||
IMAGE_ARM64EC_METADATA *metadata;
|
||||
|
||||
if (!memcmp( pRtlLookupFunctionEntry, fast_forward, sizeof(fast_forward) ))
|
||||
{
|
||||
ptr = (char *)pRtlLookupFunctionEntry + sizeof(fast_forward);
|
||||
ptr = (char *)ptr + 4 + *(int *)ptr;
|
||||
base = 0xdeadbeef;
|
||||
func = pRtlLookupFunctionTable( (ULONG_PTR)ptr, &base, &len );
|
||||
ok( base == (ULONG_PTR)GetModuleHandleA("ntdll.dll"),
|
||||
"RtlLookupFunctionTable wrong base, got: %Ix / %p\n", base, GetModuleHandleA("ntdll.dll") );
|
||||
ptr = RtlImageDirectoryEntryToData( (void *)base, TRUE, IMAGE_DIRECTORY_ENTRY_EXCEPTION, &len2 );
|
||||
ok( func != ptr, "RtlLookupFunctionTable wrong table, got: %p / %p\n", func, ptr );
|
||||
ptr = RtlImageDirectoryEntryToData( (void *)base, TRUE, IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG, &len2 );
|
||||
metadata = (void *)((IMAGE_LOAD_CONFIG_DIRECTORY *)ptr)->CHPEMetadataPointer;
|
||||
ok( (char *)func == (char *)base + metadata->ExtraRFETable,
|
||||
"RtlLookupFunctonTable wrong table, got: %p / %p\n", func, (char *)base + metadata->ExtraRFETable );
|
||||
ok( len == metadata->ExtraRFETableSize, "RtlLookupFunctionTable wrong len, got: %lu / %lu\n",
|
||||
len, metadata->ExtraRFETableSize );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int termination_handler_called;
|
||||
|
@ -13006,6 +13049,7 @@ START_TEST(exception)
|
|||
#define X(f) p##f = (void*)GetProcAddress(hntdll, #f)
|
||||
X(RtlInstallFunctionTableCallback);
|
||||
X(RtlLookupFunctionEntry);
|
||||
X(RtlLookupFunctionTable);
|
||||
X(RtlAddGrowableFunctionTable);
|
||||
X(RtlGrowFunctionTable);
|
||||
X(RtlDeleteGrowableFunctionTable);
|
||||
|
@ -13015,6 +13059,7 @@ START_TEST(exception)
|
|||
X(RtlWow64GetThreadContext);
|
||||
X(RtlWow64SetThreadContext);
|
||||
X(RtlWow64GetCpuAreaInfo);
|
||||
X(RtlGetNativeSystemInformation);
|
||||
#undef X
|
||||
p_setjmp = (void *)GetProcAddress( hmsvcrt, "_setjmp" );
|
||||
|
||||
|
|
|
@ -2074,6 +2074,7 @@ NTSYSAPI void WINAPI RtlDeleteGrowableFunctionTable(void*);
|
|||
NTSYSAPI void WINAPI RtlGrowFunctionTable(void*,DWORD);
|
||||
NTSYSAPI BOOLEAN CDECL RtlInstallFunctionTableCallback(DWORD_PTR,DWORD_PTR,DWORD,PGET_RUNTIME_FUNCTION_CALLBACK,PVOID,PCWSTR);
|
||||
NTSYSAPI PRUNTIME_FUNCTION WINAPI RtlLookupFunctionEntry(DWORD_PTR,DWORD_PTR*,UNWIND_HISTORY_TABLE*);
|
||||
NTSYSAPI PRUNTIME_FUNCTION WINAPI RtlLookupFunctionTable(DWORD_PTR,DWORD_PTR*,ULONG*);
|
||||
NTSYSAPI void WINAPI RtlUnwindEx(PVOID,PVOID,struct _EXCEPTION_RECORD*,PVOID,CONTEXT*,UNWIND_HISTORY_TABLE*);
|
||||
NTSYSAPI PVOID WINAPI RtlVirtualUnwind(DWORD,ULONG_PTR,ULONG_PTR,RUNTIME_FUNCTION*,CONTEXT*,PVOID*,ULONG_PTR*,KNONVOLATILE_CONTEXT_POINTERS*);
|
||||
|
||||
|
|
Loading…
Reference in a new issue