Loading platform neutral (anycpu) executables on 64bit machine.

Just like other Windows executable files Managed code is stored in PE format. To be more precise it can use PE (32bit) or PE+ (64bit) formats.

In unmanaged world the format of the executable tells the loader whether to run the image as 64 bit or 32 bit process. However this is not always true for managed code. Managed code can be platform neutral and be able to run as either a 32bit process or a 64bit process. Obviously neutral code has to be stored in PE (32bit) format so that it could be loaded on 32bit OSes. So what happens when we run such executable on a 64bit machine?

When windows loader loads an executable image it checks for managed modules by inspecting COFF header of the executable. If managed code is detected, then IMAGE_COR20_HEADER is examined. The structure is stored at location indicated by IMAGE_DIRECTORY_ENTRY_COMHEADER and describes the managed executable. For the loader the most interesting part of the header structure is Flags field and in particular ILONLY flag. ILONLY indicates that the executable contains pure IL code and can run either as 32bit or as a 64bit process. On 64bit machines ILONLY flag causes the loader to load the image as 64bit and invoke 64bit CLR. As the last touch upon loading 64bit CLR transforms loaded PE header into PE+ format on the fly to keep everything right.

This is not a complete process though - In addition to Flags loader checks the version of the IMAGE_COR20_HEADER. Anything less than 2.5 indicates CLR1.0 or CLR1.1 executable. For compatibility reasons such executables will run in 32bit mode.