Metadata Reading

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.

Metadata Heaps

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

mono_metadata_string_heap

mono_metadata_blob_heap

mono_metadata_user_string

mono_metadata_decode_blob_size

Metadata Tables

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)
AssemblyMONO_TABLE_ASSEMBLY Array size: MONO_ASSEMBLY_SIZE
  • MONO_ASSEMBLY_HASH_ALG
  • MONO_ASSEMBLY_MAJOR_VERSION
  • MONO_ASSEMBLY_MINOR_VERSION
  • MONO_ASSEMBLY_BUILD_NUMBER
  • MONO_ASSEMBLY_REV_NUMBER
  • MONO_ASSEMBLY_FLAGS
  • MONO_ASSEMBLY_PUBLIC_KEY
  • MONO_ASSEMBLY_NAME
  • MONO_ASSEMBLY_CULTURE
AssemblyOSMONO_TABLE_ASSEMBLYOS Array size: MONO_ASSEMBLYOS_SIZE
  • MONO_ASSEMBLYOS_PLATFORM
  • MONO_ASSEMBLYOS_MAJOR_VERSION
  • MONO_ASSEMBLYOS_MINOR_VERSION
AssemblyProcessorMONO_TABLE_ASSEMBLYPROCESSORArray size: MONO_ASSEMBLYPROCESSOR_SIZE
  • MONO_ASSEMBLY_PROCESSOR
AssemblyRefMONO_TABLE_ASSEMBLYREF Array size: MONO_ASSEMBLYREF_SIZE
  • MONO_ASSEMBLYREF_MAJOR_VERSION
  • MONO_ASSEMBLYREF_MINOR_VERSION
  • MONO_ASSEMBLYREF_BUILD_NUMBER
  • MONO_ASSEMBLYREF_REV_NUMBER
  • MONO_ASSEMBLYREF_FLAGS
  • MONO_ASSEMBLYREF_PUBLIC_KEY
  • MONO_ASSEMBLYREF_NAME
  • MONO_ASSEMBLYREF_CULTURE
  • MONO_ASSEMBLYREF_HASH_VALUE
AssemblyRefProcessorMONO_TABLE_ASSEMBLYREFPROCESSORArray size: MONO_ASSEMBLYREFPROC_SIZE
  • MONO_ASSEMBLYREFPROC_PROCESSOR
  • MONO_ASSEMBLYREFPROC_ASSEMBLYREF
AssemblyRefOSMONO_TABLE_ASSEMBLYREFOS Array size:
  • MONO_ASSEMBLYREFOS_SIZE
    • MONO_ASSEMBLYREFOS_PLATFORM
    • MONO_ASSEMBLYREFOS_MAJOR_VERSION
    • MONO_ASSEMBLYREFOS_MINOR_VERSION
    • MONO_ASSEMBLYREFOS_ASSEMBLYREF
  • ClassLayoutMONO_TABLE_CLASSLAYOUT Array size: MONO_CLASSLAYOUT_SIZE
    • MONO_CLASS_LAYOUT_PACKING_SIZE
    • MONO_CLASS_LAYOUT_CLASS_SIZE
    • MONO_CLASS_LAYOUT_PARENT
    ConstantMONO_TABLE_CONSTANT Array size: MONO_CONSTANT_SIZE
    • MONO_CONSTANT_TYPE
    • MONO_CONSTANT_PADDING
    • MONO_CONSTANT_PARENT
    • MONO_CONSTANT_VALUE
    CustomAttributeMONO_TABLE_CUSTOMATTRIBUTE Array size: MONO_CUSTOM_ATTR_SIZE
    • MONO_CUSTOM_ATTR_PARENT
    • MONO_CUSTOM_ATTR_TYPE
    • MONO_CUSTOM_ATTR_VALUE
    DeclSecurityMONO_TABLE_DECLSECURITY Array size: MONO_DECL_SECURITY_SIZE
    • MONO_DECL_SECURITY_ACTION
    • MONO_DECL_SECURITY_PARENT
    • MONO_DECL_SECURITY_PERMISSIONSET
    EventMapMONO_TABLE_EVENTMAP Array size: MONO_EVENT_MAP_SIZE
    • MONO_EVENT_MAP_PARENT
    • MONO_EVENT_MAP_EVENTLIST
    EventPtrMONO_TABLE_EVENT_POINTER Array size: MONO_EVENT_POINTER_SIZE
    • MONO_EVENT_POINTER_EVENT
    EventMONO_TABLE_EVENT Array size: MONO_EVENT_SIZE
    • MONO_EVENT_FLAGS
    • MONO_EVENT_NAME
    • MONO_EVENT_TYPE
    ExportedTypeMONO_TABLE_EXPORTEDTYPE Array size: MONO_EXPORTEDTYPE_SIZE
    • MONO_EXP_TYPE_FLAGS
    • MONO_EXP_TYPE_TYPEDEF
    • MONO_EXP_TYPE_NAME
    • MONO_EXP_TYPE_NAMESPACE
    • MONO_EXP_TYPE_IMPLEMENTATION
    FieldMONO_TABLE_FIELD Array size: MONO_FIELD_SIZE
    • MONO_FIELD_FLAGS
    • MONO_FIELD_NAME
    • MONO_FIELD_SIGNATURE
    FieldLayouttMONO_TABLE_FIELDLAYOUT Array size: MONO_FIELDLAYOUT_SIZE
    • MONO_FIELD_LAYOUT_OFFSET
    • MONO_FIELD_LAYOUT_FIELD
    FieldMarshalMONO_TABLE_FIELDMARSHAL Array size: MONO_FIELD_MARSHAL_SIZE
    • MONO_FIELD_MARSHAL_PARENT
    • MONO_FIELD_MARSHAL_NATIVE_TYPE
    FieldPtrMONO_TABLE_FIELD_POINTER Array size: MONO_FIELD_POINTER_SIZE
    • MONO_FIELD_POINTER_FIELD
    FieldRVAMONO_TABLE_FIELDRVA Array size: MONO_FIELDRVA_SIZE
    • MONO_FIELD_RVA_RVA
    • MONO_FIELD_RVA_FIELD
    FileMONO_TABLE_FILE Array size: MONO_FILE_SIZE
    • MONO_FILE_FLAGS
    • MONO_FILE_NAME
    • MONO_FILE_HASH_VALUE
    GenericParamMONO_TABLE_GENERICPARAM Array size: MONO_GENERICPARAM_SIZE
    • MONO_GENERICPARAM_NUMBER
    • MONO_GENERICPARAM_FLAGS
    • MONO_GENERICPARAM_OWNER
    • MONO_GENERICPARAM_NAME
    GenericParamConstraintMONO_TABLE_GENERICPARAMCONSTRAINTArray size: MONO_GENERICPARAMCONSTRAINT_SIZE
    • MONO_GENPARCONSTRAINT_GENERICPAR
    • MONO_GENPARCONSTRAINT_CONSTRAINT
    ImplMapMONO_TABLE_IMPLMAP Array size: MONO_IMPLMAP_SIZE
    • MONO_IMPLMAP_FLAGS
    • MONO_IMPLMAP_MEMBER
    • MONO_IMPLMAP_NAME
    • MONO_IMPLMAP_SCOPE
    InterfaceImplMONO_TABLE_INTERFACEIMPL Array size:
  • MONO_INTERFACEIMPL_SIZE
    • MONO_INTERFACEIMPL_CLASS
    • MONO_INTERFACEIMPL_INTERFACE
  • ManifestResourceMONO_TABLE_MANIFESTRESOURCEArray size: MONO_MANIFESTRESOURCE_SIZE
    • MONO_MANIFEST_OFFSET
    • MONO_MANIFEST_FLAGS
    • MONO_MANIFEST_NAME
    • MONO_MANIFEST_IMPLEMENTATION
    MemberRefMONO_TABLE_MEMBERREF Array size: MONO_MEMBERREF_SIZE
    • MONO_MEMBERREF_CLASS
    • MONO_MEMBERREF_NAME
    • MONO_MEMBERREF_SIGNATURE
    MethodImplMONO_TABLE_METHODIMPL Array size: MONO_METHODIMPL_SIZE
    • MONO_METHODIMPL_CLASS
    • MONO_METHODIMPL_BODY
    • MONO_METHODIMPL_DECLARATION
    MethodSpecMONO_TABLE_METHODSPEC Array size: MONO_METHODSPEC_SIZE
    • MONO_METHODSPEC_METHOD
    • MONO_METHODSPEC_SIGNATURE
    MethodSemanticsMONO_TABLE_METHODSEMANTICSArray size: MONO_METHOD_SEMA_SIZE
    • MONO_METHOD_SEMA_SEMANTICS
    • MONO_METHOD_SEMA_METHOD
    • MONO_METHOD_SEMA_ASSOCIATION
    ModulerefMONO_TABLE_MODULEREF Array size: MONO_MODULEREF_SIZE
    • MONO_MODULEREF_NAME
    ModuleMONO_TABLE_MODULE Array size: MONO_MODULE_SIZE
    Columns:
    • MONO_MODULE_GENERATION
    • MONO_MODULE_NAME
    • MONO_MODULE_MVID
    • MONO_MODULE_ENC
    • MONO_MODULE_ENCBASE
    TypeRefMONO_TABLE_TYPEREF Array size: MONO_TYPEREF_SIZE
    • MONO_TYPEREF_SCOPE
    • MONO_TYPEREF_NAME
    • MONO_TYPEREF_NAMESPACE
    MethodPtrMONO_TABLE_METHOD_POINTER Array size: MONO_METHOD_POINTER_SIZE
    • MONO_METHOD_POINTER_METHOD
    MethodMONO_TABLE_METHOD Array size: MONO_METHOD_SIZE
    • MONO_METHOD_RVA
    • MONO_METHOD_IMPLFLAGS
    • MONO_METHOD_FLAGS
    • MONO_METHOD_NAME
    • MONO_METHOD_SIGNATURE
    • MONO_METHOD_PARAMLIST
    NestedClassMONO_TABLE_NESTEDCLASS Array size: MONO_NESTEDCLASS_SIZE
    • MONO_NESTED_CLASS_NESTED
    • MONO_NESTED_CLASS_ENCLOSING
    ParamPtrMONO_TABLE_PARAM_POINTER Array size: MONO_PARAM_POINTER_SIZE
    • MONO_PARAM_POINTER_PARAM
    ParamMONO_TABLE_PARAM Array size: MONO_PARAM_SIZE
    • MONO_PARAM_FLAGS
    • MONO_PARAM_SEQUENCE
    • MONO_PARAM_NAME
    PropertyMapMONO_TABLE_PROPERTYMAP Array size: MONO_PROPERTY_MAP_SIZE
    • MONO_PROPERTY_MAP_PARENT
    • MONO_PROPERTY_MAP_PROPERTY_LIST
    PropertyPtrMONO_TABLE_PROPERTY_POINTERArray size: MONO_PROPERTY_POINTER_SIZE
    • MONO_PROPERTY_POINTER_PROPERTY
    PropertyMONO_TABLE_PROPERTY Array size: MONO_PROPERTY_SIZE
    • MONO_PROPERTY_FLAGS
    • MONO_PROPERTY_NAME
    • MONO_PROPERTY_TYPE
    StandaloneSigMONO_TABLE_STANDALONESIG Array size:
  • MONO_STAND_ALONE_SIGNATURE_SIZE
    • MONO_STAND_ALONE_SIGNATURE
  • TypeDefMONO_TABLE_TYPEDEF Array size: MONO_TYPEDEF_SIZE
    • MONO_TYPEDEF_FLAGS
    • MONO_TYPEDEF_NAME
    • MONO_TYPEDEF_NAMESPACE
    • MONO_TYPEDEF_EXTENDS
    • MONO_TYPEDEF_FIELD_LIST
    • MONO_TYPEDEF_METHOD_LIST
    TypeSpecMONO_TABLE_TYPESPEC Array size: MONO_TYPESPEC_SIZE
    • MONO_TYPESPEC_SIGNATURE

    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
    	

    Metadata Tables API

    These are the APIs for dealing with tables:

    mono_image_get_table_info

    mono_image_get_table_rows

    mono_metadata_decode_row_col

    mono_metadata_decode_row

    mono_metadata_compute_size

    mono_metadata_custom_attrs_from_index

    mono_metadata_decode_signed_value

    mono_metadata_decode_value

    mono_metadata_encode_value

    Metadata access API

    This is the low-level API for accessing the metadata images.

    mono_pe_file_open

    mono_metadata_events_from_typedef

    mono_metadata_decode_table_row

    mono_metadata_decode_table_row_col

    mono_metadata_field_info

    mono_metadata_free_array

    mono_metadata_free_marshal_spec

    mono_metadata_free_mh

    mono_metadata_free_type

    mono_metadata_get_constant_index

    mono_metadata_get_marshal_info

    mono_metadata_implmap_from_method

    mono_metadata_interfaces_from_typedef

    mono_metadata_locate

    mono_metadata_locate_token

    mono_metadata_methods_from_event

    mono_metadata_methods_from_property

    mono_metadata_nested_in_typedef

    mono_metadata_nesting_typedef

    mono_metadata_packing_from_typedef

    mono_metadata_properties_from_typedef

    mono_metadata_token_from_dor

    mono_metadata_translate_token_index

    mono_metadata_typedef_from_field

    mono_metadata_typedef_from_method

    mono_metadata_type_equal

    mono_metadata_type_hash

    mono_metadata_declsec_from_index

    mono_metadata_free_method_signature

    Retrieving Objects from Tokens

    mono_metadata_parse_array

    mono_metadata_parse_custom_mod

    mono_metadata_parse_field_type

    mono_metadata_parse_marshal_spec

    mono_metadata_parse_method_signature

    mono_metadata_parse_mh

    mono_metadata_parse_param

    mono_metadata_parse_signature

    mono_metadata_parse_typedef_or_ref

    mono_metadata_parse_type

    Generics Support

    mono_metadata_generic_class_is_valuetype

    Tokens

    mono_ldtoken

    mono_ldstr

    mono_exception_from_token

    OpCodes

    mono_opcode_name

    mono_opcode_value