I have one field defined in CIL like this:
.field public int32 modopt(void*) fld
I compile this to an assembly. Now I change it to:
.field public int32 modopt(int16) fld
Both how is it possible now, that ILDASM reports (when shown as hex) both those fields as this?
Field #1 (04000001)
-------------------------------------------------------
Field Name: fld (04000001)
Flags : [Public] (00000006)
CallCnvntn: [FIELD]
Field type: CMOD_OPT 1b000001 I4
Signature : 06 20 06 08
This code looks for both fields exactly the same (actually I've created the second field to match the reported signature). The signature obviously matches the second field, but the signature of the first field should look like this: 06 20 0f 01 08
! What am I missing here?
Edit:
C# cannot emit this type of field, throwing an exception about pointer and array types not supported for custom type modifiers, so this apparently solves the signature mismatch. But the question why ILDASM allows creating an invalid signature which it cannot decompile remains.
Edit #2:
It seems ILASM is actually creating correct IL, there is a difference in the hex dump I missed last time:
//the first assembly
TypeSpec #1 (1b000001)
-------------------------------------------------------
TypeSpec : Ptr Void
Signature: 0f 01
//the second assembly
TypeSpec #1 (1b000001)
-------------------------------------------------------
TypeSpec : I2
Signature: 06
So there is just a bug in ILDASM hex dump reporting wrong member signature (though I wonder where the 06
in the wrong signature came from).
Let's try to build the field signature manually based on the specification. To start, field signature is defined in §II.23.2.4. For our case with one custom modifier, it will be:
FIELD CustomMod Type
Since FIELD
is defined as 0x06, we have:
06 CustomMod Type
Our custom modifier is modopt
, so we get (based on §II.23.2.7):
06 CMOD_OPT TypeDefOrRefOrSpecEncoded Type
CMOD_OPT
is 0x20 (§II.23.1.16):
06 20 TypeDefOrRefOrSpecEncoded Type
We want to reference TypeSpec
0x1b000001, which is encoded as 0b110 (10 for TypeSpec
, 1 for 0x000001, §II.23.2.8). This is then "compressed" into the single byte 0x06 (§II.23.2):
06 20 06 Type
Finally, the type is int32
, which is ELEMENT_TYPE_I4
= 0x08 (§II.23.2.12 and §II.23.1.16):
06 20 06 08
So we get exactly the same signature as the one shown in ILDasm.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With