Browse Source

2001-06-21 Miguel de Icaza <[email protected]>

	* mono/metadata/metadata.c (mono_metadata_locate_token,
	mono_metadata_locate): Functions to locate the information
	definition given a token or a table and an index.
	(mono_metadata_compute_table_bases): New.
	(compute_size): New function to compute the sizes of the various
	tables.

	* mono/metadata/metadata.h: Finish listing the different index
	types.

	* mono/metadata/pedump.c: Improve to dump new information.

svn path=/trunk/mono/; revision=21
Miguel de Icaza 24 years ago
parent
commit
28074f5a04
5 changed files with 407 additions and 31 deletions
  1. 14 0
      ChangeLog
  2. 17 2
      mono/metadata/assembly.c
  3. 254 17
      mono/metadata/metadata.c
  4. 103 10
      mono/metadata/metadata.h
  5. 19 2
      mono/metadata/pedump.c

+ 14 - 0
ChangeLog

@@ -1,3 +1,17 @@
+2001-06-21  Miguel de Icaza  <[email protected]>
+
+	* mono/metadata/metadata.c (mono_metadata_locate_token,
+	mono_metadata_locate): Functions to locate the information
+	definition given a token or a table and an index.
+	(mono_metadata_compute_table_bases): New.
+	(compute_size): New function to compute the sizes of the various
+	tables.
+
+	* mono/metadata/metadata.h: Finish listing the different index
+	types. 
+
+	* mono/metadata/pedump.c: Improve to dump new information.
+
 2001-06-19  Miguel de Icaza  <[email protected]>
 
 	* mono/metadata/metadata.c: Entered all the tables matching

+ 17 - 2
mono/metadata/assembly.c

@@ -173,6 +173,9 @@ load_metadata_ptrs (MonoAssembly *assembly, dotnet_image_info_t *iinfo)
 	return TRUE;
 }
 
+/*
+ * Load representation of logical metadata tables, from the "#~" stream
+ */
 static gboolean
 load_tables (MonoAssembly *assembly, metadata_t *meta)
 {
@@ -180,20 +183,32 @@ load_tables (MonoAssembly *assembly, metadata_t *meta)
 	guint32 *rows;
 	guint64 valid_mask;
 	int valid = 0, table;
+	int heap_sizes;
+	
+	heap_sizes = heap_tables [6];
+	meta->idx_string_wide = ((heap_sizes & 0x01) == 1);
+	meta->idx_guid_wide   = ((heap_sizes & 0x02) == 2);
+	meta->idx_blob_wide   = ((heap_sizes & 0x04) == 4);
 	
 	valid_mask = read64 (heap_tables + 8);
 	rows = (guint32 *) (heap_tables + 24);
 	
 	for (table = 0; table < 64; table++){
 		if ((valid_mask & ((guint64) 1 << table)) == 0){
-			meta->rows [table] = 0;
+			meta->tables [table].rows = 0;
 			continue;
 		}
-		meta->rows [table] = *rows;
+		meta->tables [table].rows = read32 (rows);
 		rows++;
 		valid++;
 	}
 
+	meta->tables_base = (heap_tables + 24) + (4 * valid);
+
+	/* They must be the same */
+	g_assert (meta->tables_base == rows);
+
+	mono_metadata_compute_table_bases (meta);
 	return TRUE;
 }
 

+ 254 - 17
mono/metadata/metadata.c

@@ -92,15 +92,15 @@ static MonoMetaTable ConstantSchema [] = {
 };
 
 static MonoMetaTable CustomAttributeSchema [] = {
-	{ MONO_MT_TABLE_IDX,  "Parent" },
-	{ MONO_MT_TABLE_IDX,  "Type=CustomAttributeType" },
+	{ MONO_MT_HASCAT_IDX, "Parent" },
+	{ MONO_MT_CAT_IDX,    "Type" },
 	{ MONO_MT_BLOB_IDX,   "Value" },
 	{ MONO_MT_END, NULL }
 };
 
 static MonoMetaTable DeclSecuritySchema [] = {
 	{ MONO_MT_UINT16,     "Action" },
-	{ MONO_MT_TABLE_IDX,  "Parent=HasDeclSecurity" },
+	{ MONO_MT_HASDEC_IDX, "Parent" },
 	{ MONO_MT_BLOB_IDX,   "PermissionSet" },
 	{ MONO_MT_END, NULL }	
 };
@@ -114,7 +114,7 @@ static MonoMetaTable EventMapSchema [] = {
 static MonoMetaTable EventSchema [] = {
 	{ MONO_MT_UINT16,     "EventFlags#EventAttribute" },
 	{ MONO_MT_STRING_IDX, "Name" },
-	{ MONO_MT_TABLE_IDX,  "EventType" },
+	{ MONO_MT_TABLE_IDX,  "EventType" }, /* TypeDef or TypeRef */
 	{ MONO_MT_END, NULL }	
 };
 
@@ -123,7 +123,7 @@ static MonoMetaTable ExportedTypeSchema [] = {
 	{ MONO_MT_TABLE_IDX,  "TypeDefId" },
 	{ MONO_MT_STRING_IDX, "TypeName" },
 	{ MONO_MT_STRING_IDX, "TypeNameSpace" },
-	{ MONO_MT_TABLE_IDX,  "Implementation" },
+	{ MONO_MT_IMPL_IDX,   "Implementation" },
 	{ MONO_MT_END, NULL }	
 };
 
@@ -140,7 +140,7 @@ static MonoMetaTable FieldLayoutSchema [] = {
 };
 
 static MonoMetaTable FieldMarshalSchema [] = {
-	{ MONO_MT_TABLE_IDX,  "Parent" },
+	{ MONO_MT_HFM_IDX,    "Parent" },
 	{ MONO_MT_BLOB_IDX,   "NativeType" },
 	{ MONO_MT_END, NULL }	
 };
@@ -159,15 +159,15 @@ static MonoMetaTable FileSchema [] = {
 
 static MonoMetaTable ImplMapSchema [] = {
 	{ MONO_MT_UINT16,     "MappingFlag" },
-	{ MONO_MT_TABLE_IDX,  "MemberForwarded=MemberForwardedCodedIndex" },
+	{ MONO_MT_MF_IDX,     "MemberForwarded" },
 	{ MONO_MT_STRING_IDX, "ImportName" },
 	{ MONO_MT_TABLE_IDX,  "ImportScope:ModuleRef" },
 	{ MONO_MT_END, NULL }
 };
 
 static MonoMetaTable InterfaceImplSchema [] = {
-	{ MONO_MT_TABLE_IDX,  "Class:TypeDef" },
-	{ MONO_MT_TABLE_IDX,  "Interface=TypeDefOrRef" },
+	{ MONO_MT_TABLE_IDX,  "Class:TypeDef" }, 
+	{ MONO_MT_TDOR_IDX,  "Interface=TypeDefOrRef" },
 	{ MONO_MT_END, NULL }
 };
 
@@ -175,12 +175,12 @@ static MonoMetaTable ManifestResourceSchema [] = {
 	{ MONO_MT_UINT32,     "Offset" },
 	{ MONO_MT_UINT32,     "Flags" },
 	{ MONO_MT_STRING_IDX, "Name" },
-	{ MONO_MT_TABLE_IDX,  "Implementation=Implementation" },
+	{ MONO_MT_IMPL_IDX,   "Implementation" },
 	{ MONO_MT_END, NULL }
 };
 
 static MonoMetaTable MemberRefSchema [] = {
-	{ MONO_MT_TABLE_IDX,  "Class=MemberRefParent" },
+	{ MONO_MT_MRP_IDX,    "Class" },
 	{ MONO_MT_STRING_IDX, "Name" },
 	{ MONO_MT_BLOB_IDX,   "Signature" },
 	{ MONO_MT_END, NULL }
@@ -192,21 +192,21 @@ static MonoMetaTable MethodSchema [] = {
 	{ MONO_MT_UINT16,     "Flags#MethodAttribute" },
 	{ MONO_MT_STRING_IDX, "Name" },
 	{ MONO_MT_BLOB_IDX,   "Signature" },
-	{ MONO_MT_TABLE_IDX,  "ParamList" },
+	{ MONO_MT_TABLE_IDX,  "ParamList:Param" },
 	{ MONO_MT_END, NULL }
 };
 
 static MonoMetaTable MethodImplSchema [] = {
 	{ MONO_MT_TABLE_IDX,  "Class:TypeDef" },
-	{ MONO_MT_TABLE_IDX,  "MethodBody=MethodDefOrRef" },
-	{ MONO_MT_TABLE_IDX,  "MethodDeclaration=MethodDefOrRef" },
+	{ MONO_MT_MDOR_IDX,  "MethodBody" },
+	{ MONO_MT_MDOR_IDX,  "MethodDeclaration" },
 	{ MONO_MT_END, NULL }
 };
 
 static MonoMetaTable MethodSemanticsSchema [] = {
 	{ MONO_MT_UINT16,     "MethodSemantic" },
 	{ MONO_MT_TABLE_IDX,  "Method:Method" },
-	{ MONO_MT_TABLE_IDX,  "Association=HasSemantic" },
+	{ MONO_MT_HS_IDX,     "Association" },
 	{ MONO_MT_END, NULL }
 };
 
@@ -259,14 +259,14 @@ static MonoMetaTable TypeDefSchema [] = {
 	{ MONO_MT_UINT32,     "Flags" },
 	{ MONO_MT_STRING_IDX, "Name" },
 	{ MONO_MT_STRING_IDX, "Namespace" },
-	{ MONO_MT_TABLE_IDX,  "Extends=TypeDefOrRef" },
+	{ MONO_MT_TDOR_IDX,   "Extends" },
 	{ MONO_MT_TABLE_IDX,  "FieldList:Field" },
 	{ MONO_MT_TABLE_IDX,  "MethodList:Method" },
 	{ MONO_MT_END, NULL }
 };
 
 static MonoMetaTable TypeRefSchema [] = {
-	{ MONO_MT_TABLE_IDX,  "ResolutionScope=ResolutionScope" },
+	{ MONO_MT_RS_IDX,     "ResolutionScope=ResolutionScope" },
 	{ MONO_MT_STRING_IDX, "Name" },
 	{ MONO_MT_STRING_IDX, "Namespace" },
 	{ MONO_MT_END, NULL }
@@ -335,3 +335,240 @@ mono_meta_table_name (int table)
 	
 	return tables [table].name;
 }
+
+#define rtsize(s,b) (((s) > (1 << (b)) ? 4 : 2))
+		 
+static int
+compute_size (metadata_t *meta, MonoMetaTable *table, int rowcount)
+{
+	int tsize =  rowcount > 65536 ? 4 : 2;
+	int size = 0;
+	int i, n, code;
+
+	for (i = 0; (code = table [i].code) != MONO_MT_END; i++){
+		switch (code){
+		case MONO_MT_UINT32:
+			size += 4; break;
+			
+		case MONO_MT_UINT16:
+			size += 2; break;
+			
+		case MONO_MT_UINT8:
+			size += 1; break;
+			
+		case MONO_MT_BLOB_IDX:
+			size += meta->idx_blob_wide ? 4 : 2; break;
+			
+		case MONO_MT_STRING_IDX:
+			size += meta->idx_string_wide ? 4 : 2; break;
+			
+		case MONO_MT_GUID_IDX:
+			size += meta->idx_string_wide ? 4 : 2; break;
+
+		case MONO_MT_TABLE_IDX:
+			size += tsize; break;
+
+			/*
+			 * HasConstant: ParamDef, FieldDef, Property
+			 */
+		case MONO_MT_CONST_IDX:
+			n = MAX (meta->tables [META_TABLE_PARAM].rows,
+				 meta->tables [META_TABLE_FIELD].rows);
+			n = MAX (n, meta->tables [META_TABLE_PROPERTY].rows);
+
+			/* 2 bits to encode tag */
+			size += rtsize (n, 16-2);
+			break;
+
+			/*
+			 * HasCustomAttribute: points to any table but
+			 * itself.
+			 */
+		case MONO_MT_HASCAT_IDX:
+			/*
+			 * We believe that since the signature and
+			 * permission are indexing the Blob heap,
+			 * we should consider the blob size first
+			 */
+			if (meta->idx_blob_wide){
+				size += 4;
+				break;
+			}
+			
+			n = MAX (meta->tables [META_TABLE_METHOD].rows,
+				 meta->tables [META_TABLE_FIELD].rows);
+			n = MAX (n, meta->tables [META_TABLE_TYPEREF].rows);
+			n = MAX (n, meta->tables [META_TABLE_TYPEDEF].rows);
+			n = MAX (n, meta->tables [META_TABLE_PARAM].rows);
+			n = MAX (n, meta->tables [META_TABLE_INTERFACEIMPL].rows);
+			n = MAX (n, meta->tables [META_TABLE_MEMBERREF].rows);
+			n = MAX (n, meta->tables [META_TABLE_MODULE].rows);
+			/* Permission seems to be a blob heap pointer */
+			n = MAX (n, meta->tables [META_TABLE_PROPERTY].rows);
+			n = MAX (n, meta->tables [META_TABLE_EVENT].rows);
+			/* Signature seems to be a blob heap pointer */
+			n = MAX (n, meta->tables [META_TABLE_MODULEREF].rows);
+			n = MAX (n, meta->tables [META_TABLE_TYPESPEC].rows);
+			n = MAX (n, meta->tables [META_TABLE_ASSEMBLY].rows);
+			n = MAX (n, meta->tables [META_TABLE_ASSEMBLYREF].rows);
+			n = MAX (n, meta->tables [META_TABLE_FILE].rows);
+			n = MAX (n, meta->tables [META_TABLE_EXPORTEDTYPE].rows);
+			n = MAX (n, meta->tables [META_TABLE_MANIFESTRESOURCE].rows);
+
+			/* 5 bits to encode */
+			size += rtsize (n, 16-5);
+			break;
+
+			/*
+			 * CustomAttributeType: TypeDef, TypeRef, MethodDef, 
+			 * MemberRef and String.  
+			 */
+		case MONO_MT_CAT_IDX:
+			/* String is a heap, if it is wide, we know the size */
+			if (meta->idx_string_wide){
+				size += 4;
+				break;
+			}
+			
+			n = MAX (meta->tables [META_TABLE_TYPEREF].rows,
+				 meta->tables [META_TABLE_TYPEDEF].rows);
+			n = MAX (n, meta->tables [META_TABLE_METHOD].rows);
+			n = MAX (n, meta->tables [META_TABLE_MEMBERREF].rows);
+
+			/* 3 bits to encode */
+			size += rtsize (n, 16-3);
+			break;
+
+			/*
+			 * HasDeclSecurity: Typedef, MethodDef, Assembly
+			 */
+		case MONO_MT_HASDEC_IDX:
+			n = MAX (meta->tables [META_TABLE_TYPEDEF].rows,
+				 meta->tables [META_TABLE_METHOD].rows);
+			n = MAX (n, meta->tables [META_TABLE_ASSEMBLY].rows);
+
+			/* 2 bits to encode */
+			size += rtsize (n, 16-2);
+			break;
+
+			/*
+			 * Implementation: File, AssemblyRef, ExportedType
+			 */
+		case MONO_MT_IMPL_IDX:
+			n = MAX (meta->tables [META_TABLE_FILE].rows,
+				 meta->tables [META_TABLE_ASSEMBLYREF].rows);
+			n = MAX (n, meta->tables [META_TABLE_EXPORTEDTYPE].rows);
+
+			/* 2 bits to encode tag */
+			size += rtsize (n, 16-2);
+			break;
+
+			/*
+			 * HasFieldMarshall: FieldDef, ParamDef
+			 */
+		case MONO_MT_HFM_IDX:
+			n = MAX (meta->tables [META_TABLE_FIELD].rows,
+				 meta->tables [META_TABLE_PARAM].rows);
+
+			/* 1 bit used to encode tag */
+			size += rtsize (n, 16-1);
+			break;
+
+			/*
+			 * MemberForwarded: FieldDef, MethodDef
+			 */
+		case MONO_MT_MF_IDX:
+			n = MAX (meta->tables [META_TABLE_FIELD].rows,
+				 meta->tables [META_TABLE_METHOD].rows);
+
+			/* 1 bit used to encode tag */
+			size += rtsize (n, 16-1);
+			break;
+
+			/*
+			 * TypeDefOrRef: TypeDef, ParamDef, TypeSpec
+			 */
+		case MONO_MT_TDOR_IDX:
+			n = MAX (meta->tables [META_TABLE_TYPEDEF].rows,
+				 meta->tables [META_TABLE_PARAM].rows);
+			n = MAX (n, meta->tables [META_TABLE_TYPESPEC].rows);
+
+			/* 2 bits to encode */
+			size += rtsize (n, 16-2);
+			break;
+
+			/*
+			 * MemberRefParent: TypeDef, TypeRef, ModuleDef, ModuleRef, TypeSpec
+			 */
+		case MONO_MT_MRP_IDX:
+			n = MAX (meta->tables [META_TABLE_TYPEDEF].rows,
+				 meta->tables [META_TABLE_TYPEREF].rows);
+			n = MAX (n, meta->tables [META_TABLE_MODULE].rows);
+			n = MAX (n, meta->tables [META_TABLE_MODULEREF].rows);
+			n = MAX (n, meta->tables [META_TABLE_TYPESPEC].rows);
+
+			/* 3 bits to encode */
+			size += rtsize (n, 16 - 3);
+			break;
+			
+		case MONO_MT_MDOR_IDX:
+
+			/*
+			 * MethodDefOrRef: MethodDef, MemberRef
+			 */
+		case MONO_MT_HS_IDX:
+			n = MAX (meta->tables [META_TABLE_METHOD].rows,
+				 meta->tables [META_TABLE_MEMBERREF].rows);
+
+			/* 1 bit used to encode tag */
+			size += rtsize (n, 16-1);
+			break;
+
+			/*
+			 * ResolutionScope: Module, ModuleRef, AssemblyRef, TypeRef
+			 */
+		case MONO_MT_RS_IDX:
+			n = MAX (meta->tables [META_TABLE_MODULE].rows,
+				 meta->tables [META_TABLE_MODULEREF].rows);
+			n = MAX (n, meta->tables [META_TABLE_ASSEMBLYREF].rows);
+			n = MAX (n, meta->tables [META_TABLE_TYPEREF].rows);
+
+			/* 3 bits used to encode tag */
+			size += rtsize (n, 16 - 3);
+			break;
+		}
+	}
+
+	return size;
+}
+
+void
+mono_metadata_compute_table_bases (metadata_t *meta)
+{
+	int i;
+	char *base = meta->tables_base;
+	
+	for (i = 0; i < 64; i++){
+		if (meta->tables [i].rows == 0)
+			continue;
+
+		meta->tables [i].row_size = compute_size (
+			meta, tables [i].table, meta->tables [i].rows);
+		meta->tables [i].base = base;
+		base += meta->tables [i].rows * meta->tables [i].row_size;
+	}
+}
+	
+char *
+mono_metadata_locate (metadata_t *meta, int table, int idx)
+{
+	/* idx == 0 refers always to NULL */
+	   
+	return meta->tables [table].base + (meta->tables [table].row_size * (idx - 1));
+}
+
+char *
+mono_metadata_locate_token (metadata_t *meta, guint32 token)
+{
+	return mono_metadata_locate (meta, token >> 24, token & 0xffffff);
+}

+ 103 - 10
mono/metadata/metadata.h

@@ -4,16 +4,70 @@ typedef struct {
 	guint32 sh_size;
 } stream_header_t;
 
+enum {
+	META_TABLE_MODULE,
+	META_TABLE_TYPEREF,
+	META_TABLE_TYPEDEF,
+	META_TABLE_UNUSED1,
+	META_TABLE_FIELD,
+	META_TABLE_UNUSED2,
+	META_TABLE_METHOD,
+	META_TABLE_UNUSED3,
+	META_TABLE_PARAM,
+	META_TABLE_INTERFACEIMPL,
+	META_TABLE_MEMBERREF,
+	META_TABLE_CONSTANT,
+	META_TABLE_CUSTOMATTRIBUTE,
+	META_TABLE_FIELDMARSHAL,
+	META_TABLE_DECLSECURITY,
+	META_TABLE_CLASSLAYOUT,
+	META_TABLE_FIELDLAYOUT,
+	META_TABLE_STANDALONESIG,
+	META_TABLE_EVENTMAP,
+	META_TABLE_UNUSED4,
+	META_TABLE_EVENT,
+	META_TABLE_PROPERTYMAP,
+	META_TABLE_UNUSED5,
+	META_TABLE_PROPERTY,
+	META_TABLE_METHODSEMANTICS,
+	META_TABLE_METHODIMPL,
+	META_TABLE_MODULEREF,
+	META_TABLE_TYPESPEC,
+	META_TABLE_IMPLMAP,
+	META_TABLE_FIELDRVA,
+	META_TABLE_UNUSED6,
+	META_TABLE_UNUSED7,
+	META_TABLE_ASSEMBLY,
+	META_TABLE_ASSEMBLYPROCESSOR,
+	META_TABLE_ASSEMBLYOS,
+	META_TABLE_ASSEMBLYREF,
+	META_TABLE_ASSEMBLYREFPROCESSOR,
+	META_TABLE_ASSEMBLYREFOS,
+	META_TABLE_FILE,
+	META_TABLE_EXPORTEDTYPE,
+	META_TABLE_MANIFESTRESOURCE,
+	META_TABLE_NESTEDCLASS
+};
+
 typedef struct {
-	char             *raw_metadata;
+	guint32   rows, row_size;
+	char     *base;
+} metadata_tableinfo_t;
 
-	stream_header_t   heap_strings;
-	stream_header_t   heap_us;
-	stream_header_t   heap_blob;
-	stream_header_t   heap_guid;
-	stream_header_t   heap_tables;
+typedef struct {
+	char                *raw_metadata;
+			    
+	gboolean             idx_string_wide, idx_guid_wide, idx_blob_wide;
+			    
+	stream_header_t      heap_strings;
+	stream_header_t      heap_us;
+	stream_header_t      heap_blob;
+	stream_header_t      heap_guid;
+	stream_header_t      heap_tables;
+			    
+	char                *tables_base;
 
-	guint32           rows [64];
+	metadata_tableinfo_t tables [64];
 } metadata_t;
 
 enum {
@@ -36,13 +90,52 @@ enum {
 	/* Pointer into a table */
 	MONO_MT_TABLE_IDX,
 
-	/* Constant:Parent pointer (Param, Field or Property) */
-	MONO_MT_CONST_IDX, 
+	/* HasConstant:Parent pointer (Param, Field or Property) */
+	MONO_MT_CONST_IDX,
+
+	/* HasCustomAttribute index.  Indexes any table except CustomAttribute */
+	MONO_MT_HASCAT_IDX,
+	
+	/* CustomAttributeType encoded index */
+	MONO_MT_CAT_IDX,
+
+	/* HasDeclSecurity index: TypeDef Method or Assembly */
+	MONO_MT_HASDEC_IDX,
+
+	/* Implementation coded index: File, Export AssemblyRef */
+	MONO_MT_IMPL_IDX,
+
+	/* HasFieldMarshal coded index: Field or Param table */
+	MONO_MT_HFM_IDX,
+
+	/* MemberForwardedIndex: Field or Method */
+	MONO_MT_MF_IDX,
+
+	/* TypeDefOrRef coded index: typedef, typeref, typespec */
+	MONO_MT_TDOR_IDX,
+
+	/* MemberRefParent coded index: typeref, moduleref, method, memberref, typesepc, typedef */
+	MONO_MT_MRP_IDX,
+
+	/* MethodDefOrRef coded index: Method or Member Ref table */
+	MONO_MT_MDOR_IDX,
+
+	/* HasSemantic coded index: Event or Property */
+	MONO_MT_HS_IDX,
+
+	/* ResolutionScope coded index: Module, ModuleRef, AssemblytRef, TypeRef */
+	MONO_MT_RS_IDX
 };
 
 typedef struct {
 	int   code;
 	char *def;
-} MonoMetaSchema;
+} MonoMetaTable;
 
 const char *mono_meta_table_name (int table);
+
+/* Internal functions */
+void  mono_metadata_compute_table_bases (metadata_t *meta);
+
+char *mono_metadata_locate       (metadata_t *meta, int table, int idx);
+char *mono_metadata_locate_token (metadata_t *meta, guint32 token);

+ 19 - 2
mono/metadata/pedump.c

@@ -232,13 +232,28 @@ dump_metadata (dotnet_image_info_t *iinfo)
 
 	printf ("Rows:\n");
 	for (table = 0; table < 64; table++){
-		if (meta->rows [table] == 0)
+		if (meta->tables [table].rows == 0)
 			continue;
-		printf ("Table %s (%d): %d rows\n", mono_meta_table_name (table), table, meta->rows [table]);
+		printf ("Table %s: %p (%d, %d)\n",
+			mono_meta_table_name (table),
+			meta->tables [table].base, 
+			meta->tables [table].rows,
+			meta->tables [table].row_size
+			);
 		dump_table (meta, table);
 	}
 }
 
+static void
+dump_methoddef (dotnet_image_info_t *iinfo, guint32 token)
+{
+	char *loc;
+
+	loc = mono_metadata_locate_token (&iinfo->dn_metadata, token);
+
+	printf ("RVA for Entry Point: 0x%08x\n", (*(guint32 *)loc));
+}
+
 static void
 dump_dotnet_iinfo (dotnet_image_info_t *iinfo)
 {
@@ -246,6 +261,8 @@ dump_dotnet_iinfo (dotnet_image_info_t *iinfo)
 	dump_sections (iinfo);
 	dump_cli_header (&iinfo->dn_cli_header);
 	dump_metadata (iinfo);
+
+	dump_methoddef (iinfo, iinfo->dn_cli_header.ch_entry_point);
 }
 
 static void