Loading the Common Language Runtime

节选自Applied Microsoft .NET FrameworkProgramming

When you build an EXE assembly, the compiler/linker emits some special information into the resulting assembly’s PE file header and the file's .text section. When the EXE file is invoked, this special information causes the CLR to load and initialize. The CLR then locates the application’s entry point method and allows the application to start executing.

Similarly, if an unmanaged application calls LoadLibrary to load a managed assembly, the DLL’s entry point function knows to load the CLR in order to process the code contained within the assembly.

how a managed EXE or DLL starts the CLR?

Figure 1-3 summarizes how a managed EXE loads and initializes the CLR.

When the compiler/linker creates an executable assembly, the following 6-byte x86 stub function is emitted into the PE file’s .text section:   JMP _CorExeMain    Because the _CorExeMain function is imported from Microsoft’s MSCorEE.dll dynamic-link library, MSCorEE.dll is referenced in the assembly file’s import (.idata) section. MSCorEE.dll stands for Microsoft Component Object Runtime Execution Engine.            When the managed EXE file is invoked, Windows treats it just like any normal (unmanaged) EXE file: the Windows loader loads the file and examines the .idata section to see that MSCorEE.dll should be loaded into the process’s address space. Then the loader obtains the address of the _CorExeMain function inside MSCorEE.dll and fixes up the stub function’s JMP instruction in the managed EXE file. The process’s primary thread begins executing this x86 stub function, which immediately jumps to _CorExeMain in MSCorEE.dll. _CorExeMain initializes the CLR and then looks at the executable assembly’s CLR header to determine what managed entry point method should execute. The IL code for the method is then compiled into native CPU instructions, and the CLR jumps to the native code (using the process’s primary thread). At this point, the managed application’s code is running.

The situation is similar for a managed DLL. When building a managed DLL, the compiler/linker emits a similar 6-byte x86 stub function in the PE file’s .text section for a DLL assembly: JMP _CorDllMain The _CorDllMain function is also imported from the MSCorEE.dll, causing the DLL’s .idata section to reference MSCorEE.dll. When Windows loads the DLL, it will automatically load MSCorEE.dll (if it isn’t already loaded), obtain the address of the _CorDllMain function, and
fix up the 6-byte x86 JMP stub in the managed DLL. The thread that called LoadLibrary to load the managed DLL now jumps to the x86 stub in the managed DLL assembly, which immediately jumps to the _CorDllMain function in MSCorEE.dll. _CorDllMain initializes the CLR (if it hasn’t already been initialized for the process) and then returns so that the
application can continue executing as normal.

These 6-byte x86 stub functions are required to run managed assemblies on Windows 98, Windows 98 Second Edition, Windows Me, Windows NT 4, and Windows 2000 because all these operating systems shipped long before the CLR became available. Note that the 6- byte stub function is specifically for x86 machines.         This stub doesn’t work properly if the CLR is ported to run on other CPU architectures. Because Windows XP and the Windows .NET Server Family support both the x86 and the IA64 CPU architectures, Windows XP and the Windows .NET Server Family loader was modified to look specifically for managed assemblies.
On Windows XP and the Windows .NET Server Family, when a managed assembly is invoked (typically via CreateProcess or LoadLibrary), the OS loader detects that the file contains managed code by examining directory entry 14 in the PE file header. (See IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR in WinNT.h.) If this directory entry exists and is not 0, the loader ignores the file’s import (.idata) section and automatically loads MSCorEE.dll into the process’s address space. Once loaded, the OS loader makes the process’s thread jump directly to the correct function in MSCorEE.dll. The 6-byte x86 stub functions are ignored on machines running Windows XP and the Windows .NET Server
Family.
One last note on managed PE files: they always use the 32 bit PE file format, not the 64-bit PE file format. On 64-bit Windows systems, the OS loader detects the managed 32-bit PE file and automatically knows to create a 64-bit address space.

更正:in figure 1-3, an incorrect DLL is referenced. Change the box currently reading:   "DLL:MSCorLib.dllFunction:_CorExeMain"   To:   "DLL:MSCorEE.dllFunction:_CorExeMain"

posted on 2004-08-07 14:03  9yue  阅读(1752)  评论(0编辑  收藏  举报