2015-01-06 17 views
7

Ho un campo definito in CIL come questo:Diversi tipi avere stesse firme in CIL

.field public int32 modopt(void*) fld 

compilo questo a un assembly. Ora lo cambio a:

.field public int32 modopt(int16) fld 

Sia come sia possibile oggi, che i rapporti ILDASM (quando indicato come esadecimale) entrambi quei campi come questo?

Field #1 (04000001) 
------------------------------------------------------- 
    Field Name: fld (04000001) 
    Flags  : [Public] (00000006) 
    CallCnvntn: [FIELD] 
    Field type: CMOD_OPT 1b000001 I4 
    Signature : 06 20 06 08 

Questo codice cerca entrambi i campi esattamente lo stesso (in realtà ho creato il secondo campo per abbinare la firma riportata). La firma ovviamente corrisponde al secondo campo, ma la firma del primo campo dovrebbe assomigliare a questa: 06 20 0f 01 08! Cosa mi manca qui?

Edit:

C# non può emettere questo tipo di campo, un'eccezione circa puntatore e array di tipi non supportati per tipo personalizzato modificatori, quindi questo apparentemente risolve la mancata corrispondenza della firma. Ma la domanda per cui ILDASM consente di creare una firma non valida che non può decompilare rimane.

Edit # 2:

Sembra ILASM è in realtà la creazione corretta IL, c'è una differenza nel dump esadecimale ho perso l'ultima volta:

//the first assembly 
TypeSpeC#1 (1b000001) 
------------------------------------------------------- 
    TypeSpec : Ptr Void 
    Signature: 0f 01 

//the second assembly 
TypeSpeC#1 (1b000001) 
------------------------------------------------------- 
    TypeSpec : I2 
    Signature: 06 

Quindi non v'è solo un bug nel ILDASM esadecimale discarica segnalazione firma membro errato (anche se mi chiedo da dove viene il 06 nella firma sbagliata).

+0

Per fare la domanda ovvia: cosa ti fa pensare che dovrebbe essere "06 20 0f 01 08'? C'è un guasto/riferimento a questo? –

+0

@Marc Ho cercato nell'ECMA della CLI. Il tipo di elemento di modopt è '20', il tipo di elemento del puntatore è' 0f', di zero è '01'. Quindi, alzando tutti questi elementi, la firma di 'modopt (void *)' dovrebbe essere '20 0f 01' (' 06' è field callconv e '08' è int32). – IllidanS4

+0

è questo C#? Vedo il vuoto *! – niceman

risposta

1

Proviamo a creare manualmente la firma del campo in base a the specification. Per iniziare, la firma del campo è definita in §II.23.2.4. Per il nostro caso con il modificatore uno personalizzato, sarà:

FIELD CustomMod Type 

Dal FIELD è definito come 0x06, abbiamo:

06 CustomMod Type 

nostro modificatore personalizzato è modopt, in modo da ottenere (in base a § II .23.2.7):

06 CMOD_OPT TypeDefOrRefOrSpecEncoded Type 

CMOD_OPT è 0x20 (§II.23.1.16):

06 20 TypeDefOrRefOrSpecEncoded Type 

Vogliamo fare riferimento a TypeSpec 0x1b000001, che è codificato come 0b110 (10 per TypeSpec, 1 per 0x000001, §II.23.2.8). Questa è poi "compresso" nel singolo byte 0x06 (§II.23.2):

06 20 06 Type 

Infine, il tipo è int32, che è ELEMENT_TYPE_I4 = 0x08 (§II.23.2.12 e §II.23.1. 16):

06 20 06 08 

Quindi otteniamo esattamente la stessa firma di quella mostrata in ILDasm.

+0

Grazie, ha molto più senso. Pensavo che fosse una firma di tipo, non un token di tipo, quindi ho interpretato erroneamente i risultati dell'ILDasm. – IllidanS4