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
adb53290
Commit
adb53290
authored
May 14, 2003
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Rewrote module TLS support and moved it to ntdll.
parent
0b34697a
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
120 additions
and
78 deletions
+120
-78
loader.c
dlls/ntdll/loader.c
+118
-20
module.h
include/module.h
+2
-3
pe_image.c
loader/pe_image.c
+0
-53
process.c
scheduler/process.c
+0
-1
thread.c
scheduler/thread.c
+0
-1
No files found.
dlls/ntdll/loader.c
View file @
adb53290
...
...
@@ -63,6 +63,10 @@ static const char * const reason_names[] =
"THREAD_DETACH"
};
static
UINT
tls_module_count
;
/* number of modules with TLS directory */
static
UINT
tls_total_size
;
/* total size of TLS storage */
static
const
IMAGE_TLS_DIRECTORY
**
tls_dirs
;
/* array of TLS directories */
static
CRITICAL_SECTION
loader_section
=
CRITICAL_SECTION_INIT
(
"loader_section"
);
static
WINE_MODREF
*
cached_modref
;
static
WINE_MODREF
*
current_modref
;
...
...
@@ -399,6 +403,92 @@ WINE_MODREF *MODULE_AllocModRef( HMODULE hModule, LPCSTR filename )
/*************************************************************************
* alloc_process_tls
*
* Allocate the process-wide structure for module TLS storage.
*/
static
NTSTATUS
alloc_process_tls
(
void
)
{
WINE_MODREF
*
wm
;
IMAGE_TLS_DIRECTORY
*
dir
;
ULONG
size
,
i
;
for
(
wm
=
MODULE_modref_list
;
wm
;
wm
=
wm
->
next
)
{
if
(
!
(
dir
=
RtlImageDirectoryEntryToData
(
wm
->
ldr
.
BaseAddress
,
TRUE
,
IMAGE_DIRECTORY_ENTRY_TLS
,
&
size
)))
continue
;
size
=
(
dir
->
EndAddressOfRawData
-
dir
->
StartAddressOfRawData
)
+
dir
->
SizeOfZeroFill
;
if
(
!
size
)
continue
;
tls_total_size
+=
size
;
tls_module_count
++
;
}
if
(
!
tls_module_count
)
return
STATUS_SUCCESS
;
TRACE
(
"count %u size %u
\n
"
,
tls_module_count
,
tls_total_size
);
tls_dirs
=
RtlAllocateHeap
(
ntdll_get_process_heap
(),
0
,
tls_module_count
*
sizeof
(
*
tls_dirs
)
);
if
(
!
tls_dirs
)
return
STATUS_NO_MEMORY
;
for
(
i
=
0
,
wm
=
MODULE_modref_list
;
wm
;
wm
=
wm
->
next
)
{
if
(
!
(
dir
=
RtlImageDirectoryEntryToData
(
wm
->
ldr
.
BaseAddress
,
TRUE
,
IMAGE_DIRECTORY_ENTRY_TLS
,
&
size
)))
continue
;
tls_dirs
[
i
]
=
dir
;
*
dir
->
AddressOfIndex
=
i
;
wm
->
ldr
.
TlsIndex
=
i
;
wm
->
ldr
.
LoadCount
=
-
1
;
/* can't unload it */
i
++
;
}
return
STATUS_SUCCESS
;
}
/*************************************************************************
* alloc_thread_tls
*
* Allocate the per-thread structure for module TLS storage.
*/
static
NTSTATUS
alloc_thread_tls
(
void
)
{
void
**
pointers
;
char
*
data
;
UINT
i
;
if
(
!
tls_module_count
)
return
STATUS_SUCCESS
;
if
(
!
(
pointers
=
RtlAllocateHeap
(
ntdll_get_process_heap
(),
0
,
tls_module_count
*
sizeof
(
*
pointers
)
)))
return
STATUS_NO_MEMORY
;
if
(
!
(
data
=
RtlAllocateHeap
(
ntdll_get_process_heap
(),
0
,
tls_total_size
)))
{
RtlFreeHeap
(
ntdll_get_process_heap
(),
0
,
pointers
);
return
STATUS_NO_MEMORY
;
}
for
(
i
=
0
;
i
<
tls_module_count
;
i
++
)
{
const
IMAGE_TLS_DIRECTORY
*
dir
=
tls_dirs
[
i
];
ULONG
size
=
dir
->
EndAddressOfRawData
-
dir
->
StartAddressOfRawData
;
TRACE
(
"thread %04lx idx %d: %ld/%ld bytes from %p to %p
\n
"
,
GetCurrentThreadId
(),
i
,
size
,
dir
->
SizeOfZeroFill
,
(
void
*
)
dir
->
StartAddressOfRawData
,
data
);
pointers
[
i
]
=
data
;
memcpy
(
data
,
(
void
*
)
dir
->
StartAddressOfRawData
,
size
);
data
+=
size
;
memset
(
data
,
0
,
dir
->
SizeOfZeroFill
);
data
+=
dir
->
SizeOfZeroFill
;
}
NtCurrentTeb
()
->
tls_ptr
=
pointers
;
return
STATUS_SUCCESS
;
}
/*************************************************************************
* call_tls_callbacks
*/
static
void
call_tls_callbacks
(
HMODULE
module
,
UINT
reason
)
...
...
@@ -492,9 +582,9 @@ static BOOL MODULE_InitDLL( WINE_MODREF *wm, UINT reason, LPVOID lpReserved )
* detach notifications are called in the reverse of the sequence the attach
* notifications *returned*.
*/
BOOL
MODULE_DllProcessAttach
(
WINE_MODREF
*
wm
,
LPVOID
lpReserved
)
NTSTATUS
MODULE_DllProcessAttach
(
WINE_MODREF
*
wm
,
LPVOID
lpReserved
)
{
BOOL
retv
=
TRUE
;
NTSTATUS
status
=
STATUS_SUCCESS
;
int
i
;
RtlEnterCriticalSection
(
&
loader_section
);
...
...
@@ -502,7 +592,9 @@ BOOL MODULE_DllProcessAttach( WINE_MODREF *wm, LPVOID lpReserved )
if
(
!
wm
)
{
wm
=
exe_modref
;
PE_InitTls
();
wm
->
ldr
.
LoadCount
=
-
1
;
/* can't unload main exe */
if
((
status
=
alloc_process_tls
())
!=
STATUS_SUCCESS
)
goto
done
;
if
((
status
=
alloc_thread_tls
())
!=
STATUS_SUCCESS
)
goto
done
;
}
assert
(
wm
);
...
...
@@ -517,22 +609,26 @@ BOOL MODULE_DllProcessAttach( WINE_MODREF *wm, LPVOID lpReserved )
wm
->
ldr
.
Flags
|=
LDR_LOAD_IN_PROGRESS
;
/* Recursively attach all DLLs this one depends on */
for
(
i
=
0
;
retv
&&
i
<
wm
->
nDeps
;
i
++
)
if
(
wm
->
deps
[
i
]
)
retv
=
MODULE_DllProcessAttach
(
wm
->
deps
[
i
],
lpReserved
);
for
(
i
=
0
;
i
<
wm
->
nDeps
;
i
++
)
{
if
(
!
wm
->
deps
[
i
])
continue
;
if
((
status
=
MODULE_DllProcessAttach
(
wm
->
deps
[
i
],
lpReserved
))
!=
STATUS_SUCCESS
)
break
;
}
/* Call DLL entry point */
if
(
retv
)
if
(
status
==
STATUS_SUCCESS
)
{
WINE_MODREF
*
prev
=
current_modref
;
current_modref
=
wm
;
retv
=
MODULE_InitDLL
(
wm
,
DLL_PROCESS_ATTACH
,
lpReserved
);
if
(
retv
)
wm
->
ldr
.
Flags
|=
LDR_PROCESS_ATTACHED
;
if
(
MODULE_InitDLL
(
wm
,
DLL_PROCESS_ATTACH
,
lpReserved
))
wm
->
ldr
.
Flags
|=
LDR_PROCESS_ATTACHED
;
else
status
=
STATUS_DLL_INIT_FAILED
;
current_modref
=
prev
;
}
/* Re-insert MODREF at head of list */
if
(
retv
&&
wm
->
prev
)
if
(
status
==
STATUS_SUCCESS
&&
wm
->
prev
)
{
wm
->
prev
->
next
=
wm
->
next
;
if
(
wm
->
next
)
wm
->
next
->
prev
=
wm
->
prev
;
...
...
@@ -547,10 +643,9 @@ BOOL MODULE_DllProcessAttach( WINE_MODREF *wm, LPVOID lpReserved )
TRACE
(
"(%s,%p) - END
\n
"
,
wm
->
modname
,
lpReserved
);
done:
RtlLeaveCriticalSection
(
&
loader_section
);
return
retv
;
return
status
;
}
/*************************************************************************
...
...
@@ -573,7 +668,7 @@ static void MODULE_DllProcessDetach( BOOL bForceDetach, LPVOID lpReserved )
/* Check whether to detach this DLL */
if
(
!
(
wm
->
ldr
.
Flags
&
LDR_PROCESS_ATTACHED
)
)
continue
;
if
(
wm
->
ldr
.
LoadCount
>
0
&&
!
bForceDetach
)
if
(
wm
->
ldr
.
LoadCount
&&
!
bForceDetach
)
continue
;
/* Call detach notification */
...
...
@@ -596,17 +691,18 @@ static void MODULE_DllProcessDetach( BOOL bForceDetach, LPVOID lpReserved )
* reverse sequence of process detach notification.
*
*/
void
MODULE_DllThreadAttach
(
LPVOID
lpReserved
)
NTSTATUS
MODULE_DllThreadAttach
(
LPVOID
lpReserved
)
{
WINE_MODREF
*
wm
;
NTSTATUS
status
;
/* don't do any attach calls if process is exiting */
if
(
process_detaching
)
return
;
if
(
process_detaching
)
return
STATUS_SUCCESS
;
/* FIXME: there is still a race here */
RtlEnterCriticalSection
(
&
loader_section
);
PE_InitTls
()
;
if
((
status
=
alloc_thread_tls
())
!=
STATUS_SUCCESS
)
goto
done
;
for
(
wm
=
MODULE_modref_list
;
wm
;
wm
=
wm
->
next
)
if
(
!
wm
->
next
)
...
...
@@ -622,7 +718,9 @@ void MODULE_DllThreadAttach( LPVOID lpReserved )
MODULE_InitDLL
(
wm
,
DLL_THREAD_ATTACH
,
lpReserved
);
}
done:
RtlLeaveCriticalSection
(
&
loader_section
);
return
status
;
}
/******************************************************************
...
...
@@ -922,8 +1020,8 @@ static NTSTATUS load_dll( LPCSTR libname, DWORD flags, WINE_MODREF** pwm )
}
if
(
*
pwm
)
{
(
*
pwm
)
->
ldr
.
LoadCount
++
;
if
((
*
pwm
)
->
ldr
.
LoadCount
!=
-
1
)
(
*
pwm
)
->
ldr
.
LoadCount
++
;
if
(((
*
pwm
)
->
ldr
.
Flags
&
LDR_DONT_RESOLVE_REFS
)
&&
!
(
flags
&
DONT_RESOLVE_DLL_REFERENCES
))
{
...
...
@@ -1022,11 +1120,11 @@ NTSTATUS WINAPI LdrLoadDll(LPCWSTR path_name, DWORD flags, PUNICODE_STRING libna
switch
(
nts
=
load_dll
(
str
.
Buffer
,
flags
,
&
wm
))
{
case
STATUS_SUCCESS
:
if
(
!
MODULE_DllProcessAttach
(
wm
,
NULL
)
)
nts
=
MODULE_DllProcessAttach
(
wm
,
NULL
);
if
(
nts
!=
STATUS_SUCCESS
)
{
WARN
(
"Attach failed for module '%s'.
\n
"
,
str
.
Buffer
);
LdrUnloadDll
(
wm
->
ldr
.
BaseAddress
);
nts
=
STATUS_DLL_INIT_FAILED
;
wm
=
NULL
;
}
break
;
...
...
include/module.h
View file @
adb53290
...
...
@@ -181,8 +181,8 @@ enum binary_type
};
/* module.c */
extern
BOOL
MODULE_DllProcessAttach
(
WINE_MODREF
*
wm
,
LPVOID
lpReserved
);
extern
void
MODULE_DllThreadAttach
(
LPVOID
lpReserved
);
extern
NTSTATUS
MODULE_DllProcessAttach
(
WINE_MODREF
*
wm
,
LPVOID
lpReserved
);
extern
NTSTATUS
MODULE_DllThreadAttach
(
LPVOID
lpReserved
);
extern
WINE_MODREF
*
MODULE_FindModule
(
LPCSTR
path
);
extern
HMODULE16
MODULE_CreateDummyModule
(
LPCSTR
filename
,
HMODULE
module32
);
extern
enum
binary_type
MODULE_GetBinaryType
(
HANDLE
hfile
);
...
...
@@ -224,7 +224,6 @@ extern NTSTATUS PE_LoadLibraryExA(LPCSTR, DWORD, WINE_MODREF**);
extern
HMODULE
PE_LoadImage
(
HANDLE
hFile
,
LPCSTR
filename
,
DWORD
flags
);
extern
WINE_MODREF
*
PE_CreateModule
(
HMODULE
hModule
,
LPCSTR
filename
,
DWORD
flags
,
HANDLE
hFile
,
BOOL
builtin
);
extern
void
PE_InitTls
(
void
);
extern
DWORD
PE_fixup_imports
(
WINE_MODREF
*
wm
);
/* loader/loadorder.c */
...
...
loader/pe_image.c
View file @
adb53290
...
...
@@ -371,56 +371,3 @@ NTSTATUS PE_LoadLibraryExA (LPCSTR name, DWORD flags, WINE_MODREF** pwm)
CloseHandle
(
hFile
);
return
STATUS_SUCCESS
;
}
/************************************************************************
* PE_InitTls (internal)
*
* If included, initialises the thread local storages of modules.
* Pointers in those structs are not RVAs but real pointers which have been
* relocated by do_relocations() already.
*/
static
LPVOID
_fixup_address
(
PIMAGE_OPTIONAL_HEADER
opt
,
int
delta
,
LPVOID
addr
)
{
if
(
((
DWORD
)
addr
>
opt
->
ImageBase
)
&&
((
DWORD
)
addr
<
opt
->
ImageBase
+
opt
->
SizeOfImage
)
)
/* the address has not been relocated! */
return
(
LPVOID
)(((
DWORD
)
addr
)
+
delta
);
else
/* the address has been relocated already */
return
addr
;
}
void
PE_InitTls
(
void
)
{
WINE_MODREF
*
wm
;
IMAGE_NT_HEADERS
*
peh
;
DWORD
size
,
datasize
,
dirsize
;
LPVOID
mem
;
PIMAGE_TLS_DIRECTORY
pdir
;
int
delta
;
for
(
wm
=
MODULE_modref_list
;
wm
;
wm
=
wm
->
next
)
{
peh
=
RtlImageNtHeader
(
wm
->
ldr
.
BaseAddress
);
pdir
=
RtlImageDirectoryEntryToData
(
wm
->
ldr
.
BaseAddress
,
TRUE
,
IMAGE_DIRECTORY_ENTRY_TLS
,
&
dirsize
);
if
(
!
pdir
)
continue
;
delta
=
(
char
*
)
wm
->
ldr
.
BaseAddress
-
(
char
*
)
peh
->
OptionalHeader
.
ImageBase
;
if
(
wm
->
ldr
.
TlsIndex
==
-
1
)
{
LPDWORD
xaddr
;
wm
->
ldr
.
TlsIndex
=
TlsAlloc
();
xaddr
=
_fixup_address
(
&
(
peh
->
OptionalHeader
),
delta
,
pdir
->
AddressOfIndex
);
*
xaddr
=
wm
->
ldr
.
TlsIndex
;
}
datasize
=
pdir
->
EndAddressOfRawData
-
pdir
->
StartAddressOfRawData
;
size
=
datasize
+
pdir
->
SizeOfZeroFill
;
NtAllocateVirtualMemory
(
GetCurrentProcess
(),
&
mem
,
NULL
,
&
size
,
MEM_RESERVE
|
MEM_COMMIT
,
PAGE_READWRITE
);
memcpy
(
mem
,
_fixup_address
(
&
(
peh
->
OptionalHeader
),
delta
,(
LPVOID
)
pdir
->
StartAddressOfRawData
),
datasize
);
TlsSetValue
(
wm
->
ldr
.
TlsIndex
,
mem
);
}
}
scheduler/process.c
View file @
adb53290
...
...
@@ -539,7 +539,6 @@ static void start_process(void)
/* create the main modref and load dependencies */
if
(
!
(
wm
=
PE_CreateModule
(
current_process
.
module
,
main_exe_name
,
0
,
0
,
FALSE
)))
goto
error
;
wm
->
ldr
.
LoadCount
++
;
if
(
main_exe_file
)
CloseHandle
(
main_exe_file
);
/* we no longer need it */
...
...
scheduler/thread.c
View file @
adb53290
...
...
@@ -96,7 +96,6 @@ static BOOL THREAD_InitTEB( TEB *teb )
teb
->
except
=
(
void
*
)
~
0UL
;
teb
->
self
=
teb
;
teb
->
tibflags
=
TEBF_WIN32
;
teb
->
tls_ptr
=
teb
->
tls_array
;
teb
->
exit_code
=
STILL_ACTIVE
;
teb
->
request_fd
=
-
1
;
teb
->
reply_fd
=
-
1
;
...
...
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