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
db4c4567
Commit
db4c4567
authored
Nov 08, 2000
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Do builtin modules fixups in library/loader.c before calling the
load_dll callback.
parent
4e951ea2
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
169 additions
and
184 deletions
+169
-184
library.h
include/wine/library.h
+1
-3
loader.c
library/loader.c
+155
-6
builtin32.c
relay32/builtin32.c
+13
-175
No files found.
include/wine/library.h
View file @
db4c4567
...
...
@@ -11,9 +11,7 @@
/* dll loading */
struct
_IMAGE_NT_HEADERS
;
typedef
void
(
*
load_dll_callback_t
)(
const
struct
_IMAGE_NT_HEADERS
*
,
const
char
*
);
typedef
void
(
*
load_dll_callback_t
)(
void
*
,
const
char
*
);
extern
void
wine_dll_set_callback
(
load_dll_callback_t
load
);
extern
void
*
wine_dll_load
(
const
char
*
filename
);
...
...
library/loader.c
View file @
db4c4567
...
...
@@ -11,13 +11,17 @@
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#ifdef HAVE_SYS_MMAN_H
#include <sys/mman.h>
#endif
#ifdef HAVE_DL_API
#include <dlfcn.h>
#endif
#include "win
def
.h"
#include "win
nt
.h"
#include "wine/library.h"
#include "wine/port.h"
#define MAX_DLLS 100
...
...
@@ -116,6 +120,151 @@ static void *dlopen_dll( const char *name )
}
/* adjust an array of pointers to make them into RVAs */
static
inline
void
fixup_rva_ptrs
(
void
*
array
,
void
*
base
,
int
count
)
{
void
**
ptr
=
(
void
**
)
array
;
while
(
count
--
)
{
if
(
*
ptr
)
*
ptr
=
(
void
*
)((
char
*
)
*
ptr
-
(
char
*
)
base
);
ptr
++
;
}
}
/* fixup RVAs in the resource directory */
static
void
fixup_resources
(
IMAGE_RESOURCE_DIRECTORY
*
dir
,
char
*
root
,
void
*
base
)
{
IMAGE_RESOURCE_DIRECTORY_ENTRY
*
entry
;
int
i
;
entry
=
(
IMAGE_RESOURCE_DIRECTORY_ENTRY
*
)(
dir
+
1
);
for
(
i
=
0
;
i
<
dir
->
NumberOfNamedEntries
+
dir
->
NumberOfIdEntries
;
i
++
,
entry
++
)
{
void
*
ptr
=
root
+
entry
->
u2
.
s
.
OffsetToDirectory
;
if
(
entry
->
u2
.
s
.
DataIsDirectory
)
fixup_resources
(
ptr
,
root
,
base
);
else
{
IMAGE_RESOURCE_DATA_ENTRY
*
data
=
ptr
;
fixup_rva_ptrs
(
&
data
->
OffsetToData
,
base
,
1
);
}
}
}
/* map a builtin dll in memory and fixup RVAs */
static
void
*
map_dll
(
const
IMAGE_NT_HEADERS
*
nt_descr
)
{
IMAGE_DATA_DIRECTORY
*
dir
;
IMAGE_DOS_HEADER
*
dos
;
IMAGE_NT_HEADERS
*
nt
;
IMAGE_SECTION_HEADER
*
sec
;
BYTE
*
addr
,
*
code_start
,
*
data_start
;
size_t
page_size
=
getpagesize
();
int
nb_sections
=
2
;
/* code + data */
size_t
size
=
(
sizeof
(
IMAGE_DOS_HEADER
)
+
sizeof
(
IMAGE_NT_HEADERS
)
+
nb_sections
*
sizeof
(
IMAGE_SECTION_HEADER
));
assert
(
size
<=
page_size
);
if
(
nt_descr
->
OptionalHeader
.
ImageBase
)
{
addr
=
wine_anon_mmap
(
(
void
*
)
nt_descr
->
OptionalHeader
.
ImageBase
,
page_size
,
PROT_READ
|
PROT_WRITE
,
MAP_FIXED
);
if
(
addr
!=
(
BYTE
*
)
nt_descr
->
OptionalHeader
.
ImageBase
)
return
NULL
;
}
else
{
/* this will leak memory; but it should never happen */
addr
=
wine_anon_mmap
(
NULL
,
page_size
,
PROT_READ
|
PROT_WRITE
,
0
);
if
(
addr
==
(
BYTE
*
)
-
1
)
return
NULL
;
}
dos
=
(
IMAGE_DOS_HEADER
*
)
addr
;
nt
=
(
IMAGE_NT_HEADERS
*
)(
dos
+
1
);
sec
=
(
IMAGE_SECTION_HEADER
*
)(
nt
+
1
);
code_start
=
addr
+
page_size
;
/* HACK! */
data_start
=
code_start
+
page_size
;
/* Build the DOS and NT headers */
dos
->
e_magic
=
IMAGE_DOS_SIGNATURE
;
dos
->
e_lfanew
=
sizeof
(
*
dos
);
*
nt
=
*
nt_descr
;
nt
->
FileHeader
.
NumberOfSections
=
nb_sections
;
nt
->
OptionalHeader
.
SizeOfCode
=
data_start
-
code_start
;
nt
->
OptionalHeader
.
SizeOfInitializedData
=
0
;
nt
->
OptionalHeader
.
SizeOfUninitializedData
=
0
;
nt
->
OptionalHeader
.
ImageBase
=
(
DWORD
)
addr
;
fixup_rva_ptrs
(
&
nt
->
OptionalHeader
.
AddressOfEntryPoint
,
addr
,
1
);
/* Build the code section */
strcpy
(
sec
->
Name
,
".text"
);
sec
->
SizeOfRawData
=
data_start
-
code_start
;
sec
->
Misc
.
VirtualSize
=
sec
->
SizeOfRawData
;
sec
->
VirtualAddress
=
code_start
-
addr
;
sec
->
PointerToRawData
=
code_start
-
addr
;
sec
->
Characteristics
=
(
IMAGE_SCN_CNT_CODE
|
IMAGE_SCN_MEM_EXECUTE
|
IMAGE_SCN_MEM_READ
);
sec
++
;
/* Build the data section */
strcpy
(
sec
->
Name
,
".data"
);
sec
->
SizeOfRawData
=
0
;
sec
->
Misc
.
VirtualSize
=
sec
->
SizeOfRawData
;
sec
->
VirtualAddress
=
data_start
-
addr
;
sec
->
PointerToRawData
=
data_start
-
addr
;
sec
->
Characteristics
=
(
IMAGE_SCN_CNT_INITIALIZED_DATA
|
IMAGE_SCN_MEM_WRITE
|
IMAGE_SCN_MEM_READ
);
sec
++
;
/* Build the import directory */
dir
=
&
nt
->
OptionalHeader
.
DataDirectory
[
IMAGE_FILE_IMPORT_DIRECTORY
];
if
(
dir
->
Size
)
{
IMAGE_IMPORT_DESCRIPTOR
*
imports
=
(
void
*
)
dir
->
VirtualAddress
;
fixup_rva_ptrs
(
&
dir
->
VirtualAddress
,
addr
,
1
);
/* we can fixup everything at once since we only have pointers and 0 values */
fixup_rva_ptrs
(
imports
,
addr
,
dir
->
Size
/
sizeof
(
void
*
)
);
}
/* Build the resource directory */
dir
=
&
nt
->
OptionalHeader
.
DataDirectory
[
IMAGE_FILE_RESOURCE_DIRECTORY
];
if
(
dir
->
Size
)
{
void
*
ptr
=
(
void
*
)
dir
->
VirtualAddress
;
fixup_rva_ptrs
(
&
dir
->
VirtualAddress
,
addr
,
1
);
fixup_resources
(
ptr
,
ptr
,
addr
);
}
/* Build the export directory */
dir
=
&
nt
->
OptionalHeader
.
DataDirectory
[
IMAGE_FILE_EXPORT_DIRECTORY
];
if
(
dir
->
Size
)
{
IMAGE_EXPORT_DIRECTORY
*
exports
=
(
void
*
)
dir
->
VirtualAddress
;
fixup_rva_ptrs
(
&
dir
->
VirtualAddress
,
addr
,
1
);
fixup_rva_ptrs
(
(
void
*
)
exports
->
AddressOfFunctions
,
addr
,
exports
->
NumberOfFunctions
);
fixup_rva_ptrs
(
(
void
*
)
exports
->
AddressOfNames
,
addr
,
exports
->
NumberOfNames
);
fixup_rva_ptrs
(
&
exports
->
Name
,
addr
,
1
);
fixup_rva_ptrs
(
&
exports
->
AddressOfFunctions
,
addr
,
1
);
fixup_rva_ptrs
(
&
exports
->
AddressOfNames
,
addr
,
1
);
fixup_rva_ptrs
(
&
exports
->
AddressOfNameOrdinals
,
addr
,
1
);
}
return
addr
;
}
/***********************************************************************
* __wine_dll_register
*
...
...
@@ -123,7 +272,7 @@ static void *dlopen_dll( const char *name )
*/
void
__wine_dll_register
(
const
IMAGE_NT_HEADERS
*
header
,
const
char
*
filename
)
{
if
(
load_dll_callback
)
load_dll_callback
(
header
,
filename
);
if
(
load_dll_callback
)
load_dll_callback
(
map_dll
(
header
)
,
filename
);
else
{
if
(
!
(
header
->
FileHeader
.
Characteristics
&
IMAGE_FILE_DLL
))
...
...
@@ -154,10 +303,10 @@ void wine_dll_set_callback( load_dll_callback_t load )
const
IMAGE_NT_HEADERS
*
nt
=
builtin_dlls
[
i
].
nt
;
if
(
!
nt
)
continue
;
builtin_dlls
[
i
].
nt
=
NULL
;
load_dll_callback
(
nt
,
builtin_dlls
[
i
].
filename
);
load_dll_callback
(
map_dll
(
nt
)
,
builtin_dlls
[
i
].
filename
);
}
nb_dlls
=
0
;
if
(
main_exe
)
load_dll_callback
(
ma
in_exe
,
""
);
if
(
main_exe
)
load_dll_callback
(
ma
p_dll
(
main_exe
)
,
""
);
}
...
...
@@ -182,7 +331,7 @@ void *wine_dll_load( const char *filename )
{
const
IMAGE_NT_HEADERS
*
nt
=
builtin_dlls
[
i
].
nt
;
builtin_dlls
[
i
].
nt
=
NULL
;
load_dll_callback
(
nt
,
builtin_dlls
[
i
].
filename
);
load_dll_callback
(
map_dll
(
nt
)
,
builtin_dlls
[
i
].
filename
);
return
(
void
*
)
1
;
}
}
...
...
relay32/builtin32.c
View file @
db4c4567
...
...
@@ -47,15 +47,14 @@ void *BUILTIN32_dlopen( const char *name )
if
(
!
(
handle
=
wine_dll_load
(
name
)))
{
char
buffer
[
128
];
LPSTR
pErr
,
p
;
pErr
=
dlerror
();
p
=
strchr
(
pErr
,
':'
);
if
((
p
)
&&
(
!
strncmp
(
p
,
": undefined symbol"
,
18
)))
/* undef symbol -> ERR() */
ERR
(
"failed to load %s: %s
\n
"
,
buffer
,
pErr
);
ERR
(
"failed to load %s: %s
\n
"
,
name
,
pErr
);
else
/* WARN() for libraries that are supposed to be native */
WARN
(
"failed to load %s: %s
\n
"
,
buffer
,
pErr
);
WARN
(
"failed to load %s: %s
\n
"
,
name
,
pErr
);
}
return
handle
;
#else
...
...
@@ -77,192 +76,31 @@ int BUILTIN32_dlclose( void *handle )
/***********************************************************************
* fixup_rva_ptrs
*
* Adjust an array of pointers to make them into RVAs.
*/
static
inline
void
fixup_rva_ptrs
(
void
*
array
,
void
*
base
,
int
count
)
{
void
**
ptr
=
(
void
**
)
array
;
while
(
count
--
)
{
if
(
*
ptr
)
*
ptr
=
(
void
*
)((
char
*
)
*
ptr
-
(
char
*
)
base
);
ptr
++
;
}
}
/***********************************************************************
* fixup_resources
*/
static
void
fixup_resources
(
IMAGE_RESOURCE_DIRECTORY
*
dir
,
char
*
root
,
void
*
base
)
{
IMAGE_RESOURCE_DIRECTORY_ENTRY
*
entry
;
int
i
;
entry
=
(
IMAGE_RESOURCE_DIRECTORY_ENTRY
*
)(
dir
+
1
);
for
(
i
=
0
;
i
<
dir
->
NumberOfNamedEntries
+
dir
->
NumberOfIdEntries
;
i
++
,
entry
++
)
{
void
*
ptr
=
root
+
entry
->
u2
.
s
.
OffsetToDirectory
;
if
(
entry
->
u2
.
s
.
DataIsDirectory
)
fixup_resources
(
ptr
,
root
,
base
);
else
{
IMAGE_RESOURCE_DATA_ENTRY
*
data
=
ptr
;
fixup_rva_ptrs
(
&
data
->
OffsetToData
,
base
,
1
);
}
}
}
/***********************************************************************
* load_image
*
* Load a built-in Win32 module. Helper function for load_library.
*/
static
HMODULE
load_image
(
const
IMAGE_NT_HEADERS
*
nt_descr
,
const
char
*
filename
)
{
IMAGE_DATA_DIRECTORY
*
dir
;
IMAGE_DOS_HEADER
*
dos
;
IMAGE_NT_HEADERS
*
nt
;
IMAGE_SECTION_HEADER
*
sec
;
INT
size
,
nb_sections
;
BYTE
*
addr
,
*
code_start
,
*
data_start
;
int
page_size
=
VIRTUAL_GetPageSize
();
/* Allocate the module */
nb_sections
=
2
;
/* code + data */
size
=
(
sizeof
(
IMAGE_DOS_HEADER
)
+
sizeof
(
IMAGE_NT_HEADERS
)
+
nb_sections
*
sizeof
(
IMAGE_SECTION_HEADER
));
assert
(
size
<=
page_size
);
if
(
nt_descr
->
OptionalHeader
.
ImageBase
)
{
void
*
base
=
(
void
*
)
nt_descr
->
OptionalHeader
.
ImageBase
;
if
((
addr
=
wine_anon_mmap
(
base
,
page_size
,
PROT_READ
|
PROT_WRITE
,
MAP_FIXED
))
!=
base
)
{
ERR
(
"failed to map over PE header for %s at %p
\n
"
,
filename
,
base
);
return
0
;
}
}
else
{
if
(
!
(
addr
=
VirtualAlloc
(
NULL
,
page_size
,
MEM_COMMIT
,
PAGE_READWRITE
)))
return
0
;
}
dos
=
(
IMAGE_DOS_HEADER
*
)
addr
;
nt
=
(
IMAGE_NT_HEADERS
*
)(
dos
+
1
);
sec
=
(
IMAGE_SECTION_HEADER
*
)(
nt
+
1
);
code_start
=
addr
+
page_size
;
/* HACK! */
data_start
=
code_start
+
page_size
;
/* Build the DOS and NT headers */
dos
->
e_magic
=
IMAGE_DOS_SIGNATURE
;
dos
->
e_lfanew
=
sizeof
(
*
dos
);
*
nt
=
*
nt_descr
;
nt
->
FileHeader
.
NumberOfSections
=
nb_sections
;
nt
->
OptionalHeader
.
SizeOfCode
=
data_start
-
code_start
;
nt
->
OptionalHeader
.
SizeOfInitializedData
=
0
;
nt
->
OptionalHeader
.
SizeOfUninitializedData
=
0
;
nt
->
OptionalHeader
.
ImageBase
=
(
DWORD
)
addr
;
fixup_rva_ptrs
(
&
nt
->
OptionalHeader
.
AddressOfEntryPoint
,
addr
,
1
);
/* Build the code section */
strcpy
(
sec
->
Name
,
".text"
);
sec
->
SizeOfRawData
=
data_start
-
code_start
;
sec
->
Misc
.
VirtualSize
=
sec
->
SizeOfRawData
;
sec
->
VirtualAddress
=
code_start
-
addr
;
sec
->
PointerToRawData
=
code_start
-
addr
;
sec
->
Characteristics
=
(
IMAGE_SCN_CNT_CODE
|
IMAGE_SCN_MEM_EXECUTE
|
IMAGE_SCN_MEM_READ
);
sec
++
;
/* Build the data section */
strcpy
(
sec
->
Name
,
".data"
);
sec
->
SizeOfRawData
=
0
;
sec
->
Misc
.
VirtualSize
=
sec
->
SizeOfRawData
;
sec
->
VirtualAddress
=
data_start
-
addr
;
sec
->
PointerToRawData
=
data_start
-
addr
;
sec
->
Characteristics
=
(
IMAGE_SCN_CNT_INITIALIZED_DATA
|
IMAGE_SCN_MEM_WRITE
|
IMAGE_SCN_MEM_READ
);
sec
++
;
/* Build the import directory */
dir
=
&
nt
->
OptionalHeader
.
DataDirectory
[
IMAGE_FILE_IMPORT_DIRECTORY
];
if
(
dir
->
Size
)
{
IMAGE_IMPORT_DESCRIPTOR
*
imports
=
(
void
*
)
dir
->
VirtualAddress
;
fixup_rva_ptrs
(
&
dir
->
VirtualAddress
,
addr
,
1
);
/* we can fixup everything at once since we only have pointers and 0 values */
fixup_rva_ptrs
(
imports
,
addr
,
dir
->
Size
/
sizeof
(
void
*
)
);
}
/* Build the resource directory */
dir
=
&
nt
->
OptionalHeader
.
DataDirectory
[
IMAGE_FILE_RESOURCE_DIRECTORY
];
if
(
dir
->
Size
)
{
void
*
ptr
=
(
void
*
)
dir
->
VirtualAddress
;
fixup_rva_ptrs
(
&
dir
->
VirtualAddress
,
addr
,
1
);
fixup_resources
(
ptr
,
ptr
,
addr
);
}
/* Build the export directory */
dir
=
&
nt
->
OptionalHeader
.
DataDirectory
[
IMAGE_FILE_EXPORT_DIRECTORY
];
if
(
dir
->
Size
)
{
IMAGE_EXPORT_DIRECTORY
*
exports
=
(
void
*
)
dir
->
VirtualAddress
;
fixup_rva_ptrs
(
&
dir
->
VirtualAddress
,
addr
,
1
);
fixup_rva_ptrs
(
(
void
*
)
exports
->
AddressOfFunctions
,
addr
,
exports
->
NumberOfFunctions
);
fixup_rva_ptrs
(
(
void
*
)
exports
->
AddressOfNames
,
addr
,
exports
->
NumberOfNames
);
fixup_rva_ptrs
(
&
exports
->
Name
,
addr
,
1
);
fixup_rva_ptrs
(
&
exports
->
AddressOfFunctions
,
addr
,
1
);
fixup_rva_ptrs
(
&
exports
->
AddressOfNames
,
addr
,
1
);
fixup_rva_ptrs
(
&
exports
->
AddressOfNameOrdinals
,
addr
,
1
);
/* Setup relay debugging entry points */
if
(
TRACE_ON
(
relay
))
RELAY_SetupDLL
(
addr
);
}
return
(
HMODULE
)
addr
;
}
/***********************************************************************
* load_library
*
* Load a library in memory; callback function for wine_dll_register
*/
static
void
load_library
(
const
IMAGE_NT_HEADERS
*
nt
,
const
char
*
filename
)
static
void
load_library
(
void
*
base
,
const
char
*
filename
)
{
HMODULE
module
;
HMODULE
module
=
(
HMODULE
)
base
;
WINE_MODREF
*
wm
;
if
(
!
(
nt
->
FileHeader
.
Characteristics
&
IMAGE_FILE_DLL
))
if
(
!
base
)
{
ERR
(
"could not map image for %s
\n
"
,
filename
?
filename
:
"main exe"
);
return
;
}
if
(
!
(
PE_HEADER
(
module
)
->
FileHeader
.
Characteristics
&
IMAGE_FILE_DLL
))
{
/* if we already have an executable, ignore this one */
if
(
!
main_module
)
main_module
=
load_image
(
nt
,
"main exe"
)
;
if
(
!
main_module
)
main_module
=
module
;
return
;
/* don't create the modref here, will be done later on */
}
if
(
GetModuleHandleA
(
filename
))
MESSAGE
(
"Warning: loading builtin %s, but native version already present. Expect trouble.
\n
"
,
filename
);
/* Load built-in module */
if
(
!
(
module
=
load_image
(
nt
,
filename
)))
return
;
/* Create 32-bit MODREF */
if
(
!
(
wm
=
PE_CreateModule
(
module
,
filename
,
0
,
-
1
,
TRUE
)))
{
...
...
@@ -270,7 +108,7 @@ static void load_library( const IMAGE_NT_HEADERS *nt, const char *filename )
SetLastError
(
ERROR_OUTOFMEMORY
);
return
;
}
TRACE
(
"loaded %s %p %x
%p
\n
"
,
filename
,
wm
,
module
,
nt
);
TRACE
(
"loaded %s %p %x
\n
"
,
filename
,
wm
,
module
);
wm
->
refCount
++
;
/* we don't support freeing builtin dlls (FIXME)*/
}
...
...
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