Page 1 of 1

AMD64 32-bit

Posted: Tue Dec 22, 2015 4:56 am
by Norbert
Hi folks, I have a question about the PE executable file type, related to information that can be found in your wiki here.

Can a PeHeader with mMachine 0x8664 (AMD64) be combined with a Pe32OptionalHeader with mMagic 0x010b (32-bit/PE32)?

According to Kazinsal, who replied to my question in your IRC channel, this would be invalid, because a AMD64 machine basically says: "The code in this PE contains AMD64 instructions and is to be run in long mode."; that 64-bit datatypes cannot be contained in 32-bit data fields.

Assuming the latter is correct, then I'm wondering why the optional header even includes mMagic, because doesn't this mean that an AMD64 machine always uses the 64-bit architecture, and an i386 always 32-bit?

Re: AMD64 32-bit

Posted: Tue Dec 22, 2015 5:20 am
by Combuster
A magic number need not just have identification as a role, it can also indicate presence - in particular when its predecessor didn't cover for extensions. PE has a long history from flat .COM files, DOS executables to DPMI and 16-bit Windows and even Windows CE. Somewhere in that history it's likely the architects have decided that a magic number was considered meaningful protection from misdiagnosing older files that just happened to have a few bytes in the right place.

Re: AMD64 32-bit

Posted: Wed Dec 23, 2015 5:41 am
by onlyonemac
I haven't done a lot of research on PE, but judging from the fact that 64-bit Windows executables cannot be executed on 32-bit Windows, my assumption is that your proposed header is invalid, as it specifies that the machine must be AMD64 but that the executable is 32-bit. If you want the executable to be 32-bit, then you need to specify a 32-bit machine in the header; 64-bit machines will run it in a compatibility mode.

Re: AMD64 32-bit

Posted: Sun Dec 27, 2015 4:07 am
by Norbert
All right, thanks for the information.

Re: AMD64 32-bit

Posted: Sun Dec 27, 2015 9:12 am
by Owen
An analogous situation exists in ELF: You can code
  • An ELF32 i386 object
  • An ELF64 i386 object
  • An ELF32 AMD64 object
  • An ELF64 AMD64 object

Now, the second of these is useless, since there is no 64-bit i386. The first of these is traditional i386 32-bit code.

The fourth of these is of course the "normal" 64-bit AMD64 code. And the third of these is x32. 32-bit pointers, AMD64 instructions.

This is not unusual: The same combinations exist for ARM AArch32/AArch64; you can encode an ELF32.ARM, an ELF32.AArch64, and an ELF64.AArch64, which correspond to traditional ARM AArch32, AArch64 ILP32 and AArch64 ILP64. Some architectures, like MIPS, are different: the 64-bit architecture is a straight and strict superset of the 32-bit architecture. There there is no separate architecture code for MIPS64, and therefore no special "MIPS64 ILP32" ABI could be defined, but such an ABI would be superfluous anyway.

You could envisage similar in a PE file. Of course, PE is primarily the executable format of Windows (and secondarily of UEFI), and Windows does not presently support ILP32 ABIs, so such use is not defined.