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( &current->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