How to Determine for Which Platform an Executable Is Compiled

How can I determine for which platform an executable is compiled?

(from another Q, since removed)

Machine type: This is a quick little bit of code I based on some that gets the linker timestamp. This is in the same header, and it seems to work - it returns I386 when compiled -any cpu-, and x64 when compiled with that as the target platform.

The Exploring PE Headers (K. Stanton,MSDN) blog entry that showed me the offset, as another response noted.

public enum MachineType {
Native = 0, I386 = 0x014c, Itanium = 0x0200, x64 = 0x8664
}

public static MachineType GetMachineType(string fileName)
{
const int PE_POINTER_OFFSET = 60;
const int MACHINE_OFFSET = 4;
byte[] data = new byte[4096];
using (Stream s = new FileStream(fileName, FileMode.Open, FileAccess.Read)) {
s.Read(data, 0, 4096);
}
// dos header is 64 bytes, last element, long (4 bytes) is the address of the PE header
int PE_HEADER_ADDR = BitConverter.ToInt32(data, PE_POINTER_OFFSET);
int machineUint = BitConverter.ToUInt16(data, PE_HEADER_ADDR + MACHINE_OFFSET);
return (MachineType)machineUint;
}

How to tell whether an executable was compiled for the present machine?

You could use gcc -v to figure out what the installed/runnable gcc thinks is the target arch for hosted compiling (something like $(gcc -v 2>&1 | grep Target: | sed 's/.*: *//') in bash)

edit

If you really want to be able to do this without having anything in particular installed, you could extract the config.guess script from gcc (its in the top level directory of any gcc source package) and run that. Unfortunately this won't work for all systems and might not exactly match what the system gcc package uses for some distributions, but this is the script used to configure gcc for building unless you explicitly override it...

What does an executable file compilation depends on?

The question is that if I need to specify the 32bit or 64bit of OS (not of the CPU architecture) too?

You don't specify an Operating System (you have only one OS running on a given machine; to run several of them use an hypervisor or some VM). You specify & choose an Application Binary Interface (ABI) since some OSes are able to offer several ABIs (and runtime systems).

Is there any difference in compilation a program for above systems?

Yes, there is some difference (think of sizeof(void*) at least; also the 64 bits ISA uses more registers and the ABI could define different calling conventions, by passing more arguments thru registers). I can't tell more about Windows, which I don't know.

When I add -m32 in the options of gcc compiler, what is this 32 for?

Dive into the documentation of GCC, notably the Invoking GCC chapter.

It is some x86 option:

The -m32 option sets int, long, and pointer types to 32 bits, and generates code that runs on any i386 system.

The -m64 option sets int to 32 bits and long and pointer types to 64 bits, and generates code for the x86-64 architecture. For Darwin only the -m64 option also turns off the -fno-pic and -mdynamic-no-pic options.

Read also about the x32 ABI (which is a Linux specific thing).

I can't say more about Windows specific (which I don't know and never used). But I will explain what is happening on Linux. I leave you to seek similar knowledge for your proprietary Microsoft operating system.

On Linux, the operating system kernel can be configured (at kernel build time) to accept both 32 bits and 64 bits ELF executables and provide a system call runtime environment for both architectures. Such kernels are able to execute with execve(2) both 32 bits executables, and 64 bits executables and provide two different ABIs (one for -m32 for 686 instruction set architecture, another for -m64 for x86-64 ISA) for them. Notice that the same OS kernel enable executions of binary executables in either 32 bits or 64 bits mode.

I don't know Windows, but I could imagine that Microsoft provide also two different runtime environments & ABIs, one for 32 bits 686 ISA and another for 64 bits x86-64 ISA. Maybe one of them is optional and needs to be installed or bought separately (I really don't know and I don't care).

It is up to you to dive into Microsoft documentations to find the details of the differences.

See also x86 calling conventions wikipage.

I recommend reading something like Operating Systems : Three Easy Pieces (freely downloadable, chapter by chapter) to understand more the role of an OS, and also more about the x86-64 ISA, including its long mode.

Of course you need to care of other dependencies (or coupling). Read about DLL hell & dependency hell.

How can I determine if a .NET assembly was built for x86 or x64?

Look at System.Reflection.AssemblyName.GetAssemblyName(string assemblyFile).

You can examine assembly metadata from the returned AssemblyName instance:

Using PowerShell:


[36] C:\> [reflection.assemblyname]::GetAssemblyName("${pwd}\Microsoft.GLEE.dll") | fl

Name : Microsoft.GLEE
Version : 1.0.0.0
CultureInfo :
CodeBase : file:///C:/projects/powershell/BuildAnalyzer/...
EscapedCodeBase : file:///C:/projects/powershell/BuildAnalyzer/...
ProcessorArchitecture : MSIL
Flags : PublicKey
HashAlgorithm : SHA1
VersionCompatibility : SameMachine
KeyPair :
FullName : Microsoft.GLEE, Version=1.0.0.0, Culture=neut...

Here, ProcessorArchitecture identifies the target platform.

  • Amd64: A 64-bit processor based on the x64 architecture.
  • Arm: An ARM processor.
  • IA64: A 64-bit Intel Itanium processor only.
  • MSIL: Neutral with respect to processor and bits-per-word.
  • X86: A 32-bit Intel processor, either native or in the Windows on Windows environment on a 64-bit platform (WoW64).
  • None: An unknown or unspecified combination of processor and bits-per-word.

I'm using PowerShell in this example to call the method.

How to determine the platform tag of a .net exe

This may be able to help for executables:

http://www.mitec.cz/exe.html

If you need to programmatically check against .net dlls, then there are these posts:

How to find if a native DLL file is compiled as x64 or x86?

Check if unmanaged DLL is 32-bit or 64-bit?



Related Topics



Leave a reply



Submit