The Metadata API gives developers low-level access to the information encoded in CLI modules: type and methods definitions encoded in metadata as well as access to the CIL code and embedded resources.
Managed developers access this information using either the System.Reflection API or a library like Cecil.
To start using the Metadata API it is necessary to open an assembly or a CIL image (a .dll or .exe file) using one of the CIL image opening API calls.
ECMA CLI images contain four heaps that store different kinds of information, these are:
The ECMA file format also has an extra section called the "#~" stream, this stream is the one that holds the metadata tables. There is a high-level API to get access to the contents of this API, described in the section Metadata Tables.
mono_metadata_guid_heap
meta | metadata context |
index | index into the guid heap. |
mono_metadata_string_heap
meta | metadata context |
index | index into the string heap. |
mono_metadata_blob_heap
meta | metadata context |
index | index into the blob. |
mono_metadata_user_string
meta | metadata context |
index | index into the user string heap. |
US
).
mono_metadata_decode_blob_size
ptr | pointer to a blob object |
rptr | the new position of the pointer |
This decodes a compressed size as described by 24.2.4 (US
and Blob
a blob or user string object)
Metadata is encoded in a number of tables included on every CIL image. These tables contain type definitions, member definitions and so on, these constants are defined in the ECMA 335 specification Partition II section 22. The following table shows the C constants defined in the Mono runtime and how they map to the equivalent ECMA CLI metadata table:
ECMA CLI Table Name | C Constant Name | Table Schema (Array Size + Columns Constants) | Assembly | MONO_TABLE_ASSEMBLY |
Array size:
MONO_ASSEMBLY_SIZE
|
AssemblyOS | MONO_TABLE_ASSEMBLYOS |
Array size:
MONO_ASSEMBLYOS_SIZE
|
AssemblyProcessor | MONO_TABLE_ASSEMBLYPROCESSOR | Array
size: MONO_ASSEMBLYPROCESSOR_SIZE
|
AssemblyRef | MONO_TABLE_ASSEMBLYREF |
Array size:
MONO_ASSEMBLYREF_SIZE
|
AssemblyRefProcessor | MONO_TABLE_ASSEMBLYREFPROCESSOR | Array
size: MONO_ASSEMBLYREFPROC_SIZE
|
AssemblyRefOS | MONO_TABLE_ASSEMBLYREFOS |
Array size:
|
ClassLayout | MONO_TABLE_CLASSLAYOUT |
Array size:
MONO_CLASSLAYOUT_SIZE
|
Constant | MONO_TABLE_CONSTANT |
Array size:
MONO_CONSTANT_SIZE
|
CustomAttribute | MONO_TABLE_CUSTOMATTRIBUTE |
Array size:
MONO_CUSTOM_ATTR_SIZE
|
DeclSecurity | MONO_TABLE_DECLSECURITY |
Array size:
MONO_DECL_SECURITY_SIZE
|
EventMap | MONO_TABLE_EVENTMAP |
Array size:
MONO_EVENT_MAP_SIZE
|
EventPtr | MONO_TABLE_EVENT_POINTER |
Array size:
MONO_EVENT_POINTER_SIZE
|
Event | MONO_TABLE_EVENT |
Array size: MONO_EVENT_SIZE
|
ExportedType | MONO_TABLE_EXPORTEDTYPE |
Array size:
MONO_EXPORTEDTYPE_SIZE
|
Field | MONO_TABLE_FIELD |
Array size: MONO_FIELD_SIZE
|
FieldLayoutt | MONO_TABLE_FIELDLAYOUT |
Array size:
MONO_FIELDLAYOUT_SIZE
|
FieldMarshal | MONO_TABLE_FIELDMARSHAL |
Array size:
MONO_FIELD_MARSHAL_SIZE
|
FieldPtr | MONO_TABLE_FIELD_POINTER |
Array size:
MONO_FIELD_POINTER_SIZE
|
FieldRVA | MONO_TABLE_FIELDRVA |
Array size:
MONO_FIELDRVA_SIZE
|
File | MONO_TABLE_FILE |
Array size: MONO_FILE_SIZE
|
GenericParam | MONO_TABLE_GENERICPARAM |
Array size:
MONO_GENERICPARAM_SIZE
|
GenericParamConstraint | MONO_TABLE_GENERICPARAMCONSTRAINT | Array
size: MONO_GENERICPARAMCONSTRAINT_SIZE
|
ImplMap | MONO_TABLE_IMPLMAP |
Array size:
MONO_IMPLMAP_SIZE
|
InterfaceImpl | MONO_TABLE_INTERFACEIMPL |
Array size:
|
ManifestResource | MONO_TABLE_MANIFESTRESOURCE | Array
size: MONO_MANIFESTRESOURCE_SIZE
|
MemberRef | MONO_TABLE_MEMBERREF |
Array size:
MONO_MEMBERREF_SIZE
|
MethodImpl | MONO_TABLE_METHODIMPL |
Array size:
MONO_METHODIMPL_SIZE
|
MethodSpec | MONO_TABLE_METHODSPEC |
Array size:
MONO_METHODSPEC_SIZE
|
MethodSemantics | MONO_TABLE_METHODSEMANTICS | Array
size: MONO_METHOD_SEMA_SIZE
|
Moduleref | MONO_TABLE_MODULEREF |
Array size:
MONO_MODULEREF_SIZE
|
Module | MONO_TABLE_MODULE |
Array size:
MONO_MODULE_SIZE
Columns:
|
TypeRef | MONO_TABLE_TYPEREF |
Array size:
MONO_TYPEREF_SIZE
|
MethodPtr | MONO_TABLE_METHOD_POINTER |
Array size:
MONO_METHOD_POINTER_SIZE
|
Method | MONO_TABLE_METHOD |
Array size:
MONO_METHOD_SIZE
|
NestedClass | MONO_TABLE_NESTEDCLASS |
Array size:
MONO_NESTEDCLASS_SIZE
|
ParamPtr | MONO_TABLE_PARAM_POINTER |
Array size:
MONO_PARAM_POINTER_SIZE
|
Param | MONO_TABLE_PARAM |
Array size: MONO_PARAM_SIZE
|
PropertyMap | MONO_TABLE_PROPERTYMAP |
Array size:
MONO_PROPERTY_MAP_SIZE
|
PropertyPtr | MONO_TABLE_PROPERTY_POINTER | Array
size: MONO_PROPERTY_POINTER_SIZE
|
Property | MONO_TABLE_PROPERTY |
Array size:
MONO_PROPERTY_SIZE
|
StandaloneSig | MONO_TABLE_STANDALONESIG |
Array size:
|
TypeDef | MONO_TABLE_TYPEDEF |
Array size:
MONO_TYPEDEF_SIZE
|
TypeSpec | MONO_TABLE_TYPESPEC |
Array size:
MONO_TYPESPEC_SIZE
|
Each table can contain zero or more rows, you must call the mono_metadata_table_rows to obtain the number of rows in a table, and then you can extract individual row values by using the mono_metadata_decode_row or the mono_metadata_decode_row_col. When decoding rows you must provide an guint32 array large enough to hold as many columns as the table contains.
The metadata tables are stored in the MonoImage, you obtain a pointer to the MonoTableInfo by calling the mono_image_get_table_info and then you can scan those tables, for example:
/* * Dumps a few fields from the AssemblyRef table */ void DumpAssemblyRefs (MonoImage *image) { /* Get a pointer to the AssemblyRef metadata table */ MonoTableInfo *t = mono_image_get_table_info (image, MONO_TABLE_ASSEMBLYREF); /* Fetch the number of rows available in the table */ int rows = mono_table_info_get_rows (t); int i; /* For each row, print some of its values */ for (i = 0; i < rows; i++){ /* Space where we extract one row from the metadata table */ guint32 cols [MONO_ASSEMBLYREF_SIZE]; /* Extract the row into the array cols */ mono_metadata_decode_row (t, i, cols, MONO_ASSEMBLYREF_SIZE); fprintf (output, "%d: Version=%d.%d.%d.%d\n\tName=%s\n", i + 1, cols [MONO_ASSEMBLYREF_MAJOR_VERSION], cols [MONO_ASSEMBLYREF_MINOR_VERSION], cols [MONO_ASSEMBLYREF_BUILD_NUMBER], cols [MONO_ASSEMBLYREF_REV_NUMBER], mono_metadata_string_heap (image, cols [MONO_ASSEMBLYREF_NAME])); } }
The above program shows the following output when ran on the C# compiler:
1: Version=1.0.5000.0 Name=mscorlib 2: Version=1.0.5000.0 Name=System 3: Version=1.0.5000.0 Name=System.Xml
These are the APIs for dealing with tables:
mono_image_get_table_info
mono_image_get_table_rows
mono_metadata_decode_row_col
t | table to extract information from. |
idx | index for row in table. |
col | column in the row. |
This function returns the value of column col from the idx row in the table t .
mono_metadata_decode_row
t | table to extract information from. |
idx | index in table. |
res | array of res_size cols to store the results in |
This decompresses the metadata element idx in table t
into the guint32
res array that has res_size elements
mono_metadata_compute_size
meta | metadata context |
tableindex | metadata table number |
result_bitfield | pointer to guint32 where to store additional info |
mono_metadata_compute_size
computes the length in bytes of a single
row in a metadata table. The size of each column is encoded in the
result_bitfield return value along with the number of columns in the table.
the resulting bitfield should be handed to the mono_metadata_table_size
and mono_metadata_table_count
macros.
This is a Mono runtime internal only function.
mono_metadata_custom_attrs_from_index
meta | metadata context |
index | token representing the parent |
returns | the 1-based index into the CustomAttribute table of the first |
mono_metadata_decode_signed_value
ptr | pointer to decode from |
rptr | the new position of the pointer |
This routine decompresses 32-bit signed values (not specified in the spec)
mono_metadata_decode_value
ptr | pointer to decode from |
rptr | the new position of the pointer |
This routine decompresses 32-bit values as specified in the "Blob and Signature" section (23.2)
mono_metadata_encode_value
This is the low-level API for accessing the metadata images.
mono_pe_file_open
fname | filename that points to the module we want to open |
status | An error condition is returned in this field |
MonoImage
or NULL
on error. if
NULL
, then check the value of status for details on the error.
This variant for mono_image_open
DOES NOT SET UP CLI METADATA.
It's just a PE file loader, used for FileVersionInfo
. It also does
not use the image cache.mono_metadata_events_from_typedef
meta | metadata context |
index | 0-based index (in the TypeDef table) describing a type |
Event
table for the events in the
type. The last event that belongs to the type (plus 1) is stored
in the end_idx pointer.mono_metadata_decode_table_row
Same as mono_metadata_decode_row
, but takes an image + table ID pair, and takes
uncompressed metadata into account, so it should be used to access the
Method
, Field
, Param
and Event
tables when the access is made from metadata, i.e.
idx is retrieved from a metadata table, like MONO_TYPEDEF_FIELD_LIST
.
mono_metadata_decode_table_row_col
Same as mono_metadata_decode_row_col
, but takes an image + table ID pair, and takes
uncompressed metadata into account, so it should be used to access the
Method
, Field
, Param
and Event
tables.
mono_metadata_field_info
meta | the Image the field is defined in |
index | the index in the field table representing the field |
offset | a pointer to an integer where to store the offset that may have been specified for the field in a FieldLayout table |
rva | a pointer to the RVA of the field data in the image that may have been defined in a FieldRVA table |
marshal_spec | a pointer to the marshal spec that may have been defined for the field in a FieldMarshal table. |
Gather info for field index that may have been defined in the FieldLayout
,
FieldRVA
and FieldMarshal
tables.
Either of offset, rva and marshal_spec can be NULL
if you're not interested
in the data.
mono_metadata_free_array
array | array description |
Frees the array description returned from mono_metadata_parse_array
.
mono_metadata_free_marshal_spec
mono_metadata_free_mh
mh | a method header |
Free the memory allocated for the method header.
mono_metadata_free_type
type | type to free |
Free the memory allocated for type type which is allocated on the heap.
mono_metadata_get_constant_index
meta | the Image the field is defined in |
index | the token that may have a row defined in the constants table |
hint | possible position for the row |
Constants
table or 0 if not found.
token must be a FieldDef
, ParamDef
or PropertyDef
token.
mono_metadata_get_marshal_info
mono_metadata_implmap_from_method
mono_metadata_interfaces_from_typedef
meta | metadata context |
index | typedef token |
count | Out parameter used to store the number of interfaces |
NULL
on failure.
The array of interfaces that the index typedef token implements is returned in
interfaces. The number of elements in the array is returned in count. The returned
array is allocated with g_malloc
and the caller must free it.
LOCKING: Acquires the loader lock .
mono_metadata_locate
meta | metadata context |
table | table code. |
idx | index of element to retrieve from table. |
mono_metadata_locate_token
meta | metadata context |
token | metadata token |
mono_metadata_methods_from_event
meta | metadata context |
index | 0-based index (in the Event table) describing a event |
MethodDef
table for the methods in the
event. The last method that belongs to the event (plus 1) is stored
in the end_idx pointer.mono_metadata_methods_from_property
meta | metadata context |
index | 0-based index (in the PropertyDef table) describing a property |
MethodDef
table for the methods in the
property. The last method that belongs to the property (plus 1) is stored
in the end_idx pointer.mono_metadata_nested_in_typedef
meta | metadata context |
index | typedef token |
mono_metadata_nesting_typedef
meta | metadata context |
index | typedef token |
TypeDef
table of the first type
that is nested inside the type described by index. The search starts at
start_index. Returns 0 if no such type is found.mono_metadata_packing_from_typedef
meta | metadata context |
index | token representing a type |
ClassLayout
table for the given typedef token
into the packing and size pointers.
Returns 0 if the info is not found.mono_metadata_properties_from_typedef
meta | metadata context |
index | 0-based index (in the TypeDef table) describing a type |
Property
table for the properties in the
type. The last property that belongs to the type (plus 1) is stored
in the end_idx pointer.mono_metadata_token_from_dor
dor_token | A TypeDefOrRef coded index |
dor_token is a TypeDefOrRef
coded index: it contains either
a TypeDef
, TypeRef
or TypeSpec
in the lower bits, and the upper
bits contain an index into the table.
mono_metadata_translate_token_index
Method
, Field
, Event
, or Param
tables
using the *Ptr
tables in uncompressed metadata, if they are available.
FIXME: The caller is not forced to call this function, which is error-prone, since forgetting to call it would only show up as a bug on uncompressed metadata.
mono_metadata_typedef_from_field
meta | metadata context |
index | FieldDef token |
TypeDef
table of the type that
declared the field described by index, or 0 if not found.mono_metadata_typedef_from_method
meta | metadata context |
index | MethodDef token |
TypeDef
table of the type that
declared the method described by index. 0 if not found.mono_metadata_type_equal
mono_metadata_type_hash
t1 | a type |
GHashTable
.
The returned hash is guaranteed to be the same across executions.mono_metadata_declsec_from_index
meta | metadata context |
index | token representing the parent |
DeclarativeSecurity
table of the first
attribute which belongs to the metadata object described by index.
Returns -1
if no such attribute is found.mono_metadata_free_method_signature
sig | signature to destroy |
Free the memory allocated in the signature sig. This method needs to be robust and work also on partially-built signatures, so it does extra checks.
mono_metadata_parse_array
mono_metadata_parse_custom_mod
m | a metadata context. |
dest | storage where the info about the custom modifier is stored (may be NULL ) |
ptr | a pointer to (possibly) the start of a custom modifier list |
rptr | pointer updated to match the end of the decoded stream |
TRUE
if a custom modifier was found, FALSE
if not.
Checks if ptr points to a type custom modifier compressed representation.
mono_metadata_parse_field_type
m | metadata context to extract information from |
ptr | pointer to the field signature |
rptr | pointer updated to match the end of the decoded stream |
MonoType
that was extracted from ptr .
Parses the field signature, and returns the type information for it.
mono_metadata_parse_marshal_spec
mono_metadata_parse_method_signature
m | metadata context |
def | the MethodDef index or 0 for Ref signatures. |
ptr | pointer to the signature metadata representation |
rptr | pointer updated to match the end of the decoded stream |
MonoMethodSignature
describing the signature.
Decode a method signature stored at ptr. This is a Mono runtime internal function.
LOCKING: Assumes the loader lock is held.
mono_metadata_parse_mh
generic_context | generics context |
ptr | pointer to the method header. |
MonoMethodHeader
allocated from the heap.
Decode the method header at ptr, including pointer to the IL code, info about local variables and optional exception tables.
mono_metadata_parse_param
m | metadata context to extract information from |
ptr | pointer to the param signature |
rptr | pointer updated to match the end of the decoded stream |
MonoType
that was extracted from ptr .
Parses the param signature, and returns the type information for it.
mono_metadata_parse_signature
image | metadata context |
token | metadata token |
MonoMethodSignature
describing the signature.
Decode a method signature stored in the StandAloneSig
table
mono_metadata_parse_typedef_or_ref
m | a metadata context. |
ptr | a pointer to an encoded TypedefOrRef in m |
rptr | pointer updated to match the end of the decoded stream |
mono_metadata_parse_type
m | metadata context |
mode | kind of type that may be found at ptr |
opt_attrs | optional attributes to store in the returned type |
ptr | pointer to the type representation |
rptr | pointer updated to match the end of the decoded stream |
transient | whenever to allocate the result from the heap or from a mempool |
MonoType
structure representing the decoded type.
Decode a compressed type description found at ptr in m .
mode can be one of MONO_PARSE_MOD_TYPE
, MONO_PARSE_PARAM
, MONO_PARSE_RET
,
MONO_PARSE_FIELD
, MONO_PARSE_LOCAL
, MONO_PARSE_TYPE
.
This function can be used to decode type descriptions in method signatures,
field signatures, locals signatures etc.
To parse a generic type, generic_container
points to the current class'es
(the generic_container
field in the MonoClass
) or the current generic method's
(stored in image->property_hash
) generic container.
When we encounter a MONO_TYPE_VAR
or MONO_TYPE_MVAR
, it's looked up in
this MonoGenericContainer
.
LOCKING: Acquires the loader lock.
mono_metadata_generic_class_is_valuetype
mono_ldtoken
mono_ldstr
domain | the domain where the string will be used. |
image | a metadata context |
idx | index into the user string table. |
ldstr
opcode.mono_exception_from_token
image | the Mono image where to look for the class |
token | The type token of the class |
Creates an exception of the type given by token.
mono_opcode_name