Commit cb14be78 authored by Alexandre Julliard's avatar Alexandre Julliard

ntdll: Move the builtin image checks to virtual_map_builtin_module().

parent 24a5a101
...@@ -94,8 +94,6 @@ ...@@ -94,8 +94,6 @@
WINE_DEFAULT_DEBUG_CHANNEL(module); WINE_DEFAULT_DEBUG_CHANNEL(module);
#define IMAGE_DLLCHARACTERISTICS_PREFER_NATIVE 0x0010 /* Wine extension */
void (WINAPI *pDbgUiRemoteBreakin)( void *arg ) = NULL; void (WINAPI *pDbgUiRemoteBreakin)( void *arg ) = NULL;
NTSTATUS (WINAPI *pKiRaiseUserExceptionDispatcher)(void) = NULL; NTSTATUS (WINAPI *pKiRaiseUserExceptionDispatcher)(void) = NULL;
void (WINAPI *pKiUserApcDispatcher)(CONTEXT*,ULONG_PTR,ULONG_PTR,ULONG_PTR,PNTAPCFUNC) = NULL; void (WINAPI *pKiUserApcDispatcher)(CONTEXT*,ULONG_PTR,ULONG_PTR,ULONG_PTR,PNTAPCFUNC) = NULL;
...@@ -1169,23 +1167,6 @@ static NTSTATUS CDECL load_so_dll( UNICODE_STRING *nt_name, void **module ) ...@@ -1169,23 +1167,6 @@ static NTSTATUS CDECL load_so_dll( UNICODE_STRING *nt_name, void **module )
} }
/* check a PE library architecture */
static BOOL is_valid_binary( const SECTION_IMAGE_INFORMATION *info )
{
#ifdef __i386__
return info->Machine == IMAGE_FILE_MACHINE_I386;
#elif defined(__arm__)
return info->Machine == IMAGE_FILE_MACHINE_ARM ||
info->Machine == IMAGE_FILE_MACHINE_THUMB ||
info->Machine == IMAGE_FILE_MACHINE_ARMNT;
#elif defined(__x86_64__)
/* we don't support 32-bit IL-only builtins yet */
return info->Machine == IMAGE_FILE_MACHINE_AMD64;
#elif defined(__aarch64__)
return info->Machine == IMAGE_FILE_MACHINE_ARM64;
#endif
}
/* check if the library is the correct architecture */ /* check if the library is the correct architecture */
/* only returns false for a valid library of the wrong arch */ /* only returns false for a valid library of the wrong arch */
static int check_library_arch( int fd ) static int check_library_arch( int fd )
...@@ -1234,7 +1215,8 @@ static inline char *prepend( char *buffer, const char *str, size_t len ) ...@@ -1234,7 +1215,8 @@ static inline char *prepend( char *buffer, const char *str, size_t len )
* Open a file for a new dll. Helper for open_builtin_file. * Open a file for a new dll. Helper for open_builtin_file.
*/ */
static NTSTATUS open_dll_file( const char *name, OBJECT_ATTRIBUTES *attr, void **module, static NTSTATUS open_dll_file( const char *name, OBJECT_ATTRIBUTES *attr, void **module,
SIZE_T *size_ptr, SECTION_IMAGE_INFORMATION *image_info, BOOL prefer_native ) SIZE_T *size_ptr, SECTION_IMAGE_INFORMATION *image_info,
WORD machine, BOOL prefer_native )
{ {
LARGE_INTEGER size; LARGE_INTEGER size;
NTSTATUS status; NTSTATUS status;
...@@ -1261,27 +1243,7 @@ static NTSTATUS open_dll_file( const char *name, OBJECT_ATTRIBUTES *attr, void * ...@@ -1261,27 +1243,7 @@ static NTSTATUS open_dll_file( const char *name, OBJECT_ATTRIBUTES *attr, void *
NtClose( handle ); NtClose( handle );
if (status) return status; if (status) return status;
NtQuerySection( mapping, SectionImageInformation, image_info, sizeof(*image_info), NULL ); status = virtual_map_builtin_module( mapping, module, size_ptr, image_info, machine, prefer_native );
/* ignore non-builtins */
if (!(image_info->u.s.WineBuiltin))
{
WARN( "%s found in WINEDLLPATH but not a builtin, ignoring\n", debugstr_a(name) );
NtClose( mapping );
return STATUS_DLL_NOT_FOUND;
}
if (!is_valid_binary( image_info ))
{
TRACE( "%s is for arch %x, continuing search\n", debugstr_a(name), image_info->Machine );
NtClose( mapping );
return STATUS_IMAGE_MACHINE_TYPE_MISMATCH;
}
if (prefer_native && (image_info->DllCharacteristics & IMAGE_DLLCHARACTERISTICS_PREFER_NATIVE))
{
TRACE( "%s has prefer-native flag, ignoring builtin\n", debugstr_a(name) );
NtClose( mapping );
return STATUS_IMAGE_ALREADY_LOADED;
}
status = virtual_map_builtin_module( mapping, module, size_ptr );
NtClose( mapping ); NtClose( mapping );
return status; return status;
} }
...@@ -1291,13 +1253,13 @@ static NTSTATUS open_dll_file( const char *name, OBJECT_ATTRIBUTES *attr, void * ...@@ -1291,13 +1253,13 @@ static NTSTATUS open_dll_file( const char *name, OBJECT_ATTRIBUTES *attr, void *
* open_builtin_file * open_builtin_file
*/ */
static NTSTATUS open_builtin_file( char *name, OBJECT_ATTRIBUTES *attr, void **module, SIZE_T *size, static NTSTATUS open_builtin_file( char *name, OBJECT_ATTRIBUTES *attr, void **module, SIZE_T *size,
SECTION_IMAGE_INFORMATION *image_info, BOOL prefer_native ) SECTION_IMAGE_INFORMATION *image_info, WORD machine, BOOL prefer_native )
{ {
NTSTATUS status; NTSTATUS status;
int fd; int fd;
*module = NULL; *module = NULL;
status = open_dll_file( name, attr, module, size, image_info, prefer_native ); status = open_dll_file( name, attr, module, size, image_info, machine, prefer_native );
if (status != STATUS_DLL_NOT_FOUND) return status; if (status != STATUS_DLL_NOT_FOUND) return status;
/* try .so file */ /* try .so file */
...@@ -1328,7 +1290,7 @@ static NTSTATUS open_builtin_file( char *name, OBJECT_ATTRIBUTES *attr, void **m ...@@ -1328,7 +1290,7 @@ static NTSTATUS open_builtin_file( char *name, OBJECT_ATTRIBUTES *attr, void **m
* find_builtin_dll * find_builtin_dll
*/ */
static NTSTATUS find_builtin_dll( UNICODE_STRING *nt_name, void **module, SIZE_T *size_ptr, static NTSTATUS find_builtin_dll( UNICODE_STRING *nt_name, void **module, SIZE_T *size_ptr,
SECTION_IMAGE_INFORMATION *image_info, BOOL prefer_native ) SECTION_IMAGE_INFORMATION *image_info, WORD machine, BOOL prefer_native )
{ {
unsigned int i, pos, namepos, namelen, maxlen = 0; unsigned int i, pos, namepos, namelen, maxlen = 0;
unsigned int len = nt_name->Length / sizeof(WCHAR); unsigned int len = nt_name->Length / sizeof(WCHAR);
...@@ -1369,7 +1331,7 @@ static NTSTATUS find_builtin_dll( UNICODE_STRING *nt_name, void **module, SIZE_T ...@@ -1369,7 +1331,7 @@ static NTSTATUS find_builtin_dll( UNICODE_STRING *nt_name, void **module, SIZE_T
ptr = prepend( ptr, ptr, namelen ); ptr = prepend( ptr, ptr, namelen );
ptr = prepend( ptr, "/dlls", sizeof("/dlls") - 1 ); ptr = prepend( ptr, "/dlls", sizeof("/dlls") - 1 );
ptr = prepend( ptr, build_dir, strlen(build_dir) ); ptr = prepend( ptr, build_dir, strlen(build_dir) );
status = open_builtin_file( ptr, &attr, module, size_ptr, image_info, prefer_native ); status = open_builtin_file( ptr, &attr, module, size_ptr, image_info, machine, prefer_native );
if (status != STATUS_DLL_NOT_FOUND) goto done; if (status != STATUS_DLL_NOT_FOUND) goto done;
/* now as a program */ /* now as a program */
...@@ -1380,7 +1342,7 @@ static NTSTATUS find_builtin_dll( UNICODE_STRING *nt_name, void **module, SIZE_T ...@@ -1380,7 +1342,7 @@ static NTSTATUS find_builtin_dll( UNICODE_STRING *nt_name, void **module, SIZE_T
ptr = prepend( ptr, ptr, namelen ); ptr = prepend( ptr, ptr, namelen );
ptr = prepend( ptr, "/programs", sizeof("/programs") - 1 ); ptr = prepend( ptr, "/programs", sizeof("/programs") - 1 );
ptr = prepend( ptr, build_dir, strlen(build_dir) ); ptr = prepend( ptr, build_dir, strlen(build_dir) );
status = open_builtin_file( ptr, &attr, module, size_ptr, image_info, prefer_native ); status = open_builtin_file( ptr, &attr, module, size_ptr, image_info, machine, prefer_native );
if (status != STATUS_DLL_NOT_FOUND) goto done; if (status != STATUS_DLL_NOT_FOUND) goto done;
} }
...@@ -1388,7 +1350,7 @@ static NTSTATUS find_builtin_dll( UNICODE_STRING *nt_name, void **module, SIZE_T ...@@ -1388,7 +1350,7 @@ static NTSTATUS find_builtin_dll( UNICODE_STRING *nt_name, void **module, SIZE_T
{ {
file[pos + len + 1] = 0; file[pos + len + 1] = 0;
ptr = prepend( file + pos, dll_paths[i], strlen(dll_paths[i]) ); ptr = prepend( file + pos, dll_paths[i], strlen(dll_paths[i]) );
status = open_builtin_file( ptr, &attr, module, size_ptr, image_info, prefer_native ); status = open_builtin_file( ptr, &attr, module, size_ptr, image_info, machine, prefer_native );
if (status == STATUS_IMAGE_MACHINE_TYPE_MISMATCH) found_image = TRUE; if (status == STATUS_IMAGE_MACHINE_TYPE_MISMATCH) found_image = TRUE;
else if (status != STATUS_DLL_NOT_FOUND) goto done; else if (status != STATUS_DLL_NOT_FOUND) goto done;
} }
...@@ -1415,7 +1377,7 @@ static NTSTATUS CDECL load_builtin_dll( UNICODE_STRING *nt_name, void **module, ...@@ -1415,7 +1377,7 @@ static NTSTATUS CDECL load_builtin_dll( UNICODE_STRING *nt_name, void **module,
SIZE_T size; SIZE_T size;
NTSTATUS status; NTSTATUS status;
status = find_builtin_dll( nt_name, module, &size, image_info, prefer_native ); status = find_builtin_dll( nt_name, module, &size, image_info, current_machine, prefer_native );
if (status == STATUS_IMAGE_NOT_AT_BASE) status = STATUS_SUCCESS; if (status == STATUS_IMAGE_NOT_AT_BASE) status = STATUS_SUCCESS;
return status; return status;
} }
...@@ -1430,6 +1392,7 @@ static NTSTATUS CDECL load_builtin_dll( UNICODE_STRING *nt_name, void **module, ...@@ -1430,6 +1392,7 @@ static NTSTATUS CDECL load_builtin_dll( UNICODE_STRING *nt_name, void **module,
NTSTATUS load_builtin( const pe_image_info_t *image_info, const WCHAR *filename, NTSTATUS load_builtin( const pe_image_info_t *image_info, const WCHAR *filename,
void **module, SIZE_T *size ) void **module, SIZE_T *size )
{ {
WORD machine = image_info->machine; /* request same machine as the native one */
NTSTATUS status; NTSTATUS status;
UNICODE_STRING nt_name; UNICODE_STRING nt_name;
SECTION_IMAGE_INFORMATION info; SECTION_IMAGE_INFORMATION info;
...@@ -1450,7 +1413,7 @@ NTSTATUS load_builtin( const pe_image_info_t *image_info, const WCHAR *filename, ...@@ -1450,7 +1413,7 @@ NTSTATUS load_builtin( const pe_image_info_t *image_info, const WCHAR *filename,
case LO_BUILTIN: case LO_BUILTIN:
case LO_BUILTIN_NATIVE: case LO_BUILTIN_NATIVE:
case LO_DEFAULT: case LO_DEFAULT:
status = find_builtin_dll( &nt_name, module, size, &info, FALSE ); status = find_builtin_dll( &nt_name, module, size, &info, machine, FALSE );
if (status == STATUS_DLL_NOT_FOUND) return STATUS_IMAGE_ALREADY_LOADED; if (status == STATUS_DLL_NOT_FOUND) return STATUS_IMAGE_ALREADY_LOADED;
return status; return status;
default: default:
...@@ -1466,7 +1429,7 @@ NTSTATUS load_builtin( const pe_image_info_t *image_info, const WCHAR *filename, ...@@ -1466,7 +1429,7 @@ NTSTATUS load_builtin( const pe_image_info_t *image_info, const WCHAR *filename,
case LO_BUILTIN: case LO_BUILTIN:
case LO_BUILTIN_NATIVE: case LO_BUILTIN_NATIVE:
case LO_DEFAULT: case LO_DEFAULT:
return find_builtin_dll( &nt_name, module, size, &info, FALSE ); return find_builtin_dll( &nt_name, module, size, &info, machine, FALSE );
default: default:
return STATUS_DLL_NOT_FOUND; return STATUS_DLL_NOT_FOUND;
} }
...@@ -1477,10 +1440,10 @@ NTSTATUS load_builtin( const pe_image_info_t *image_info, const WCHAR *filename, ...@@ -1477,10 +1440,10 @@ NTSTATUS load_builtin( const pe_image_info_t *image_info, const WCHAR *filename,
case LO_NATIVE_BUILTIN: case LO_NATIVE_BUILTIN:
return STATUS_IMAGE_ALREADY_LOADED; return STATUS_IMAGE_ALREADY_LOADED;
case LO_BUILTIN: case LO_BUILTIN:
return find_builtin_dll( &nt_name, module, size, &info, FALSE ); return find_builtin_dll( &nt_name, module, size, &info, machine, FALSE );
case LO_BUILTIN_NATIVE: case LO_BUILTIN_NATIVE:
case LO_DEFAULT: case LO_DEFAULT:
status = find_builtin_dll( &nt_name, module, size, &info, (loadorder == LO_DEFAULT) ); status = find_builtin_dll( &nt_name, module, size, &info, machine, (loadorder == LO_DEFAULT) );
if (status == STATUS_DLL_NOT_FOUND) return STATUS_IMAGE_ALREADY_LOADED; if (status == STATUS_DLL_NOT_FOUND) return STATUS_IMAGE_ALREADY_LOADED;
return status; return status;
default: default:
...@@ -1587,7 +1550,7 @@ static void load_ntdll(void) ...@@ -1587,7 +1550,7 @@ static void load_ntdll(void)
init_unicode_string( &str, path ); init_unicode_string( &str, path );
InitializeObjectAttributes( &attr, &str, 0, 0, NULL ); InitializeObjectAttributes( &attr, &str, 0, 0, NULL );
name[strlen(name) - 3] = 0; /* remove .so */ name[strlen(name) - 3] = 0; /* remove .so */
status = open_builtin_file( name, &attr, &module, &size, &info, FALSE ); status = open_builtin_file( name, &attr, &module, &size, &info, current_machine, FALSE );
if (status == STATUS_IMAGE_NOT_AT_BASE) relocate_ntdll( module ); if (status == STATUS_IMAGE_NOT_AT_BASE) relocate_ntdll( module );
else if (status) fatal_error( "failed to load %s error %x\n", name, status ); else if (status) fatal_error( "failed to load %s error %x\n", name, status );
free( name ); free( name );
......
...@@ -180,7 +180,8 @@ extern void *anon_mmap_alloc( size_t size, int prot ) DECLSPEC_HIDDEN; ...@@ -180,7 +180,8 @@ extern void *anon_mmap_alloc( size_t size, int prot ) DECLSPEC_HIDDEN;
extern void virtual_init(void) DECLSPEC_HIDDEN; extern void virtual_init(void) DECLSPEC_HIDDEN;
extern ULONG_PTR get_system_affinity_mask(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 void virtual_get_system_info( SYSTEM_BASIC_INFORMATION *info ) DECLSPEC_HIDDEN;
extern NTSTATUS virtual_map_builtin_module( HANDLE mapping, void **module, SIZE_T *size ) DECLSPEC_HIDDEN; extern NTSTATUS virtual_map_builtin_module( HANDLE mapping, void **module, SIZE_T *size,
SECTION_IMAGE_INFORMATION *info, WORD machine, BOOL prefer_native ) DECLSPEC_HIDDEN;
extern NTSTATUS virtual_create_builtin_view( void *module, const UNICODE_STRING *nt_name, extern NTSTATUS virtual_create_builtin_view( void *module, const UNICODE_STRING *nt_name,
pe_image_info_t *info, void *so_handle ) DECLSPEC_HIDDEN; pe_image_info_t *info, void *so_handle ) DECLSPEC_HIDDEN;
extern TEB *virtual_alloc_first_teb(void) DECLSPEC_HIDDEN; extern TEB *virtual_alloc_first_teb(void) DECLSPEC_HIDDEN;
...@@ -261,6 +262,8 @@ extern void WINAPI call_raise_user_exception_dispatcher( NTSTATUS (WINAPI *dispa ...@@ -261,6 +262,8 @@ extern void WINAPI call_raise_user_exception_dispatcher( NTSTATUS (WINAPI *dispa
extern void *get_syscall_frame(void) DECLSPEC_HIDDEN; extern void *get_syscall_frame(void) DECLSPEC_HIDDEN;
extern void set_syscall_frame(void *frame) DECLSPEC_HIDDEN; extern void set_syscall_frame(void *frame) DECLSPEC_HIDDEN;
#define IMAGE_DLLCHARACTERISTICS_PREFER_NATIVE 0x0010 /* Wine extension */
#define TICKSPERSEC 10000000 #define TICKSPERSEC 10000000
#define SECS_1601_TO_1970 ((369 * 365 + 89) * (ULONGLONG)86400) #define SECS_1601_TO_1970 ((369 * 365 + 89) * (ULONGLONG)86400)
......
...@@ -2735,7 +2735,8 @@ void virtual_get_system_info( SYSTEM_BASIC_INFORMATION *info ) ...@@ -2735,7 +2735,8 @@ void virtual_get_system_info( SYSTEM_BASIC_INFORMATION *info )
/*********************************************************************** /***********************************************************************
* virtual_map_builtin_module * virtual_map_builtin_module
*/ */
NTSTATUS virtual_map_builtin_module( HANDLE mapping, void **module, SIZE_T *size ) NTSTATUS virtual_map_builtin_module( HANDLE mapping, void **module, SIZE_T *size,
SECTION_IMAGE_INFORMATION *info, WORD machine, BOOL prefer_native )
{ {
mem_size_t full_size; mem_size_t full_size;
unsigned int sec_flags; unsigned int sec_flags;
...@@ -2753,8 +2754,29 @@ NTSTATUS virtual_map_builtin_module( HANDLE mapping, void **module, SIZE_T *size ...@@ -2753,8 +2754,29 @@ NTSTATUS virtual_map_builtin_module( HANDLE mapping, void **module, SIZE_T *size
*module = NULL; *module = NULL;
*size = 0; *size = 0;
filename = (WCHAR *)(image_info + 1); filename = (WCHAR *)(image_info + 1);
status = virtual_map_image( mapping, SECTION_MAP_READ | SECTION_MAP_EXECUTE,
module, size, 0, shared_file, 0, image_info, filename, TRUE ); if (!(image_info->image_flags & IMAGE_FLAGS_WineBuiltin)) /* ignore non-builtins */
{
WARN( "%s found in WINEDLLPATH but not a builtin, ignoring\n", debugstr_w(filename) );
status = STATUS_DLL_NOT_FOUND;
}
else if (machine && image_info->machine != machine)
{
TRACE( "%s is for arch %04x, continuing search\n", debugstr_w(filename), image_info->machine );
status = STATUS_IMAGE_MACHINE_TYPE_MISMATCH;
}
else if (prefer_native && (image_info->dll_charact & IMAGE_DLLCHARACTERISTICS_PREFER_NATIVE))
{
TRACE( "%s has prefer-native flag, ignoring builtin\n", debugstr_w(filename) );
status = STATUS_IMAGE_ALREADY_LOADED;
}
else
{
status = virtual_map_image( mapping, SECTION_MAP_READ | SECTION_MAP_EXECUTE,
module, size, 0, shared_file, 0, image_info, filename, TRUE );
virtual_fill_image_information( image_info, info );
}
if (shared_file) NtClose( shared_file ); if (shared_file) NtClose( shared_file );
free( image_info ); free( image_info );
return status; return status;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment