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
9f32a5c8
Commit
9f32a5c8
authored
Aug 09, 2005
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Added a VIRTUAL_alloc_teb function to allocate TEBs while making sure
they don't end up above the address space limit.
parent
b8d0f4cd
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
78 additions
and
45 deletions
+78
-45
ntdll_misc.h
dlls/ntdll/ntdll_misc.h
+1
-1
thread.c
dlls/ntdll/thread.c
+30
-42
virtual.c
dlls/ntdll/virtual.c
+47
-2
No files found.
dlls/ntdll/ntdll_misc.h
View file @
9f32a5c8
...
...
@@ -51,7 +51,6 @@ extern NTSTATUS NTDLL_wait_for_multiple_objects( UINT count, const HANDLE *handl
extern
BOOL
SIGNAL_Init
(
void
);
extern
void
debug_init
(
void
);
extern
void
thread_init
(
void
);
extern
void
virtual_init
(
void
);
/* server support */
extern
time_t
server_start_time
;
...
...
@@ -90,6 +89,7 @@ extern NTSTATUS FILE_GetNtStatus(void);
extern
BOOL
DIR_is_hidden_file
(
const
UNICODE_STRING
*
name
);
/* virtual memory */
extern
NTSTATUS
VIRTUAL_alloc_teb
(
void
**
ret
,
size_t
size
,
BOOL
first
);
extern
NTSTATUS
VIRTUAL_HandleFault
(
LPCVOID
addr
);
extern
BOOL
VIRTUAL_HasMapping
(
LPCVOID
addr
);
extern
void
VIRTUAL_UseLargeAddressSpace
(
void
);
...
...
dlls/ntdll/thread.c
View file @
9f32a5c8
...
...
@@ -55,29 +55,26 @@ static LIST_ENTRY tls_links;
/***********************************************************************
*
alloc
_teb
*
init
_teb
*/
static
TEB
*
alloc_teb
(
ULONG
*
size
)
static
inline
NTSTATUS
init_teb
(
TEB
*
teb
)
{
TEB
*
teb
;
struct
ntdll_thread_data
*
thread_data
;
struct
ntdll_thread_data
*
thread_data
=
(
struct
ntdll_thread_data
*
)
teb
->
SystemReserved2
;
*
size
=
SIGNAL_STACK_SIZE
+
sizeof
(
TEB
);
teb
=
wine_anon_mmap
(
NULL
,
*
size
,
PROT_READ
|
PROT_WRITE
,
0
);
if
(
teb
==
(
TEB
*
)
-
1
)
return
NULL
;
thread_data
=
(
struct
ntdll_thread_data
*
)
teb
->
SystemReserved2
;
if
(
!
(
thread_data
->
teb_sel
=
wine_ldt_alloc_fs
()))
{
munmap
(
teb
,
*
size
);
return
NULL
;
}
teb
->
Tib
.
ExceptionList
=
(
void
*
)
~
0UL
;
teb
->
Tib
.
StackBase
=
(
void
*
)
~
0UL
;
teb
->
Tib
.
Self
=
&
teb
->
Tib
;
teb
->
Peb
=
&
peb
;
teb
->
StaticUnicodeString
.
Buffer
=
teb
->
StaticUnicodeBuffer
;
teb
->
StaticUnicodeString
.
MaximumLength
=
sizeof
(
teb
->
StaticUnicodeBuffer
);
return
teb
;
if
(
!
(
thread_data
->
teb_sel
=
wine_ldt_alloc_fs
()))
return
STATUS_TOO_MANY_THREADS
;
thread_data
->
request_fd
=
-
1
;
thread_data
->
reply_fd
=
-
1
;
thread_data
->
wait_fd
[
0
]
=
-
1
;
thread_data
->
wait_fd
[
1
]
=
-
1
;
return
STATUS_SUCCESS
;
}
...
...
@@ -107,7 +104,7 @@ void thread_init(void)
{
TEB
*
teb
;
void
*
addr
;
ULONG
size
,
info_size
;
ULONG
info_size
;
struct
ntdll_thread_data
*
thread_data
;
struct
wine_pthread_thread_info
thread_info
;
static
struct
debug_info
debug_info
;
/* debug info for initial thread */
...
...
@@ -127,19 +124,17 @@ void thread_init(void)
InitializeListHead
(
&
ldr
.
InInitializationOrderModuleList
);
InitializeListHead
(
&
tls_links
);
teb
=
alloc_teb
(
&
size
);
thread_info
.
teb_size
=
SIGNAL_STACK_SIZE
+
sizeof
(
TEB
);
VIRTUAL_alloc_teb
(
&
addr
,
thread_info
.
teb_size
,
TRUE
);
teb
=
addr
;
init_teb
(
teb
);
thread_data
=
(
struct
ntdll_thread_data
*
)
teb
->
SystemReserved2
;
thread_data
->
request_fd
=
-
1
;
thread_data
->
reply_fd
=
-
1
;
thread_data
->
wait_fd
[
0
]
=
-
1
;
thread_data
->
wait_fd
[
1
]
=
-
1
;
thread_data
->
debug_info
=
&
debug_info
;
InsertHeadList
(
&
tls_links
,
&
teb
->
TlsLinks
);
thread_info
.
stack_base
=
NULL
;
thread_info
.
stack_size
=
0
;
thread_info
.
teb_base
=
teb
;
thread_info
.
teb_size
=
size
;
thread_info
.
teb_sel
=
thread_data
->
teb_sel
;
wine_pthread_init_current_teb
(
&
thread_info
);
wine_pthread_init_thread
(
&
thread_info
);
...
...
@@ -147,17 +142,11 @@ void thread_init(void)
debug_info
.
str_pos
=
debug_info
.
strings
;
debug_info
.
out_pos
=
debug_info
.
output
;
debug_init
();
virtual_init
();
/* setup the server connection */
server_init_process
();
info_size
=
server_init_thread
(
thread_info
.
pid
,
thread_info
.
tid
,
NULL
);
/* create a memory view for the TEB */
addr
=
teb
;
NtAllocateVirtualMemory
(
NtCurrentProcess
(),
&
addr
,
0
,
&
size
,
MEM_SYSTEM
,
PAGE_READWRITE
);
/* create the process heap */
if
(
!
(
peb
.
ProcessHeap
=
RtlCreateHeap
(
HEAP_GROWABLE
,
NULL
,
0
,
0
,
NULL
,
NULL
)))
{
...
...
@@ -245,12 +234,12 @@ NTSTATUS WINAPI RtlCreateUserThread( HANDLE process, const SECURITY_DESCRIPTOR *
PRTL_THREAD_START_ROUTINE
start
,
void
*
param
,
HANDLE
*
handle_ptr
,
CLIENT_ID
*
id
)
{
struct
ntdll_thread_data
*
thread_data
;
struct
ntdll_thread_data
*
thread_data
=
NULL
;
struct
startup_info
*
info
=
NULL
;
void
*
addr
;
HANDLE
handle
=
0
;
TEB
*
teb
=
NULL
;
TEB
*
teb
;
DWORD
tid
=
0
;
ULONG
size
;
int
request_pipe
[
2
];
NTSTATUS
status
;
...
...
@@ -286,24 +275,18 @@ NTSTATUS WINAPI RtlCreateUserThread( HANDLE process, const SECURITY_DESCRIPTOR *
goto
error
;
}
i
f
(
!
(
teb
=
alloc_teb
(
&
size
)))
{
status
=
STATUS_NO_MEMORY
;
goto
error
;
}
i
nfo
->
pthread_info
.
teb_size
=
SIGNAL_STACK_SIZE
+
sizeof
(
TEB
);
if
((
status
=
VIRTUAL_alloc_teb
(
&
addr
,
info
->
pthread_info
.
teb_size
,
FALSE
)))
goto
error
;
teb
=
addr
;
if
((
status
=
init_teb
(
teb
)))
goto
error
;
teb
->
ClientId
.
UniqueProcess
=
(
HANDLE
)
GetCurrentProcessId
();
teb
->
ClientId
.
UniqueThread
=
(
HANDLE
)
tid
;
thread_data
=
(
struct
ntdll_thread_data
*
)
teb
->
SystemReserved2
;
thread_data
->
request_fd
=
request_pipe
[
1
];
thread_data
->
reply_fd
=
-
1
;
thread_data
->
wait_fd
[
0
]
=
-
1
;
thread_data
->
wait_fd
[
1
]
=
-
1
;
info
->
pthread_info
.
teb_base
=
teb
;
NtAllocateVirtualMemory
(
NtCurrentProcess
(),
&
info
->
pthread_info
.
teb_base
,
0
,
&
size
,
MEM_SYSTEM
,
PAGE_READWRITE
);
info
->
pthread_info
.
teb_size
=
size
;
info
->
pthread_info
.
teb_sel
=
thread_data
->
teb_sel
;
if
(
!
stack_reserve
||
!
stack_commit
)
...
...
@@ -335,7 +318,12 @@ NTSTATUS WINAPI RtlCreateUserThread( HANDLE process, const SECURITY_DESCRIPTOR *
return
STATUS_SUCCESS
;
error:
if
(
teb
)
free_teb
(
teb
);
if
(
thread_data
)
wine_ldt_free_fs
(
thread_data
->
teb_sel
);
if
(
addr
)
{
ULONG
size
=
0
;
NtFreeVirtualMemory
(
NtCurrentProcess
(),
&
addr
,
&
size
,
MEM_RELEASE
);
}
if
(
info
)
RtlFreeHeap
(
GetProcessHeap
(),
0
,
info
);
if
(
handle
)
NtClose
(
handle
);
close
(
request_pipe
[
1
]
);
...
...
dlls/ntdll/virtual.c
View file @
9f32a5c8
...
...
@@ -1081,7 +1081,7 @@ BOOL is_current_process( HANDLE handle )
/***********************************************************************
* virtual_init
*/
void
virtual_init
(
void
)
static
inline
void
virtual_init
(
void
)
{
#ifndef page_mask
page_size
=
getpagesize
();
...
...
@@ -1095,6 +1095,51 @@ void virtual_init(void)
/***********************************************************************
* VIRTUAL_alloc_teb
*
* Allocate a memory view for a new TEB. We don't care about granularity for TEBs.
*/
NTSTATUS
VIRTUAL_alloc_teb
(
void
**
ret
,
size_t
size
,
BOOL
first
)
{
void
*
ptr
;
NTSTATUS
status
;
struct
file_view
*
view
;
BYTE
vprot
=
VPROT_READ
|
VPROT_WRITE
|
VPROT_COMMITTED
;
if
(
first
)
virtual_init
();
*
ret
=
NULL
;
size
=
ROUND_SIZE
(
0
,
size
);
for
(;;)
{
if
((
ptr
=
wine_anon_mmap
(
NULL
,
size
,
VIRTUAL_GetUnixProt
(
vprot
),
0
))
==
(
void
*
)
-
1
)
{
if
(
errno
==
ENOMEM
)
return
STATUS_NO_MEMORY
;
return
STATUS_INVALID_PARAMETER
;
}
/* if we got something beyond the user limit, unmap it and retry */
if
(
is_beyond_limit
(
ptr
,
size
,
user_space_limit
))
add_reserved_area
(
ptr
,
size
);
else
break
;
}
if
(
!
first
)
RtlEnterCriticalSection
(
&
csVirtual
);
status
=
create_view
(
&
view
,
ptr
,
size
,
vprot
);
if
(
status
==
STATUS_SUCCESS
)
{
view
->
flags
|=
VFLAG_VALLOC
;
*
ret
=
ptr
;
}
else
unmap_area
(
ptr
,
size
);
if
(
!
first
)
RtlLeaveCriticalSection
(
&
csVirtual
);
return
status
;
}
/***********************************************************************
* VIRTUAL_HandleFault
*/
NTSTATUS
VIRTUAL_HandleFault
(
LPCVOID
addr
)
...
...
@@ -1456,7 +1501,7 @@ NTSTATUS WINAPI NtQueryVirtualMemory( HANDLE process, LPCVOID addr,
{
/* make the address space end at the user limit, except if
* the last view was mapped beyond that */
if
(
alloc_base
<
(
char
*
)
user_space_limit
)
if
(
alloc_base
<
=
(
char
*
)
user_space_limit
)
{
if
(
user_space_limit
&&
base
>=
(
char
*
)
user_space_limit
)
{
...
...
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