为什么.Net IL不可验证?
我有一点自定义IL我写的,它不会通过PEVerify。我得到的错误是 $ peverify foo.exe Microsoft (R) .NET Framework PE Verifier. Version 4.0.30319.17929 Copyright (c) Microsoft Corporation. All rights reserved. [IL]: Error: [Z:\virtualbox_shared\foo.exe : HelloWorld.Program::Main][offset 0x00000021] Stack height at all points must be determinable in a single forward scan of IL. 1 Error(s) Verifying foo.exe 完整的源代码在为什么.Net IL不可验证?,.net,verification,il,peverify,.net,Verification,Il,Peverify,我有一点自定义IL我写的,它不会通过PEVerify。我得到的错误是 $ peverify foo.exe Microsoft (R) .NET Framework PE Verifier. Version 4.0.30319.17929 Copyright (c) Microsoft Corporation. All rights reserved. [IL]: Error: [Z:\virtualbox_shared\foo.exe : HelloWorld.Program::Ma
为什么我会出现这个错误?我不完全理解为什么这是答案,但这导致它验证:
.method private static hidebysig
default void Main (string[] args) cil managed
{
// Method begins at RVA 0x2050
.entrypoint
// Code size 54 (0x36)
.maxstack 2
//custom IL
ldc.i4 1
ldc.i4 1
ceq
switch(first, second)
first:
ldc.i4 1
br.s temp
ldc.i4 1 //not reached, but required!
popit: pop
br.s second
temp: ldc.i4 1
brfalse temp2
temp2: br.s popit
second:
ldc.i4 2
pop
ret
} // end of method Program::Main
必须在IL的单个正向扫描中确定
这是验证失败的关键部分。验证器不会尝试验证每个分支路径,这需要解决停止问题。它对POP不满意,它无法在一次正向扫描中看到此操作码是由具有非空堆栈的反向分支到达的,因此是有效的。我不完全理解逻辑,但它看起来与1.7.5反向分支约束有关()@Prescott我并不认为它在这里适用。看看通过验证的代码(特别是IL0018标签),这样看来,即使是我的“变通方法”也只是碰巧通过了微软的peverify。从ECMA规范第III部分1.7.5来看,该规范似乎完全不符合要求。我假设在这种情况下应该使用局部变量,而不是堆栈,这是任何真正的编译器都会做的,是的。
.method private static hidebysig
default void Main (string[] args) cil managed
{
// Method begins at RVA 0x2050
.entrypoint
// Code size 54 (0x36)
.maxstack 2
//custom IL
ldc.i4 1
ldc.i4 1
ceq
switch(first, second)
first:
ldc.i4 1
br.s temp
ldc.i4 1 //not reached, but required!
popit: pop
br.s second
temp: ldc.i4 1
brfalse temp2
temp2: br.s popit
second:
ldc.i4 2
pop
ret
} // end of method Program::Main