Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Where exactly is .NET Runtime (CLR), JIT Compiler located?

This question might look a bit foolish or odd but I have heard a lot of about .NET CLR, JIT compiler and how it works blah blah blah... But now I am wondering where exactly it is located or hosted.

Is it -

  • Hosted as a part of Windows Operating system when we actually install .NET Framework?

OR

  • It is a part of some .exe which we can see in task manager

I am looking for the detailed answer on this. Someone might frame this question as "How Windows Operating System triggers/executes .NET Executable inside .NET Runtime?

like image 848
Parag Meshram Avatar asked Jun 12 '15 11:06

Parag Meshram


2 Answers

where exactly it is located or hosted

It is just a plain DLL, you'll find back the x86 version of it in C:\Windows\Microsoft.NET\Framework\v4.0.30319\clrjit.dll. The x64 version is in the Framework64 directory. The .NET v2 version had a different name, mscorjit.dll, find it back in the v2.0.50727 directories.

It is not "hosted" at all, the operating system is completely unaware that it exists. The CLR knows how to locate and load it. Necessarily so, it is the CLR that decides when to start a program. It simply has the DLL name hard-coded and use LoadLibrary("clrjit.dll") to load it, GetProcAddress("getJit") to get the factory function. Something you can see back in the CoreCLR source code, albeit that the jitter is not a separate DLL anymore in that CLR version.

You can see the CLR with Explorer as well, again just a plain DLL. It is clr.dll in the v4 versions, mscorwks.dll and mscorsvc.dll in the v2 versions. Two different ones back then with different garbage collectors, "wks" is the workstation version, "svc" is the server version. Compare to the <gcServer> config file entry.

Which moves the question to "how does the CLR get loaded?" That's the job of c:\windows\syswow64\mscoree.dll, you'll use c:\windows\system32\mscoree.dll when you target x64 in your EXE project. Every .NET assembly has 5 or 9 bytes of unmanaged code, a jump into that DLL. Either _CorExeMain or _CorDllMain, depending on whether the assembly was built as an exe or a library. mscoree.dll takes a look at the metadata in the assembly and decides what version of the CLR needs to loaded so it can be properly executed.

Lots more shenanigans going on, I just posted the 10,000 feet view you asked for. If this interests you then you probably want to find out more about custom CLR hosting to see the man behind the curtain.

like image 185
Hans Passant Avatar answered Oct 21 '22 20:10

Hans Passant


How Windows Operating System triggers/executes .NET Executable Runs inside .NET Runtime?

Every .NET managed assembly or executable has special CLR headers, which you can see by viewing the assembly in ILDASM. This headers points to the version of the runtime that needs to be loaded. Also, there is the Image Section with the Import Address Table, pointing to what needs to be loaded:

----- Image sections: Import Address Table DLL : mscoree.dll           0x00002000 Import Address Table           0x0000a37e Import Name Table           0          Time Date Stamp           0          Index of First Forwarder Reference            0x0000  _CorDllMain   ----- CLR Header:  Header size:                        0x00000048  Major runtime version:              0x0002  Minor runtime version:              0x0005  0x00003184 [0x00007078] address [size] of Metadata Directory:          Flags:                              0x00000001  Entry point token:                  0x00000000  0x00000000 [0x00000000] address [size] of Resources Directory:         0x00000000 [0x00000000] address [size] of Strong Name Signature:       0x00000000 [0x00000000] address [size] of CodeManager Table:           0x00000000 [0x00000000] address [size] of VTableFixups Directory:      0x00000000 [0x00000000] address [size] of Export Address Table:        0x00000000 [0x00000000] address [size] of Precompile Header:    

When ran by the operating system, mscoree.dll (or The Shim) is loaded, and it is the bootstrapper to clr.dll and clrjit.dll for .NET 4.0 and above, or mscordacwks.dll and mscorjit.dll for .NET 2.0 or below, which are the runtime and the JIT, respectively. You can see that the native dll entry point is instructed to be the _CorDllMain method for a class library, and _CorExeMain for an executable, which is responsible for the loading and jitting of the entry point. They, in turn, will call your applications entry point, in the managed environment.

like image 22
Yuval Itzchakov Avatar answered Oct 21 '22 21:10

Yuval Itzchakov