Alexandre Julliard : ntdll: Create a SEC_IMAGE view also for .so builtins.
Alexandre Julliard
julliard at winehq.org
Tue Jan 26 15:54:06 CST 2021
Module: wine
Branch: master
Commit: ced3892c65b33149a490b2c2191098c0c6aa1eeb
URL: https://source.winehq.org/git/wine.git/?a=commit;h=ced3892c65b33149a490b2c2191098c0c6aa1eeb
Author: Alexandre Julliard <julliard at winehq.org>
Date: Tue Jan 26 11:55:37 2021 +0100
ntdll: Create a SEC_IMAGE view also for .so builtins.
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/ntdll/unix/loader.c | 2 +-
dlls/ntdll/unix/unix_private.h | 2 +-
dlls/ntdll/unix/virtual.c | 47 +++++++++++++++++++++++-------------------
include/wine/server_protocol.h | 3 ++-
server/mapping.c | 30 ++++++++++++++++++++++++++-
server/protocol.def | 3 ++-
server/trace.c | 1 +
7 files changed, 62 insertions(+), 26 deletions(-)
diff --git a/dlls/ntdll/unix/loader.c b/dlls/ntdll/unix/loader.c
index 5e2d5aeff7c..8caddb19abf 100644
--- a/dlls/ntdll/unix/loader.c
+++ b/dlls/ntdll/unix/loader.c
@@ -1028,7 +1028,7 @@ static NTSTATUS dlopen_dll( const char *so_name, void **ret_module, pe_image_inf
dlclose( handle );
return STATUS_NO_MEMORY;
}
- virtual_create_builtin_view( module );
+ virtual_create_builtin_view( module, image_info );
*ret_module = module;
return STATUS_SUCCESS;
diff --git a/dlls/ntdll/unix/unix_private.h b/dlls/ntdll/unix/unix_private.h
index f8f50d0ab27..1d6ba95d2a1 100644
--- a/dlls/ntdll/unix/unix_private.h
+++ b/dlls/ntdll/unix/unix_private.h
@@ -179,7 +179,7 @@ extern void *anon_mmap_alloc( size_t size, int prot ) DECLSPEC_HIDDEN;
extern void virtual_init(void) DECLSPEC_HIDDEN;
extern ULONG_PTR get_system_affinity_mask(void) DECLSPEC_HIDDEN;
extern void virtual_get_system_info( SYSTEM_BASIC_INFORMATION *info ) DECLSPEC_HIDDEN;
-extern NTSTATUS virtual_create_builtin_view( void *module ) DECLSPEC_HIDDEN;
+extern NTSTATUS virtual_create_builtin_view( void *module, pe_image_info_t *info ) DECLSPEC_HIDDEN;
extern TEB *virtual_alloc_first_teb(void) DECLSPEC_HIDDEN;
extern NTSTATUS virtual_alloc_teb( TEB **ret_teb ) DECLSPEC_HIDDEN;
extern void virtual_free_teb( TEB *teb ) DECLSPEC_HIDDEN;
diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c
index e96bda722f6..c1e79a210f4 100644
--- a/dlls/ntdll/unix/virtual.c
+++ b/dlls/ntdll/unix/virtual.c
@@ -2483,20 +2483,18 @@ void virtual_get_system_info( SYSTEM_BASIC_INFORMATION *info )
/***********************************************************************
* virtual_create_builtin_view
*/
-NTSTATUS virtual_create_builtin_view( void *module )
+NTSTATUS virtual_create_builtin_view( void *module, pe_image_info_t *info )
{
NTSTATUS status;
sigset_t sigset;
IMAGE_DOS_HEADER *dos = module;
IMAGE_NT_HEADERS *nt = (IMAGE_NT_HEADERS *)((char *)dos + dos->e_lfanew);
- SIZE_T size = nt->OptionalHeader.SizeOfImage;
+ SIZE_T size = info->map_size;
IMAGE_SECTION_HEADER *sec;
struct file_view *view;
- void *base;
+ void *base = wine_server_get_ptr( info->base );
int i;
- size = ROUND_SIZE( module, size );
- base = ROUND_ADDR( module, page_mask );
server_enter_uninterrupted_section( &virtual_mutex, &sigset );
status = create_view( &view, base, size, SEC_IMAGE | SEC_FILE | VPROT_SYSTEM |
VPROT_COMMITTED | VPROT_READ | VPROT_WRITECOPY | VPROT_EXEC );
@@ -2517,10 +2515,25 @@ NTSTATUS virtual_create_builtin_view( void *module )
if (sec[i].Characteristics & IMAGE_SCN_MEM_WRITE) flags |= VPROT_WRITE;
set_page_vprot( (char *)base + sec[i].VirtualAddress, sec[i].Misc.VirtualSize, flags );
}
- VIRTUAL_DEBUG_DUMP_VIEW( view );
- if (is_beyond_limit( base, size, working_set_limit )) working_set_limit = address_space_limit;
+
+ SERVER_START_REQ( map_view )
+ {
+ req->base = wine_server_client_ptr( view->base );
+ req->size = size;
+ wine_server_add_data( req, info, sizeof(*info) );
+ status = wine_server_call( req );
+ }
+ SERVER_END_REQ;
+
+ if (status >= 0)
+ {
+ VIRTUAL_DEBUG_DUMP_VIEW( view );
+ if (is_beyond_limit( base, size, working_set_limit )) working_set_limit = address_space_limit;
+ }
+ else delete_view( view );
}
server_leave_uninterrupted_section( &virtual_mutex, &sigset );
+
return status;
}
@@ -4065,22 +4078,14 @@ NTSTATUS WINAPI NtUnmapViewOfSection( HANDLE process, PVOID addr )
server_enter_uninterrupted_section( &virtual_mutex, &sigset );
if ((view = find_view( addr, 0 )) && !is_view_valloc( view ))
{
- if (!(view->protect & VPROT_SYSTEM))
+ SERVER_START_REQ( unmap_view )
{
- SERVER_START_REQ( unmap_view )
- {
- req->base = wine_server_client_ptr( view->base );
- status = wine_server_call( req );
- }
- SERVER_END_REQ;
- if (!status) delete_view( view );
- else FIXME( "failed to unmap %p %x\n", view->base, status );
- }
- else
- {
- delete_view( view );
- status = STATUS_SUCCESS;
+ req->base = wine_server_client_ptr( view->base );
+ status = wine_server_call( req );
}
+ SERVER_END_REQ;
+ if (!status) delete_view( view );
+ else FIXME( "failed to unmap %p %x\n", view->base, status );
}
server_leave_uninterrupted_section( &virtual_mutex, &sigset );
return status;
diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h
index 0dd5803a79e..f070c604fdd 100644
--- a/include/wine/server_protocol.h
+++ b/include/wine/server_protocol.h
@@ -1903,6 +1903,7 @@ struct map_view_request
client_ptr_t base;
mem_size_t size;
file_pos_t start;
+ /* VARARG(image,pe_image_info); */
};
struct map_view_reply
{
@@ -6190,7 +6191,7 @@ union generic_reply
/* ### protocol_version begin ### */
-#define SERVER_PROTOCOL_VERSION 653
+#define SERVER_PROTOCOL_VERSION 654
/* ### protocol_version end ### */
diff --git a/server/mapping.c b/server/mapping.c
index 4e38e8e40da..9c51aa3bec7 100644
--- a/server/mapping.c
+++ b/server/mapping.c
@@ -316,6 +316,21 @@ static struct memory_view *find_mapped_view( struct process *process, client_ptr
return NULL;
}
+/* add a view to the process list */
+static void add_process_view( struct process *process, struct memory_view *view )
+{
+ if (view->flags & SEC_IMAGE)
+ {
+ if (!is_process_init_done( process ) && !(view->image.image_charact & IMAGE_FILE_DLL))
+ {
+ /* main exe */
+ list_add_head( &process->views, &view->entry );
+ return;
+ }
+ }
+ list_add_tail( &process->views, &view->entry );
+}
+
static void free_memory_view( struct memory_view *view )
{
if (view->fd) release_object( view->fd );
@@ -1097,6 +1112,19 @@ DECL_HANDLER(map_view)
return;
}
+ if (!req->mapping) /* image mapping for a .so dll */
+ {
+ if (!(view = mem_alloc( sizeof(*view) ))) return;
+ memset( view, 0, sizeof(*view) );
+ view->base = req->base;
+ view->size = req->size;
+ view->start = req->start;
+ view->flags = SEC_IMAGE;
+ memcpy( &view->image, get_req_data(), min( sizeof(view->image), get_req_data_size() ));
+ add_process_view( current->process, view );
+ return;
+ }
+
if (!(mapping = get_mapping_obj( current->process, req->mapping, req->access ))) return;
if (mapping->flags & SEC_IMAGE)
@@ -1129,7 +1157,7 @@ DECL_HANDLER(map_view)
view->image = mapping->image;
if (view->base != mapping->image.base) set_error( STATUS_IMAGE_NOT_AT_BASE );
}
- list_add_tail( ¤t->process->views, &view->entry );
+ add_process_view( current->process, view );
}
done:
diff --git a/server/protocol.def b/server/protocol.def
index e6c23aa77b0..bac6b58e215 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -1515,11 +1515,12 @@ enum server_fd_type
/* Add a memory view in the current process */
@REQ(map_view)
- obj_handle_t mapping; /* file mapping handle */
+ obj_handle_t mapping; /* file mapping handle, or 0 for .so builtin */
unsigned int access; /* wanted access rights */
client_ptr_t base; /* view base address (page-aligned) */
mem_size_t size; /* view size */
file_pos_t start; /* start offset in mapping */
+ VARARG(image,pe_image_info);/* image info for .so builtins */
@END
diff --git a/server/trace.c b/server/trace.c
index 4c1ff57186b..750b83281c8 100644
--- a/server/trace.c
+++ b/server/trace.c
@@ -2107,6 +2107,7 @@ static void dump_map_view_request( const struct map_view_request *req )
dump_uint64( ", base=", &req->base );
dump_uint64( ", size=", &req->size );
dump_uint64( ", start=", &req->start );
+ dump_varargs_pe_image_info( ", image=", cur_size );
}
static void dump_unmap_view_request( const struct unmap_view_request *req )
More information about the wine-cvs
mailing list