kernel32: Determine the module architecture for all binary types.

This commit is contained in:
Alexandre Julliard 2013-11-22 12:18:31 +01:00
parent f6b5dc246a
commit f2c54dba01
3 changed files with 50 additions and 5 deletions

View File

@ -81,6 +81,7 @@ enum binary_type
struct binary_info
{
enum binary_type type;
DWORD arch;
DWORD flags;
void *res_start;
void *res_end;

View File

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

View File

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