2012-11-07 19 views
6

Ho un po 'di IL personalizzata che ho scritto e non passerà PEVerify. L'errore che ottengo èPerché questo .Net IL non è verificabile?

 
$ 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 

Il programma tuttavia funziona senza eccezioni. Ecco la IL del metodo in questione:

.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 
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 codice sorgente completo è a pastebin

Perché mi appare questo errore?

+0

Non capisco appieno la logica, ma sembra correlata a 1.7.5 Controindicazioni a ritroso (http://books.google.com/books?id=50PhgS8vjhwC&pg=PA500&lpg=PA500&dq=1.7.5+Backward+ Branch + Constraints & source = bl & ots = vZJvWiy5mP & sig = SGz2IS1A4ynarLdB5aMg2ZGQ16g & hl = it & sa = X & ei = b5KaUOzZNuHWiwK87IGgCw & ved = 0CFYQ6AEwBQ # v = onepage & q & f = false) – Prescott

+0

@Prescott Non lo vedo davvero come si applica qui. Dai un'occhiata al codice [this] (http://pastebin.com/YSPY5szf) che supera la verifica. (In particolare, l'etichetta IL_0018) – Earlz

risposta

6

deve essere determinabile in una singola scansione in avanti di IL

Questo è il parte fondamentale del fallimento della verifica. Il verificatore non tenta di verificare ogni singolo percorso di diramazione, che richiederebbe di risolvere il problema di interruzione. Non è soddisfatto del POP, non è possibile vedere in una singola scansione in avanti che questo codice operativo venga raggiunto dal ramo inverso con uno stack non vuoto ed è quindi valido.

+0

Quindi sembrerebbe che anche la mia "soluzione alternativa" capiti solo per passare la peverify di Microsoft. Guardando nella partizione III 1.7.5 delle specifiche ECMA, questo codice sembra completamente non conforme. Suppongo che le variabili locali in questo caso debbano essere usate piuttosto che lo stack – Earlz

+1

Questo è quello che farebbe un vero compilatore, sì. –

0

Non capisco pienamente perché questa è la risposta, ma questo ha causato la PEVerify:

.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 
Problemi correlati