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
efd03f40
Commit
efd03f40
authored
Oct 05, 2023
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
server: Assign a system-wide mapping address for dynamic base modules.
parent
4847c1d8
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
200 additions
and
9 deletions
+200
-9
virtual.c
dlls/ntdll/unix/virtual.c
+24
-3
server_protocol.h
include/wine/server_protocol.h
+18
-1
fd.c
server/fd.c
+21
-0
file.h
server/file.h
+4
-0
main.c
server/main.c
+1
-0
mapping.c
server/mapping.c
+102
-3
protocol.def
server/protocol.def
+9
-0
request.h
server/request.h
+7
-1
trace.c
server/trace.c
+13
-0
make_requests
tools/make_requests
+1
-1
No files found.
dlls/ntdll/unix/virtual.c
View file @
efd03f40
...
...
@@ -2936,7 +2936,7 @@ static NTSTATUS map_image_view( struct file_view **view_ret, pe_image_info_t *im
ULONG_PTR
limit_low
,
ULONG_PTR
limit_high
,
ULONG
alloc_type
)
{
unsigned
int
vprot
=
SEC_IMAGE
|
SEC_FILE
|
VPROT_COMMITTED
|
VPROT_READ
|
VPROT_EXEC
|
VPROT_WRITECOPY
;
void
*
base
=
wine_server_get_ptr
(
image_info
->
base
)
;
void
*
base
;
NTSTATUS
status
;
ULONG_PTR
start
,
end
;
BOOL
top_down
=
(
image_info
->
image_charact
&
IMAGE_FILE_DLL
)
&&
...
...
@@ -2947,9 +2947,18 @@ static NTSTATUS map_image_view( struct file_view **view_ret, pe_image_info_t *im
/* first try the specified base */
if
(
base
&&
(
ULONG_PTR
)
base
==
image_info
->
base
)
if
(
image_info
->
map_addr
)
{
base
=
wine_server_get_ptr
(
image_info
->
map_addr
);
if
((
ULONG_PTR
)
base
!=
image_info
->
map_addr
)
base
=
NULL
;
}
else
{
base
=
wine_server_get_ptr
(
image_info
->
base
);
if
((
ULONG_PTR
)
base
!=
image_info
->
base
)
base
=
NULL
;
}
if
(
base
)
{
if
(
top_down
)
alloc_type
|=
MEM_TOP_DOWN
;
status
=
map_view
(
view_ret
,
base
,
size
,
alloc_type
,
vprot
,
limit_low
,
limit_high
,
0
);
if
(
!
status
)
return
status
;
}
...
...
@@ -3005,6 +3014,18 @@ static NTSTATUS virtual_map_image( HANDLE mapping, void **addr_ptr, SIZE_T *size
return
status
;
}
if
(
!
image_info
->
map_addr
&&
(
image_info
->
image_charact
&
IMAGE_FILE_DLL
)
&&
(
image_info
->
image_flags
&
IMAGE_FLAGS_ImageDynamicallyRelocated
))
{
SERVER_START_REQ
(
get_image_map_address
)
{
req
->
handle
=
wine_server_obj_handle
(
mapping
);
if
(
!
wine_server_call
(
req
))
image_info
->
map_addr
=
reply
->
addr
;
}
SERVER_END_REQ
;
}
server_enter_uninterrupted_section
(
&
virtual_mutex
,
&
sigset
);
status
=
map_image_view
(
&
view
,
image_info
,
size
,
limit_low
,
limit_high
,
alloc_type
);
...
...
include/wine/server_protocol.h
View file @
efd03f40
...
...
@@ -827,6 +827,7 @@ typedef union
typedef
struct
{
client_ptr_t
base
;
client_ptr_t
map_addr
;
mem_size_t
stack_size
;
mem_size_t
stack_commit
;
unsigned
int
entry_point
;
...
...
@@ -1997,6 +1998,19 @@ struct get_mapping_info_reply
struct
get_image_map_address_request
{
struct
request_header
__header
;
obj_handle_t
handle
;
};
struct
get_image_map_address_reply
{
struct
reply_header
__header
;
client_ptr_t
addr
;
};
struct
map_view_request
{
struct
request_header
__header
;
...
...
@@ -5687,6 +5701,7 @@ enum request
REQ_create_mapping
,
REQ_open_mapping
,
REQ_get_mapping_info
,
REQ_get_image_map_address
,
REQ_map_view
,
REQ_map_image_view
,
REQ_map_builtin_view
,
...
...
@@ -5977,6 +5992,7 @@ union generic_request
struct
create_mapping_request
create_mapping_request
;
struct
open_mapping_request
open_mapping_request
;
struct
get_mapping_info_request
get_mapping_info_request
;
struct
get_image_map_address_request
get_image_map_address_request
;
struct
map_view_request
map_view_request
;
struct
map_image_view_request
map_image_view_request
;
struct
map_builtin_view_request
map_builtin_view_request
;
...
...
@@ -6265,6 +6281,7 @@ union generic_reply
struct
create_mapping_reply
create_mapping_reply
;
struct
open_mapping_reply
open_mapping_reply
;
struct
get_mapping_info_reply
get_mapping_info_reply
;
struct
get_image_map_address_reply
get_image_map_address_reply
;
struct
map_view_reply
map_view_reply
;
struct
map_image_view_reply
map_image_view_reply
;
struct
map_builtin_view_reply
map_builtin_view_reply
;
...
...
@@ -6487,7 +6504,7 @@ union generic_reply
/* ### protocol_version begin ### */
#define SERVER_PROTOCOL_VERSION 78
3
#define SERVER_PROTOCOL_VERSION 78
4
/* ### protocol_version end ### */
...
...
server/fd.c
View file @
efd03f40
...
...
@@ -136,6 +136,8 @@ struct fd
struct
closed_fd
*
closed
;
/* structure to store the unix fd at destroy time */
struct
object
*
user
;
/* object using this file descriptor */
struct
list
locks
;
/* list of locks on this fd */
client_ptr_t
map_addr
;
/* default mapping address for PE files */
mem_size_t
map_size
;
/* mapping size for PE files */
unsigned
int
access
;
/* file access (FILE_READ_DATA etc.) */
unsigned
int
options
;
/* file options (FILE_DELETE_ON_CLOSE, FILE_SYNCHRONOUS...) */
unsigned
int
sharing
;
/* file sharing mode */
...
...
@@ -1547,6 +1549,7 @@ static void fd_destroy( struct object *obj )
free_async_queue
(
&
fd
->
write_q
);
free_async_queue
(
&
fd
->
wait_q
);
if
(
fd
->
map_addr
)
free_map_addr
(
fd
->
map_addr
,
fd
->
map_size
);
if
(
fd
->
completion
)
release_object
(
fd
->
completion
);
remove_fd_locks
(
fd
);
list_remove
(
&
fd
->
inode_entry
);
...
...
@@ -1665,6 +1668,8 @@ static struct fd *alloc_fd_object(void)
fd
->
user
=
NULL
;
fd
->
inode
=
NULL
;
fd
->
closed
=
NULL
;
fd
->
map_addr
=
0
;
fd
->
map_size
=
0
;
fd
->
access
=
0
;
fd
->
options
=
0
;
fd
->
sharing
=
0
;
...
...
@@ -1703,6 +1708,8 @@ struct fd *alloc_pseudo_fd( const struct fd_ops *fd_user_ops, struct object *use
fd
->
user
=
user
;
fd
->
inode
=
NULL
;
fd
->
closed
=
NULL
;
fd
->
map_addr
=
0
;
fd
->
map_size
=
0
;
fd
->
access
=
0
;
fd
->
options
=
options
;
fd
->
sharing
=
0
;
...
...
@@ -2095,6 +2102,20 @@ int get_unix_fd( struct fd *fd )
return
fd
->
unix_fd
;
}
/* retrieve the suggested mapping address for the fd */
client_ptr_t
get_fd_map_address
(
struct
fd
*
fd
)
{
return
fd
->
map_addr
;
}
/* set the suggested mapping address for the fd */
void
set_fd_map_address
(
struct
fd
*
fd
,
client_ptr_t
addr
,
mem_size_t
size
)
{
assert
(
!
fd
->
map_addr
);
fd
->
map_addr
=
addr
;
fd
->
map_size
=
size
;
}
/* check if two file descriptors point to the same file */
int
is_same_file_fd
(
struct
fd
*
fd1
,
struct
fd
*
fd2
)
{
...
...
server/file.h
View file @
efd03f40
...
...
@@ -94,6 +94,8 @@ extern unsigned int get_fd_options( struct fd *fd );
extern
unsigned
int
get_fd_comp_flags
(
struct
fd
*
fd
);
extern
int
is_fd_overlapped
(
struct
fd
*
fd
);
extern
int
get_unix_fd
(
struct
fd
*
fd
);
extern
client_ptr_t
get_fd_map_address
(
struct
fd
*
fd
);
extern
void
set_fd_map_address
(
struct
fd
*
fd
,
client_ptr_t
addr
,
mem_size_t
size
);
extern
int
is_same_file_fd
(
struct
fd
*
fd1
,
struct
fd
*
fd2
);
extern
int
is_fd_removable
(
struct
fd
*
fd
);
extern
int
check_fd_events
(
struct
fd
*
fd
,
int
events
);
...
...
@@ -172,7 +174,9 @@ extern int is_file_executable( const char *name );
struct
memory_view
;
extern
void
init_memory
(
void
);
extern
int
grow_file
(
int
unix_fd
,
file_pos_t
new_size
);
extern
void
free_map_addr
(
client_ptr_t
base
,
mem_size_t
size
);
extern
struct
memory_view
*
find_mapped_view
(
struct
process
*
process
,
client_ptr_t
base
);
extern
struct
memory_view
*
get_exe_view
(
struct
process
*
process
);
extern
struct
file
*
get_view_file
(
const
struct
memory_view
*
view
,
unsigned
int
access
,
unsigned
int
sharing
);
...
...
server/main.c
View file @
efd03f40
...
...
@@ -232,6 +232,7 @@ int main( int argc, char *argv[] )
if
(
debug_level
)
fprintf
(
stderr
,
"wineserver: starting (pid=%ld)
\n
"
,
(
long
)
getpid
()
);
set_current_time
();
init_signals
();
init_memory
();
init_directories
(
load_intl_file
()
);
init_registry
();
main_loop
();
...
...
server/mapping.c
View file @
efd03f40
...
...
@@ -208,10 +208,31 @@ static const struct fd_ops mapping_fd_ops =
default_fd_reselect_async
/* reselect_async */
};
/* free address ranges for PE image mappings */
struct
addr_range
{
unsigned
int
count
;
unsigned
int
size
;
struct
{
client_ptr_t
base
;
mem_size_t
size
;
}
*
free
;
};
static
size_t
page_mask
;
static
const
mem_size_t
granularity_mask
=
0xffff
;
static
struct
addr_range
ranges32
;
static
struct
addr_range
ranges64
;
#define ROUND_SIZE(size) (((size) + page_mask) & ~page_mask)
void
init_memory
(
void
)
{
page_mask
=
sysconf
(
_SC_PAGESIZE
)
-
1
;
free_map_addr
(
0x60000000
,
0x1c000000
);
free_map_addr
(
0x600000000000
,
0x100000000000
);
}
static
void
ranges_dump
(
struct
object
*
obj
,
int
verbose
)
{
...
...
@@ -826,6 +847,7 @@ static unsigned int get_image_params( struct mapping *mapping, file_pos_t file_s
return
STATUS_INVALID_IMAGE_FORMAT
;
}
mapping
->
image
.
map_addr
=
get_fd_map_address
(
mapping
->
fd
);
mapping
->
image
.
image_charact
=
nt
.
FileHeader
.
Characteristics
;
mapping
->
image
.
machine
=
nt
.
FileHeader
.
Machine
;
mapping
->
image
.
dbg_offset
=
nt
.
FileHeader
.
PointerToSymbolTable
;
...
...
@@ -919,8 +941,6 @@ static struct mapping *create_mapping( struct object *root, const struct unicode
int
unix_fd
;
struct
stat
st
;
if
(
!
page_mask
)
page_mask
=
sysconf
(
_SC_PAGESIZE
)
-
1
;
if
(
!
(
mapping
=
create_named_object
(
root
,
&
mapping_ops
,
name
,
attr
,
sd
)))
return
NULL
;
if
(
get_error
()
==
STATUS_OBJECT_NAME_EXISTS
)
...
...
@@ -1137,9 +1157,70 @@ static enum server_fd_type mapping_get_fd_type( struct fd *fd )
return
FD_TYPE_FILE
;
}
/* assign a mapping address to a PE image mapping */
static
client_ptr_t
assign_map_address
(
struct
mapping
*
mapping
)
{
unsigned
int
i
;
client_ptr_t
ret
;
struct
addr_range
*
range
=
(
mapping
->
image
.
base
>>
32
)
?
&
ranges64
:
&
ranges32
;
mem_size_t
size
=
(
mapping
->
size
+
granularity_mask
)
&
~
granularity_mask
;
if
(
!
(
mapping
->
image
.
image_charact
&
IMAGE_FILE_DLL
))
return
0
;
if
((
ret
=
get_fd_map_address
(
mapping
->
fd
)))
return
ret
;
for
(
i
=
0
;
i
<
range
->
count
;
i
++
)
{
if
(
range
->
free
[
i
].
size
<
size
)
continue
;
range
->
free
[
i
].
size
-=
size
;
ret
=
range
->
free
[
i
].
base
+
range
->
free
[
i
].
size
;
set_fd_map_address
(
mapping
->
fd
,
ret
,
size
);
return
ret
;
}
return
0
;
}
/* free a PE mapping address range when the last mapping is closed */
void
free_map_addr
(
client_ptr_t
base
,
mem_size_t
size
)
{
unsigned
int
i
;
client_ptr_t
end
=
base
+
size
;
struct
addr_range
*
range
=
(
base
>>
32
)
?
&
ranges64
:
&
ranges32
;
for
(
i
=
0
;
i
<
range
->
count
;
i
++
)
{
if
(
range
->
free
[
i
].
base
>
end
)
continue
;
if
(
range
->
free
[
i
].
base
+
range
->
free
[
i
].
size
<
base
)
break
;
if
(
range
->
free
[
i
].
base
==
end
)
{
if
(
i
+
1
<
range
->
count
&&
range
->
free
[
i
+
1
].
base
+
range
->
free
[
i
+
1
].
size
==
base
)
{
size
+=
range
->
free
[
i
].
size
;
range
->
count
--
;
memmove
(
&
range
->
free
[
i
],
&
range
->
free
[
i
+
1
],
(
range
->
count
-
i
)
*
sizeof
(
*
range
->
free
)
);
}
else
range
->
free
[
i
].
base
=
base
;
}
range
->
free
[
i
].
size
+=
size
;
return
;
}
if
(
range
->
count
==
range
->
size
)
{
unsigned
int
new_size
=
max
(
256
,
range
->
size
*
2
);
void
*
new_free
=
realloc
(
range
->
free
,
new_size
*
sizeof
(
*
range
->
free
)
);
if
(
!
new_free
)
return
;
range
->
size
=
new_size
;
range
->
free
=
new_free
;
}
memmove
(
&
range
->
free
[
i
+
1
],
&
range
->
free
[
i
],
(
range
->
count
-
i
)
*
sizeof
(
*
range
->
free
)
);
range
->
free
[
i
].
base
=
base
;
range
->
free
[
i
].
size
=
size
;
range
->
count
++
;
}
int
get_page_size
(
void
)
{
if
(
!
page_mask
)
page_mask
=
sysconf
(
_SC_PAGESIZE
)
-
1
;
return
page_mask
+
1
;
}
...
...
@@ -1233,6 +1314,24 @@ DECL_HANDLER(get_mapping_info)
release_object
(
mapping
);
}
/* get the address to use to map an image mapping */
DECL_HANDLER
(
get_image_map_address
)
{
struct
mapping
*
mapping
;
if
(
!
(
mapping
=
get_mapping_obj
(
current
->
process
,
req
->
handle
,
SECTION_MAP_READ
)))
return
;
if
((
mapping
->
flags
&
SEC_IMAGE
)
&&
(
mapping
->
image
.
image_flags
&
IMAGE_FLAGS_ImageDynamicallyRelocated
))
{
if
(
!
mapping
->
image
.
map_addr
)
mapping
->
image
.
map_addr
=
assign_map_address
(
mapping
);
reply
->
addr
=
mapping
->
image
.
map_addr
;
}
else
set_error
(
STATUS_INVALID_PARAMETER
);
release_object
(
mapping
);
}
/* add a memory view in the current process */
DECL_HANDLER
(
map_view
)
{
...
...
server/protocol.def
View file @
efd03f40
...
...
@@ -843,6 +843,7 @@ typedef union
typedef struct
{
client_ptr_t base;
client_ptr_t map_addr;
mem_size_t stack_size;
mem_size_t stack_commit;
unsigned int entry_point;
...
...
@@ -1612,6 +1613,14 @@ enum server_fd_type
@END
/* Get the address to use to map an image mapping */
@REQ(get_image_map_address)
obj_handle_t handle; /* handle to the mapping */
@REPLY
client_ptr_t addr; /* map address */
@END
/* Add a memory view in the current process */
@REQ(map_view)
obj_handle_t mapping; /* file mapping handle */
...
...
server/request.h
View file @
efd03f40
...
...
@@ -184,6 +184,7 @@ DECL_HANDLER(read_change);
DECL_HANDLER
(
create_mapping
);
DECL_HANDLER
(
open_mapping
);
DECL_HANDLER
(
get_mapping_info
);
DECL_HANDLER
(
get_image_map_address
);
DECL_HANDLER
(
map_view
);
DECL_HANDLER
(
map_image_view
);
DECL_HANDLER
(
map_builtin_view
);
...
...
@@ -473,6 +474,7 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] =
(
req_handler
)
req_create_mapping
,
(
req_handler
)
req_open_mapping
,
(
req_handler
)
req_get_mapping_info
,
(
req_handler
)
req_get_image_map_address
,
(
req_handler
)
req_map_view
,
(
req_handler
)
req_map_image_view
,
(
req_handler
)
req_map_builtin_view
,
...
...
@@ -717,7 +719,7 @@ C_ASSERT( sizeof(mem_size_t) == 8 );
C_ASSERT
(
sizeof
(
message_data_t
)
==
56
);
C_ASSERT
(
sizeof
(
mod_handle_t
)
==
8
);
C_ASSERT
(
sizeof
(
obj_handle_t
)
==
4
);
C_ASSERT
(
sizeof
(
pe_image_info_t
)
==
8
0
);
C_ASSERT
(
sizeof
(
pe_image_info_t
)
==
8
8
);
C_ASSERT
(
sizeof
(
process_id_t
)
==
4
);
C_ASSERT
(
sizeof
(
property_data_t
)
==
16
);
C_ASSERT
(
sizeof
(
rectangle_t
)
==
16
);
...
...
@@ -1143,6 +1145,10 @@ C_ASSERT( FIELD_OFFSET(struct get_mapping_info_reply, flags) == 16 );
C_ASSERT
(
FIELD_OFFSET
(
struct
get_mapping_info_reply
,
shared_file
)
==
20
);
C_ASSERT
(
FIELD_OFFSET
(
struct
get_mapping_info_reply
,
total
)
==
24
);
C_ASSERT
(
sizeof
(
struct
get_mapping_info_reply
)
==
32
);
C_ASSERT
(
FIELD_OFFSET
(
struct
get_image_map_address_request
,
handle
)
==
12
);
C_ASSERT
(
sizeof
(
struct
get_image_map_address_request
)
==
16
);
C_ASSERT
(
FIELD_OFFSET
(
struct
get_image_map_address_reply
,
addr
)
==
8
);
C_ASSERT
(
sizeof
(
struct
get_image_map_address_reply
)
==
16
);
C_ASSERT
(
FIELD_OFFSET
(
struct
map_view_request
,
mapping
)
==
12
);
C_ASSERT
(
FIELD_OFFSET
(
struct
map_view_request
,
access
)
==
16
);
C_ASSERT
(
FIELD_OFFSET
(
struct
map_view_request
,
base
)
==
24
);
...
...
server/trace.c
View file @
efd03f40
...
...
@@ -2199,6 +2199,16 @@ static void dump_get_mapping_info_reply( const struct get_mapping_info_reply *re
dump_varargs_unicode_str
(
", name="
,
cur_size
);
}
static
void
dump_get_image_map_address_request
(
const
struct
get_image_map_address_request
*
req
)
{
fprintf
(
stderr
,
" handle=%04x"
,
req
->
handle
);
}
static
void
dump_get_image_map_address_reply
(
const
struct
get_image_map_address_reply
*
req
)
{
dump_uint64
(
" addr="
,
&
req
->
addr
);
}
static
void
dump_map_view_request
(
const
struct
map_view_request
*
req
)
{
fprintf
(
stderr
,
" mapping=%04x"
,
req
->
mapping
);
...
...
@@ -4662,6 +4672,7 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
(
dump_func
)
dump_create_mapping_request
,
(
dump_func
)
dump_open_mapping_request
,
(
dump_func
)
dump_get_mapping_info_request
,
(
dump_func
)
dump_get_image_map_address_request
,
(
dump_func
)
dump_map_view_request
,
(
dump_func
)
dump_map_image_view_request
,
(
dump_func
)
dump_map_builtin_view_request
,
...
...
@@ -4948,6 +4959,7 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
(
dump_func
)
dump_create_mapping_reply
,
(
dump_func
)
dump_open_mapping_reply
,
(
dump_func
)
dump_get_mapping_info_reply
,
(
dump_func
)
dump_get_image_map_address_reply
,
NULL
,
NULL
,
NULL
,
...
...
@@ -5234,6 +5246,7 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
"create_mapping"
,
"open_mapping"
,
"get_mapping_info"
,
"get_image_map_address"
,
"map_view"
,
"map_image_view"
,
"map_builtin_view"
,
...
...
tools/make_requests
View file @
efd03f40
...
...
@@ -58,7 +58,7 @@ my %formats =
"cursor_pos_t"
=>
[
24
,
8
],
"debug_event_t"
=>
[
160
,
8
],
"message_data_t"
=>
[
56
,
8
],
"pe_image_info_t"
=>
[
8
0
,
8
],
"pe_image_info_t"
=>
[
8
8
,
8
],
"property_data_t"
=>
[
16
,
8
],
"select_op_t"
=>
[
264
,
8
],
"startup_info_t"
=>
[
96
,
4
],
...
...
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