diff options
author | Zoltan Varga <vargaz@gmail.com> | 2017-02-28 03:28:52 +0300 |
---|---|---|
committer | Zoltan Varga <vargaz@gmail.com> | 2017-02-28 03:28:52 +0300 |
commit | 8551448ac78194dd1f83bdd32071fc4d5b197f64 (patch) | |
tree | 285211dc5c5af0bfc362626de28b385b5ba9d84c | |
parent | 1307bdd36056498ee62e1bc845768ba380964d51 (diff) |
Add --customattr option to dump the CustomAttribute metadata table.
-rw-r--r-- | Program.cs | 4 | ||||
-rw-r--r-- | TableDumper.cs | 87 |
2 files changed, 90 insertions, 1 deletions
@@ -49,7 +49,8 @@ namespace Ildasm { "assembly", v =>tableToDump = MetadataTableIndex.Assembly }, { "assemblyref", v =>tableToDump = MetadataTableIndex.AssemblyRef }, { "moduleref", v =>tableToDump = MetadataTableIndex.ModuleRef }, - { "exported", v =>tableToDump = MetadataTableIndex.ExportedType } + { "exported", v =>tableToDump = MetadataTableIndex.ExportedType }, + { "customattr", v =>tableToDump = MetadataTableIndex.CustomAttribute }, }; args = p.Parse (args).ToArray (); if (printUsage) { @@ -202,6 +203,7 @@ namespace Ildasm Console.WriteLine (" -assemblyref Dumps the contents of the AssemblyRef table"); Console.WriteLine (" -moduleref Dumps the contents of the ModuleRef table"); Console.WriteLine (" -exportedtype Dumps the contents of the ExportedType table"); + Console.WriteLine (" -customattr Dumps the contents of the CustomAttribute table"); } else { Console.WriteLine(" /OUT=<file name> Direct output to file rather than to stdout."); Console.WriteLine(" /COMPAT=<version> Match ildasm behavior. (<version> = 2.0 | 4.0 | 4.5)"); diff --git a/TableDumper.cs b/TableDumper.cs index 148868d..0366f3c 100644 --- a/TableDumper.cs +++ b/TableDumper.cs @@ -32,6 +32,7 @@ using IKVM.Reflection.Metadata; namespace Ildasm { enum MetadataTableIndex { + CustomAttribute = 0xc, ModuleRef = 0x1a, Assembly = 0x20, AssemblyRef = 0x23, @@ -75,6 +76,9 @@ namespace Ildasm case MetadataTableIndex.ExportedType: DumpExportedTypeTable (w); break; + case MetadataTableIndex.CustomAttribute: + DumpCustomAttributeTable (w); + break; default: throw new NotImplementedException (); } @@ -172,5 +176,88 @@ namespace Ildasm rowIndex ++; } } + + void DumpCustomAttributeTable (TextWriter w) { + var t = module.CustomAttribute; + w.WriteLine ("CustomAttribute Table (1.." + t.RowCount + ")"); + int rowIndex = 1; + foreach (var r in t.records) { + } + + Dictionary<int, string> table_names = new Dictionary<int, string> () { + { MethodDefTable.Index, "MethodDef" }, + { FieldTable.Index, "FieldDef" }, + { TypeRefTable.Index, "TypeRef" }, + { TypeDefTable.Index, "TypeDef" }, + { ParamTable.Index, "Param" }, + { InterfaceImplTable.Index, "InterfaceImpl" }, + { MemberRefTable.Index, "MemberRef" }, + { AssemblyTable.Index, "Assembly" }, + { ModuleTable.Index, "Module" }, + { PropertyTable.Index, "Property" }, + { EventTable.Index, "Event" }, + { StandAloneSigTable.Index, "StandAloneSignature" }, + { ModuleRefTable.Index, "ModuleRef" }, + { TypeSpecTable.Index, "TypeSpec" }, + { AssemblyRefTable.Index, "AssemblyRef" }, + { FileTable.Index, "File" }, + { ExportedTypeTable.Index, "ExportedType" }, + { ManifestResourceTable.Index, "Manifest" }, + { GenericParamTable.Index, "GenericParam" } + }; + + string StringifyCattrValue (object val) { + if (val.GetType () == typeof (string)) + return String.Format ("\"{0}\"", val); + else if (val == null) + return "null"; + else + return val.ToString (); + } + + foreach (var cattr in module.__EnumerateCustomAttributeTable ()) { + //Console.WriteLine (cattr); + + int parent_token = cattr.__Parent; + + string parent; + int table_idx = parent_token >> 24; + int row = parent_token & 0xffffff; + if (!table_names.TryGetValue (table_idx, out parent)) + parent = "Unknown"; + + var args = new StringBuilder (); + args.Append ("["); + bool first_arg = true; + var sep = ""; + foreach (var arg in cattr.ConstructorArguments) { + args.Append (sep).Append (StringifyCattrValue (arg.Value)); + sep = ", "; + } + foreach (var named_arg in cattr.NamedArguments) { + args.Append (sep); + args.Append ("{"); + args.Append (String.Format ("{0} = {1}", named_arg.MemberName, StringifyCattrValue (named_arg.TypedValue.Value))); + args.Append ("}"); + sep = ", "; + } + args.Append ("]"); + + var ctor = cattr.Constructor; + var method = new StringBuilder (); + method.Append ("instance void class "); + method.Append (String.Format ("[{0}]{1}", ctor.DeclaringType.Assembly.GetName ().Name, ctor.DeclaringType.ToString ())); + method.Append ("::'.ctor'("); + sep = ""; + foreach (var arg in ctor.GetParameters ()) { + method.Append (sep).Append (arg.ParameterType); + sep = ", "; + } + method.Append (")"); + + w.WriteLine (String.Format ("{0}: {1}: {2} {3} {4}", rowIndex, parent, row, method, args)); + rowIndex ++; + } + } } } |