Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
de492f9a
Commit
de492f9a
authored
Feb 12, 2024
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ntdll: Implement RtlLookupFunctionTable.
parent
165830c3
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
120 additions
and
9 deletions
+120
-9
exception.c
dlls/ntdll/exception.c
+2
-8
ntdll.spec
dlls/ntdll/ntdll.spec
+1
-0
signal_arm.c
dlls/ntdll/signal_arm.c
+13
-0
signal_arm64.c
dlls/ntdll/signal_arm64.c
+14
-0
signal_arm64ec.c
dlls/ntdll/signal_arm64ec.c
+29
-0
signal_x86_64.c
dlls/ntdll/signal_x86_64.c
+14
-0
exception.c
dlls/ntdll/tests/exception.c
+46
-1
winnt.h
include/winnt.h
+1
-0
No files found.
dlls/ntdll/exception.c
View file @
de492f9a
...
...
@@ -640,15 +640,9 @@ 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
)
);
}
func
=
find_function_info
(
pc
,
(
ULONG_PTR
)(
*
module
)
->
DllBase
,
func
,
size
/
sizeof
(
*
func
)
);
}
else
{
...
...
dlls/ntdll/ntdll.spec
View file @
de492f9a
...
...
@@ -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
...
...
dlls/ntdll/signal_arm.c
View file @
de492f9a
...
...
@@ -1192,6 +1192,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
*
* Wrapper function to call a consolidate callback from a fake frame.
...
...
dlls/ntdll/signal_arm64.c
View file @
de492f9a
...
...
@@ -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
*
...
...
dlls/ntdll/signal_arm64ec.c
View file @
de492f9a
...
...
@@ -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.@)
*/
...
...
dlls/ntdll/signal_x86_64.c
View file @
de492f9a
...
...
@@ -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
;
...
...
dlls/ntdll/tests/exception.c
View file @
de492f9a
...
...
@@ -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"
);
...
...
include/winnt.h
View file @
de492f9a
...
...
@@ -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
*
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment