22 Metadata Logical Format: Other Structures


22.1 Bitmasks and Flags

This section explains the various flags and bitmasks used in the various metadata tables.

22.1.1 Values for AssemblyHashAlgorithm

Algorithm

Value

None

0x0000

Reserved (MD5)

0x8003

SHA1

0x8004

ANNOTATION

For more information on the SHA1 hash algorithm, see Partition II, section 6.2.1.1.


22.1.2 Values for AssemblyFlags

Flag

Value

Description

PublicKey

0x0001

The assembly reference holds the full (unhashed) public key.

SideBySideCompatible

0x0000

The assembly is side by side compatible.

<reserved>

0x0030

Reserved: both bits shall be zero.

Retargetable

0x0100

The implementation of this assembly used at runtime is not expected to match the version seen at compile time. (See the text following this table.)

EnableJITcompileTracking

0x8000

Reserved (a conforming implementation of the CLI may ignore this setting on read; some implementations might use this bit to indicate that a CIL-to-native-code compiler should generate CIL-to-native-code map).

DisableJITcompileOptimizer

0x4000

Reserved (a conforming implementation of the CLI may ignore this setting on read; some implementations might use this bit to indicate that a CIL-to-native-code compiler should not generate optimized code).

In portable programs, the Retargetable (0x100) bit shall be set on all references to assemblies specified in this standard.

ANNOTATION

For more information on the originator's public key, see Partition II, section 6.2.1.3.


22.1.3 Values for Culture

ar-SA

ar-IQ

ar-EG

ar-LY

ar-DZ

ar-MA

ar-TN

ar-OM

ar-YE

ar-SY

ar-JO

ar-LB

ar-KW

ar-AE

ar-BH

ar-QA

bg-BG

ca-ES

zh-TW

zh-CN

zh-HK

zh-SG

zh-MO

cs-CZ

da-DK

de-DE

de-CH

de-AT

de-LU

de-LI

el-GR

en-US

en-GB

en-AU

en-CA

en-NZ

en-IE

en-ZA

en-JM

en-CB

en-BZ

en-TT

en-ZW

en-PH

es-ES-Ts

es-MX

es-ES-Is

es-GT

es-CR

es-PA

es-DO

es-VE

es-CO

es-PE

es-AR

es-EC

es-CL

es-UY

es-PY

es-BO

es-SV

es-HN

es-NI

es-PR

Fi-FI

fr-FR

fr-BE

fr-CA

Fr-CH

fr-LU

fr-MC

he-IL

hu-HU

is-IS

it-IT

it-CH

Ja-JP

ko-KR

nl-NL

nl-BE

nb-NO

nn-NO

pl-PL

pt-BR

pt-PT

ro-RO

ru-RU

hr-HR

Lt-sr-SP

Cy-sr-SP

sk-SK

sq-AL

sv-SE

sv-FI

th-TH

tr-TR

ur-PK

id-ID

uk-UA

be-BY

sl-SI

et-EE

lv-LV

lt-LT

fa-IR

vi-VN

hy-AM

Lt-az-AZ

Cy-az-AZ

eu-ES

mk-MK

af-ZA

ka-GE

fo-FO

hi-IN

ms-MY

ms-BN

kk-KZ

ky-KZ

sw-KE

Lt-uz-UZ

Cy-uz-UZ

tt-TA

pa-IN

gu-IN

ta-IN

te-IN

kn-IN

mr-IN

sa-IN

mn-MN

gl-ES

kok-IN

syr-SY

div-MV

 

Note on RFC 1766 Locale names: a typical string would be "en-US". The first part ("en" in the example) uses ISO 639 characters ("Latin-alphabet characters in lowercase. No diacritical marks of modified characters are used"). The second part ("US" in the example) uses ISO 3166 characters (similar to ISO 639, but uppercase). In other words, the familiar ASCII characters a z and A Z, respectively. However, while RFC 1766 recommends the first part is lowercase, the second part uppercase, it allows mixed case. Therefore, the validation rule checks only that Culture is one of the strings in the list above but the check is totally case-blind where case-blind is the familiar fold on values less than U+0080.

ANNOTATION

For more information on the culture, see Partition II, section 6.2.1.2.


22.1.4 Flags for Events (EventAttributes)

Flag

Value

Description

SpecialName

0x0200

Event is special.

RTSpecialName

0x0400

CLI provides "special" behavior, depending upon the name of the event.

ANNOTATION

The SpecialName attribute is also used for properties, and compilers can designate any name they choose as SpecialName. RTSpecialName is used for certain other names that require special treatment by the VES. For more information on designating names as special, to either the compiler or the runtime, see Partition II, section 9.1.6, and Partition I, sections 8.11.3 and 8.11.4.


22.1.5 Flags for Fields (FieldAttributes)

Flag

Value

Description

FieldAccessMask

0x0007

 

CompilerControlled

0x0000

Member not referenceable.

Private

0x0001

Accessible only by the parent type.

FamANDAssem

0x0002

Accessible by subtypes only in this Assembly.

Assembly

0x0003

Accessibly by anyone in the Assembly.

Family

0x0004

Accessible only by type and subtypes.

FamORAssem

0x0005

Accessibly by subtypes anywhere, plus anyone in assembly.

Public

0x0006

Accessibly by anyone who has visibility to this scope field contract attributes.

Static

0x0010

Defined on type, else per instance.

InitOnly

0x0020

Field may only be initialized, not written to after init.

Literal

0x0040

Value is compile-time constant.

NotSerialized

0x0080

Field does not have to be serialized when type is remoted.

SpecialName

0x0200

Field is special.

Interop Attributes

PInvokeImpl

0x2000

Implementation is forwarded through PInvoke.

Additional Flags

RTSpecialName

0x0400

CLI provides "special" behavior, depending upon the name of the field.

HasFieldMarshal

0x1000

Field has marshalling information.

HasDefault

0x8000

Field has default.

HasFieldRVA

0x0100

Field has RVA.

ANNOTATION

For more information on NotSerialized, see Partition II, sections 9.1.6 and 15.1.2.

For more information on the accessibility options, see Partition II, section 8 and its subsections.


22.1.6 Flags for Files (FileAttributes)

Flag

Value

Description

ContainsMetaData

0x0000

This is not a resource file.

ContainsNoMetaData

0x0001

This is a resource file or other non-metadata-containing file.

22.1.7 Flags for ImplMap (PInvokeAttributes)

Flag

Value

Description

NoMangle

0x0001

PInvoke is to use the member name as specified.

Character Set

CharSetMask

0x0006

This is a resource file or other non-metadata-containing file.

CharSetNotSpec

0x0000

 

CharSetAnsi

0x0002

 

CharSetUnicode

0x0004

 

CharSetAuto

0x0006

 

SupportsLastError

0x0040

Information about target function. Not relevant for fields.

Calling Convention

CallConvMask

0x0700

 

CallConvWinapi

0x0100

 

CallConvCdecl

0x0200

 

CallConvStdcall

0x0300

 

CallConvThiscall

0x0400

 

CallConvFastcall

0x0500

 

ANNOTATION

For more information on character sets, see Partition II, section 9.1.5. For more information on calling conventions, see Partition II, section 14.3.


22.1.8 Flags for ManifestResource (ManifestResourceAttributes)

Flag

Value

Description

VisibilityMask

0x0007

 

Public

0x0001

The Resource is exported from the Assembly.

Private

0x0002

The Resource is private to the Assembly.

ANNOTATION

For more information on visibility, see Partition II, section 8 and its subsections.


22.1.9 Flags for Methods (MethodAttributes)

Flag

Value

Description

MemberAccessMask

0x0007

 

CompilerControlled

0x0000

Member not referenceable.

Private

0x0001

Accessible only by the parent type.

FamANDAssem

0x0002

Accessible by subtypes only in this Assembly.

Assem

0x0003

Accessibly by anyone in the Assembly.

Family

0x0004

Accessible only by type and subtypes.

FamORAssem

0x0005

Accessibly by subtypes anywhere, plus anyone in assembly.

Public

0x0006

Accessibly by anyone who has visibility to this scope.

Static

0x0010

Defined on type, else per instance.

Final

0x0020

Method may not be overridden.

Virtual

0x0040

Method is virtual.

HideBySig

0x0080

Method hides by name+sig, else just by name.

VtableLayoutMask

0x0100

Use this mask to retrieve vtable attributes.

ReuseSlot

0x0000

Method reuses existing slot in vtable.

NewSlot

0x0100

Method always gets a new slot in the vtable.

Abstract

0x0400

Method does not provide an implementation.

SpecialName

0x0800

Method is special.

Interop Attributes

PInvokeImpl

0x2000

Implementation is forwarded through PInvoke.

UnmanagedExport

0x0008

Reserved: shall be zero for conforming implementations.

Additional Flags

RTSpecialName

0x1000

CLI provides "special" behavior, depending upon the name of the method.

HasSecurity

0x4000

Method has security associate with it.

RequireSecObject

0x8000

Method calls another method containing security code.

ANNOTATION

For more information on the accessibility options and hiding, see Partition II, section 8 and its subsections. For information on overriding (the NewSlot flag), see Partition II, section 9.3.1.


ANNOTATION

Implementation-Specific (Microsoft): UnmanagedExport indicates a managed method exported via thunk to unmanaged code.


22.1.10 Flags for Methods (MethodImplAttributes)

Flag

Value

Description

CodeTypeMask

0x0003

 

IL

0x0000

Method impl is CIL.

Native

0x0001

Method impl is native.

OPTIL

0x0002

Reserved: shall be zero in conforming implementations.

Runtime

0x0003

Method impl is provided by the runtime.

ManagedMask

0x0004

Flags specifying whether the code is managed or unmanaged.

Unmanaged

0x0004

Method impl is unmanaged, otherwise managed.

Managed

0x0000

Method impl is managed.

Implementation Info and Interop

ForwardRef

0x0010

Indicates method is defined; used primarily in merge scenarios.

PreserveSig

0x0080

Reserved: conforming implementations may ignore.

InternalCall

0x1000

Reserved: shall be zero in conforming implementations.

Synchronized

0x0020

Method is single-threaded through the body.

NoInlining

0x0008

Method may not be inlined.

MaxMethodImplVal

0xffff

Range check value.

ANNOTATION

Implementation-Specific (Microsoft): The PreserveSig method signature is not to be mangled to do HRESULT conversion.


22.1.11 Flags for MethodSemantics (MethodSemanticsAttributes)

Flag

Value

Description

Setter

0x0001

Setter for property

Getter

0x0002

Getter for property

Other

0x0004

Other method for property or event

AddOn

0x0008

AddOn method for event

RemoveOn

0x0010

RemoveOn method for event

Fire

0x0020

Fire method for event

ANNOTATION

For more information on properties and events, see Partition II, sections 16 and 17.


22.1.12 Flags for Params (ParamAttributes)

Flag

Value

Description

In

0x0001

Param is [In].

Out

0x0002

Param is [Out].

Optional

0x0010

Param is optional.

HasDefault

0x1000

Param has default value.

HasFieldMarshal

0x2000

Param has FieldMarshal.

Unused

0xcfe0

Reserved: shall be zero in a conforming implementation.

22.1.13 Flags for Properties (PropertyAttributes)

Flag

Value

Description

SpecialName

0x0200

Property is special.

RTSpecialName

0x0400

Runtime (metadata internal APIs) should check name encoding.

HasDefault

0x1000

Property has default.

Unused

0xe9ff

Reserved: shall be zero in a conforming implementation.

22.1.14 Flags for Types (TypeAttributes)

Flag

Value

Description

Visibility Attributes

VisibilityMask

0x00000007

Use this mask to retrieve visibility information.

NotPublic

0x00000000

Class has no public scope.

Public

0x00000001

Class has public scope.

NestedPublic

0x00000002

Class is nested with public visibility.

NestedPrivate

0x00000003

Class is nested with private visibility.

NestedFamily

0x00000004

Class is nested with family visibility.

NestedAssembly

0x00000005

Class is nested with assembly visibility.

NestedFamANDAssem

0x00000006

Class is nested with family and assembly visibility.

NestedFamORAssem

0x00000007

Class is nested with family or assembly visibility.

Class Layout Attributes

LayoutMask

0x00000018

Use this mask to retrieve class layout information.

AutoLayout

0x00000000

Class fields are auto-laid out.

SequentialLayout

0x00000008

Class fields are laid out sequentially.

ExplicitLayout

0x00000010

Layout is supplied explicitly.

Class Semantics Attributes

ClassSemanticsMask

0x00000020

Use this mask to retrieve class semantics information.

Class

0x00000000

Type is a class.

Interface

0x00000020

Type is an interface.

Special Semantics in Addition to Class Semantics

Abstract

0x00000080

Class is abstract.

Sealed

0x00000100

Class cannot be extended.

SpecialName

0x00000400

Class name is special.

Implementation Attributes

Import

0x00001000

Class/Interface is imported.

Serializable

0x00002000

Class is serializable.

String Formatting Attributes

StringFormatMask

0x00030000

Use this mask to retrieve string information for native interop.

AnsiClass

0x00000000

LPSTR is interpreted as ANSI.

UnicodeClass

0x00010000

LPSTR is interpreted as Unicode.

AutoClass

0x00020000

LPSTR is interpreted automatically.

Class Initialization Attributes

BeforeFieldInit

0x00100000

Initialize the class before first static field access.

Additional Flags

RTSpecialName

0x00000800

CLI provides "special" behavior, depending upon the name of the Type.

HasSecurity

0x00040000

Type has security associated with it.

22.1.15 Element Types Used in Signatures

The following table lists the values for ELEMENT_TYPE constants. These are used extensively in metadata signature blobs see Partition II, section 22.2.

ANNOTATION

For more information on element types, see Partition II, sections 21.9 and 21.10.


ANNOTATION

Implementation-Specific (Microsoft): These values are defined in the file inc\CorHdr.h in the Microsoft .NET SDK.


Name

Value

Remarks

ELEMENT_TYPE_END

0x00

Marks end of a list.

ELEMENT_TYPE_VOID

0x01

 

ELEMENT_TYPE_BOOLEAN

0x02

 

ELEMENT_TYPE_CHAR

0x03

 

ELEMENT_TYPE_I1

0x04

 

ELEMENT_TYPE_U1

0x05

 

ELEMENT_TYPE_I2

0x06

 

ELEMENT_TYPE_U2

0x07

 

ELEMENT_TYPE_I4

0x08

 

ELEMENT_TYPE_U4

0x09

 

ELEMENT_TYPE_I8

0x0a

 

ELEMENT_TYPE_U8

0x0b

 

ELEMENT_TYPE_R4

0x0c

 

ELEMENT_TYPE_R8

0x0d

 

ELEMENT_TYPE_STRING

0x0e

 

ELEMENT_TYPE_PTR

0x0f

Followed by <type> token.

ELEMENT_TYPE_BYREF

0x10

Followed by <type> token.

ELEMENT_TYPE_VALUETYPE

0x11

Followed by TypeDef or TypeRef token.

ELEMENT_TYPE_CLASS

0x12

Followed by TypeDef or TypeRef token.

ELEMENT_TYPE_ARRAY

0x14

<type> <rank> <boundsCount> <bound1> … <loCount> <lo1> …

ELEMENT_TYPE_TYPEDBYREF

0x16

 

ELEMENT_TYPE_I

0x18

System.IntPtr.

ELEMENT_TYPE_U

0x19

System.UIntPtr.

ELEMENT_TYPE_FNPTR

0x1b

Followed by full method signature.

ELEMENT_TYPE_OBJECT

0x1c

System.Object.

ELEMENT_TYPE_SZARRAY

0x1d

Single-dim array with 0 lower bound.

ELEMENT_TYPE_CMOD_REQD

0x1f

Required modifier: followed by a TypeDef or TypeRef token.

ELEMENT_TYPE_CMOD_OPT

0x20

Optional modifier: followed by a TypeDef or TypeRef token.

ELEMENT_TYPE_INTERNAL

0x21

Implemented within the CLI.

ELEMENT_TYPE_MODIFIER

0x40

OR'd with following element types.

ELEMENT_TYPE_SENTINEL

0x41

Sentinel for varargs method signature.

ELEMENT_TYPE_PINNED

0x45

Denotes a local variable that points at a pinned object.

22.2 Blobs and Signatures

The word "signature" is conventionally used to describe the type info for a function or method that is, the type of each of its parameters, and the type of its return value. Within metadata, the word "signature" is also used to describe the type info for fields, properties, and local variables. Each Signature is stored as a (counted) byte array in the Blob heap. There are six kinds of Signatures, as follows:

  • MethodRefSig differs from a MethodDefSig only for VARARG calls

  • MethodDefSig

  • FieldSig

  • PropertySig

  • LocalVarSig

  • TypeSpec

The value of the leading byte of a Signature "blob" indicates what kind of Signature it is. This section defines the binary "blob" format for each kind of Signature.

Note that Signatures are compressed before being stored into the Blob heap (described below) by compressing the integers embedded in the signature. The maximum encodable integer is 29 bits long, 0x1FFFFFFF. The compression algorithm used is as follows (bit 0 is the least significant bit):

  • If the value lies between 0 (0x00) and 127 (0x7F), inclusive, encode as a 1-byte integer (bit #7 is clear, value held in bits #6 through #0).

  • If the value lies between 28 (0x80) and 214 1 (0x3FFF), inclusive, encode as a 2-byte integer with bit #15 set, bit #14 clear (value held in bits #13 through #0).

  • Otherwise, encode as a 4-byte integer, with bit #31 set, bit #30 set, bit #29 clear (value held in bits #28 through #0).

  • A null string should be represented with the reserved single-byte 0xFF, and no following data.

NOTE

The table below shows several examples. The first column gives a value, expressed in familiar (C-like) hex notation. The second column shows the corresponding, compressed result, as it would appear in a PE file, with successive bytes of the result lying at successively higher byte offsets within the file. (This is the opposite order from how regular binary integers are laid out in a PE file.)

Original Value

Compressed Representation

0x03

03

0x7F

7F (7 bits set)

0x80

8080

0x2E57

AE57

0x3FFF

BFFF

0x4000

C000 4000

0x1FFF FFFF

DFFF FFFF

Thus, the most significant bits (the first ones encountered in a PE file) of a "compressed" field, can reveal whether it occupies 1, 2, or 4 bytes, as well as its value. For this to work, the "compressed" value, as explained above, is stored in big-endian order with the most significant byte at the smallest offset within the file.


ANNOTATION

As you will note, the "compressions" above do not always reduce the size of the values. This type of compression allows smaller values to be stored in fewer than 4 bytes, because statistically, more small positive or negative numbers are used than larger values. Integers near zero use only 1 byte instead of 4, and slightly larger values use 2 bytes instead of 4.


Signatures make extensive use of constant values called ELEMENT_TYPE_xxx see Partition II, section 22.1.15. In particular, signatures include two modifiers called:

ELEMENT_TYPE_BYREF this element is a managed pointer [see the annotation to Partition I, section 8.9.2]. This modifier can only occur in the definition of Param (Partition II, section 22.2.10) or RetType (Partition II, section 22.2.11). It shall not occur within the definition of a Field (Partition II, section 22.2.4).

ELEMENT_TYPE_PTR this element is an unmanaged pointer (see Partition I [section 8.9.2]). This modifier can occur in the definition of Param (Partition II, section 22.2.10) or RetType (Partition II, section 22.2.11) or Field (Partition II, section 22.2.4).

ANNOTATION

For a field, the signature would be the type of the field. For a method, it would be the return type, the number of parameters, all of the parameter types, etc.


22.2.1 MethodDefSig

A MethodDefSig is indexed by the Method.Signature column. It captures the signature of a method or global function. The syntax chart for a MethodDefSig is:

graphics/05inf09.gif

This chart uses the following abbreviations (see Partition II, section 14.3):

HASTHIS = 0x20, used to encode the keyword instance in the calling convention

EXPLICITTHIS = 0x40, used to encode the keyword explicit in the calling convention

DEFAULT = 0x0, used to encode the keyword default in the calling convention

VARARG = 0x5, used to encode the keyword vararg in the calling convention

ANNOTATION

Implementation-Specific (Microsoft): The above names are defined in the file inc\CorHdr.h as part of the Microsoft .NET SDK, using a prefix of IMAGE_CEE_ CS_CALLCONV_.


The first byte of the Signature holds bits for HASTHIS, EXPLICITTHIS, and calling convention DEFAULT or VARARG. These are OR'd together.

ParamCount is an integer that holds the number of parameters (0 or more). It can be any number between 0 and 0x1FFFFFFF. The compiler compresses it too (see Partition II, Metadata Validation [section 3]) before storing into the "blob" (ParamCount counts just the method parameters it does not include the method's return type).

The RetType item describes the type of the method's return value (see Partition II, section 22.2.11).

The Param item describes the type of each of the method's parameters. There shall be ParamCount instances of the Param item (see Partition II, section 22.2.10).

22.2.2 MethodRefSig

A MethodRefSig is indexed by the MemberRef.Signature column. This provides the call-site Signature for a method. Normally, this call-site Signature shall match exactly the Signature specified in the definition of the target method. For example, if a method Foo is defined that takes two uint32's and returns void; then any call site shall index a signature that takes exactly two uint32's and returns void. In this case, the syntax chart for a MethodRefSig is identical with that for a MethodDefSig see Partition II, section 22.2.1.

The Signature at a call site differs from that at its definition, only for a method with the VARARG calling convention. In this case, the call-site Signature is extended to include info about the extra VARARG arguments (for example, corresponding to the "..." in C syntax). The syntax chart for this case is:

graphics/05inf10.gif

This chart uses the following abbreviations (see Partition II, section 14.3):

HASTHIS = 0x20, used to encode the keyword instance in the calling convention

EXPLICITTHIS = 0x40, used to encode the keyword explicit in the calling convention

DEFAULT = 0x0, used to encode the keyword default in the calling convention

VARARG = 0x5, used to encode the keyword vararg in the calling convention

SENTINEL = 0x41 (see Partition II, section 22.1.15), used to encode "..." in the parameter list

ANNOTATION

Implementation-Specific (Microsoft): The above names are defined in the file inc\CorHdr.h as part of the SDK, using a prefix of IMAGE_CEE_CS_CALLCONV_.


  • The first byte of the Signature holds bits for HASTHIS, EXPLICITTHIS, and calling convention DEFAULT, VARARG, C, STDCALL, THISCALL, or FASTCALL. These are OR'd together.

  • ParamCount is an integer that holds the number of parameters (0 or more). It can be any number between 0 and 0x1FFFFFFF. The compiler compresses it too (see Partition II, Metadata Validation [section 3]) before storing into the "blob" (ParamCount counts just the method parameters it does not include the method's return type).

  • The RetType item describes the type of the method's return value (see Partition II, section 22.2.11).

  • The Param item describes the type of each of the method's parameters. There shall be ParamCount instances of the Param item (see Partition II, section 22.2.10).

The Param item describes the type of each of the method's parameters. There shall be ParamCount instances of the Param item. This starts just like the MethodDefSig for a VARARG method (see Partition II, section 22.2.1). But then a SENTINEL token is appended, followed by extra Param items to describe the extra VARARG arguments. Note that the ParamCount item shall indicate the total number of Param items in the Signature before and after the SENTINEL byte (0x41).

In the unusual case that a call site supplies no extra arguments, the signature shall not include a SENTINEL (this is the route shown by the lower arrow that bypasses SENTINEL and goes to the end of the MethodRefSig definition).

22.2.3 StandAloneMethodSig

A StandAloneMethodSig is indexed by the StandAloneSig.Signature column. It is typically created as preparation for executing a calli instruction. It is similar to a MethodRefSig, in that it represents a call-site signature, but its calling convention may specify an unmanaged target (the calli instruction invokes either managed or unmanaged code). Its syntax chart is:

graphics/05inf11.gif

This chart uses the following abbreviations (see Partition II, section 14.3):

HASTHIS for 0x20

EXPLICITTHIS for 0x40

DEFAULT for 0x0

VARARG for 0x5

C for 0x1

STDCALL for 0x2

THISCALL for 0x3

FASTCALL for 0x4

SENTINEL for 0x41 (see Partition II, section 22.1.15 and Partition II, section 14.3)

ANNOTATION

Implementation-Specific (Microsoft): The above names are defined in the file inc\CorHdr.h as part of the Microsoft .NET SDK, using a prefix of IMAGE_CEE_CS_ CALLCONV_.


  • The first byte of the Signature holds bits for HASTHIS, EXPLICITTHIS, and calling convention DEFAULT, VARARG, C, STDCALL, THISCALL, or FASTCALL. These are OR'd together.

  • ParamCount is an integer that holds the number of parameters (0 or more). It can be any number between 0 and 0x1FFFFFFF. The compiler compresses it too (see Partition II, Metadata Validation [section 3]) before storing into the "blob" (ParamCount counts just the method parameters it does not include the method's return type).

  • The RetType item describes the type of the method's return value (see Partition II, section 22.2.11).

  • The Param item describes the type of each of the method's parameters. There shall be ParamCount instances of the Param item (see Partition II, section 22.2.10).

This is the most complex of the various method signatures. Two separate charts have been combined into one in this diagram, using shading to distinguish between them. Thus, for the following calling conventions: DEFAULT (managed), STDCALL, THISCALL, and FASTCALL (unmanaged), the signature ends just before the SENTINEL item (these are all non-vararg signatures). However, for the managed and unmanaged vararg calling conventions: VARARG (managed) and C (unmanaged), the signature can include the SENTINEL and final Param items (they are not required, however). These options are indicated by the shading of boxes in the syntax chart.

22.2.4 FieldSig

A FieldSig is indexed by the Field.Signature column or by the MemberRef.Signature column (in the case where it specifies a reference to a field, not a method, of course). The Signature captures the field's definition. The field may be a static or instance field in a class, or it may be a global variable. The syntax chart for a FieldSig looks like this:

graphics/05inf12.gif

This chart uses the following abbreviations:

FIELD for 0x6

ANNOTATION

Implementation-Specific (Microsoft): The above name is defined in the file inc\CorHdr.h as part of the Microsoft .NET SDK, using a prefix of IMAGE_CEE_CS_ CALLCONV_FIELD.


CustomMod is defined in Partition II, section 22.2.7. Type is defined in Partition II, section 22.2.12.

22.2.5 PropertySig

A PropertySig is indexed by the Property.Type column. It captures the type information for a Property essentially, the signature of its getter method:

How many parameters are supplied to its getter method

The base type of the Property the type returned by its getter method

Type information for each parameter in the getter method that is, the index parameters

Note that the signatures of the getter and setter are related precisely as follows:

  • The types of a getter's paramCount parameters are exactly the same as the first paramCount parameters of the setter.

  • The return type of a getter is exactly the same as the type of the last parameter supplied to the setter.

The syntax chart for a PropertySig looks like this:

graphics/05inf13.gif

This chart uses the following abbreviations:

PROPERTY for 0x8

ANNOTATION

Implementation-Specific (Microsoft): The above name is defined in the file inc\CorHdr.h as part of the Microsoft .NET SDK, using a prefix of IMAGE_CEE_CS_ CALLCONV_PROPERTY.


Type specifies the type returned by the getter method for this property. Type is defined in Partition II, section 22.2.12. Param is defined in Partition II, section 22.2.10.

ParamCount is an integer that holds the number of index parameters in the getter methods (0 or more) (see Partition II, section 22.2.1). (ParamCount counts just the method parameters it does not include the method's base type of the Property.)

22.2.6 LocalVarSig

A LocalVarSig is indexed by the StandAloneSig.Signature column. It captures the type of all the local variables in a method. Its syntax chart is:

graphics/05inf14.gif

This chart uses the following abbreviations:

LOCAL_SIG for 0x7, used for the .locals directive (see Partition II, section 14.4.1.3)

ANNOTATION

Implementation-Specific (Microsoft): The above name is defined in the file inc\CorHdr.h as part of the Microsoft .NET SDK, using a prefix of IMAGE_CEE_CS_ CALLCONV_LOCAL_SIG.


BYREF for ELEMENT_TYPE_BYREF (see Partition II, section 22.1.15)

Constraint is defined in Partition II, section 22.2.9.

Type is defined in Partition II, section 22.2.12.

Count is an unsigned integer that holds the number of local variables. It can be any number between 1 and 0xFFFE.

There shall be Count instances of the Type in the LocalVarSig.

22.2.7 CustomMod

The CustomMod (custom modifier) item in Signatures has a syntax chart like this:

graphics/05inf15.gif

This chart uses the following abbreviations:

CMOD_OPT

for

LEMENT_TYPE_CMOD_OPT (see Partition II, section 22.1.15)

CMOD_REQD

for

ELEMENT_TYPE_CMOD_REQD (see Partition II, section 22.1.15)

The CMOD_OPT or CMOD_REQD value is compressed (see Partition II, section 22.2).

The CMOD_OPT or CMOD_REQD is followed by a metadata token that indexes a row in the TypeDef table or the TypeRef table. However, these tokens are encoded and compressed see Partition II, section 22.2.8 for details.

If the custom modifier is tagged CMOD_OPT, then any importing compiler can freely ignore it entirely. Conversely, if the custom modifier is tagged CMOD_REQD, any importing compiler shall "understand|" the semantic implied by this custom modifier in order to reference the surrounding Signature.

ANNOTATION

Implementation-Specific (Microsoft): A typical use for a custom modifier is for Visual C++ .NET to denote a method parameter as const. It does this using a CMOD_OPT, followed by a TypeRef to Microsoft.VisualC.IsConstModifier (defined in Microsoft.VisualC.DLL).

Visual C++ .NET also uses a custom modifier (embedded within a RetType see Partition II, section 22.2.11) to mark the native calling convention of a function. Of course, if that routine is implemented as managed code, this info is not used. But if it turns out to be implemented as unmanaged code, it becomes crucial that automatically generated thunks marshal the arguments correctly. This technique is used in IJW ("It Just Works") scenarios. Strictly speaking, such a custom modifier does not apply only to the RetType; it really applies to the whole function. In these cases, the TypeRef following the CMOD_OPT is to one of CallConvCdecl, CallConvStdcall, CallConvThiscall, or CallConvFastcall.


22.2.8 TypeDef or Ref Encoded

These items are compact ways to store a TypeDef or TypeRef token in a Signature (see Partition II, section 22.2.12).

Consider a regular TypeRef token, such as 0x01000012. The top byte of 0x01 indicates that this is a TypeRef token (see Partition V for a list of the supported metadata token types). The lower 3 bytes (0x000012) index row number 0x12 in the TypeRef table.

The encoded version of this TypeRef token is made up as follows:

  1. Encode the table that this token indexes as the least significant 2 bits. The bit values to use are 0, 1, and 2, specifying the target table is the TypeDef, TypeRef, or TypeSpec table, respectively.

  2. Shift the 3-byte row index (0x000012 in this example) left by 2 bits, and OR into the 2-bit encoding from step 1.

  3. Compress the resulting value (see Partition II, section 22.2). This example yields the following encoded value:

     
     a)  encoded = value for TypeRef table = 0x01 (from 1. above) b)  encoded = ( 0x000012 << 2 ) |  0x01             = 0x48 | 0x01             = 0x49 c)  encoded = Compress (0x49)             = 0x49 

So, instead of the original, regular TypeRef token value of 0x01000012, requiring 4 bytes of space in the Signature "blob," this TypeRef token is encoded as a single byte.

22.2.9 Constraint

The Constraint item in Signatures currently has only one possible value ELEMENT_TYPE_PINNED (see Partition II, section 22.1.15), which specifies that the target type is pinned in the runtime heap, and will not be moved by the actions of garbage collection.

A Constraint can only be applied within a LocalVarSig (not a FieldSig). The Type of the local variable shall either be a reference type (in other words, it points to the actual variable for example, an Object or a String); or it shall include the BYREF item. The reason is that local variables are allocated on the runtime stack they are never allocated from the runtime heap; so unless the local variable points at an object allocated in the GC heap, pinning makes no sense.

22.2.10 Param

The Param (parameter) item in Signatures has this syntax chart:

graphics/05inf16.gif

This chart uses the following abbreviations:

BYREF

for

0x10 (see Partition II, section 22.1.15)

TYPEDBYREF

for

0x16 (see Partition II, section 22.1.15)

CustomMod is defined in Partition II, section 22.2.7. Type is defined in Partition II, section 22.2.12.

22.2.11 RetType

The RetType (return type) item in Signatures has this syntax chart:

graphics/05inf17.gif

RetType is identical to Param except for one extra possibility, that it can include the type VOID. This chart uses the following abbreviations:

BYREF

for

ELEMENT_TYPE_BYREF (see Partition II, section 22.1.15)

TYPEDBYREF

for

ELEMENT_TYPE_TYPEDBYREF (see Partition II, section 22.1.15)

VOID

for

ELEMENT_TYPE_VOID (see Partition II, section 22.1.15)

22.2.12 Type

Type is encoded in signatures as follows (I1 is an abbreviation for ELEMENT_TYPE_I1, etc.; see Partition II, section 22.1.15):

 
 Type ::= BOOLEAN | CHAR | I1 | U1 | I2 | U2 | I4 | U4 | I8 | U8 | R4 | R8 | I  | U | | VALUETYPE TypeDefOrRefEncoded | CLASS TypeDefOrRefEncoded | STRING | OBJECT | PTR CustomMod* VOID | PTR CustomMod* Type | FNPTR MethodDefSig | FNPTR MethodRefSig | ARRAY Type ArrayShape  (general array, see Partition II, section 22.2.13) | SZARRAY CustomMod* Type (single-dimensional, zero-based array--i.e., vector) 
22.2.13 ArrayShape

An ArrayShape has the following syntax chart:

graphics/05inf18.gif

Rank is an integer (stored in compressed form; see Partition II, section 22.2) that specifies the number of dimensions in the array (shall be 1 or more). NumSizes is a compressed integer that says how many dimensions have specified sizes (it shall be 0 or more). Size is a compressed integer specifying the size of that dimension the sequence starts at the first dimension, and goes on for a total of NumSizes items. Similarly, NumLoBounds is a compressed integer that says how many dimensions have specified lower bounds (it shall be 0 or more). And LoBound is a compressed integer specifying the lower bound of that dimension the sequence starts at the first dimension and goes on for a total of NumLoBounds items. None of the dimensions in these two sequences can be skipped, but the number of specified dimensions can be less than Rank.

Here are a few examples, all for element type int32:

 

Type

Rank

NumSizes

Size

NumLoBounds

LoBound

       

[0...2]

I4

1

1

3

0

 

[,,,,,,]

I4

7

0

 

0

 

[0...3, 0...2,,,,]

I4

6

2

4 3

2

0 0

[1...2, 6...8]

I4

2

2

2 3

2

1 6

[5, 3...5, , ]

I4

4

2

5 3

2

0 3

NOTE

Definitions can nest, since the Type may itself be an array.


22.2.14 TypeSpec

The signature in the Blob heap indexed by a TypeSpec token has the following format:

 
 TypeSpecBlob :==   PTR      CustomMod*  VOID | PTR      CustomMod*  Type | FNPTR    MethodDefSig | FNPTR    MethodRefSig | ARRAY    Type  ArrayShape | SZARRAY  CustomMod*  Type 

For compactness, the ELEMENT_TYPE_ prefixes have been omitted from this list. So, for example, PTR is shorthand for ELEMENT_TYPE_PTR (see Partition II, section 22.1.15). Note that a TypeSpecBlob does not begin with a calling-convention byte, so it differs from the various other signatures that are stored into metadata.

22.2.15 Short-Form Signatures

The general specification for signatures leaves some leeway in how to encode certain items. For example, it appears legal to encode a String as either

Long-form: ELEMENT_TYPE_CLASS, TypeRef-to-System.String

Short-form: ELEMENT_TYPE_STRING

Only the short form is valid. The following table shows which short forms should be used in place of each long-form item. (As usual, for compactness, the ELEMENT_TYPE_ prefixes have been omitted here so VALUETYPE is short for ELEMENT_TYPE_VALUETYPE.)

Long Form

Short Form

Prefix

TypeRef to:

 

CLASS

System.String

STRING

CLASS

System.Object

OBJECT

VALUETYPE

System.Void

VOID

VALUETYPE

System.Boolean

BOOLEAN

VALUETYPE

System.Char

CHAR

VALUETYPE

System.Byte

U1

VALUETYPE

System.Sbyte

I1

VALUETYPE

System.Int16

I2

VALUETYPE

System.UInt16

U2

VALUETYPE

System.Int32

I4

VALUETYPE

System.UInt32

U4

VALUETYPE

System.Int64

I8

VALUETYPE

System.UInt64

U8

VALUETYPE

System.IntPtr

I

VALUETYPE

System.UIntPtr

U

VALUETYPE

System.TypedReference

TYPEDBYREF

NOTE

Arrays shall be encoded in signatures using one of ELEMENT_TYPE_ARRAY or ELEMENT_TYPE_SZARRAY. There is no long form involving a TypeRef to System.Array.


22.3 Custom Attributes

A Custom Attribute has the following syntax chart:

graphics/05inf19.gif

All binary values are stored in little-endian format (except PackedLen items used only as counts for the number of bytes to follow in a UTF8 string). If there are no fields, parameters, or properties specified, the entire attribute may be represented as an empty blob.

CustomAttrib starts with a Prolog an unsigned int16, with value 0x0001.

Next comes a description of the fixed arguments for the constructor method. Their number and type is found by examining that constructor's MethodDef; this info is not repeated in the CustomAttrib itself. As the syntax chart shows, there can be zero or more FixedArgs. (Note that VARARG constructor methods are not allowed in the definition of Custom Attributes.)

Next is a description of the optional "named" fields and properties. This starts with NumNamed an unsigned int16 giving the number of "named" properties or fields that follow. Note that NumNamed shall always be present. If its value is zero, there are no "named" properties or fields to follow (and of course, in this case, the CustomAttrib shall end immediately after NumNamed). In the case where NumNamed is non-zero, it is followed by NumNamed repeats of NamedArgs.

graphics/05inf20.gif

The format for each FixedArg depends upon whether that argument is single, or an SZARRAY this is shown in the upper and lower paths, respectively, of the syntax chart [above]. So each FixedArg is either a single Elem, or NumElem repeats of Elem.

(SZARRAY is the single byte 0x1d and denotes a vector a single-dimension array with a lower bound of zero.)

NumElem is an unsigned int32 specifying the number of elements in the SZARRAY, or 0xFFFFFFFF to indicate that the value is null.

graphics/05inf21.gif

An Elem takes one of three forms:

  • If the parameter kind is simple (bool, char, float32, float64, int8, int16, int32, int64, unsigned int8, unsigned int16, unsigned int32, or unsigned int64) then the "blob" contains its binary value (Val). This pattern is also used if the parameter kind is an enum simply store the value of the enum's underlying integer type.

  • If the parameter kind is string or type, then the blob contains a SerString a PackedLen count of bytes, followed by the UTF8 characters. A type is stored as a string giving the full name of that type. Where the actual argument value is null, it shall be encoded as the single byte 0xFF.

  • For parameters, fields, or properties whose formal (static) type is System.Object, the blob contains the actual type's FieldOrPropType (see below), followed by the representation of the actual parameter. (Note: it is not possible to pass a value of null in this case.)

Val is the binary value for a simple type. A bool is a single byte with value 0 (false) or 1 (true); char is a two-byte unicode character; and the others have their obvious meaning.

graphics/05inf22.gif

A NamedArg is simply a FixedArg (discussed above) preceded by information to identify which field or property it represents.

FIELD is the single byte 0x53.

PROPERTY is the single byte 0x54.

If the parameter kind is a boxed simple value type (bool, char, float32, float64, int8, int16, int32, int64, unsigned int8, unsigned int16, unsigned int32, or unsigned int64), then FieldOrPropType is immediately preceded by a byte containing the value 0x51.

The FieldOrPropType shall be exactly one of: ELEMENT_TYPE_BOOLEAN, ELEMENT_TYPE_CHAR, ELEMENT_TYPE_I1, ELEMENT_TYPE_U1, ELEMENT_TYPE_I2, ELEMENT_TYPE_U2, ELEMENT_TYPE_I4, ELEMENT_TYPE_U4, ELEMENT_TYPE_I8, ELEMENT_TYPE_U8, ELEMENT_TYPE_R4, ELEMENT_TYPE_R8, ELEMENT_TYPE_STRING, or the constant 0x50 (for an argument of type Type). A single-dimensional, zero-based array is specified as a single byte 0x1D followed by the FieldOrPropType of the element type. (See Partition II, section 22.1.15.)

The FieldOrPropName is the name of the field or property, stored as a SerString (defined above).

The SerString used to encode an argument of type Type includes the full type name, followed optionally by the assembly where it is defined, its version, culture, and public key token. If the assembly name is omitted, the CLI looks first in this assembly, and then the assembly named mscorlib.

For example, consider the Type string "Ozzy.OutBack.Kangaroo+Wallaby, MyAssembly" for a class "Wallaby" nested within class "Ozzy.OutBack.Kangaroo", defined in the assembly "MyAssembly".

22.4 Marshalling Descriptors

A marshalling descriptor is like a signature it's a "blob" of binary data. It describes how a field or parameter (which, as usual, covers the method return, as parameter number 0) should be marshalled when calling to or from unmanaged code via PInvoke dispatch. The ilasm syntax marshal can be used to create a marshalling descriptor, as can the pseudo custom attribute MarshalAsAttribute see Partition II, section 20.2.1.)

Note that a conforming implementation of the CLI need only support marshalling of the types specified earlier see Partition II, section 14.5.5.

Marshalling descriptors make use of constants named NATIVE_TYPE_xxx. Their names and values are listed in the following table:

Name

Value

NATIVE_TYPE_BOOLEAN

0x02

NATIVE_TYPE_I1

0x03

NATIVE_TYPE_U1

0x04

NATIVE_TYPE_I2

0x05

NATIVE_TYPE_U2

0x06

NATIVE_TYPE_I4

0x07

NATIVE_TYPE_U4

0x08

NATIVE_TYPE_I8

0x09

NATIVE_TYPE_U8

0x0a

NATIVE_TYPE_R4

0x0b

NATIVE_TYPE_R8

0x0c

NATIVE_TYPE_LPSTR

0x14

NATIVE_TYPE_INT

0x1f

NATIVE_TYPE_UINT

0x20

NATIVE_TYPE_FUNC

0x26

NATIVE_TYPE_ARRAY

0x2a

ANNOTATION

Implementation-Specific (Microsoft): The Microsoft implementation supports a richer set of types to describe marshalling between Windows native types and COM. These additional options are listed in the following table:


Name

Value

Remarks

NATIVE_TYPE_CURRENCY

0x0f

 

NATIVE_TYPE_BSTR

0x13

 

NATIVE_TYPE_LPWSTR

0x15

 

NATIVE_TYPE_LPTSTR

0x16

 

NATIVE_TYPE_FIXEDSYSSTRING

0x17

 

NATIVE_TYPE_IUNKNOWN

0x19

 

NATIVE_TYPE_IDISPATCH

0x1a

 

NATIVE_TYPE_STRUCT

0x1b

 

NATIVE_TYPE_INTF

0x1c

 

NATIVE_TYPE_SAFEARRAY

0x1d

 

NATIVE_TYPE_FIXEDARRAY

0x1e

 

NATIVE_TYPE_BYVALSTR

0x22

 

NATIVE_TYPE_ANSIBSTR

0x23

 

NATIVE_TYPE_TBSTR

0x24

Selects BSTR or ANSIBSTR depending on platform.

NATIVE_TYPE_VARIANTBOOL

0x25

2-byte Boolean value: false = 0; true = 1.

NATIVE_TYPE_ASANY

0x28

 

NATIVE_TYPE_LPSTRUCT

0x2b

 

NATIVE_TYPE_CUSTOMMARSHALER

0x2c

Custom marshaller native type. Shall be followed by a string in the format:

"Native type name/0Custom marshaler type name/0Optional cookie/0"

OR

"{Native type GUID}/0Custom marshaler type name/0Optional cookie/0"

NATIVE_TYPE_ERROR

0x2d

This native type coupled with ELEMENT_TYPE_I4 will map to VT_HRESULT.

NATIVE_TYPE_MAX

0X50

Used to indicate "no info."

The "blob" has the following format:

 
 MarshalSpec ::=   NativeInstrinsic | ARRAY ArrayElemType ParamNum ElemMult NumElem 

ANNOTATION

Implementation-Specific (Microsoft): The Microsoft implementation supports a wider range of options:

MarshalSpec ::=

NativeIntrinsic

| ARRAY ArrayElemType ParamNum ElemMult NumElem

| CUSTOMMARSHALLER Guid UnmanagedType ManagedType Cookie

| FIXEDARRAY NumElem ArrayElemType

| SAFEARRAY SafeArrayElemType


 
 NativeInstrinsic ::=   BOOLEAN | I1 | U1 | I2 | U2 | I4 | U4 | I8 | U8 | R4 | R8 | CURRENCY | BSTR | LPSTR | LPWSTR | LPTSTR | INT | UINT | FUNC | LPVOID 

For compactness, the NATIVE_TYPE_ prefixes have been omitted in the above lists. So, for example, ARRAY is shorthand for NATIVE_TYPE_ARRAY.

ANNOTATION

Implementation-Specific (Microsoft): NativeIntrinsic ::= …

 
 | FIXEDSYSSTRING | STRUCT | INTF | FIXEDARRAY | BYVALSTR | ANSIBSTR | | TBSTR | VARIANTBOOL | ASANY | LPSTRUCT | ERROR 

Guid is a counted-UTF8 string e.g., "{90883F05-3D28-11D2-8F17-00A0C9A6186D}" it shall include leading "{" and trailing "}" and be exactly 38 characters long.

UnmanagedType is a counted-UTF8 string e.g., "Point".

ManagedType is a counted-UTF8 string e.g., "System.Util.MyGeometry" it shall be the fully qualified name (namespace and name) of a managed Type defined within the current Assembly (that Type shall implement ICustomMarshaller, and provides a "to" and "from" marshalling method).

Cookie is a counted-UTF8 string e.g., "123" an empty string is allowed.


NumElem is an integer (compressed as described in Partition II, section 22.2) that specifies how many elements are in the array.

 
 ArrayElemType :==    NativeInstrinsic | BOOLEAN | I1 | U1 | I2 | U2 |  I4 | U4 | I8 | U8 | R4 | R8 | LPSTR | INT | UINT | FUNC | LPVOID 

ANNOTATION

Implementation-Specific (Microsoft): ArrayElemType ::= …

 
 | BSTR | LPWSTR | LPTSTR | FIXEDSYSSTRING | STRUCT | INTF | BYVALSTR | ANSIBSTR | TBSTR | VARIANTBOOL | ASANY | LPSTRUCT | ERROR | MAX 

The value MAX is used to indicate "no info."

The following information and table are specific to the Microsoft implementation of the CLI:

 
 SafeArrayElemType ::=   I2 | I4 | R4 | R8 | CY | DATE | BSTR | DISPATCH |   | ERROR | BOOL | VARIANT | UNKNOWN | DECIMAL | I1 | UI1 | UI2   | UI4 | INT | UINT 

where each is prefixed by VT_. The values for the VT_xxx constants are given in the following table:

Constant

Value

VT_I2

= 2,

VT_I4

= 3,

VT_R4

= 4,

VT_R8

= 5,

VT_CY

= 6,

VT_DATE

= 7,

VT_BSTR

= 8,

VT_DISPATCH

= 9,

VT_ERROR

= 10,

VT_BOOL

= 11,

VT_VARIANT

= 12,

VT_UNKNOWN

= 13,

VT_DECIMAL

= 14,

VT_I1

= 16,

VT_UI1

= 17,

VT_UI2

= 18,

VT_UI4

= 19,

VT_INT

= 22,

VT_UINT

= 23,


ParamNum is an integer (compressed as described in Partition II, section 22.2) specifying the parameter in the method call that provides the number of elements in the array see below.

ElemMult is an integer compressed as described in Partition II, section 22.2 (says by whatfactor to multiply see below).

NOTE

For example, in the method declaration:

 
 Foo (int ar1[], int size1, byte ar2[], int size2) 

The ar1 parameter might own a row in the FieldMarshal table, which indexes a MarshalSpec in the Blob heap with the format:

 
 ARRAY  MAX 2 1 0 

This says the parameter is marshalled to a NATIVE_TYPE_ARRAY. There is no additional info about the type of each element (signified by that NATIVE_TYPE_MAX). The value of ParamNum is 2, which indicates that parameter number 2 in the method (the one called "size1") will specify the number of elements in the actual array let's suppose its value on a particular call is 42. The value of ElemMult is 1. The value of NumElem is 0. The calculated total size, in bytes, of the array is given by the formula:

 
 if ParamNum == 0 SizeInBytes = NumElem * sizeof (elem) else SizeInBytes = ( @ParamNum * ElemMult + NumElem ) * sizeof (elem) endif 

The syntax "@ParamNum" is used here to denote the value passed in for parameter number ParamNum it would be 42 in this example. The size of each element is calculated from the metadata for the ar1 parameter in Foo's signature an ELEMENT_TYPE_I4 (see Partition II, section 22.1.15) of size 4 bytes.




The Common Language Infrastructure Annotated Standard (Microsoft. NET Development Series)
The Common Language Infrastructure Annotated Standard (Microsoft. NET Development Series)
ISBN: N/A
EAN: N/A
Year: 2002
Pages: 121

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net