server: Allow creating image mappings for all supported CPU platforms.

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Alexandre Julliard 2018-01-30 10:47:32 +01:00
parent 9256017adf
commit f9bd73c4d6
4 changed files with 47 additions and 52 deletions

View File

@ -49,6 +49,7 @@ struct PROCESS_BASIC_INFORMATION_PRIVATE
static LONG *child_failures;
static WORD cb_count;
static DWORD page_size;
static BOOL is_wow64;
static NTSTATUS (WINAPI *pNtCreateSection)(HANDLE *, ACCESS_MASK, const OBJECT_ATTRIBUTES *,
const LARGE_INTEGER *, ULONG, ULONG, HANDLE );
@ -289,12 +290,15 @@ static BOOL query_image_section( int id, const char *dll_name, const IMAGE_NT_HE
entry_point = (char *)(ULONG_PTR)nt32->OptionalHeader.ImageBase + nt32->OptionalHeader.AddressOfEntryPoint;
truncated = nt_header->FileHeader.SizeOfOptionalHeader < sizeof(IMAGE_OPTIONAL_HEADER32);
}
todo_wine_if (entry_point == (void *)0x81231234 )
ok( (char *)image.TransferAddress == (char *)entry_point,
"%u: TransferAddress wrong %p / %p (%08x)\n", id,
image.TransferAddress, entry_point, nt_header->OptionalHeader.AddressOfEntryPoint );
ok( image.ZeroBits == 0, "%u: ZeroBits wrong %08x\n", id, image.ZeroBits );
todo_wine_if (entry_point == (void *)0x81231234 )
ok( image.MaximumStackSize == max_stack || broken(truncated),
"%u: MaximumStackSize wrong %lx / %lx\n", id, image.MaximumStackSize, max_stack );
todo_wine_if (entry_point == (void *)0x81231234 )
ok( image.CommittedStackSize == commit_stack || broken(truncated),
"%u: CommittedStackSize wrong %lx / %lx\n", id, image.CommittedStackSize, commit_stack );
if (truncated)
@ -424,7 +428,7 @@ static NTSTATUS map_image_section( const IMAGE_NT_HEADERS *nt_header, int line )
{
ok( mod != NULL, "%u: loading failed err %u\n", line, GetLastError() );
}
else
else todo_wine_if (is_wow64)
{
ok( !mod, "%u: loading succeeded\n", line );
ok( GetLastError() == ERROR_BAD_EXE_FORMAT, "%u: wrong error %u\n", line, GetLastError() );
@ -869,9 +873,7 @@ static void test_Loader(void)
if (nt_header.OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC)
{
IMAGE_NT_HEADERS64 nt64;
BOOL is_wow64 = FALSE;
if (pIsWow64Process) pIsWow64Process( GetCurrentProcess(), &is_wow64 );
memset( &nt64, 0, sizeof(nt64) );
nt64.Signature = IMAGE_NT_SIGNATURE;
nt64.FileHeader.Machine = orig_machine;
@ -896,7 +898,6 @@ static void test_Loader(void)
section.Characteristics = IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_EXECUTE;
status = map_image_section( (IMAGE_NT_HEADERS *)&nt64, __LINE__ );
todo_wine_if(!is_wow64)
ok( status == (is_wow64 ? STATUS_INVALID_IMAGE_FORMAT : STATUS_INVALID_IMAGE_WIN_64),
"NtCreateSection error %08x\n", status );
@ -906,13 +907,11 @@ static void test_Loader(void)
case IMAGE_FILE_MACHINE_ARMNT: nt64.FileHeader.Machine = IMAGE_FILE_MACHINE_AMD64; break;
}
status = map_image_section( (IMAGE_NT_HEADERS *)&nt64, __LINE__ );
todo_wine_if(!is_wow64)
ok( status == (is_wow64 ? STATUS_INVALID_IMAGE_FORMAT : STATUS_INVALID_IMAGE_WIN_64),
"NtCreateSection error %08x\n", status );
nt64.FileHeader.Machine = nt_header.FileHeader.Machine;
status = map_image_section( (IMAGE_NT_HEADERS *)&nt64, __LINE__ );
todo_wine
ok( status == (is_wow64 ? STATUS_SUCCESS : STATUS_INVALID_IMAGE_WIN_64),
"NtCreateSection error %08x\n", status );
@ -920,7 +919,6 @@ static void test_Loader(void)
nt64.OptionalHeader.AddressOfEntryPoint = 0x1000;
section.Characteristics = IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_CODE;
status = map_image_section( (IMAGE_NT_HEADERS *)&nt64, __LINE__ );
todo_wine
ok( status == (is_wow64 ? STATUS_SUCCESS : STATUS_INVALID_IMAGE_WIN_64),
"NtCreateSection error %08x\n", status );
@ -928,7 +926,6 @@ static void test_Loader(void)
nt64.OptionalHeader.AddressOfEntryPoint = 0;
section.Characteristics = IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_EXECUTE;
status = map_image_section( (IMAGE_NT_HEADERS *)&nt64, __LINE__ );
todo_wine
ok( status == (is_wow64 ? STATUS_SUCCESS : STATUS_INVALID_IMAGE_WIN_64),
"NtCreateSection error %08x\n", status );
@ -936,7 +933,6 @@ static void test_Loader(void)
nt64.OptionalHeader.AddressOfEntryPoint = 0;
section.Characteristics = IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_CODE;
status = map_image_section( (IMAGE_NT_HEADERS *)&nt64, __LINE__ );
todo_wine
ok( status == (is_wow64 ? STATUS_SUCCESS : STATUS_INVALID_IMAGE_WIN_64),
"NtCreateSection error %08x\n", status );
@ -944,7 +940,6 @@ static void test_Loader(void)
nt64.OptionalHeader.AddressOfEntryPoint = 0;
section.Characteristics = IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_CODE;
status = map_image_section( (IMAGE_NT_HEADERS *)&nt64, __LINE__ );
todo_wine
ok( status == (is_wow64 ? STATUS_SUCCESS : STATUS_INVALID_IMAGE_WIN_64),
"NtCreateSection error %08x\n", status );
}
@ -989,35 +984,30 @@ static void test_Loader(void)
nt32.FileHeader.Machine = nt_header.FileHeader.Machine;
status = map_image_section( (IMAGE_NT_HEADERS *)&nt32, __LINE__ );
todo_wine
ok( status == STATUS_SUCCESS, "NtCreateSection error %08x\n", status );
nt32.OptionalHeader.SizeOfCode = 0;
nt32.OptionalHeader.AddressOfEntryPoint = 0x1000;
section.Characteristics = IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_CODE;
status = map_image_section( (IMAGE_NT_HEADERS *)&nt32, __LINE__ );
todo_wine
ok( status == STATUS_SUCCESS, "NtCreateSection error %08x\n", status );
nt32.OptionalHeader.SizeOfCode = 0;
nt32.OptionalHeader.AddressOfEntryPoint = 0;
section.Characteristics = IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_EXECUTE;
status = map_image_section( (IMAGE_NT_HEADERS *)&nt32, __LINE__ );
todo_wine
ok( status == STATUS_SUCCESS, "NtCreateSection error %08x\n", status );
nt32.OptionalHeader.SizeOfCode = 0x1000;
nt32.OptionalHeader.AddressOfEntryPoint = 0;
section.Characteristics = IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_CODE;
status = map_image_section( (IMAGE_NT_HEADERS *)&nt32, __LINE__ );
todo_wine
ok( status == STATUS_SUCCESS, "NtCreateSection error %08x\n", status );
nt32.OptionalHeader.SizeOfCode = 0;
nt32.OptionalHeader.AddressOfEntryPoint = 0;
section.Characteristics = IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_CODE;
status = map_image_section( (IMAGE_NT_HEADERS *)&nt32, __LINE__ );
todo_wine
ok( status == STATUS_SUCCESS, "NtCreateSection error %08x\n", status );
}
@ -3236,6 +3226,7 @@ START_TEST(loader)
pIsWow64Process = (void *)GetProcAddress(kernel32, "IsWow64Process");
pResolveDelayLoadedAPI = (void *)GetProcAddress(kernel32, "ResolveDelayLoadedAPI");
if (pIsWow64Process) pIsWow64Process( GetCurrentProcess(), &is_wow64 );
GetSystemInfo( &si );
page_size = si.dwPageSize;
dos_header.e_magic = IMAGE_DOS_SIGNATURE;

View File

@ -136,7 +136,6 @@ struct mapping
mem_size_t size; /* mapping size */
unsigned int flags; /* SEC_* flags */
struct fd *fd; /* fd for mapped file */
enum cpu_type cpu; /* client CPU (for PE image mapping) */
pe_image_info_t image; /* image info (for PE image mapping) */
struct ranges *committed; /* list of committed ranges in this mapping */
struct shared_map *shared; /* temp file for shared PE mapping */
@ -540,6 +539,7 @@ static unsigned int get_image_params( struct mapping *mapping, file_pos_t file_s
} nt;
off_t pos;
int size;
unsigned int cpu_mask = get_supported_cpu_mask();
/* load the headers */
@ -559,38 +559,25 @@ static unsigned int get_image_params( struct mapping *mapping, file_pos_t file_s
return STATUS_INVALID_IMAGE_PROTECT;
}
mapping->cpu = current->process->cpu;
switch (mapping->cpu)
{
case CPU_x86:
if (nt.FileHeader.Machine != IMAGE_FILE_MACHINE_I386) return STATUS_INVALID_IMAGE_FORMAT;
if (nt.opt.hdr32.Magic != IMAGE_NT_OPTIONAL_HDR32_MAGIC) return STATUS_INVALID_IMAGE_FORMAT;
break;
case CPU_x86_64:
if (nt.FileHeader.Machine != IMAGE_FILE_MACHINE_AMD64) return STATUS_INVALID_IMAGE_FORMAT;
if (nt.opt.hdr64.Magic != IMAGE_NT_OPTIONAL_HDR64_MAGIC) return STATUS_INVALID_IMAGE_FORMAT;
break;
case CPU_POWERPC:
if (nt.FileHeader.Machine != IMAGE_FILE_MACHINE_POWERPC) return STATUS_INVALID_IMAGE_FORMAT;
if (nt.opt.hdr32.Magic != IMAGE_NT_OPTIONAL_HDR32_MAGIC) return STATUS_INVALID_IMAGE_FORMAT;
break;
case CPU_ARM:
if (nt.FileHeader.Machine != IMAGE_FILE_MACHINE_ARM &&
nt.FileHeader.Machine != IMAGE_FILE_MACHINE_THUMB &&
nt.FileHeader.Machine != IMAGE_FILE_MACHINE_ARMNT) return STATUS_INVALID_IMAGE_FORMAT;
if (nt.opt.hdr32.Magic != IMAGE_NT_OPTIONAL_HDR32_MAGIC) return STATUS_INVALID_IMAGE_FORMAT;
break;
case CPU_ARM64:
if (nt.FileHeader.Machine != IMAGE_FILE_MACHINE_ARM64) return STATUS_INVALID_IMAGE_FORMAT;
if (nt.opt.hdr64.Magic != IMAGE_NT_OPTIONAL_HDR64_MAGIC) return STATUS_INVALID_IMAGE_FORMAT;
break;
default:
return STATUS_INVALID_IMAGE_FORMAT;
}
switch (nt.opt.hdr32.Magic)
{
case IMAGE_NT_OPTIONAL_HDR32_MAGIC:
switch (nt.FileHeader.Machine)
{
case IMAGE_FILE_MACHINE_I386:
if (cpu_mask & (CPU_FLAG(CPU_x86) | CPU_FLAG(CPU_x86_64))) break;
return STATUS_INVALID_IMAGE_FORMAT;
case IMAGE_FILE_MACHINE_ARM:
case IMAGE_FILE_MACHINE_THUMB:
case IMAGE_FILE_MACHINE_ARMNT:
if (cpu_mask & (CPU_FLAG(CPU_ARM) | CPU_FLAG(CPU_ARM64))) break;
return STATUS_INVALID_IMAGE_FORMAT;
case IMAGE_FILE_MACHINE_POWERPC:
if (cpu_mask & CPU_FLAG(CPU_POWERPC)) break;
return STATUS_INVALID_IMAGE_FORMAT;
default:
return STATUS_INVALID_IMAGE_FORMAT;
}
mapping->image.base = nt.opt.hdr32.ImageBase;
mapping->image.entry_point = nt.opt.hdr32.ImageBase + nt.opt.hdr32.AddressOfEntryPoint;
mapping->image.map_size = ROUND_SIZE( nt.opt.hdr32.SizeOfImage );
@ -604,7 +591,20 @@ static unsigned int get_image_params( struct mapping *mapping, file_pos_t file_s
mapping->image.header_size = nt.opt.hdr32.SizeOfHeaders;
mapping->image.checksum = nt.opt.hdr32.CheckSum;
break;
case IMAGE_NT_OPTIONAL_HDR64_MAGIC:
if (!(cpu_mask & CPU_64BIT_MASK)) return STATUS_INVALID_IMAGE_WIN_64;
switch (nt.FileHeader.Machine)
{
case IMAGE_FILE_MACHINE_AMD64:
if (cpu_mask & (CPU_FLAG(CPU_x86) | CPU_FLAG(CPU_x86_64))) break;
return STATUS_INVALID_IMAGE_FORMAT;
case IMAGE_FILE_MACHINE_ARM64:
if (cpu_mask & (CPU_FLAG(CPU_ARM) | CPU_FLAG(CPU_ARM64))) break;
return STATUS_INVALID_IMAGE_FORMAT;
default:
return STATUS_INVALID_IMAGE_FORMAT;
}
mapping->image.base = nt.opt.hdr64.ImageBase;
mapping->image.entry_point = nt.opt.hdr64.ImageBase + nt.opt.hdr64.AddressOfEntryPoint;
mapping->image.map_size = ROUND_SIZE( nt.opt.hdr64.SizeOfImage );
@ -618,7 +618,11 @@ static unsigned int get_image_params( struct mapping *mapping, file_pos_t file_s
mapping->image.header_size = nt.opt.hdr64.SizeOfHeaders;
mapping->image.checksum = nt.opt.hdr64.CheckSum;
break;
default:
return STATUS_INVALID_IMAGE_FORMAT;
}
mapping->image.image_charact = nt.FileHeader.Characteristics;
mapping->image.machine = nt.FileHeader.Machine;
mapping->image.zerobits = 0; /* FIXME */
@ -901,13 +905,6 @@ DECL_HANDLER(get_mapping_info)
return;
}
if ((mapping->flags & SEC_IMAGE) && mapping->cpu != current->process->cpu)
{
set_error( STATUS_INVALID_IMAGE_FORMAT );
release_object( mapping );
return;
}
if (mapping->shared)
reply->shared_file = alloc_handle( current->process, mapping->shared->file,
GENERIC_READ|GENERIC_WRITE, 0 );

View File

@ -1234,6 +1234,12 @@ int is_cpu_supported( enum cpu_type cpu )
return 0;
}
/* return the cpu mask for supported cpus */
unsigned int get_supported_cpu_mask(void)
{
return supported_cpus & get_prefix_cpu_mask();
}
/* create a new thread */
DECL_HANDLER(new_thread)
{

View File

@ -128,6 +128,7 @@ extern struct thread_snapshot *thread_snap( int *count );
extern struct token *thread_get_impersonation_token( struct thread *thread );
extern int set_thread_affinity( struct thread *thread, affinity_t affinity );
extern int is_cpu_supported( enum cpu_type cpu );
extern unsigned int get_supported_cpu_mask(void);
/* ptrace functions */