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
14e34bed
Commit
14e34bed
authored
Aug 19, 2019
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ntdll: Share dynamic exception table functions across platforms.
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
44a60433
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
368 additions
and
498 deletions
+368
-498
api-ms-win-core-rtlsupport-l1-1-0.spec
...-rtlsupport-l1-1-0/api-ms-win-core-rtlsupport-l1-1-0.spec
+1
-1
exception.c
dlls/ntdll/exception.c
+340
-0
ntdll.spec
dlls/ntdll/ntdll.spec
+1
-1
ntdll_misc.h
dlls/ntdll/ntdll_misc.h
+4
-0
signal_arm.c
dlls/ntdll/signal_arm.c
+0
-121
signal_arm64.c
dlls/ntdll/signal_arm64.c
+0
-57
signal_x86_64.c
dlls/ntdll/signal_x86_64.c
+0
-302
winnt.h
include/winnt.h
+22
-16
No files found.
dlls/api-ms-win-core-rtlsupport-l1-1-0/api-ms-win-core-rtlsupport-l1-1-0.spec
View file @
14e34bed
...
...
@@ -6,7 +6,7 @@
@ cdecl -arch=arm,arm64,x86_64 RtlDeleteFunctionTable(ptr) ntdll.RtlDeleteFunctionTable
@ stdcall RtlFillMemory(ptr long long) ntdll.RtlFillMemory
@ cdecl -arch=arm,arm64,x86_64 RtlInstallFunctionTableCallback(long long long ptr ptr wstr) ntdll.RtlInstallFunctionTableCallback
@ stdcall -arch=arm,x86_64 RtlLookupFunctionEntry(long ptr ptr) ntdll.RtlLookupFunctionEntry
@ stdcall -arch=arm,
arm64,
x86_64 RtlLookupFunctionEntry(long ptr ptr) ntdll.RtlLookupFunctionEntry
@ stdcall RtlPcToFileHeader(ptr ptr) ntdll.RtlPcToFileHeader
@ stdcall -norelay RtlRaiseException(ptr) ntdll.RtlRaiseException
@ stdcall -arch=x86_64 RtlRestoreContext(ptr ptr) ntdll.RtlRestoreContext
...
...
dlls/ntdll/exception.c
View file @
14e34bed
...
...
@@ -27,6 +27,8 @@
#include <signal.h>
#include <stdarg.h>
#define NONAMELESSUNION
#define NONAMELESSSTRUCT
#include "ntstatus.h"
#define WIN32_NO_STATUS
#include "windef.h"
...
...
@@ -327,6 +329,344 @@ LONG WINAPI call_unhandled_exception_filter( PEXCEPTION_POINTERS eptr )
}
#if defined(__x86_64__) || defined(__arm__) || defined(__aarch64__)
struct
dynamic_unwind_entry
{
struct
list
entry
;
ULONG_PTR
base
;
ULONG_PTR
end
;
RUNTIME_FUNCTION
*
table
;
DWORD
count
;
DWORD
max_count
;
PGET_RUNTIME_FUNCTION_CALLBACK
callback
;
PVOID
context
;
};
static
struct
list
dynamic_unwind_list
=
LIST_INIT
(
dynamic_unwind_list
);
static
RTL_CRITICAL_SECTION
dynamic_unwind_section
;
static
RTL_CRITICAL_SECTION_DEBUG
dynamic_unwind_debug
=
{
0
,
0
,
&
dynamic_unwind_section
,
{
&
dynamic_unwind_debug
.
ProcessLocksList
,
&
dynamic_unwind_debug
.
ProcessLocksList
},
0
,
0
,
{
(
DWORD_PTR
)(
__FILE__
": dynamic_unwind_section"
)
}
};
static
RTL_CRITICAL_SECTION
dynamic_unwind_section
=
{
&
dynamic_unwind_debug
,
-
1
,
0
,
0
,
0
,
0
};
static
ULONG_PTR
get_runtime_function_end
(
RUNTIME_FUNCTION
*
func
,
ULONG_PTR
addr
)
{
#ifdef __x86_64__
return
func
->
EndAddress
;
#elif defined(__arm__)
if
(
func
->
u
.
s
.
Flag
)
return
func
->
BeginAddress
+
func
->
u
.
s
.
FunctionLength
*
2
;
else
{
struct
unwind_info
{
DWORD
function_length
:
18
;
DWORD
version
:
2
;
DWORD
x
:
1
;
DWORD
e
:
1
;
DWORD
f
:
1
;
DWORD
count
:
5
;
DWORD
words
:
4
;
}
*
info
=
(
struct
unwind_info
*
)(
addr
+
func
->
u
.
UnwindData
);
return
func
->
BeginAddress
+
info
->
function_length
*
2
;
}
#else
/* __aarch64__ */
if
(
func
->
u
.
s
.
Flag
)
return
func
->
BeginAddress
+
func
->
u
.
s
.
FunctionLength
*
4
;
else
{
struct
unwind_info
{
DWORD
function_length
:
18
;
DWORD
version
:
2
;
DWORD
x
:
1
;
DWORD
e
:
1
;
DWORD
epilog
:
5
;
DWORD
codes
:
5
;
}
*
info
=
(
struct
unwind_info
*
)(
addr
+
func
->
u
.
UnwindData
);
return
func
->
BeginAddress
+
info
->
function_length
*
4
;
}
#endif
}
/**********************************************************************
* RtlAddFunctionTable (NTDLL.@)
*/
BOOLEAN
CDECL
RtlAddFunctionTable
(
RUNTIME_FUNCTION
*
table
,
DWORD
count
,
ULONG_PTR
addr
)
{
struct
dynamic_unwind_entry
*
entry
;
TRACE
(
"%p %u %lx
\n
"
,
table
,
count
,
addr
);
/* NOTE: Windows doesn't check if table is aligned or a NULL pointer */
entry
=
RtlAllocateHeap
(
GetProcessHeap
(),
0
,
sizeof
(
*
entry
)
);
if
(
!
entry
)
return
FALSE
;
entry
->
base
=
addr
;
entry
->
end
=
addr
+
(
count
?
get_runtime_function_end
(
&
table
[
count
-
1
],
addr
)
:
0
);
entry
->
table
=
table
;
entry
->
count
=
count
;
entry
->
max_count
=
0
;
entry
->
callback
=
NULL
;
entry
->
context
=
NULL
;
RtlEnterCriticalSection
(
&
dynamic_unwind_section
);
list_add_tail
(
&
dynamic_unwind_list
,
&
entry
->
entry
);
RtlLeaveCriticalSection
(
&
dynamic_unwind_section
);
return
TRUE
;
}
/**********************************************************************
* RtlInstallFunctionTableCallback (NTDLL.@)
*/
BOOLEAN
CDECL
RtlInstallFunctionTableCallback
(
ULONG_PTR
table
,
ULONG_PTR
base
,
DWORD
length
,
PGET_RUNTIME_FUNCTION_CALLBACK
callback
,
PVOID
context
,
PCWSTR
dll
)
{
struct
dynamic_unwind_entry
*
entry
;
TRACE
(
"%lx %lx %d %p %p %s
\n
"
,
table
,
base
,
length
,
callback
,
context
,
wine_dbgstr_w
(
dll
)
);
/* NOTE: Windows doesn't check if the provided callback is a NULL pointer */
/* both low-order bits must be set */
if
((
table
&
0x3
)
!=
0x3
)
return
FALSE
;
entry
=
RtlAllocateHeap
(
GetProcessHeap
(),
0
,
sizeof
(
*
entry
)
);
if
(
!
entry
)
return
FALSE
;
entry
->
base
=
base
;
entry
->
end
=
base
+
length
;
entry
->
table
=
(
RUNTIME_FUNCTION
*
)
table
;
entry
->
count
=
0
;
entry
->
max_count
=
0
;
entry
->
callback
=
callback
;
entry
->
context
=
context
;
RtlEnterCriticalSection
(
&
dynamic_unwind_section
);
list_add_tail
(
&
dynamic_unwind_list
,
&
entry
->
entry
);
RtlLeaveCriticalSection
(
&
dynamic_unwind_section
);
return
TRUE
;
}
/*************************************************************************
* RtlAddGrowableFunctionTable (NTDLL.@)
*/
DWORD
WINAPI
RtlAddGrowableFunctionTable
(
void
**
table
,
RUNTIME_FUNCTION
*
functions
,
DWORD
count
,
DWORD
max_count
,
ULONG_PTR
base
,
ULONG_PTR
end
)
{
struct
dynamic_unwind_entry
*
entry
;
TRACE
(
"%p, %p, %u, %u, %lx, %lx
\n
"
,
table
,
functions
,
count
,
max_count
,
base
,
end
);
entry
=
RtlAllocateHeap
(
GetProcessHeap
(),
0
,
sizeof
(
*
entry
)
);
if
(
!
entry
)
return
STATUS_NO_MEMORY
;
entry
->
base
=
base
;
entry
->
end
=
end
;
entry
->
table
=
functions
;
entry
->
count
=
count
;
entry
->
max_count
=
max_count
;
entry
->
callback
=
NULL
;
entry
->
context
=
NULL
;
RtlEnterCriticalSection
(
&
dynamic_unwind_section
);
list_add_tail
(
&
dynamic_unwind_list
,
&
entry
->
entry
);
RtlLeaveCriticalSection
(
&
dynamic_unwind_section
);
*
table
=
entry
;
return
STATUS_SUCCESS
;
}
/*************************************************************************
* RtlGrowFunctionTable (NTDLL.@)
*/
void
WINAPI
RtlGrowFunctionTable
(
void
*
table
,
DWORD
count
)
{
struct
dynamic_unwind_entry
*
entry
;
TRACE
(
"%p, %u
\n
"
,
table
,
count
);
RtlEnterCriticalSection
(
&
dynamic_unwind_section
);
LIST_FOR_EACH_ENTRY
(
entry
,
&
dynamic_unwind_list
,
struct
dynamic_unwind_entry
,
entry
)
{
if
(
entry
==
table
)
{
if
(
count
>
entry
->
count
&&
count
<=
entry
->
max_count
)
entry
->
count
=
count
;
break
;
}
}
RtlLeaveCriticalSection
(
&
dynamic_unwind_section
);
}
/*************************************************************************
* RtlDeleteGrowableFunctionTable (NTDLL.@)
*/
void
WINAPI
RtlDeleteGrowableFunctionTable
(
void
*
table
)
{
struct
dynamic_unwind_entry
*
entry
,
*
to_free
=
NULL
;
TRACE
(
"%p
\n
"
,
table
);
RtlEnterCriticalSection
(
&
dynamic_unwind_section
);
LIST_FOR_EACH_ENTRY
(
entry
,
&
dynamic_unwind_list
,
struct
dynamic_unwind_entry
,
entry
)
{
if
(
entry
==
table
)
{
to_free
=
entry
;
list_remove
(
&
entry
->
entry
);
break
;
}
}
RtlLeaveCriticalSection
(
&
dynamic_unwind_section
);
RtlFreeHeap
(
GetProcessHeap
(),
0
,
to_free
);
}
/**********************************************************************
* RtlDeleteFunctionTable (NTDLL.@)
*/
BOOLEAN
CDECL
RtlDeleteFunctionTable
(
RUNTIME_FUNCTION
*
table
)
{
struct
dynamic_unwind_entry
*
entry
,
*
to_free
=
NULL
;
TRACE
(
"%p
\n
"
,
table
);
RtlEnterCriticalSection
(
&
dynamic_unwind_section
);
LIST_FOR_EACH_ENTRY
(
entry
,
&
dynamic_unwind_list
,
struct
dynamic_unwind_entry
,
entry
)
{
if
(
entry
->
table
==
table
)
{
to_free
=
entry
;
list_remove
(
&
entry
->
entry
);
break
;
}
}
RtlLeaveCriticalSection
(
&
dynamic_unwind_section
);
if
(
!
to_free
)
return
FALSE
;
RtlFreeHeap
(
GetProcessHeap
(),
0
,
to_free
);
return
TRUE
;
}
/* helper for lookup_function_info() */
static
RUNTIME_FUNCTION
*
find_function_info
(
ULONG_PTR
pc
,
ULONG_PTR
base
,
RUNTIME_FUNCTION
*
func
,
ULONG
size
)
{
int
min
=
0
;
int
max
=
size
-
1
;
while
(
min
<=
max
)
{
#ifdef __x86_64__
int
pos
=
(
min
+
max
)
/
2
;
if
(
pc
<
base
+
func
[
pos
].
BeginAddress
)
max
=
pos
-
1
;
else
if
(
pc
>=
base
+
func
[
pos
].
EndAddress
)
min
=
pos
+
1
;
else
{
func
+=
pos
;
while
(
func
->
UnwindData
&
1
)
/* follow chained entry */
func
=
(
RUNTIME_FUNCTION
*
)(
base
+
(
func
->
UnwindData
&
~
1
));
return
func
;
}
#elif defined(__arm__)
int
pos
=
(
min
+
max
)
/
2
;
if
(
pc
<
base
+
(
func
[
pos
].
BeginAddress
&
~
1
))
max
=
pos
-
1
;
else
if
(
pc
>=
base
+
get_runtime_function_end
(
&
func
[
pos
],
base
))
min
=
pos
+
1
;
else
return
func
+
pos
;
#else
/* __aarch64__ */
int
pos
=
(
min
+
max
)
/
2
;
if
(
pc
<
base
+
func
[
pos
].
BeginAddress
)
max
=
pos
-
1
;
else
if
(
pc
>=
base
+
get_runtime_function_end
(
&
func
[
pos
],
base
))
min
=
pos
+
1
;
else
return
func
+
pos
;
#endif
}
return
NULL
;
}
/**********************************************************************
* lookup_function_info
*/
RUNTIME_FUNCTION
*
lookup_function_info
(
ULONG_PTR
pc
,
ULONG_PTR
*
base
,
LDR_MODULE
**
module
)
{
RUNTIME_FUNCTION
*
func
=
NULL
;
struct
dynamic_unwind_entry
*
entry
;
ULONG
size
;
/* PE module or wine module */
if
(
!
LdrFindEntryForAddress
(
(
void
*
)
pc
,
module
))
{
*
base
=
(
ULONG_PTR
)(
*
module
)
->
BaseAddress
;
if
((
func
=
RtlImageDirectoryEntryToData
(
(
*
module
)
->
BaseAddress
,
TRUE
,
IMAGE_DIRECTORY_ENTRY_EXCEPTION
,
&
size
)))
{
/* lookup in function table */
func
=
find_function_info
(
pc
,
(
ULONG_PTR
)(
*
module
)
->
BaseAddress
,
func
,
size
/
sizeof
(
*
func
)
);
}
}
else
{
*
module
=
NULL
;
RtlEnterCriticalSection
(
&
dynamic_unwind_section
);
LIST_FOR_EACH_ENTRY
(
entry
,
&
dynamic_unwind_list
,
struct
dynamic_unwind_entry
,
entry
)
{
if
(
pc
>=
entry
->
base
&&
pc
<
entry
->
end
)
{
*
base
=
entry
->
base
;
/* use callback or lookup in function table */
if
(
entry
->
callback
)
func
=
entry
->
callback
(
pc
,
entry
->
context
);
else
func
=
find_function_info
(
pc
,
entry
->
base
,
entry
->
table
,
entry
->
count
);
break
;
}
}
RtlLeaveCriticalSection
(
&
dynamic_unwind_section
);
}
return
func
;
}
/**********************************************************************
* RtlLookupFunctionEntry (NTDLL.@)
*/
PRUNTIME_FUNCTION
WINAPI
RtlLookupFunctionEntry
(
ULONG_PTR
pc
,
ULONG_PTR
*
base
,
UNWIND_HISTORY_TABLE
*
table
)
{
LDR_MODULE
*
module
;
RUNTIME_FUNCTION
*
func
;
/* FIXME: should use the history table to make things faster */
if
(
!
(
func
=
lookup_function_info
(
pc
,
base
,
&
module
)))
{
*
base
=
0
;
WARN
(
"no exception table found for %lx
\n
"
,
pc
);
}
return
func
;
}
#endif
/* __x86_64__ || __arm__ || __aarch64__ */
/*************************************************************
* __wine_spec_unimplemented_stub
*
...
...
dlls/ntdll/ntdll.spec
View file @
14e34bed
...
...
@@ -805,7 +805,7 @@
@ stdcall RtlLookupAtomInAtomTable(ptr wstr ptr)
@ stub RtlLookupElementGenericTable
# @ stub RtlLookupElementGenericTableAvl
@ stdcall -arch=arm,x86_64 RtlLookupFunctionEntry(long ptr ptr)
@ stdcall -arch=arm,
arm64,
x86_64 RtlLookupFunctionEntry(long ptr ptr)
@ stdcall RtlMakeSelfRelativeSD(ptr ptr ptr)
@ stdcall RtlMapGenericMask(ptr ptr)
# @ stub RtlMapSecurityErrorToNtStatus
...
...
dlls/ntdll/ntdll_misc.h
View file @
14e34bed
...
...
@@ -60,6 +60,10 @@ extern NTSTATUS set_thread_context( HANDLE handle, const context_t *context, BOO
extern
NTSTATUS
get_thread_context
(
HANDLE
handle
,
context_t
*
context
,
unsigned
int
flags
,
BOOL
*
self
)
DECLSPEC_HIDDEN
;
extern
LONG
WINAPI
call_unhandled_exception_filter
(
PEXCEPTION_POINTERS
eptr
)
DECLSPEC_HIDDEN
;
#if defined(__x86_64__) || defined(__arm__) || defined(__aarch64__)
extern
RUNTIME_FUNCTION
*
lookup_function_info
(
ULONG_PTR
pc
,
ULONG_PTR
*
base
,
LDR_MODULE
**
module
)
DECLSPEC_HIDDEN
;
#endif
/* debug helpers */
extern
LPCSTR
debugstr_us
(
const
UNICODE_STRING
*
str
)
DECLSPEC_HIDDEN
;
extern
LPCSTR
debugstr_ObjectAttributes
(
const
OBJECT_ATTRIBUTES
*
oa
)
DECLSPEC_HIDDEN
;
...
...
dlls/ntdll/signal_arm.c
View file @
14e34bed
...
...
@@ -128,15 +128,6 @@ 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
;
};
/***********************************************************************
* get_trap_code
*
...
...
@@ -1064,118 +1055,6 @@ void signal_init_process(void)
}
/**********************************************************************
* RtlAddFunctionTable (NTDLL.@)
*/
BOOLEAN
CDECL
RtlAddFunctionTable
(
RUNTIME_FUNCTION
*
table
,
DWORD
count
,
DWORD
addr
)
{
FIXME
(
"%p %u %x: stub
\n
"
,
table
,
count
,
addr
);
return
TRUE
;
}
/**********************************************************************
* RtlInstallFunctionTableCallback (NTDLL.@)
*/
BOOLEAN
CDECL
RtlInstallFunctionTableCallback
(
DWORD
table
,
DWORD
base
,
DWORD
length
,
PGET_RUNTIME_FUNCTION_CALLBACK
callback
,
PVOID
context
,
PCWSTR
dll
)
{
FIXME
(
"%x %x %d %p %p %s: stub
\n
"
,
table
,
base
,
length
,
callback
,
context
,
wine_dbgstr_w
(
dll
)
);
return
TRUE
;
}
/*************************************************************************
* RtlAddGrowableFunctionTable (NTDLL.@)
*/
DWORD
WINAPI
RtlAddGrowableFunctionTable
(
void
**
table
,
RUNTIME_FUNCTION
*
functions
,
DWORD
count
,
DWORD
max_count
,
ULONG_PTR
base
,
ULONG_PTR
end
)
{
FIXME
(
"(%p, %p, %d, %d, %ld, %ld) stub!
\n
"
,
table
,
functions
,
count
,
max_count
,
base
,
end
);
if
(
table
)
*
table
=
NULL
;
return
STATUS_SUCCESS
;
}
/*************************************************************************
* RtlGrowFunctionTable (NTDLL.@)
*/
void
WINAPI
RtlGrowFunctionTable
(
void
*
table
,
DWORD
count
)
{
FIXME
(
"(%p, %d) stub!
\n
"
,
table
,
count
);
}
/*************************************************************************
* RtlDeleteGrowableFunctionTable (NTDLL.@)
*/
void
WINAPI
RtlDeleteGrowableFunctionTable
(
void
*
table
)
{
FIXME
(
"(%p) stub!
\n
"
,
table
);
}
/**********************************************************************
* RtlDeleteFunctionTable (NTDLL.@)
*/
BOOLEAN
CDECL
RtlDeleteFunctionTable
(
RUNTIME_FUNCTION
*
table
)
{
FIXME
(
"%p: stub
\n
"
,
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.@)
*/
...
...
dlls/ntdll/signal_arm64.c
View file @
14e34bed
...
...
@@ -971,63 +971,6 @@ void signal_init_process(void)
}
/**********************************************************************
* RtlAddFunctionTable (NTDLL.@)
*/
BOOLEAN
CDECL
RtlAddFunctionTable
(
RUNTIME_FUNCTION
*
table
,
DWORD
count
,
ULONG_PTR
addr
)
{
FIXME
(
"%p %u %lx: stub
\n
"
,
table
,
count
,
addr
);
return
TRUE
;
}
/**********************************************************************
* RtlInstallFunctionTableCallback (NTDLL.@)
*/
BOOLEAN
CDECL
RtlInstallFunctionTableCallback
(
ULONG_PTR
table
,
ULONG_PTR
base
,
DWORD
length
,
PGET_RUNTIME_FUNCTION_CALLBACK
callback
,
PVOID
context
,
PCWSTR
dll
)
{
FIXME
(
"%lx %lx %d %p %p %s: stub
\n
"
,
table
,
base
,
length
,
callback
,
context
,
wine_dbgstr_w
(
dll
)
);
return
TRUE
;
}
/*************************************************************************
* RtlAddGrowableFunctionTable (NTDLL.@)
*/
DWORD
WINAPI
RtlAddGrowableFunctionTable
(
void
**
table
,
RUNTIME_FUNCTION
*
functions
,
DWORD
count
,
DWORD
max_count
,
ULONG_PTR
base
,
ULONG_PTR
end
)
{
FIXME
(
"(%p, %p, %d, %d, %ld, %ld) stub!
\n
"
,
table
,
functions
,
count
,
max_count
,
base
,
end
);
if
(
table
)
*
table
=
NULL
;
return
STATUS_SUCCESS
;
}
/*************************************************************************
* RtlGrowFunctionTable (NTDLL.@)
*/
void
WINAPI
RtlGrowFunctionTable
(
void
*
table
,
DWORD
count
)
{
FIXME
(
"(%p, %d) stub!
\n
"
,
table
,
count
);
}
/*************************************************************************
* RtlDeleteGrowableFunctionTable (NTDLL.@)
*/
void
WINAPI
RtlDeleteGrowableFunctionTable
(
void
*
table
)
{
FIXME
(
"(%p) stub!
\n
"
,
table
);
}
/**********************************************************************
* RtlDeleteFunctionTable (NTDLL.@)
*/
BOOLEAN
CDECL
RtlDeleteFunctionTable
(
RUNTIME_FUNCTION
*
table
)
{
FIXME
(
"%p: stub
\n
"
,
table
);
return
TRUE
;
}
/***********************************************************************
* RtlUnwind (NTDLL.@)
*/
...
...
dlls/ntdll/signal_x86_64.c
View file @
14e34bed
...
...
@@ -306,39 +306,6 @@ static inline struct amd64_thread_data *amd64_thread_data(void)
}
/***********************************************************************
* Dynamic unwind table
*/
struct
dynamic_unwind_entry
{
struct
list
entry
;
/* memory region which matches this entry */
DWORD64
base
;
DWORD64
end
;
/* lookup table */
RUNTIME_FUNCTION
*
table
;
DWORD
count
;
DWORD
max_count
;
/* user defined callback */
PGET_RUNTIME_FUNCTION_CALLBACK
callback
;
PVOID
context
;
};
static
struct
list
dynamic_unwind_list
=
LIST_INIT
(
dynamic_unwind_list
);
static
RTL_CRITICAL_SECTION
dynamic_unwind_section
;
static
RTL_CRITICAL_SECTION_DEBUG
dynamic_unwind_debug
=
{
0
,
0
,
&
dynamic_unwind_section
,
{
&
dynamic_unwind_debug
.
ProcessLocksList
,
&
dynamic_unwind_debug
.
ProcessLocksList
},
0
,
0
,
{
(
DWORD_PTR
)(
__FILE__
": dynamic_unwind_section"
)
}
};
static
RTL_CRITICAL_SECTION
dynamic_unwind_section
=
{
&
dynamic_unwind_debug
,
-
1
,
0
,
0
,
0
,
0
};
/***********************************************************************
* Definitions for Win32 unwind tables
*/
...
...
@@ -2501,76 +2468,6 @@ static inline CONTEXT *get_exception_context( EXCEPTION_RECORD *rec )
}
/**********************************************************************
* find_function_info
*/
static
RUNTIME_FUNCTION
*
find_function_info
(
ULONG64
pc
,
HMODULE
module
,
RUNTIME_FUNCTION
*
func
,
ULONG
size
)
{
int
min
=
0
;
int
max
=
size
-
1
;
while
(
min
<=
max
)
{
int
pos
=
(
min
+
max
)
/
2
;
if
((
char
*
)
pc
<
(
char
*
)
module
+
func
[
pos
].
BeginAddress
)
max
=
pos
-
1
;
else
if
((
char
*
)
pc
>=
(
char
*
)
module
+
func
[
pos
].
EndAddress
)
min
=
pos
+
1
;
else
{
func
+=
pos
;
while
(
func
->
UnwindData
&
1
)
/* follow chained entry */
func
=
(
RUNTIME_FUNCTION
*
)((
char
*
)
module
+
(
func
->
UnwindData
&
~
1
));
return
func
;
}
}
return
NULL
;
}
/**********************************************************************
* lookup_function_info
*/
static
RUNTIME_FUNCTION
*
lookup_function_info
(
ULONG64
pc
,
ULONG64
*
base
,
LDR_MODULE
**
module
)
{
RUNTIME_FUNCTION
*
func
=
NULL
;
struct
dynamic_unwind_entry
*
entry
;
ULONG
size
;
/* PE module or wine module */
if
(
!
LdrFindEntryForAddress
(
(
void
*
)
pc
,
module
))
{
*
base
=
(
ULONG64
)(
*
module
)
->
BaseAddress
;
if
((
func
=
RtlImageDirectoryEntryToData
(
(
*
module
)
->
BaseAddress
,
TRUE
,
IMAGE_DIRECTORY_ENTRY_EXCEPTION
,
&
size
)))
{
/* lookup in function table */
func
=
find_function_info
(
pc
,
(
*
module
)
->
BaseAddress
,
func
,
size
/
sizeof
(
*
func
)
);
}
}
else
{
*
module
=
NULL
;
RtlEnterCriticalSection
(
&
dynamic_unwind_section
);
LIST_FOR_EACH_ENTRY
(
entry
,
&
dynamic_unwind_list
,
struct
dynamic_unwind_entry
,
entry
)
{
if
(
pc
>=
entry
->
base
&&
pc
<
entry
->
end
)
{
*
base
=
entry
->
base
;
/* use callback or lookup in function table */
if
(
entry
->
callback
)
func
=
entry
->
callback
(
pc
,
entry
->
context
);
else
func
=
find_function_info
(
pc
,
(
HMODULE
)
entry
->
base
,
entry
->
table
,
entry
->
count
);
break
;
}
}
RtlLeaveCriticalSection
(
&
dynamic_unwind_section
);
}
return
func
;
}
static
DWORD
__cdecl
nested_exception_handler
(
EXCEPTION_RECORD
*
rec
,
EXCEPTION_REGISTRATION_RECORD
*
frame
,
CONTEXT
*
context
,
EXCEPTION_REGISTRATION_RECORD
**
dispatcher
)
{
...
...
@@ -3436,205 +3333,6 @@ void signal_init_process(void)
}
/**********************************************************************
* RtlAddFunctionTable (NTDLL.@)
*/
BOOLEAN
CDECL
RtlAddFunctionTable
(
RUNTIME_FUNCTION
*
table
,
DWORD
count
,
DWORD64
addr
)
{
struct
dynamic_unwind_entry
*
entry
;
TRACE
(
"%p %u %lx
\n
"
,
table
,
count
,
addr
);
/* NOTE: Windows doesn't check if table is aligned or a NULL pointer */
entry
=
RtlAllocateHeap
(
GetProcessHeap
(),
0
,
sizeof
(
*
entry
)
);
if
(
!
entry
)
return
FALSE
;
entry
->
base
=
addr
;
entry
->
end
=
addr
+
(
count
?
table
[
count
-
1
].
EndAddress
:
0
);
entry
->
table
=
table
;
entry
->
count
=
count
;
entry
->
max_count
=
0
;
entry
->
callback
=
NULL
;
entry
->
context
=
NULL
;
RtlEnterCriticalSection
(
&
dynamic_unwind_section
);
list_add_tail
(
&
dynamic_unwind_list
,
&
entry
->
entry
);
RtlLeaveCriticalSection
(
&
dynamic_unwind_section
);
return
TRUE
;
}
/**********************************************************************
* RtlInstallFunctionTableCallback (NTDLL.@)
*/
BOOLEAN
CDECL
RtlInstallFunctionTableCallback
(
DWORD64
table
,
DWORD64
base
,
DWORD
length
,
PGET_RUNTIME_FUNCTION_CALLBACK
callback
,
PVOID
context
,
PCWSTR
dll
)
{
struct
dynamic_unwind_entry
*
entry
;
TRACE
(
"%lx %lx %d %p %p %s
\n
"
,
table
,
base
,
length
,
callback
,
context
,
wine_dbgstr_w
(
dll
)
);
/* NOTE: Windows doesn't check if the provided callback is a NULL pointer */
/* both low-order bits must be set */
if
((
table
&
0x3
)
!=
0x3
)
return
FALSE
;
entry
=
RtlAllocateHeap
(
GetProcessHeap
(),
0
,
sizeof
(
*
entry
)
);
if
(
!
entry
)
return
FALSE
;
entry
->
base
=
base
;
entry
->
end
=
base
+
length
;
entry
->
table
=
(
RUNTIME_FUNCTION
*
)
table
;
entry
->
count
=
0
;
entry
->
max_count
=
0
;
entry
->
callback
=
callback
;
entry
->
context
=
context
;
RtlEnterCriticalSection
(
&
dynamic_unwind_section
);
list_add_tail
(
&
dynamic_unwind_list
,
&
entry
->
entry
);
RtlLeaveCriticalSection
(
&
dynamic_unwind_section
);
return
TRUE
;
}
/*************************************************************************
* RtlAddGrowableFunctionTable (NTDLL.@)
*/
DWORD
WINAPI
RtlAddGrowableFunctionTable
(
void
**
table
,
RUNTIME_FUNCTION
*
functions
,
DWORD
count
,
DWORD
max_count
,
ULONG_PTR
base
,
ULONG_PTR
end
)
{
struct
dynamic_unwind_entry
*
entry
;
TRACE
(
"%p, %p, %u, %u, %lx, %lx
\n
"
,
table
,
functions
,
count
,
max_count
,
base
,
end
);
entry
=
RtlAllocateHeap
(
GetProcessHeap
(),
0
,
sizeof
(
*
entry
)
);
if
(
!
entry
)
return
STATUS_NO_MEMORY
;
entry
->
base
=
base
;
entry
->
end
=
end
;
entry
->
table
=
functions
;
entry
->
count
=
count
;
entry
->
max_count
=
max_count
;
entry
->
callback
=
NULL
;
entry
->
context
=
NULL
;
RtlEnterCriticalSection
(
&
dynamic_unwind_section
);
list_add_tail
(
&
dynamic_unwind_list
,
&
entry
->
entry
);
RtlLeaveCriticalSection
(
&
dynamic_unwind_section
);
*
table
=
entry
;
return
STATUS_SUCCESS
;
}
/*************************************************************************
* RtlGrowFunctionTable (NTDLL.@)
*/
void
WINAPI
RtlGrowFunctionTable
(
void
*
table
,
DWORD
count
)
{
struct
dynamic_unwind_entry
*
entry
;
TRACE
(
"%p, %u
\n
"
,
table
,
count
);
RtlEnterCriticalSection
(
&
dynamic_unwind_section
);
LIST_FOR_EACH_ENTRY
(
entry
,
&
dynamic_unwind_list
,
struct
dynamic_unwind_entry
,
entry
)
{
if
(
entry
==
table
)
{
if
(
count
>
entry
->
count
&&
count
<=
entry
->
max_count
)
entry
->
count
=
count
;
break
;
}
}
RtlLeaveCriticalSection
(
&
dynamic_unwind_section
);
}
/*************************************************************************
* RtlDeleteGrowableFunctionTable (NTDLL.@)
*/
void
WINAPI
RtlDeleteGrowableFunctionTable
(
void
*
table
)
{
struct
dynamic_unwind_entry
*
entry
,
*
to_free
=
NULL
;
TRACE
(
"%p
\n
"
,
table
);
RtlEnterCriticalSection
(
&
dynamic_unwind_section
);
LIST_FOR_EACH_ENTRY
(
entry
,
&
dynamic_unwind_list
,
struct
dynamic_unwind_entry
,
entry
)
{
if
(
entry
==
table
)
{
to_free
=
entry
;
list_remove
(
&
entry
->
entry
);
break
;
}
}
RtlLeaveCriticalSection
(
&
dynamic_unwind_section
);
RtlFreeHeap
(
GetProcessHeap
(),
0
,
to_free
);
}
/**********************************************************************
* RtlDeleteFunctionTable (NTDLL.@)
*/
BOOLEAN
CDECL
RtlDeleteFunctionTable
(
RUNTIME_FUNCTION
*
table
)
{
struct
dynamic_unwind_entry
*
entry
,
*
to_free
=
NULL
;
TRACE
(
"%p
\n
"
,
table
);
RtlEnterCriticalSection
(
&
dynamic_unwind_section
);
LIST_FOR_EACH_ENTRY
(
entry
,
&
dynamic_unwind_list
,
struct
dynamic_unwind_entry
,
entry
)
{
if
(
entry
->
table
==
table
)
{
to_free
=
entry
;
list_remove
(
&
entry
->
entry
);
break
;
}
}
RtlLeaveCriticalSection
(
&
dynamic_unwind_section
);
if
(
!
to_free
)
return
FALSE
;
RtlFreeHeap
(
GetProcessHeap
(),
0
,
to_free
);
return
TRUE
;
}
/**********************************************************************
* RtlLookupFunctionEntry (NTDLL.@)
*/
PRUNTIME_FUNCTION
WINAPI
RtlLookupFunctionEntry
(
ULONG64
pc
,
ULONG64
*
base
,
UNWIND_HISTORY_TABLE
*
table
)
{
LDR_MODULE
*
module
;
RUNTIME_FUNCTION
*
func
;
/* FIXME: should use the history table to make things faster */
func
=
lookup_function_info
(
pc
,
base
,
&
module
);
if
(
!
func
)
{
*
base
=
0
;
if
(
module
)
WARN
(
"no exception table found in module %p pc %lx
\n
"
,
module
->
BaseAddress
,
pc
);
else
WARN
(
"module not found for %lx
\n
"
,
pc
);
}
return
func
;
}
static
ULONG64
get_int_reg
(
CONTEXT
*
context
,
int
reg
)
{
return
*
(
&
context
->
Rax
+
reg
);
...
...
include/winnt.h
View file @
14e34bed
...
...
@@ -1248,13 +1248,7 @@ typedef struct _DISPATCHER_CONTEXT
typedef
LONG
(
CALLBACK
*
PEXCEPTION_FILTER
)(
struct
_EXCEPTION_POINTERS
*
,
PVOID
);
typedef
void
(
CALLBACK
*
PTERMINATION_HANDLER
)(
BOOLEAN
,
PVOID
);
typedef
PRUNTIME_FUNCTION
(
CALLBACK
*
PGET_RUNTIME_FUNCTION_CALLBACK
)(
DWORD64
,
PVOID
);
BOOLEAN
CDECL
RtlAddFunctionTable
(
RUNTIME_FUNCTION
*
,
DWORD
,
DWORD64
);
BOOLEAN
CDECL
RtlDeleteFunctionTable
(
RUNTIME_FUNCTION
*
);
BOOLEAN
CDECL
RtlInstallFunctionTableCallback
(
DWORD64
,
DWORD64
,
DWORD
,
PGET_RUNTIME_FUNCTION_CALLBACK
,
PVOID
,
PCWSTR
);
PRUNTIME_FUNCTION
WINAPI
RtlLookupFunctionEntry
(
DWORD64
,
DWORD64
*
,
UNWIND_HISTORY_TABLE
*
);
PVOID
WINAPI
RtlVirtualUnwind
(
ULONG
,
ULONG64
,
ULONG64
,
RUNTIME_FUNCTION
*
,
CONTEXT
*
,
PVOID
*
,
ULONG64
*
,
KNONVOLATILE_CONTEXT_POINTERS
*
);
PVOID
WINAPI
RtlVirtualUnwind
(
ULONG
,
ULONG64
,
ULONG64
,
RUNTIME_FUNCTION
*
,
CONTEXT
*
,
PVOID
*
,
ULONG64
*
,
KNONVOLATILE_CONTEXT_POINTERS
*
);
#define UNW_FLAG_NHANDLER 0
#define UNW_FLAG_EHANDLER 1
...
...
@@ -1821,12 +1815,11 @@ typedef struct _DISPATCHER_CONTEXT
typedef
LONG
(
CALLBACK
*
PEXCEPTION_FILTER
)(
struct
_EXCEPTION_POINTERS
*
,
DWORD
);
typedef
void
(
CALLBACK
*
PTERMINATION_HANDLER
)(
BOOLEAN
,
DWORD
);
typedef
PRUNTIME_FUNCTION
(
CALLBACK
*
PGET_RUNTIME_FUNCTION_CALLBACK
)(
DWORD
,
PVOID
);
PVOID
WINAPI
RtlVirtualUnwind
(
DWORD
,
DWORD
,
DWORD
,
RUNTIME_FUNCTION
*
,
CONTEXT
*
,
PVOID
*
,
DWORD
*
,
KNONVOLATILE_CONTEXT_POINTERS
*
);
BOOLEAN
CDECL
RtlAddFunctionTable
(
RUNTIME_FUNCTION
*
,
DWORD
,
DWORD
);
BOOLEAN
CDECL
RtlDeleteFunctionTable
(
RUNTIME_FUNCTION
*
);
BOOLEAN
CDECL
RtlInstallFunctionTableCallback
(
DWORD
,
DWORD
,
DWORD
,
PGET_RUNTIME_FUNCTION_CALLBACK
,
PVOID
,
PCWSTR
);
PRUNTIME_FUNCTION
WINAPI
RtlLookupFunctionEntry
(
ULONG_PTR
,
DWORD
*
,
UNWIND_HISTORY_TABLE
*
);
#define UNW_FLAG_NHANDLER 0
#define UNW_FLAG_EHANDLER 1
#define UNW_FLAG_UHANDLER 2
#endif
/* __arm__ */
...
...
@@ -2000,11 +1993,11 @@ typedef struct _DISPATCHER_CONTEXT
typedef
LONG
(
CALLBACK
*
PEXCEPTION_FILTER
)(
struct
_EXCEPTION_POINTERS
*
,
DWORD64
);
typedef
void
(
CALLBACK
*
PTERMINATION_HANDLER
)(
BOOLEAN
,
DWORD64
);
typedef
PRUNTIME_FUNCTION
(
CALLBACK
*
PGET_RUNTIME_FUNCTION_CALLBACK
)(
DWORD64
,
PVOID
);
PVOID
WINAPI
RtlVirtualUnwind
(
DWORD
,
ULONG_PTR
,
ULONG_PTR
,
RUNTIME_FUNCTION
*
,
CONTEXT
*
,
PVOID
*
,
ULONG_PTR
*
,
KNONVOLATILE_CONTEXT_POINTERS
*
);
BOOLEAN
CDECL
RtlAddFunctionTable
(
RUNTIME_FUNCTION
*
,
DWORD
,
ULONG_PTR
);
BOOLEAN
CDECL
RtlDeleteFunctionTable
(
RUNTIME_FUNCTION
*
);
BOOLEAN
CDECL
RtlInstallFunctionTableCallback
(
ULONG_PTR
,
ULONG_PTR
,
DWORD
,
PGET_RUNTIME_FUNCTION_CALLBACK
,
PVOID
,
PCWSTR
);
#define UNW_FLAG_NHANDLER 0
#define UNW_FLAG_EHANDLER 1
#define UNW_FLAG_UHANDLER 2
#endif
/* __aarch64__ */
...
...
@@ -2315,6 +2308,19 @@ typedef struct _WOW64_CONTEXT
}
WOW64_CONTEXT
,
*
PWOW64_CONTEXT
;
#include "poppack.h"
#if defined(__x86_64__) || defined(__arm__) || defined(__aarch64__)
typedef
PRUNTIME_FUNCTION
(
CALLBACK
*
PGET_RUNTIME_FUNCTION_CALLBACK
)(
DWORD_PTR
,
PVOID
);
BOOLEAN
CDECL
RtlAddFunctionTable
(
RUNTIME_FUNCTION
*
,
DWORD
,
DWORD_PTR
);
DWORD
WINAPI
RtlAddGrowableFunctionTable
(
void
**
,
PRUNTIME_FUNCTION
,
DWORD
,
DWORD
,
ULONG_PTR
,
ULONG_PTR
);
BOOLEAN
CDECL
RtlDeleteFunctionTable
(
RUNTIME_FUNCTION
*
);
void
WINAPI
RtlDeleteGrowableFunctionTable
(
void
*
);
void
WINAPI
RtlGrowFunctionTable
(
void
*
,
DWORD
);
BOOLEAN
CDECL
RtlInstallFunctionTableCallback
(
DWORD_PTR
,
DWORD_PTR
,
DWORD
,
PGET_RUNTIME_FUNCTION_CALLBACK
,
PVOID
,
PCWSTR
);
PRUNTIME_FUNCTION
WINAPI
RtlLookupFunctionEntry
(
DWORD_PTR
,
DWORD_PTR
*
,
UNWIND_HISTORY_TABLE
*
);
void
WINAPI
RtlUnwindEx
(
PVOID
,
PVOID
,
struct
_EXCEPTION_RECORD
*
,
PVOID
,
CONTEXT
*
,
UNWIND_HISTORY_TABLE
*
);
#endif
/*
* Product types
...
...
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