ntdll: Create a SEC_IMAGE view also for .so builtins.

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Alexandre Julliard 2021-01-26 11:55:37 +01:00
parent 6b90b96e21
commit ced3892c65
7 changed files with 62 additions and 26 deletions

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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 ### */

View File

@ -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:

View File

@ -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

View File

@ -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 )