public static void WriteTo(this Instruction instruction, MethodDef method, CilBody body, ITextOutput writer) { writer.WriteDefinition(dnlibExtensions.OffsetToString(instruction.Offset), instruction, true); writer.Write(": "); writer.WriteReference(instruction.OpCode.Name, instruction.OpCode, true); if (instruction.Operand != null) { writer.Write(' '); if (instruction.OpCode == OpCodes.Ldtoken) { if (dnlibExtensions.IsMethod(instruction.Operand)) { writer.WriteKeyword("method "); } else if (dnlibExtensions.IsField(instruction.Operand)) { writer.WriteKeyword("field "); } } WriteOperand(writer, instruction.Operand); } else if (method != null && body != null) { switch (instruction.OpCode.Code) { case Code.Ldloc_0: case Code.Ldloc_1: case Code.Ldloc_2: case Code.Ldloc_3: writer.WriteComment(" // "); var local = instruction.GetLocal(body.Variables); if (local != null) { WriteOperand(writer, local); } break; case Code.Ldarg_0: case Code.Ldarg_1: case Code.Ldarg_2: case Code.Ldarg_3: writer.WriteComment(" // "); var arg = instruction.GetParameter(method.Parameters); if (arg != null) { WriteOperand(writer, arg); } break; } } }
public void WriteKeyword(string keyword) { IMemberRef memberRef = GetCurrentMemberReference(); var node = nodeStack.Peek(); if (memberRef != null && (node is ConstructorInitializer || node is PrimitiveType)) { output.WriteReference(keyword, memberRef); } else { output.WriteKeyword(keyword); } }
public static void WriteTo(this Instruction instruction, MethodDef method, CilBody body, ITextOutput writer) { writer.WriteDefinition(dnlibExtensions.OffsetToString(instruction.Offset), instruction, true); writer.Write(": "); writer.WriteReference(instruction.OpCode.Name, instruction.OpCode, true); if (instruction.Operand != null) { writer.Write(' '); if (instruction.OpCode == OpCodes.Ldtoken) { if (dnlibExtensions.IsMethod(instruction.Operand)) writer.WriteKeyword("method "); else if (dnlibExtensions.IsField(instruction.Operand)) writer.WriteKeyword("field "); } WriteOperand(writer, instruction.Operand); } else if (method != null && body != null) { switch (instruction.OpCode.Code) { case Code.Ldloc_0: case Code.Ldloc_1: case Code.Ldloc_2: case Code.Ldloc_3: writer.WriteComment(" // "); var local = instruction.GetLocal(body.Variables); if (local != null) WriteOperand(writer, local); break; case Code.Ldarg_0: case Code.Ldarg_1: case Code.Ldarg_2: case Code.Ldarg_3: writer.WriteComment(" // "); var arg = instruction.GetParameter(method.Parameters); if (arg != null) WriteOperand(writer, arg); break; } } }
public static void WriteTo(this ITypeDefOrRef type, ITextOutput writer, ILNameSyntax syntax = ILNameSyntax.Signature) { if (type is TypeSpec) { ((TypeSpec)type).TypeSig.WriteTo(writer, syntax); return; } string name = PrimitiveTypeName(type.FullName); if (syntax == ILNameSyntax.ShortTypeName) { if (name != null) writer.WriteKeyword(name); else writer.WriteReference(Escape(type.Name), type); } else if ((syntax == ILNameSyntax.Signature || syntax == ILNameSyntax.SignatureNoNamedTypeParameters) && name != null) { writer.WriteKeyword(name); } else { if (syntax == ILNameSyntax.Signature || syntax == ILNameSyntax.SignatureNoNamedTypeParameters) writer.WriteKeyword(type.IsValueType ? "valuetype " : "class "); if (type.DeclaringType != null) { type.DeclaringType.WriteTo(writer, ILNameSyntax.TypeName); writer.Write('/'); writer.WriteReference(Escape(type.Name), type); } else { if (!(type is TypeDef) && type.Scope != null) { IAssembly assembly; if (type.Scope is IAssembly) assembly = (IAssembly)type.Scope; else if (type.Scope is ModuleRef) assembly = ((ModuleRef)type.Scope).DefinitionAssembly; else if (type.Scope is ModuleDef) assembly = ((ModuleDef)type.Scope).Assembly; else throw new NotSupportedException(); writer.Write("["); writer.WriteReference(Escape(assembly.Name), assembly); writer.Write("]"); } writer.WriteReference(Escape(type.FullName), type); } } }
public static void WriteTo(this TypeSig type, ITextOutput writer, ILNameSyntax syntax = ILNameSyntax.Signature) { ILNameSyntax syntaxForElementTypes = syntax == ILNameSyntax.SignatureNoNamedTypeParameters ? syntax : ILNameSyntax.Signature; if (type is PinnedSig) { type.Next.WriteTo(writer, syntaxForElementTypes); writer.WriteKeyword(" pinned"); } else if (type is SZArraySig) { type.Next.WriteTo(writer, syntaxForElementTypes); writer.Write("[]"); } else if (type is ArraySig) { ArraySig sig = (ArraySig)type; type.Next.WriteTo(writer, syntaxForElementTypes); writer.Write('['); for (int i = 0; i < sig.Rank; i++) { if (i != 0) writer.Write(", "); int? lower = i < sig.LowerBounds.Count ? sig.LowerBounds[i] : (int?)null; uint? size = i < sig.Sizes.Count ? sig.Sizes[i] : (uint?)null; if (lower != null) { writer.Write(lower.ToString()); writer.Write(".."); if (size != null) writer.Write((lower.Value + (int)size.Value - 1).ToString()); else writer.Write("."); } } writer.Write(']'); } else if (type is GenericSig) { writer.Write('!'); if (type is GenericMVar) writer.Write('!'); var genericParam = ((GenericSig)type).GenericParam; if (genericParam == null || string.IsNullOrEmpty(genericParam.Name) || syntax == ILNameSyntax.SignatureNoNamedTypeParameters) writer.Write(((GenericSig)type).Number.ToString()); else writer.Write(Escape(genericParam.Name)); } else if (type is ByRefSig) { type.Next.WriteTo(writer, syntaxForElementTypes); writer.Write('&'); } else if (type is PtrSig) { type.Next.WriteTo(writer, syntaxForElementTypes); writer.Write('*'); } else if (type is GenericInstSig) { ((GenericInstSig)type).GenericType.WriteTo(writer, syntaxForElementTypes); writer.Write('<'); var arguments = ((GenericInstSig)type).GenericArguments; for (int i = 0; i < arguments.Count; i++) { if (i > 0) writer.Write(", "); arguments[i].WriteTo(writer, syntaxForElementTypes); } writer.Write('>'); } else if (type is CModOptSig) { type.Next.WriteTo(writer, syntax); writer.WriteKeyword(" modopt("); ((CModOptSig)type).Modifier.WriteTo(writer, ILNameSyntax.TypeName); writer.WriteKeyword(") "); } else if (type is CModReqdSig) { type.Next.WriteTo(writer, syntax); writer.WriteKeyword(" modreq("); ((CModReqdSig)type).Modifier.WriteTo(writer, ILNameSyntax.TypeName); writer.WriteKeyword(") "); } else if (type is ValueArraySig) { type.Next.WriteTo(writer, syntax); writer.WriteKeyword(" ValueArray("); writer.Write(((ValueArraySig)type).Size.ToString()); writer.WriteKeyword(") "); } else if (type is ModuleSig) { type.Next.WriteTo(writer, syntax); writer.WriteKeyword(" Module("); writer.Write(((ModuleSig)type).Index.ToString()); writer.WriteKeyword(") "); } else if (type is FnPtrSig) { ((FnPtrSig)type).MethodSig.WriteTo(null, writer); } else if (type is TypeDefOrRefSig) { ((TypeDefOrRefSig)type).TypeDefOrRef.WriteTo(writer, syntax); } }
public static void WriteTo(this MethodSig signature, IMethod method, ITextOutput writer) { if (signature.ExplicitThis) { writer.WriteKeyword("instance explicit "); } else if (signature.HasThis) { writer.WriteKeyword("instance "); } signature.RetType.WriteTo(writer, ILNameSyntax.SignatureNoNamedTypeParameters); writer.Write(' '); if (method != null && method.DeclaringType != null) { method.DeclaringType.WriteTo(writer, ILNameSyntax.TypeName); writer.Write("::"); } MethodDef md = method as MethodDef; if (md != null && md.IsCompilerControlled) { writer.WriteReference(Escape(method.Name + "$PST" + method.MDToken.Raw.ToString("X8")), method); } else if (method != null) { writer.WriteReference(Escape(method.Name), method); } else { writer.Write("(*)"); } MethodSpec methodSpec = method as MethodSpec; if (methodSpec != null) { writer.Write('<'); var genArgs = methodSpec.GenericInstMethodSig.GenericArguments; for (int i = 0; i < genArgs.Count; i++) { if (i > 0) writer.Write(", "); genArgs[i].WriteTo(writer); } writer.Write('>'); } writer.Write("("); for (int i = 0; i < signature.Params.Count; ++i) { if (i > 0) writer.Write(", "); signature.Params[i].WriteTo(writer, ILNameSyntax.SignatureNoNamedTypeParameters); } if (signature.ParamsAfterSentinel != null && signature.ParamsAfterSentinel.Count > 0) { if (signature.Params.Count > 0) writer.Write(", "); writer.Write("..."); for (int i = 0; i < signature.ParamsAfterSentinel.Count; ++i) { if (i > 0) writer.Write(", "); signature.ParamsAfterSentinel[i].WriteTo(writer, ILNameSyntax.SignatureNoNamedTypeParameters); } } writer.Write(")"); }
public static void WriteTo(this ITypeDefOrRef type, ITextOutput writer, ILNameSyntax syntax = ILNameSyntax.Signature) { if (type is TypeSpec) { ((TypeSpec)type).TypeSig.WriteTo(writer, syntax); return; } string name = PrimitiveTypeName(type.FullName); if (syntax == ILNameSyntax.ShortTypeName) { if (name != null) { writer.WriteKeyword(name); } else { writer.WriteReference(Escape(type.Name), type); } } else if ((syntax == ILNameSyntax.Signature || syntax == ILNameSyntax.SignatureNoNamedTypeParameters) && name != null) { writer.WriteKeyword(name); } else { if (syntax == ILNameSyntax.Signature || syntax == ILNameSyntax.SignatureNoNamedTypeParameters) { writer.WriteKeyword(type.IsValueType ? "valuetype " : "class "); } if (type.DeclaringType != null) { type.DeclaringType.WriteTo(writer, ILNameSyntax.TypeName); writer.Write('/'); writer.WriteReference(Escape(type.Name), type); } else { if (!(type is TypeDef) && type.Scope != null) { IAssembly assembly; if (type.Scope is IAssembly) { assembly = (IAssembly)type.Scope; } else if (type.Scope is ModuleRef) { assembly = ((ModuleRef)type.Scope).DefinitionAssembly; } else if (type.Scope is ModuleDef) { assembly = ((ModuleDef)type.Scope).Assembly; } else { throw new NotSupportedException(); } writer.Write("["); writer.WriteReference(Escape(assembly.Name), assembly); writer.Write("]"); } writer.WriteReference(Escape(type.FullName), type); } } }
public static void WriteTo(this TypeSig type, ITextOutput writer, ILNameSyntax syntax = ILNameSyntax.Signature) { ILNameSyntax syntaxForElementTypes = syntax == ILNameSyntax.SignatureNoNamedTypeParameters ? syntax : ILNameSyntax.Signature; if (type is PinnedSig) { type.Next.WriteTo(writer, syntaxForElementTypes); writer.WriteKeyword(" pinned"); } else if (type is SZArraySig) { type.Next.WriteTo(writer, syntaxForElementTypes); writer.Write("[]"); } else if (type is ArraySig) { ArraySig sig = (ArraySig)type; type.Next.WriteTo(writer, syntaxForElementTypes); writer.Write('['); for (int i = 0; i < sig.Rank; i++) { if (i != 0) { writer.Write(", "); } int? lower = i < sig.LowerBounds.Count ? sig.LowerBounds[i] : (int?)null; uint?size = i < sig.Sizes.Count ? sig.Sizes[i] : (uint?)null; if (lower != null) { writer.Write(lower.ToString()); writer.Write(".."); if (size != null) { writer.Write((lower.Value + (int)size.Value - 1).ToString()); } else { writer.Write("."); } } } writer.Write(']'); } else if (type is GenericSig) { writer.Write('!'); if (type is GenericMVar) { writer.Write('!'); } var genericParam = ((GenericSig)type).GenericParam; if (genericParam == null || string.IsNullOrEmpty(genericParam.Name) || syntax == ILNameSyntax.SignatureNoNamedTypeParameters) { writer.Write(((GenericSig)type).Number.ToString()); } else { writer.Write(Escape(genericParam.Name)); } } else if (type is ByRefSig) { type.Next.WriteTo(writer, syntaxForElementTypes); writer.Write('&'); } else if (type is PtrSig) { type.Next.WriteTo(writer, syntaxForElementTypes); writer.Write('*'); } else if (type is GenericInstSig) { ((GenericInstSig)type).GenericType.WriteTo(writer, syntaxForElementTypes); writer.Write('<'); var arguments = ((GenericInstSig)type).GenericArguments; for (int i = 0; i < arguments.Count; i++) { if (i > 0) { writer.Write(", "); } arguments[i].WriteTo(writer, syntaxForElementTypes); } writer.Write('>'); } else if (type is CModOptSig) { type.Next.WriteTo(writer, syntax); writer.WriteKeyword(" modopt("); ((CModOptSig)type).Modifier.WriteTo(writer, ILNameSyntax.TypeName); writer.WriteKeyword(") "); } else if (type is CModReqdSig) { type.Next.WriteTo(writer, syntax); writer.WriteKeyword(" modreq("); ((CModReqdSig)type).Modifier.WriteTo(writer, ILNameSyntax.TypeName); writer.WriteKeyword(") "); } else if (type is ValueArraySig) { type.Next.WriteTo(writer, syntax); writer.WriteKeyword(" ValueArray("); writer.Write(((ValueArraySig)type).Size.ToString()); writer.WriteKeyword(") "); } else if (type is ModuleSig) { type.Next.WriteTo(writer, syntax); writer.WriteKeyword(" Module("); writer.Write(((ModuleSig)type).Index.ToString()); writer.WriteKeyword(") "); } else if (type is FnPtrSig) { ((FnPtrSig)type).MethodSig.WriteTo(null, writer); } else if (type is TypeDefOrRefSig) { ((TypeDefOrRefSig)type).TypeDefOrRef.WriteTo(writer, syntax); } }
public static void WriteTo(this MethodSig signature, IMethod method, ITextOutput writer) { if (signature.ExplicitThis) { writer.WriteKeyword("instance explicit "); } else if (signature.HasThis) { writer.WriteKeyword("instance "); } signature.RetType.WriteTo(writer, ILNameSyntax.SignatureNoNamedTypeParameters); writer.Write(' '); if (method != null && method.DeclaringType != null) { method.DeclaringType.WriteTo(writer, ILNameSyntax.TypeName); writer.Write("::"); } MethodDef md = method as MethodDef; if (md != null && md.IsCompilerControlled) { writer.WriteReference(Escape(method.Name + "$PST" + method.MDToken.Raw.ToString("X8")), method); } else if (method != null) { writer.WriteReference(Escape(method.Name), method); } else { writer.Write("(*)"); } MethodSpec methodSpec = method as MethodSpec; if (methodSpec != null) { writer.Write('<'); var genArgs = methodSpec.GenericInstMethodSig.GenericArguments; for (int i = 0; i < genArgs.Count; i++) { if (i > 0) { writer.Write(", "); } genArgs[i].WriteTo(writer); } writer.Write('>'); } writer.Write("("); for (int i = 0; i < signature.Params.Count; ++i) { if (i > 0) { writer.Write(", "); } signature.Params[i].WriteTo(writer, ILNameSyntax.SignatureNoNamedTypeParameters); } if (signature.ParamsAfterSentinel != null && signature.ParamsAfterSentinel.Count > 0) { if (signature.Params.Count > 0) { writer.Write(", "); } writer.Write("..."); for (int i = 0; i < signature.ParamsAfterSentinel.Count; ++i) { if (i > 0) { writer.Write(", "); } signature.ParamsAfterSentinel[i].WriteTo(writer, ILNameSyntax.SignatureNoNamedTypeParameters); } } writer.Write(")"); }
public void Disassemble(MethodDef method, CilBody body, MemberMapping methodMapping) { // start writing IL code output.WriteLineComment("// Method Token is 0x{0:x8}", method.MDToken.Raw); output.WriteLineComment("// Method begins at RVA 0x{0:x}", method.RVA); output.WriteLineComment("// Code size {0} (0x{0:x})", body.GetCodeSize()); output.WriteKeyword(".maxstack "); output.WriteLiteral(body.MaxStack.ToString()); output.WriteLine(); if (method.DeclaringType.Module.Assembly != null && method.DeclaringType.Module.EntryPoint == method) { output.WriteKeyword(".entrypoint"); output.WriteLine(); } if (method.Body.HasVariables) { output.WriteKeyword(".locals "); if (method.Body.InitLocals) { output.WriteKeyword("init "); } output.WriteLine("("); output.Indent(); foreach (var v in method.Body.Variables) { output.WriteDefinition("[" + v.Index + "]", v, true); output.Write(" "); v.Type.WriteTo(output); if (!string.IsNullOrEmpty(v.Name)) { output.Write(' '); output.Write(DisassemblerHelpers.Escape(v.Name)); } if (v.Index + 1 < method.Body.Variables.Count) { output.Write(','); } output.WriteLine(); } output.Unindent(); output.WriteLine(")"); } output.WriteLine(); if (detectControlStructure && body.Instructions.Count > 0) { Instruction inst = body.Instructions[0]; var branchTargets = GetBranchTargets(body.Instructions); WriteStructureBody(method, body, new ILStructure(body), branchTargets, ref inst, methodMapping, method.Body.GetCodeSize()); } else { foreach (var inst in method.Body.Instructions) { var startLocation = output.Location; inst.WriteTo(method, body, output); if (methodMapping != null) { var next = inst.GetNext(body); // add IL code mappings - used in debugger methodMapping.MemberCodeMappings.Add( new SourceCodeMapping() { StartLocation = output.Location, EndLocation = output.Location, ILInstructionOffset = new ILRange { From = inst.Offset, To = next == null ? method.Body.GetCodeSize() : next.Offset }, MemberMapping = methodMapping }); } output.WriteLine(); } if (method.Body.HasExceptionHandlers) { output.WriteLine(); foreach (var eh in method.Body.ExceptionHandlers) { eh.WriteTo(output); output.WriteLine(); } } } }
public void WriteKeyword(string keyword) { output.WriteKeyword(keyword); }