From f2c54dba015f6f3e359f87c0950b25b9ffeb1e96 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Fri, 22 Nov 2013 12:18:31 +0100 Subject: [PATCH] kernel32: Determine the module architecture for all binary types. --- dlls/kernel32/kernel_private.h | 1 + dlls/kernel32/module.c | 34 +++++++++++++++++++++++++++++++++- dlls/kernel32/process.c | 20 ++++++++++++++++---- 3 files changed, 50 insertions(+), 5 deletions(-) diff --git a/dlls/kernel32/kernel_private.h b/dlls/kernel32/kernel_private.h index cfc2935b5ee..5c6c197c159 100644 --- a/dlls/kernel32/kernel_private.h +++ b/dlls/kernel32/kernel_private.h @@ -81,6 +81,7 @@ enum binary_type struct binary_info { enum binary_type type; + DWORD arch; DWORD flags; void *res_start; void *res_end; diff --git a/dlls/kernel32/module.c b/dlls/kernel32/module.c index babc7566731..63cf0120da3 100644 --- a/dlls/kernel32/module.c +++ b/dlls/kernel32/module.c @@ -264,22 +264,52 @@ void MODULE_get_binary_info( HANDLE hfile, struct binary_info *info ) if (!memcmp( header.elf.magic, "\177ELF", 4 )) { if (header.elf.class == 2) info->flags |= BINARY_FLAG_64BIT; - /* FIXME: we don't bother to check byte order, architecture, etc. */ +#ifdef WORDS_BIGENDIAN + if (header.elf.data == 1) +#else + if (header.elf.data == 2) +#endif + { + header.elf.type = RtlUshortByteSwap( header.elf.type ); + header.elf.machine = RtlUshortByteSwap( header.elf.machine ); + } switch(header.elf.type) { case 2: info->type = BINARY_UNIX_EXE; break; case 3: info->type = BINARY_UNIX_LIB; break; } + switch(header.elf.machine) + { + case 3: info->arch = IMAGE_FILE_MACHINE_I386; break; + case 20: info->arch = IMAGE_FILE_MACHINE_POWERPC; break; + case 40: info->arch = IMAGE_FILE_MACHINE_ARMNT; break; + case 50: info->arch = IMAGE_FILE_MACHINE_IA64; break; + case 62: info->arch = IMAGE_FILE_MACHINE_AMD64; break; + case 183: info->arch = IMAGE_FILE_MACHINE_ARM64; break; + } } /* Mach-o File with Endian set to Big Endian or Little Endian */ else if (header.macho.magic == 0xfeedface || header.macho.magic == 0xcefaedfe) { if ((header.macho.cputype >> 24) == 1) info->flags |= BINARY_FLAG_64BIT; + if (header.macho.magic == 0xcefaedfe) + { + header.macho.filetype = RtlUlongByteSwap( header.macho.filetype ); + header.macho.cputype = RtlUlongByteSwap( header.macho.cputype ); + } switch(header.macho.filetype) { case 2: info->type = BINARY_UNIX_EXE; break; case 8: info->type = BINARY_UNIX_LIB; break; } + switch(header.macho.cputype) + { + case 0x00000007: info->arch = IMAGE_FILE_MACHINE_I386; break; + case 0x01000007: info->arch = IMAGE_FILE_MACHINE_AMD64; break; + case 0x0000000c: info->arch = IMAGE_FILE_MACHINE_ARMNT; break; + case 0x0100000c: info->arch = IMAGE_FILE_MACHINE_ARM64; break; + case 0x00000012: info->arch = IMAGE_FILE_MACHINE_POWERPC; break; + } } /* Not ELF, try DOS */ else if (header.mz.e_magic == IMAGE_DOS_SIGNATURE) @@ -298,6 +328,7 @@ void MODULE_get_binary_info( HANDLE hfile, struct binary_info *info ) * to read or not. */ info->type = BINARY_DOS; + info->arch = IMAGE_FILE_MACHINE_I386; if (SetFilePointer( hfile, header.mz.e_lfanew, NULL, SEEK_SET ) == -1) return; if (!ReadFile( hfile, &ext_header, sizeof(ext_header), &len, NULL ) || len < 4) return; @@ -309,6 +340,7 @@ void MODULE_get_binary_info( HANDLE hfile, struct binary_info *info ) if (len >= sizeof(ext_header.nt.FileHeader)) { info->type = BINARY_PE; + info->arch = ext_header.nt.FileHeader.Machine; if (ext_header.nt.FileHeader.Characteristics & IMAGE_FILE_DLL) info->flags |= BINARY_FLAG_DLL; if (len < sizeof(ext_header.nt)) /* clear remaining part of header if missing */ diff --git a/dlls/kernel32/process.c b/dlls/kernel32/process.c index afbdf72f581..0bacd60b44a 100644 --- a/dlls/kernel32/process.c +++ b/dlls/kernel32/process.c @@ -208,6 +208,18 @@ static BOOL get_builtin_path( const WCHAR *libname, const WCHAR *ext, WCHAR *fil binary_info->flags = flags; binary_info->res_start = NULL; binary_info->res_end = NULL; + /* assume current arch */ +#if defined(__i386__) || defined(__x86_64__) + binary_info->arch = (flags & BINARY_FLAG_64BIT) ? IMAGE_FILE_MACHINE_AMD64 : IMAGE_FILE_MACHINE_I386; +#elif defined(__powerpc__) + binary_info->arch = IMAGE_FILE_MACHINE_POWERPC; +#elif defined(__arm__) && !defined(__ARMEB__) + binary_info->arch = IMAGE_FILE_MACHINE_ARMNT; +#elif defined(__aarch64__) + binary_info->arch = IMAGE_FILE_MACHINE_ARM64; +#else + binary_info->arch = IMAGE_FILE_MACHINE_UNKNOWN; +#endif return TRUE; } @@ -2286,9 +2298,9 @@ static BOOL create_process_impl( LPCWSTR app_name, LPWSTR cmd_line, LPSECURITY_A else switch (binary_info.type) { case BINARY_PE: - TRACE( "starting %s as Win%d binary (%p-%p)\n", + TRACE( "starting %s as Win%d binary (%p-%p, arch %04x)\n", debugstr_w(name), (binary_info.flags & BINARY_FLAG_64BIT) ? 64 : 32, - binary_info.res_start, binary_info.res_end ); + binary_info.res_start, binary_info.res_end, binary_info.arch ); retv = create_process( hFile, name, tidy_cmdline, envW, cur_dir, process_attr, thread_attr, inherit, flags, startup_info, info, unixdir, &binary_info, FALSE ); break; @@ -2431,9 +2443,9 @@ static void exec_process( LPCWSTR name ) switch (binary_info.type) { case BINARY_PE: - TRACE( "starting %s as Win%d binary (%p-%p)\n", + TRACE( "starting %s as Win%d binary (%p-%p, arch %04x)\n", debugstr_w(name), (binary_info.flags & BINARY_FLAG_64BIT) ? 64 : 32, - binary_info.res_start, binary_info.res_end ); + binary_info.res_start, binary_info.res_end, binary_info.arch ); create_process( hFile, name, GetCommandLineW(), NULL, NULL, NULL, NULL, FALSE, 0, &startup_info, &info, NULL, &binary_info, TRUE ); break;