/// <summary> /// Allocates a metadata (IL) representation along with a source level representation of the body of a method or of a property/event accessor. /// </summary> /// <param name="ilMethodBody">A method body whose IL operations should be decompiled into a block of statements that will be the /// result of the Block property of the resulting source method body.</param> /// <param name="host">An object representing the application that is hosting the converter. It is used to obtain access to some global /// objects and services such as the shared name table and the table for interning references.</param> /// <param name="sourceLocationProvider">An object that can map some kinds of ILocation objects to IPrimarySourceLocation objects. May be null.</param> /// <param name="localScopeProvider">An object that can provide information about the local scopes of a method.</param> /// <param name="options">Set of options that control decompilation.</param> public SourceMethodBody(IMethodBody ilMethodBody, IMetadataHost host, ISourceLocationProvider /*?*/ sourceLocationProvider, ILocalScopeProvider /*?*/ localScopeProvider, DecompilerOptions options = DecompilerOptions.None) : base(host, sourceLocationProvider, localScopeProvider) { Contract.Requires(ilMethodBody != null); Contract.Requires(host != null); this.ilMethodBody = ilMethodBody; this.host = host; this.nameTable = host.NameTable; this.sourceLocationProvider = sourceLocationProvider; this.pdbReader = sourceLocationProvider as PdbReader; this.localScopeProvider = localScopeProvider; this.options = options; this.platformType = ilMethodBody.MethodDefinition.ContainingTypeDefinition.PlatformType; if (IteratorHelper.EnumerableIsNotEmpty(ilMethodBody.LocalVariables)) { this.LocalsAreZeroed = ilMethodBody.LocalsAreZeroed; } else { this.LocalsAreZeroed = true; } this.MethodDefinition = ilMethodBody.MethodDefinition; this.privateHelperFieldsToRemove = null; this.privateHelperMethodsToRemove = null; this.privateHelperTypesToRemove = null; this.cdfg = ControlAndDataFlowGraph <BasicBlock <Instruction>, Instruction> .GetControlAndDataFlowGraphFor(host, ilMethodBody, localScopeProvider); }
public override void Traverse(IMethodBody methodBody) { sourceEmitterOutput.WriteLine(""); this.sourceEmitterOutput.WriteLine(MemberHelper.GetMethodSignature(methodBody.MethodDefinition, NameFormattingOptions.Signature | NameFormattingOptions.ReturnType | NameFormattingOptions.ParameterModifiers | NameFormattingOptions.ParameterName)); sourceEmitterOutput.WriteLine(""); if (this.pdbReader != null) { PrintScopes(methodBody); } else { PrintLocals(methodBody.LocalVariables); } this.cdfg = ControlAndDataFlowGraph <AiBasicBlock <Instruction>, Instruction> .GetControlAndDataFlowGraphFor(host, methodBody, this.pdbReader); this.cfgQueries = new ControlGraphQueries <AiBasicBlock <Instruction>, Instruction>(this.cdfg); SingleAssigner <AiBasicBlock <Instruction>, Instruction> .GetInSingleAssignmentForm(host.NameTable, this.cdfg, this.cfgQueries, this.pdbReader); this.valueMappings = new ValueMappings <Instruction>(this.host.PlatformType, new Z3Wrapper.Wrapper(host.PlatformType)); AbstractInterpreter <AiBasicBlock <Instruction>, Instruction> .InterpretUsingAbstractValues(this.cdfg, this.cfgQueries, this.valueMappings); var numberOfBlocks = this.cdfg.BlockFor.Count; foreach (var block in this.cdfg.AllBlocks) { this.PrintBlock(block); } sourceEmitterOutput.WriteLine("**************************************************************"); sourceEmitterOutput.WriteLine(); }
public override void Visit(IMethodBody methodBody) { Console.WriteLine(); Console.WriteLine("=========================="); Console.WriteLine("{0}", MemberHelper.GetMemberSignature(methodBody.MethodDefinition, NameFormattingOptions.DocumentationId)); var cdfg = ControlAndDataFlowGraph <EnhancedBasicBlock <Instruction>, Instruction> .GetControlAndDataFlowGraphFor(this.host, methodBody, this.pdbReader); var cfgQueries = new ControlGraphQueries <EnhancedBasicBlock <Instruction>, Instruction>(cdfg); var numberOfBlocks = cdfg.BlockFor.Count; Console.WriteLine("# blocks: {0}", numberOfBlocks); Console.WriteLine("CFG"); foreach (var block in cdfg.AllBlocks) { Console.WriteLine("{0:X}, Successors: {1}", block.Offset, Offsets(cdfg.SuccessorsFor(block))); } Dictionary <EnhancedBasicBlock <Instruction>, List <EnhancedBasicBlock <Instruction> > > dominators = new Dictionary <EnhancedBasicBlock <Instruction>, List <EnhancedBasicBlock <Instruction> > >(); foreach (var b in cdfg.AllBlocks) { var dom = new List <EnhancedBasicBlock <Instruction> >(); foreach (var c in cdfg.AllBlocks) { if (cfgQueries.Dominates(c, b)) { dom.Add(c); } } dominators.Add(b, dom); } var surroundingLoops = LoopFinder.GetLoopInformation(cdfg, cfgQueries, methodBody); Console.WriteLine("\nLoop information"); foreach (var b in cdfg.AllBlocks) { List <EnhancedBasicBlock <Instruction> > loops; if (surroundingLoops.TryGetValue(b, out loops)) { Console.WriteLine("{0:X}: ({1} loop{3}) {2}", b.Offset, loops.Count(), String.Join(",", loops.Select(l => String.Format("{0:X}", l.Offset))), loops.Count() > 1 ? "s" : "" ); } else { //Console.WriteLine("{0:X} is not contained in a loop", b.Offset); } } return; }
public void RunOnMethod(IMethodDefinition methodDefinition, IMetadataHost host) { ControlAndDataFlowGraph <BasicBlock <Instruction>, Instruction> cfg = ControlAndDataFlowGraph <BasicBlock <Instruction>, Instruction> .GetControlAndDataFlowGraphFor(host, methodDefinition.Body); // Note: we assume the first root block is the entrypoint of the function (and not, say, an exception handler // This may not be warranted; should perhaps check IL offset? BasicBlock <Instruction> entryBlock = cfg.RootBlocks.First(); RunOnControlFlowGraph(cfg, entryBlock); }
public override void Visit(IMethodBody methodBody) { var method = methodBody.MethodDefinition; this.currentMethod = method; if (methodBody.Operations != null) { var cdfg = ControlAndDataFlowGraph <EnhancedBasicBlock <Instruction>, Instruction> .GetControlAndDataFlowGraphFor(this.host, methodBody, this.pdbReader); var cfgQueries = new ControlGraphQueries <EnhancedBasicBlock <Instruction>, Instruction>(cdfg); this.FindObjectSourcesWithoutSinks(method, cdfg); } return; }
public override void Traverse(IMethodBody methodBody) { sourceEmitterOutput.WriteLine(""); if (this.pdbReader != null) { PrintScopes(methodBody); } else { PrintLocals(methodBody.LocalVariables); } this.cdfg = ControlAndDataFlowGraph <BasicBlock <Instruction>, Instruction> .GetControlAndDataFlowGraphFor(host, methodBody, this.pdbReader); var numberOfBlocks = this.cdfg.BlockFor.Count; foreach (var block in this.cdfg.AllBlocks) { this.PrintBlock(block); } sourceEmitterOutput.WriteLine("**************************************************************"); sourceEmitterOutput.WriteLine(); }
public override IMethodBody Rewrite(IMethodBody methodBody) { this.cdfg = ControlAndDataFlowGraph <BasicBlock <Instruction>, Instruction> .GetControlAndDataFlowGraphFor(this.host, methodBody); this.ilGenerator = new ILGenerator(host, methodBody.MethodDefinition); var numberOfBlocks = this.cdfg.BlockFor.Count; this.labelFor = new Hashtable <ILGeneratorLabel>(numberOfBlocks); this.counterFieldsForCurrentMethod = new NestedTypeDefinition() { BaseClasses = new List <ITypeReference>(1) { this.host.PlatformType.SystemObject }, ContainingTypeDefinition = methodBody.MethodDefinition.ContainingTypeDefinition, Fields = new List <IFieldDefinition>((int)numberOfBlocks * 2), Methods = new List <IMethodDefinition>(1), InternFactory = this.host.InternFactory, IsBeforeFieldInit = true, IsClass = true, IsSealed = true, IsAbstract = true, Name = this.host.NameTable.GetNameFor(methodBody.MethodDefinition.Name + "_Counters" + methodBody.MethodDefinition.InternedKey), Visibility = TypeMemberVisibility.Assembly, }; this.fieldOffsets = new List <uint>((int)numberOfBlocks * 2); foreach (var exceptionInfo in methodBody.OperationExceptionInformation) { this.ilGenerator.AddExceptionHandlerInformation(exceptionInfo.HandlerKind, exceptionInfo.ExceptionType, this.GetLabelFor(exceptionInfo.TryStartOffset), this.GetLabelFor(exceptionInfo.TryEndOffset), this.GetLabelFor(exceptionInfo.HandlerStartOffset), this.GetLabelFor(exceptionInfo.HandlerEndOffset), exceptionInfo.HandlerKind == HandlerKind.Filter ? this.GetLabelFor(exceptionInfo.FilterDecisionStartOffset) : null); } if (this.pdbReader == null) { foreach (var localDef in methodBody.LocalVariables) { this.ilGenerator.AddVariableToCurrentScope(localDef); } } else { foreach (var ns in this.pdbReader.GetNamespaceScopes(methodBody)) { foreach (var uns in ns.UsedNamespaces) { this.ilGenerator.UseNamespace(uns.NamespaceName.Value); } } this.scopeEnumerator = this.pdbReader.GetLocalScopes(methodBody).GetEnumerator(); this.scopeEnumeratorIsValid = this.scopeEnumerator.MoveNext(); } foreach (var block in this.cdfg.AllBlocks) { this.InstrumentBlock(block); } while (this.scopeStack.Count > 0) { this.ilGenerator.EndScope(); this.scopeStack.Pop(); } this.ilGenerator.AdjustBranchSizesToBestFit(); this.InjectMethodToDumpCounters(); return(new ILGeneratorMethodBody(this.ilGenerator, methodBody.LocalsAreZeroed, (ushort)(methodBody.MaxStack + 2), methodBody.MethodDefinition, methodBody.LocalVariables, IteratorHelper.GetSingletonEnumerable((ITypeDefinition)this.counterFieldsForCurrentMethod))); }
public bool AnalyzeMethods() { foreach (INamedTypeDefinition t in PrimaryModule.GetAllTypes()) { if (t.IsClass && t.Methods.Count() > 0 && !t.Name.Value.StartsWith("<")) { Environment.Message("Class {0} has {1} members, {2} methods.", t.Name.Value, t.Members.Count(), t.Methods.Count()); List <IMethodDefinition> methods = t.Methods.ToList(); foreach (IMethodDefinition m in methods) { ControlAndDataFlowGraph <EnhancedBasicBlock <Instruction>, Instruction> cdfg = ControlAndDataFlowGraph <EnhancedBasicBlock <Instruction>, Instruction> .GetControlAndDataFlowGraphFor(MetadataReaderHost, m.Body); ControlGraphQueries <EnhancedBasicBlock <Instruction>, Instruction> query = new ControlGraphQueries <EnhancedBasicBlock <Instruction>, Instruction>(cdfg); Environment.Message(" Method {0} has visibility {3}, {1} parameters, {2} local variables in body, {4} total basic blocks or nodes and {5} successor edges in CFG.\n", m.Name.Value, m.ParameterCount, m.Body.LocalVariables.Count(), m.Visibility.ToString(), cdfg.AllBlocks.Count, cdfg.SuccessorEdges.Count); } } } return(true); }