简体   繁体   English

本地 .NET 映像中的 IL(中间语言)代码

[英]IL (Intermediate Language) Code in Native .NET Images

Consider a simple Console .NET app, that only contains the Visual Studio's auto-generated and empty Main method.考虑一个简单的 Console .NET 应用程序,它只包含 Visual Studio 自动生成的空 Main 方法。

As per Jeffrey Richter's "CLR via C#" in the context of mscorlib.dll : " This assembly is automatically loaded when the CLR initializes ".根据杰弗里·里希特 (Jeffrey Richter) 在mscorlib.dll上下文中的“CLR via C#”:“ CLR 初始化时会自动加载此程序集”。 Quite understandable, given that this assembly contains - among others - the core types.很容易理解,因为这个程序集包含 - 除其他外 - 核心类型。

Running the application and setting a filter to look for "mscorlib" file references only yields hits both for mscorlib.dll as well as mscorlib.ni.dll :运行应用程序并设置过滤器以查找“mscorlib”文件引用只会产生mscorlib.dllmscorlib.ni.dll命中:

在此处输入图片说明

The "ni" stands for native image, and given that the mscorlib.dll assembly is so heavily used, it makes sense to make a native image out of it - mscorlib.ni.dll -, which the CLR will load instead of the "classical", mscorlib.dll one. “ni”代表本机映像,鉴于mscorlib.dll程序集被大量使用,因此可以从中制作本机映像 - mscorlib.ni.dll - CLR 将加载它而不是“经典”, mscorlib.dll之一。

The fact that both files are being accessed is expected, since the CLR will only use the native image as long as it's still in sync with the original assembly it was generated from.这两个文件都被访问的事实是预料之中的,因为 CLR 只会使用本机映像,只要它仍然与生成它的原始程序集同步。 If for example the source assembly changes, the native image is no longer used .例如,如果源程序集更改,则不再使用本机映像。 Therefore both need to be checked before loading the native one.因此,在加载本机之前都需要检查两者。 All clear so far.到目前为止一切都清楚。

The native images, as Microsoft states here , " are files containing compiled processor-specific machine code ".正如微软在此声明的那样,本机映像“是包含编译过的特定于处理器的机器代码的文件”。

Assuming a native image only contains machine code, I went ahead and tried to open mscorlib.ni.dll with a disassembler ( ILSpy ), simply expecting the "PE file does not contain any managed metadata" error to be thrown.假设本机映像包含机器代码,我继续尝试使用反汇编程序 ( ILSpy ) 打开mscorlib.ni.dll ,只是期望抛出“PE 文件不包含任何托管元数据”错误。 I was however surprised to see ILSpy correctly loading the assembly, complete with manifest, type members, as well as IL code displayed for methods:然而,我很惊讶地看到 ILSpy 正确加载了程序集,包括清单、类型成员以及为方法显示的IL 代码

在此处输入图片说明

I suspected that somehow a reference to mscorlib.dll is used, and the whole data is extracted from there actually.我怀疑以某种方式使用了对mscorlib.dll的引用,并且实际上从那里提取了整个数据。 However Process Monitor filtered for ILSpy's image name proved me wrong: there's not even one attempt to open mscorlib.dll ;然而,针对 ILSpy 图像名称过滤的进程监视器证明我错了:甚至没有一次尝试打开mscorlib.dll there are only some attempts to get the .pdb file - most likely looking for symbols - that fail due to that file not existing.只有一些尝试获取 .pdb 文件 - 很可能是寻找符号 - 由于该文件不存在而失败。

In fact both assemblies - mscorlib.dll and mscorlib.ni.dll - are striking similar, with just the difference of IL_ONLY vs IL_LIBRARY in the Corflags structure.事实上,两个程序集 - mscorlib.dllmscorlib.ni.dll - 非常相似,只是在 Corflags 结构中 IL_ONLY 与 IL_LIBRARY 不同。

Trying to load other native images from within the NIC (Native Image Cache) resulted in a similar behavior.尝试从 NIC(本机映像缓存)中加载其他本机映像会导致类似的行为。

I could find advanced details about how a native image is still deemed valid ( here ), but no so much about my actual question:我可以找到有关如何仍将本机图像视为有效的高级详细信息( 此处),但与我的实际问题无关:

How come native images can be disassembled down to the IL code level ?为什么本地图像可以分解到 IL 代码级别? Is the IL as well as the machine code stored within the native image ? IL 和机器代码是否存储在本机映像中?

Update 5/27/2019 : It seems that Microsoft's definition is somewhat elusive. 2019 年 5 月 27 日更新:微软的定义似乎有些难以捉摸。 It should probably be interpreted as native images " are files containing compiled processor-specific machine code ", aside the regular assembly metadata and IL code .除了常规的程序集元数据和 IL 代码之外,它可能应该被解释为本机映像“是包含编译过的特定于处理器的机器代码的文件”。 The "native" particle inside the term leads one to the wrong meaning apparently.术语中的“本地”粒子显然会导致错误的含义。

The 2 good comments received lead to the next natural question: Where is the machine code actually stored inside the image file itself ?收到的 2 条好评引出了下一个自然问题:机器代码实际上存储在图像文件本身的何处?

In terms of details about the image file content, CFF Explorer showed a bit more than JetBrain dotPeek, and highlighted 2 extra sections, a rather large Relocation Directory entry and a mysterious Native Header in favor of the native image, but that was pretty much it.在关于图像文件内容的细节方面, CFF Explorer显示的比 JetBrain dotPeek 多一点,并突出显示了 2 个额外的部分,一个相当大的 Relocation Directory 条目和一个支持原生图像的神秘的 Native Header,但仅此而已.

在此处输入图片说明

The ECMA 335 standard enter link description here has but a few words about the physical layout of the image file concerning the code itself in section II.25.4. ECMA 335 标准在此处输入链接描述仅在第 II.25.4 节中介绍了与代码本身有关的图像文件的物理布局。 Aside from the fact that the method body immediately follows the method header, and that there's sometimes an extra method data section when dealing with exception handling, the standard doesn't really tell anything about the location of the machine code itself.除了方法主体紧跟在方法头之后,并且在处理异常处理时有时会有一个额外的方法数据部分之外,标准并没有真正说明机器代码本身的位置。

If no native image is available for a particular method, NGEN falls back to JITing code.如果没有可用于特定方法的本机映像,NGEN 将回退到 JITing 代码。 This means that native images must continue to include metadata and IL in the event that NGEN needs to fall back to JIT compilation.这意味着在 NGEN 需要回退到 JIT 编译的情况下,本机映像必须继续包含元数据和 IL。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM