Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-cw
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-cw
Commits
6169cacd
Commit
6169cacd
authored
Apr 01, 2020
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ntdll: Move support for getting LDT entries to the platform-specific files.
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
73dad192
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
151 additions
and
74 deletions
+151
-74
thread.c
dlls/kernel32/tests/thread.c
+47
-0
ntdll_misc.h
dlls/ntdll/ntdll_misc.h
+1
-0
signal_arm.c
dlls/ntdll/signal_arm.c
+8
-0
signal_arm64.c
dlls/ntdll/signal_arm64.c
+8
-0
signal_i386.c
dlls/ntdll/signal_i386.c
+68
-1
signal_powerpc.c
dlls/ntdll/signal_powerpc.c
+8
-0
signal_x86_64.c
dlls/ntdll/signal_x86_64.c
+8
-0
thread.c
dlls/ntdll/thread.c
+3
-73
No files found.
dlls/kernel32/tests/thread.c
View file @
6169cacd
...
...
@@ -1195,6 +1195,19 @@ static void test_GetThreadSelectorEntry(void)
ok
(
ret
,
"GetThreadSelectorEntry(SegCs) error %u
\n
"
,
GetLastError
());
ret
=
GetThreadSelectorEntry
(
GetCurrentThread
(),
ctx
.
SegDs
,
&
entry
);
ok
(
ret
,
"GetThreadSelectorEntry(SegDs) error %u
\n
"
,
GetLastError
());
ret
=
GetThreadSelectorEntry
(
GetCurrentThread
(),
ctx
.
SegDs
&
~
3
,
&
entry
);
ok
(
ret
,
"GetThreadSelectorEntry(SegDs) error %u
\n
"
,
GetLastError
());
ret
=
GetThreadSelectorEntry
(
GetCurrentThread
(),
0
,
&
entry
);
ok
(
ret
,
"GetThreadSelectorEntry(SegDs) error %u
\n
"
,
GetLastError
());
ret
=
GetThreadSelectorEntry
(
GetCurrentThread
(),
3
,
&
entry
);
ok
(
ret
,
"GetThreadSelectorEntry(SegDs) error %u
\n
"
,
GetLastError
());
SetLastError
(
0xdeadbeef
);
ret
=
GetThreadSelectorEntry
(
GetCurrentThread
(),
0xdeadbeef
,
&
entry
);
ok
(
!
ret
,
"GetThreadSelectorEntry(invalid) succeeded
\n
"
);
ok
(
GetLastError
()
==
ERROR_GEN_FAILURE
,
"wrong error %u
\n
"
,
GetLastError
()
);
ret
=
GetThreadSelectorEntry
(
GetCurrentThread
(),
ctx
.
SegDs
+
0x100
,
&
entry
);
ok
(
!
ret
,
"GetThreadSelectorEntry(invalid) succeeded
\n
"
);
ok
(
GetLastError
()
==
ERROR_GEN_FAILURE
,
"wrong error %u
\n
"
,
GetLastError
()
);
memset
(
&
entry
,
0x11
,
sizeof
(
entry
));
ret
=
GetThreadSelectorEntry
(
GetCurrentThread
(),
ctx
.
SegFs
,
&
entry
);
...
...
@@ -1213,6 +1226,40 @@ static void test_GetThreadSelectorEntry(void)
ok
(
entry
.
HighWord
.
Bits
.
Reserved_0
==
0
,
"expected 0, got %u
\n
"
,
entry
.
HighWord
.
Bits
.
Reserved_0
);
ok
(
entry
.
HighWord
.
Bits
.
Default_Big
==
1
,
"expected 1, got %u
\n
"
,
entry
.
HighWord
.
Bits
.
Default_Big
);
ok
(
entry
.
HighWord
.
Bits
.
Granularity
==
0
,
"expected 0, got %u
\n
"
,
entry
.
HighWord
.
Bits
.
Granularity
);
memset
(
&
entry
,
0x11
,
sizeof
(
entry
));
ret
=
GetThreadSelectorEntry
(
GetCurrentThread
(),
ctx
.
SegCs
,
&
entry
);
ok
(
ret
,
"GetThreadSelectorEntry(SegDs) error %u
\n
"
,
GetLastError
());
entry
.
HighWord
.
Bits
.
Type
&=
~
1
;
/* ignore accessed bit */
base
=
(
void
*
)((
entry
.
HighWord
.
Bits
.
BaseHi
<<
24
)
|
(
entry
.
HighWord
.
Bits
.
BaseMid
<<
16
)
|
entry
.
BaseLow
);
limit
=
(
entry
.
HighWord
.
Bits
.
LimitHi
<<
16
)
|
entry
.
LimitLow
;
ok
(
base
==
0
,
"got base %p
\n
"
,
base
);
ok
(
limit
==
~
0u
>>
12
,
"got limit %#x
\n
"
,
limit
);
ok
(
entry
.
HighWord
.
Bits
.
Type
==
0x1a
,
"expected 0x12, got %#x
\n
"
,
entry
.
HighWord
.
Bits
.
Type
);
ok
(
entry
.
HighWord
.
Bits
.
Dpl
==
3
,
"expected 3, got %u
\n
"
,
entry
.
HighWord
.
Bits
.
Dpl
);
ok
(
entry
.
HighWord
.
Bits
.
Pres
==
1
,
"expected 1, got %u
\n
"
,
entry
.
HighWord
.
Bits
.
Pres
);
ok
(
entry
.
HighWord
.
Bits
.
Sys
==
0
,
"expected 0, got %u
\n
"
,
entry
.
HighWord
.
Bits
.
Sys
);
ok
(
entry
.
HighWord
.
Bits
.
Reserved_0
==
0
,
"expected 0, got %u
\n
"
,
entry
.
HighWord
.
Bits
.
Reserved_0
);
ok
(
entry
.
HighWord
.
Bits
.
Default_Big
==
1
,
"expected 1, got %u
\n
"
,
entry
.
HighWord
.
Bits
.
Default_Big
);
ok
(
entry
.
HighWord
.
Bits
.
Granularity
==
1
,
"expected 1, got %u
\n
"
,
entry
.
HighWord
.
Bits
.
Granularity
);
memset
(
&
entry
,
0x11
,
sizeof
(
entry
));
ret
=
GetThreadSelectorEntry
(
GetCurrentThread
(),
ctx
.
SegDs
,
&
entry
);
ok
(
ret
,
"GetThreadSelectorEntry(SegDs) error %u
\n
"
,
GetLastError
());
entry
.
HighWord
.
Bits
.
Type
&=
~
1
;
/* ignore accessed bit */
base
=
(
void
*
)((
entry
.
HighWord
.
Bits
.
BaseHi
<<
24
)
|
(
entry
.
HighWord
.
Bits
.
BaseMid
<<
16
)
|
entry
.
BaseLow
);
limit
=
(
entry
.
HighWord
.
Bits
.
LimitHi
<<
16
)
|
entry
.
LimitLow
;
ok
(
base
==
0
,
"got base %p
\n
"
,
base
);
ok
(
limit
==
~
0u
>>
12
,
"got limit %#x
\n
"
,
limit
);
ok
(
entry
.
HighWord
.
Bits
.
Type
==
0x12
,
"expected 0x12, got %#x
\n
"
,
entry
.
HighWord
.
Bits
.
Type
);
ok
(
entry
.
HighWord
.
Bits
.
Dpl
==
3
,
"expected 3, got %u
\n
"
,
entry
.
HighWord
.
Bits
.
Dpl
);
ok
(
entry
.
HighWord
.
Bits
.
Pres
==
1
,
"expected 1, got %u
\n
"
,
entry
.
HighWord
.
Bits
.
Pres
);
ok
(
entry
.
HighWord
.
Bits
.
Sys
==
0
,
"expected 0, got %u
\n
"
,
entry
.
HighWord
.
Bits
.
Sys
);
ok
(
entry
.
HighWord
.
Bits
.
Reserved_0
==
0
,
"expected 0, got %u
\n
"
,
entry
.
HighWord
.
Bits
.
Reserved_0
);
ok
(
entry
.
HighWord
.
Bits
.
Default_Big
==
1
,
"expected 1, got %u
\n
"
,
entry
.
HighWord
.
Bits
.
Default_Big
);
ok
(
entry
.
HighWord
.
Bits
.
Granularity
==
1
,
"expected 1, got %u
\n
"
,
entry
.
HighWord
.
Bits
.
Granularity
);
}
#endif
/* __i386__ */
...
...
dlls/ntdll/ntdll_misc.h
View file @
6169cacd
...
...
@@ -58,6 +58,7 @@ extern NTSTATUS context_to_server( context_t *to, const CONTEXT *from ) DECLSPEC
extern
NTSTATUS
context_from_server
(
CONTEXT
*
to
,
const
context_t
*
from
)
DECLSPEC_HIDDEN
;
extern
NTSTATUS
set_thread_context
(
HANDLE
handle
,
const
context_t
*
context
,
BOOL
*
self
)
DECLSPEC_HIDDEN
;
extern
NTSTATUS
get_thread_context
(
HANDLE
handle
,
context_t
*
context
,
unsigned
int
flags
,
BOOL
*
self
)
DECLSPEC_HIDDEN
;
extern
NTSTATUS
get_thread_ldt_entry
(
HANDLE
handle
,
void
*
data
,
ULONG
len
,
ULONG
*
ret_len
)
DECLSPEC_HIDDEN
;
extern
LONG
WINAPI
call_unhandled_exception_filter
(
PEXCEPTION_POINTERS
eptr
)
DECLSPEC_HIDDEN
;
#if defined(__x86_64__) || defined(__arm__) || defined(__aarch64__)
...
...
dlls/ntdll/signal_arm.c
View file @
6169cacd
...
...
@@ -1278,6 +1278,14 @@ void signal_exit_process( int status )
}
/**********************************************************************
* get_thread_ldt_entry
*/
NTSTATUS
get_thread_ldt_entry
(
HANDLE
handle
,
void
*
data
,
ULONG
len
,
ULONG
*
ret_len
)
{
return
STATUS_NOT_IMPLEMENTED
;
}
/**********************************************************************
* DbgBreakPoint (NTDLL.@)
*/
void
WINAPI
DbgBreakPoint
(
void
)
...
...
dlls/ntdll/signal_arm64.c
View file @
6169cacd
...
...
@@ -2106,6 +2106,14 @@ void signal_exit_process( int status )
}
/**********************************************************************
* get_thread_ldt_entry
*/
NTSTATUS
get_thread_ldt_entry
(
HANDLE
handle
,
void
*
data
,
ULONG
len
,
ULONG
*
ret_len
)
{
return
STATUS_NOT_IMPLEMENTED
;
}
/**********************************************************************
* DbgBreakPoint (NTDLL.@)
*/
__ASM_STDCALL_FUNC
(
DbgBreakPoint
,
0
,
"brk #0; ret"
)
...
...
dlls/ntdll/signal_i386.c
View file @
6169cacd
...
...
@@ -523,6 +523,14 @@ extern DWORD EXC_CallHandler( EXCEPTION_RECORD *record, EXCEPTION_REGISTRATION_R
PEXCEPTION_HANDLER
handler
,
PEXCEPTION_HANDLER
nested_handler
);
/***********************************************************************
* is_gdt_sel
*/
static
inline
int
is_gdt_sel
(
WORD
sel
)
{
return
!
(
sel
&
4
);
}
/***********************************************************************
* dispatch_signal
*/
static
inline
int
dispatch_signal
(
unsigned
int
sig
)
...
...
@@ -2242,7 +2250,7 @@ int CDECL __wine_set_signal_handler(unsigned int sig, wine_signal_handler wsh)
/***********************************************************************
*
locking for LDT routines
*
LDT support
*/
static
RTL_CRITICAL_SECTION
ldt_section
;
static
RTL_CRITICAL_SECTION_DEBUG
critsect_debug
=
...
...
@@ -2254,6 +2262,8 @@ static RTL_CRITICAL_SECTION_DEBUG critsect_debug =
static
RTL_CRITICAL_SECTION
ldt_section
=
{
&
critsect_debug
,
-
1
,
0
,
0
,
0
,
0
};
static
sigset_t
ldt_sigset
;
static
const
LDT_ENTRY
null_entry
;
static
void
ldt_lock
(
void
)
{
sigset_t
sigset
;
...
...
@@ -2274,6 +2284,63 @@ static void ldt_unlock(void)
else
RtlLeaveCriticalSection
(
&
ldt_section
);
}
static
LDT_ENTRY
ldt_make_entry
(
void
*
base
,
unsigned
int
limit
,
unsigned
char
flags
)
{
LDT_ENTRY
entry
;
wine_ldt_set_base
(
&
entry
,
base
);
wine_ldt_set_limit
(
&
entry
,
limit
);
wine_ldt_set_flags
(
&
entry
,
flags
);
return
entry
;
}
/**********************************************************************
* get_thread_ldt_entry
*/
NTSTATUS
get_thread_ldt_entry
(
HANDLE
handle
,
void
*
data
,
ULONG
len
,
ULONG
*
ret_len
)
{
THREAD_DESCRIPTOR_INFORMATION
*
info
=
data
;
NTSTATUS
status
=
STATUS_SUCCESS
;
if
(
len
<
sizeof
(
*
info
))
return
STATUS_INFO_LENGTH_MISMATCH
;
if
(
info
->
Selector
>>
16
)
return
STATUS_UNSUCCESSFUL
;
if
(
is_gdt_sel
(
info
->
Selector
))
{
if
(
!
(
info
->
Selector
&
~
3
))
info
->
Entry
=
null_entry
;
else
if
((
info
->
Selector
|
3
)
==
wine_get_cs
())
info
->
Entry
=
ldt_make_entry
(
0
,
~
0u
,
WINE_LDT_FLAGS_CODE
|
WINE_LDT_FLAGS_32BIT
);
else
if
((
info
->
Selector
|
3
)
==
wine_get_ds
())
info
->
Entry
=
ldt_make_entry
(
0
,
~
0u
,
WINE_LDT_FLAGS_DATA
|
WINE_LDT_FLAGS_32BIT
);
else
if
((
info
->
Selector
|
3
)
==
wine_get_fs
())
info
->
Entry
=
ldt_make_entry
(
NtCurrentTeb
(),
0xfff
,
WINE_LDT_FLAGS_DATA
|
WINE_LDT_FLAGS_32BIT
);
else
return
STATUS_UNSUCCESSFUL
;
}
else
{
SERVER_START_REQ
(
get_selector_entry
)
{
req
->
handle
=
wine_server_obj_handle
(
handle
);
req
->
entry
=
info
->
Selector
>>
3
;
status
=
wine_server_call
(
req
);
if
(
!
status
)
{
if
(
reply
->
flags
)
info
->
Entry
=
ldt_make_entry
(
(
void
*
)
reply
->
base
,
reply
->
limit
,
reply
->
flags
);
else
status
=
STATUS_UNSUCCESSFUL
;
}
}
SERVER_END_REQ
;
}
if
(
status
==
STATUS_SUCCESS
&&
ret_len
)
/* yes, that's a bit strange, but it's the way it is */
*
ret_len
=
sizeof
(
info
->
Entry
);
return
status
;
}
/**********************************************************************
* signal_alloc_thread
...
...
dlls/ntdll/signal_powerpc.c
View file @
6169cacd
...
...
@@ -1256,6 +1256,14 @@ void signal_exit_process( int status )
}
/**********************************************************************
* get_thread_ldt_entry
*/
NTSTATUS
get_thread_ldt_entry
(
HANDLE
handle
,
void
*
data
,
ULONG
len
,
ULONG
*
ret_len
)
{
return
STATUS_NOT_IMPLEMENTED
;
}
/**********************************************************************
* DbgBreakPoint (NTDLL.@)
*/
void
WINAPI
DbgBreakPoint
(
void
)
...
...
dlls/ntdll/signal_x86_64.c
View file @
6169cacd
...
...
@@ -4279,6 +4279,14 @@ void signal_exit_process( int status )
}
/**********************************************************************
* get_thread_ldt_entry
*/
NTSTATUS
get_thread_ldt_entry
(
HANDLE
handle
,
void
*
data
,
ULONG
len
,
ULONG
*
ret_len
)
{
return
STATUS_NOT_IMPLEMENTED
;
}
/**********************************************************************
* DbgBreakPoint (NTDLL.@)
*/
__ASM_STDCALL_FUNC
(
DbgBreakPoint
,
0
,
"int $3; ret"
)
...
...
dlls/ntdll/thread.c
View file @
6169cacd
...
...
@@ -980,80 +980,10 @@ NTSTATUS WINAPI NtQueryInformationThread( HANDLE handle, THREADINFOCLASS class,
}
}
return
status
;
case
ThreadDescriptorTableEntry
:
{
#ifdef __i386__
THREAD_DESCRIPTOR_INFORMATION
*
tdi
=
data
;
if
(
length
<
sizeof
(
*
tdi
))
status
=
STATUS_INFO_LENGTH_MISMATCH
;
else
if
(
!
(
tdi
->
Selector
&
4
))
/* GDT selector */
{
unsigned
sel
=
LOWORD
(
tdi
->
Selector
)
&
~
3
;
/* ignore RPL */
status
=
STATUS_SUCCESS
;
if
(
!
sel
)
/* null selector */
memset
(
&
tdi
->
Entry
,
0
,
sizeof
(
tdi
->
Entry
)
);
else
{
tdi
->
Entry
.
BaseLow
=
0
;
tdi
->
Entry
.
HighWord
.
Bits
.
BaseMid
=
0
;
tdi
->
Entry
.
HighWord
.
Bits
.
BaseHi
=
0
;
tdi
->
Entry
.
LimitLow
=
0xffff
;
tdi
->
Entry
.
HighWord
.
Bits
.
LimitHi
=
0xf
;
tdi
->
Entry
.
HighWord
.
Bits
.
Dpl
=
3
;
tdi
->
Entry
.
HighWord
.
Bits
.
Sys
=
0
;
tdi
->
Entry
.
HighWord
.
Bits
.
Pres
=
1
;
tdi
->
Entry
.
HighWord
.
Bits
.
Granularity
=
1
;
tdi
->
Entry
.
HighWord
.
Bits
.
Default_Big
=
1
;
tdi
->
Entry
.
HighWord
.
Bits
.
Type
=
0x12
;
tdi
->
Entry
.
HighWord
.
Bits
.
Reserved_0
=
0
;
/* it has to be one of the system GDT selectors */
if
(
sel
!=
(
wine_get_ds
()
&
~
3
)
&&
sel
!=
(
wine_get_ss
()
&
~
3
))
{
if
(
sel
==
(
wine_get_cs
()
&
~
3
))
tdi
->
Entry
.
HighWord
.
Bits
.
Type
|=
8
;
/* code segment */
else
if
(
sel
==
(
wine_get_fs
()
&
~
3
))
{
ULONG_PTR
fs_base
=
(
ULONG_PTR
)
NtCurrentTeb
();
tdi
->
Entry
.
BaseLow
=
fs_base
&
0xffff
;
tdi
->
Entry
.
HighWord
.
Bits
.
BaseMid
=
(
fs_base
>>
16
)
&
0xff
;
tdi
->
Entry
.
HighWord
.
Bits
.
BaseHi
=
(
fs_base
>>
24
)
&
0xff
;
tdi
->
Entry
.
LimitLow
=
0x0fff
;
tdi
->
Entry
.
HighWord
.
Bits
.
LimitHi
=
0
;
tdi
->
Entry
.
HighWord
.
Bits
.
Granularity
=
0
;
}
else
status
=
STATUS_ACCESS_DENIED
;
}
}
}
else
{
SERVER_START_REQ
(
get_selector_entry
)
{
req
->
handle
=
wine_server_obj_handle
(
handle
);
req
->
entry
=
LOWORD
(
tdi
->
Selector
)
>>
3
;
status
=
wine_server_call
(
req
);
if
(
!
status
)
{
if
(
!
(
reply
->
flags
&
WINE_LDT_FLAGS_ALLOCATED
))
status
=
STATUS_ACCESS_VIOLATION
;
else
{
wine_ldt_set_base
(
&
tdi
->
Entry
,
(
void
*
)
reply
->
base
);
wine_ldt_set_limit
(
&
tdi
->
Entry
,
reply
->
limit
);
wine_ldt_set_flags
(
&
tdi
->
Entry
,
reply
->
flags
);
}
}
}
SERVER_END_REQ
;
}
if
(
status
==
STATUS_SUCCESS
&&
ret_len
)
/* yes, that's a bit strange, but it's the way it is */
*
ret_len
=
sizeof
(
LDT_ENTRY
);
#else
status
=
STATUS_NOT_IMPLEMENTED
;
#endif
return
status
;
}
return
get_thread_ldt_entry
(
handle
,
data
,
length
,
ret_len
);
case
ThreadAmILastThread
:
{
SERVER_START_REQ
(
get_thread_info
)
...
...
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