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
c1dc5021
Commit
c1dc5021
authored
Jun 17, 2020
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ntdll: Dynamically load callback functions from the Unix library.
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
0b48050d
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
74 additions
and
53 deletions
+74
-53
loader.c
dlls/ntdll/unix/loader.c
+59
-41
server.c
dlls/ntdll/unix/server.c
+1
-1
signal_arm.c
dlls/ntdll/unix/signal_arm.c
+1
-1
signal_arm64.c
dlls/ntdll/unix/signal_arm64.c
+2
-2
signal_i386.c
dlls/ntdll/unix/signal_i386.c
+2
-2
signal_x86_64.c
dlls/ntdll/unix/signal_x86_64.c
+2
-2
thread.c
dlls/ntdll/unix/thread.c
+2
-2
unix_private.h
dlls/ntdll/unix/unix_private.h
+5
-2
No files found.
dlls/ntdll/unix/loader.c
View file @
c1dc5021
...
...
@@ -77,7 +77,13 @@
WINE_DEFAULT_DEBUG_CHANNEL
(
ntdll
);
extern
IMAGE_NT_HEADERS
__wine_spec_nt_header
;
extern
void
CDECL
__wine_set_unix_funcs
(
int
version
,
const
struct
unix_funcs
*
funcs
);
void
(
WINAPI
*
pDbgUiRemoteBreakin
)(
void
*
arg
)
=
NULL
;
NTSTATUS
(
WINAPI
*
pKiUserExceptionDispatcher
)(
EXCEPTION_RECORD
*
,
CONTEXT
*
)
=
NULL
;
void
(
WINAPI
*
pLdrInitializeThunk
)(
CONTEXT
*
,
void
**
,
ULONG_PTR
,
ULONG_PTR
)
=
NULL
;
void
(
WINAPI
*
pRtlUserThreadStart
)(
PRTL_THREAD_START_ROUTINE
entry
,
void
*
arg
)
=
NULL
;
static
void
(
CDECL
*
p__wine_set_unix_funcs
)(
int
version
,
const
struct
unix_funcs
*
funcs
);
#ifdef __GNUC__
static
void
fatal_error
(
const
char
*
err
,
...
)
__attribute__
((
noreturn
,
format
(
printf
,
1
,
2
)));
...
...
@@ -713,33 +719,38 @@ static ULONG_PTR find_ordinal_export( HMODULE module, const IMAGE_EXPORT_DIRECTO
}
static
ULONG_PTR
find_named_export
(
HMODULE
module
,
const
IMAGE_EXPORT_DIRECTORY
*
exports
,
const
IMAGE_IMPORT_BY_NAME
*
name
)
const
char
*
name
)
{
const
WORD
*
ordinals
=
(
const
WORD
*
)((
BYTE
*
)
module
+
exports
->
AddressOfNameOrdinals
);
const
DWORD
*
names
=
(
const
DWORD
*
)((
BYTE
*
)
module
+
exports
->
AddressOfNames
);
int
min
=
0
,
max
=
exports
->
NumberOfNames
-
1
;
/* first check the hint */
if
(
name
->
Hint
<=
max
)
{
char
*
ename
=
(
char
*
)
module
+
names
[
name
->
Hint
];
if
(
!
strcmp
(
ename
,
(
char
*
)
name
->
Name
))
return
find_ordinal_export
(
module
,
exports
,
ordinals
[
name
->
Hint
]
);
}
/* then do a binary search */
while
(
min
<=
max
)
{
int
res
,
pos
=
(
min
+
max
)
/
2
;
char
*
ename
=
(
char
*
)
module
+
names
[
pos
];
if
(
!
(
res
=
strcmp
(
ename
,
(
char
*
)
name
->
Name
)))
return
find_ordinal_export
(
module
,
exports
,
ordinals
[
pos
]
);
if
(
!
(
res
=
strcmp
(
ename
,
name
)))
return
find_ordinal_export
(
module
,
exports
,
ordinals
[
pos
]
);
if
(
res
>
0
)
max
=
pos
-
1
;
else
min
=
pos
+
1
;
}
return
0
;
}
static
ULONG_PTR
find_pe_export
(
HMODULE
module
,
const
IMAGE_EXPORT_DIRECTORY
*
exports
,
const
IMAGE_IMPORT_BY_NAME
*
name
)
{
const
WORD
*
ordinals
=
(
const
WORD
*
)((
BYTE
*
)
module
+
exports
->
AddressOfNameOrdinals
);
const
DWORD
*
names
=
(
const
DWORD
*
)((
BYTE
*
)
module
+
exports
->
AddressOfNames
);
if
(
name
->
Hint
<
exports
->
NumberOfNames
)
{
char
*
ename
=
(
char
*
)
module
+
names
[
name
->
Hint
];
if
(
!
strcmp
(
ename
,
(
char
*
)
name
->
Name
))
return
find_ordinal_export
(
module
,
exports
,
ordinals
[
name
->
Hint
]
);
}
return
find_named_export
(
module
,
exports
,
(
char
*
)
name
->
Name
);
}
static
void
fixup_ntdll_imports
(
const
IMAGE_NT_HEADERS
*
nt
,
HMODULE
ntdll_module
)
{
const
IMAGE_EXPORT_DIRECTORY
*
ntdll_exports
=
get_export_dir
(
ntdll_module
);
...
...
@@ -750,38 +761,45 @@ static void fixup_ntdll_imports( const IMAGE_NT_HEADERS *nt, HMODULE ntdll_modul
assert
(
ntdll_exports
);
descr
=
get_rva
(
nt
,
nt
->
OptionalHeader
.
DataDirectory
[
IMAGE_FILE_IMPORT_DIRECTORY
].
VirtualAddress
);
while
(
descr
->
Name
)
{
/* ntdll must be the only import */
assert
(
!
strcmp
(
get_rva
(
nt
,
descr
->
Name
),
"ntdll.dll"
));
thunk_list
=
get_rva
(
nt
,
(
DWORD
)
descr
->
FirstThunk
);
if
(
descr
->
u
.
OriginalFirstThunk
)
import_list
=
get_rva
(
nt
,
(
DWORD
)
descr
->
u
.
OriginalFirstThunk
);
else
import_list
=
thunk_list
;
/* ntdll must be the only import */
assert
(
!
strcmp
(
get_rva
(
nt
,
descr
->
Name
),
"ntdll.dll"
));
assert
(
!
descr
[
1
].
Name
);
thunk_list
=
get_rva
(
nt
,
(
DWORD
)
descr
->
FirstThunk
);
if
(
descr
->
u
.
OriginalFirstThunk
)
import_list
=
get_rva
(
nt
,
(
DWORD
)
descr
->
u
.
OriginalFirstThunk
);
else
import_list
=
thunk_list
;
while
(
import_list
->
u1
.
Ordinal
)
while
(
import_list
->
u1
.
Ordinal
)
{
if
(
IMAGE_SNAP_BY_ORDINAL
(
import_list
->
u1
.
Ordinal
))
{
if
(
IMAGE_SNAP_BY_ORDINAL
(
import_list
->
u1
.
Ordinal
))
{
int
ordinal
=
IMAGE_ORDINAL
(
import_list
->
u1
.
Ordinal
)
-
ntdll_exports
->
Base
;
thunk_list
->
u1
.
Function
=
find_ordinal_export
(
ntdll_module
,
ntdll_exports
,
ordinal
);
if
(
!
thunk_list
->
u1
.
Function
)
ERR
(
"ordinal %u not found
\n
"
,
ordinal
);
}
else
/* import by name */
{
IMAGE_IMPORT_BY_NAME
*
pe_name
=
get_rva
(
nt
,
import_list
->
u1
.
AddressOfData
);
thunk_list
->
u1
.
Function
=
find_named_export
(
ntdll_module
,
ntdll_exports
,
pe_name
);
if
(
!
thunk_list
->
u1
.
Function
)
ERR
(
"%s not found
\n
"
,
pe_name
->
Name
);
}
import_list
++
;
thunk_list
++
;
int
ordinal
=
IMAGE_ORDINAL
(
import_list
->
u1
.
Ordinal
)
-
ntdll_exports
->
Base
;
thunk_list
->
u1
.
Function
=
find_ordinal_export
(
ntdll_module
,
ntdll_exports
,
ordinal
);
if
(
!
thunk_list
->
u1
.
Function
)
ERR
(
"ordinal %u not found
\n
"
,
ordinal
);
}
descr
++
;
else
/* import by name */
{
IMAGE_IMPORT_BY_NAME
*
pe_name
=
get_rva
(
nt
,
import_list
->
u1
.
AddressOfData
);
thunk_list
->
u1
.
Function
=
find_pe_export
(
ntdll_module
,
ntdll_exports
,
pe_name
);
if
(
!
thunk_list
->
u1
.
Function
)
ERR
(
"%s not found
\n
"
,
pe_name
->
Name
);
}
import_list
++
;
thunk_list
++
;
}
#define GET_FUNC(name) \
if (!(p##name = (void *)find_named_export( ntdll_module, ntdll_exports, #name ))) \
ERR( "%s not found\n", #name )
GET_FUNC
(
DbgUiRemoteBreakin
);
GET_FUNC
(
KiUserExceptionDispatcher
);
GET_FUNC
(
LdrInitializeThunk
);
GET_FUNC
(
RtlUserThreadStart
);
GET_FUNC
(
__wine_set_unix_funcs
);
#undef GET_FUNC
}
/***********************************************************************
...
...
@@ -979,7 +997,7 @@ struct apple_stack_info
static
void
*
apple_wine_thread
(
void
*
arg
)
{
__wine_set_unix_funcs
(
NTDLL_UNIXLIB_VERSION
,
&
unix_funcs
);
p
__wine_set_unix_funcs
(
NTDLL_UNIXLIB_VERSION
,
&
unix_funcs
);
return
NULL
;
}
...
...
@@ -1234,7 +1252,7 @@ void __wine_main( int argc, char *argv[], char *envp[] )
#ifdef __APPLE__
apple_main_thread
();
#endif
__wine_set_unix_funcs
(
NTDLL_UNIXLIB_VERSION
,
&
unix_funcs
);
p
__wine_set_unix_funcs
(
NTDLL_UNIXLIB_VERSION
,
&
unix_funcs
);
}
...
...
dlls/ntdll/unix/server.c
View file @
c1dc5021
...
...
@@ -587,7 +587,7 @@ static void invoke_system_apc( const apc_call_t *call, apc_result_t *result )
result
->
type
=
APC_BREAK_PROCESS
;
result
->
break_process
.
status
=
NtCreateThreadEx
(
&
handle
,
THREAD_ALL_ACCESS
,
NULL
,
NtCurrentProcess
(),
DbgUiRemoteBreakin
,
NULL
,
NtCurrentProcess
(),
p
DbgUiRemoteBreakin
,
NULL
,
0
,
0
,
0
,
0
,
NULL
);
if
(
!
result
->
break_process
.
status
)
NtClose
(
handle
);
break
;
...
...
dlls/ntdll/unix/signal_arm.c
View file @
c1dc5021
...
...
@@ -906,7 +906,7 @@ PCONTEXT DECLSPEC_HIDDEN attach_thread( LPTHREAD_START_ROUTINE entry, void *arg,
}
pthread_sigmask
(
SIG_UNBLOCK
,
&
server_block_set
,
NULL
);
ctx
->
ContextFlags
=
CONTEXT_FULL
;
LdrInitializeThunk
(
ctx
,
(
void
**
)
&
ctx
->
R0
,
0
,
0
);
p
LdrInitializeThunk
(
ctx
,
(
void
**
)
&
ctx
->
R0
,
0
,
0
);
return
ctx
;
}
...
...
dlls/ntdll/unix/signal_arm64.c
View file @
c1dc5021
...
...
@@ -483,7 +483,7 @@ static void setup_raise_exception( ucontext_t *sigcontext, struct stack_layout *
PC_sig
(
sigcontext
)
=
(
ULONG_PTR
)
raise_func_trampoline
;
/* raise_generic_exception; */
REGn_sig
(
0
,
sigcontext
)
=
(
ULONG_PTR
)
&
stack
->
rec
;
/* first arg for raise_generic_exception */
REGn_sig
(
1
,
sigcontext
)
=
(
ULONG_PTR
)
&
stack
->
context
;
/* second arg for raise_generic_exception */
REGn_sig
(
2
,
sigcontext
)
=
(
ULONG_PTR
)
KiUserExceptionDispatcher
;
/* third arg for raise_func_trampoline */
REGn_sig
(
2
,
sigcontext
)
=
(
ULONG_PTR
)
p
KiUserExceptionDispatcher
;
/* third arg for raise_func_trampoline */
REGn_sig
(
18
,
sigcontext
)
=
(
ULONG_PTR
)
NtCurrentTeb
();
}
...
...
@@ -828,7 +828,7 @@ PCONTEXT DECLSPEC_HIDDEN attach_thread( LPTHREAD_START_ROUTINE entry, void *arg,
}
pthread_sigmask
(
SIG_UNBLOCK
,
&
server_block_set
,
NULL
);
ctx
->
ContextFlags
=
CONTEXT_FULL
;
LdrInitializeThunk
(
ctx
,
(
void
**
)
&
ctx
->
u
.
s
.
X0
,
0
,
0
);
p
LdrInitializeThunk
(
ctx
,
(
void
**
)
&
ctx
->
u
.
s
.
X0
,
0
,
0
);
return
ctx
;
}
...
...
dlls/ntdll/unix/signal_i386.c
View file @
c1dc5021
...
...
@@ -1565,7 +1565,7 @@ static void setup_raise_exception( ucontext_t *sigcontext, struct stack_layout *
return
;
}
ESP_sig
(
sigcontext
)
=
(
DWORD
)
stack
;
EIP_sig
(
sigcontext
)
=
(
DWORD
)
KiUserExceptionDispatcher
;
EIP_sig
(
sigcontext
)
=
(
DWORD
)
p
KiUserExceptionDispatcher
;
/* clear single-step, direction, and align check flag */
EFL_sig
(
sigcontext
)
&=
~
(
0x100
|
0x400
|
0x40000
);
CS_sig
(
sigcontext
)
=
get_cs
();
...
...
@@ -2290,7 +2290,7 @@ PCONTEXT DECLSPEC_HIDDEN attach_thread( LPTHREAD_START_ROUTINE entry, void *arg,
}
pthread_sigmask
(
SIG_UNBLOCK
,
&
server_block_set
,
NULL
);
ctx
->
ContextFlags
=
CONTEXT_FULL
|
CONTEXT_FLOATING_POINT
|
CONTEXT_EXTENDED_REGISTERS
;
LdrInitializeThunk
(
ctx
,
(
void
**
)
&
ctx
->
Eax
,
0
,
0
);
p
LdrInitializeThunk
(
ctx
,
(
void
**
)
&
ctx
->
Eax
,
0
,
0
);
return
ctx
;
}
...
...
dlls/ntdll/unix/signal_x86_64.c
View file @
c1dc5021
...
...
@@ -893,7 +893,7 @@ static void setup_raise_exception( ucontext_t *sigcontext, struct stack_layout *
RIP_sig
(
sigcontext
)
=
(
ULONG_PTR
)
raise_func_trampoline
;
RCX_sig
(
sigcontext
)
=
(
ULONG_PTR
)
&
stack
->
rec
;
RDX_sig
(
sigcontext
)
=
(
ULONG_PTR
)
&
stack
->
context
;
R8_sig
(
sigcontext
)
=
(
ULONG_PTR
)
KiUserExceptionDispatcher
;
R8_sig
(
sigcontext
)
=
(
ULONG_PTR
)
p
KiUserExceptionDispatcher
;
RBP_sig
(
sigcontext
)
=
(
ULONG_PTR
)
rsp_ptr
;
RSP_sig
(
sigcontext
)
=
(
ULONG_PTR
)
stack
;
/* clear single-step, direction, and align check flag */
...
...
@@ -1458,7 +1458,7 @@ PCONTEXT DECLSPEC_HIDDEN attach_thread( LPTHREAD_START_ROUTINE entry, void *arg,
}
pthread_sigmask
(
SIG_UNBLOCK
,
&
server_block_set
,
NULL
);
ctx
->
ContextFlags
=
CONTEXT_FULL
;
LdrInitializeThunk
(
ctx
,
(
void
**
)
&
ctx
->
Rcx
,
0
,
0
);
p
LdrInitializeThunk
(
ctx
,
(
void
**
)
&
ctx
->
Rcx
,
0
,
0
);
return
ctx
;
}
...
...
dlls/ntdll/unix/thread.c
View file @
c1dc5021
...
...
@@ -152,7 +152,7 @@ static void start_thread( TEB *teb )
RtlActivateActivationContext
(
0
,
info
->
actctx
,
&
cookie
);
RtlReleaseActivationContext
(
info
->
actctx
);
}
signal_start_thread
(
info
->
entry
,
info
->
arg
,
suspend
,
RtlUserThreadStart
,
teb
);
signal_start_thread
(
info
->
entry
,
info
->
arg
,
suspend
,
p
RtlUserThreadStart
,
teb
);
}
...
...
@@ -456,7 +456,7 @@ NTSTATUS WINAPI NtRaiseException( EXCEPTION_RECORD *rec, CONTEXT *context, BOOL
if
(
status
==
DBG_CONTINUE
||
status
==
DBG_EXCEPTION_HANDLED
)
NtSetContextThread
(
GetCurrentThread
(),
context
);
if
(
first_chance
)
KiUserExceptionDispatcher
(
rec
,
context
);
if
(
first_chance
)
p
KiUserExceptionDispatcher
(
rec
,
context
);
if
(
rec
->
ExceptionFlags
&
EH_STACK_INVALID
)
ERR
(
"Exception frame is not in stack limits => unable to dispatch exception.
\n
"
);
...
...
dlls/ntdll/unix/unix_private.h
View file @
c1dc5021
...
...
@@ -56,8 +56,11 @@ static inline struct ntdll_thread_data *ntdll_get_thread_data(void)
static
const
UINT_PTR
page_size
=
0x1000
;
NTSTATUS
WINAPI
KiUserExceptionDispatcher
(
EXCEPTION_RECORD
*
,
CONTEXT
*
);
void
WINAPI
LdrInitializeThunk
(
CONTEXT
*
,
void
**
,
ULONG_PTR
,
ULONG_PTR
);
/* callbacks to PE ntdll from the Unix side */
extern
void
(
WINAPI
*
pDbgUiRemoteBreakin
)(
void
*
arg
)
DECLSPEC_HIDDEN
;
extern
NTSTATUS
(
WINAPI
*
pKiUserExceptionDispatcher
)(
EXCEPTION_RECORD
*
,
CONTEXT
*
)
DECLSPEC_HIDDEN
;
extern
void
(
WINAPI
*
pLdrInitializeThunk
)(
CONTEXT
*
,
void
**
,
ULONG_PTR
,
ULONG_PTR
)
DECLSPEC_HIDDEN
;
extern
void
(
WINAPI
*
pRtlUserThreadStart
)(
PRTL_THREAD_START_ROUTINE
entry
,
void
*
arg
)
DECLSPEC_HIDDEN
;
extern
NTSTATUS
CDECL
fast_RtlpWaitForCriticalSection
(
RTL_CRITICAL_SECTION
*
crit
,
int
timeout
)
DECLSPEC_HIDDEN
;
extern
NTSTATUS
CDECL
fast_RtlpUnWaitCriticalSection
(
RTL_CRITICAL_SECTION
*
crit
)
DECLSPEC_HIDDEN
;
...
...
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