private void WriteStructureBody(ILBlock s, HashSet<int> branchTargets, ref Instruction inst, MemberMapping currentMethodMapping, int codeSize) { bool isFirstInstructionInStructure = true; bool prevInstructionWasBranch = false; int childIndex = 0; while (inst != null && inst.Offset < s.EndOffset) { int offset = inst.Offset; if (childIndex < s.Children.Count && s.Children[childIndex].StartOffset <= offset && offset < s.Children[childIndex].EndOffset) { ILBlock child = s.Children[childIndex++]; WriteStructureHeader(child); WriteStructureBody(child, branchTargets, ref inst, currentMethodMapping, codeSize); WriteStructureFooter(child); } else { if (!isFirstInstructionInStructure && (prevInstructionWasBranch || branchTargets.Contains(offset))) { WriteLine(); } WriteInstruction(inst); if (currentMethodMapping != null) { currentMethodMapping.MemberCodeMappings.Add( new SourceCodeMapping() { ILInstructionOffset = new ILRange { From = inst.Offset, To = inst.Next == null ? codeSize : inst.Next.Offset }, MemberMapping = currentMethodMapping }); } WriteLine(); prevInstructionWasBranch = (inst.OpCode.FlowControl == FlowControl.Branch) || (inst.OpCode.FlowControl == FlowControl.Cond_Branch) || (inst.OpCode.FlowControl == FlowControl.Return) || (inst.OpCode.FlowControl == FlowControl.Throw); inst = inst.Next; } isFirstInstructionInStructure = false; } }
internal static MemberMapping CreateCodeMapping(MethodDefinition member, CodeMappings codeMappings) { if (member == null || !member.HasBody) return null; if (codeMappings == null) return null; MemberMapping currentMemberMapping = null; if (codeMappings.FullName == member.DeclaringType.FullName) { var mapping = codeMappings.Mapping; if (mapping.Find(map => (int)map.MetadataToken == member.MetadataToken.ToInt32()) == null) { currentMemberMapping = new MemberMapping() { MetadataToken = (uint)member.MetadataToken.ToInt32(), MemberReference = member.DeclaringType.Resolve(), MemberCodeMappings = new List<SourceCodeMapping>(), CodeSize = member.Body.CodeSize }; mapping.Add(currentMemberMapping); } } return currentMemberMapping; }
private void Disassemble(MethodBody body, MemberMapping methodMapping) { MethodDefinition method = body.Method; if (method.DeclaringType.Module.Assembly.EntryPoint == method) { WriteKeyword(".entrypoint"); WriteLine(); } if (method.Body.HasVariables) { WriteMethodVariables(method); WriteLine(); } if (shouldGenerateBlocks && body.Instructions.Count > 0) { Instruction inst = body.Instructions[0]; HashSet<int> branchTargets = GetBranchTargets(body.Instructions); WriteStructureBody(new ILBlock(body), branchTargets, ref inst, methodMapping, method.Body.CodeSize); } else { foreach (var inst in method.Body.Instructions) { WriteInstruction(inst); if (methodMapping != null) { methodMapping.MemberCodeMappings.Add( new SourceCodeMapping() { ILInstructionOffset = new ILRange { From = inst.Offset, To = inst.Next == null ? method.Body.CodeSize : inst.Next.Offset }, MemberMapping = methodMapping }); } WriteLine(); } if (method.Body.HasExceptionHandlers) { WriteLine(); foreach (var eh in method.Body.ExceptionHandlers) { WriteExceptionHandler(eh); WriteLine(); } } } }