コード例 #1
0
		public void Disassemble(MethodBody body, MemberMapping methodMapping)
		{
			// start writing IL code
			MethodDefinition method = body.Method;
			output.WriteLine("// Method begins at RVA 0x{0:x4}", method.RVA);
			output.WriteLine("// Code size {0} (0x{0:x})", body.CodeSize);
			output.WriteLine(".maxstack {0}", body.MaxStackSize);
			if (method.DeclaringType.Module.Assembly.EntryPoint == method)
				output.WriteLine (".entrypoint");
			
			if (method.Body.HasVariables) {
				output.Write(".locals ");
				if (method.Body.InitLocals)
					output.Write("init ");
				output.WriteLine("(");
				output.Indent();
				foreach (var v in method.Body.Variables) {
					output.WriteDefinition("[" + v.Index + "] ", v);
					v.VariableType.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];
				HashSet<int> branchTargets = GetBranchTargets(body.Instructions);
				WriteStructureBody(new ILStructure(body), branchTargets, ref inst, methodMapping, method.Body.CodeSize);
			} else {
				foreach (var inst in method.Body.Instructions) {
					inst.WriteTo(output);
					
					if (methodMapping != null) {
						// add IL code mappings - used in debugger
						methodMapping.MemberCodeMappings.Add(
							new SourceCodeMapping() {
								SourceCodeLine = output.CurrentLine,
								ILInstructionOffset = new ILRange { From = inst.Offset, To = inst.Next == null ? method.Body.CodeSize : inst.Next.Offset },
								MemberMapping = methodMapping
							});
					}
					
					output.WriteLine();
				}
				if (method.Body.HasExceptionHandlers) {
					output.WriteLine();
					foreach (var eh in method.Body.ExceptionHandlers) {
						eh.WriteTo(output);
						output.WriteLine();
					}
				}
			}
		}
コード例 #2
0
		/// <summary>
		/// Create code mapping for a method.
		/// </summary>
		/// <param name="method">Method to create the mapping for.</param>
		/// <param name="codeMappings">Source code mapping storage.</param>
		/// <param name="actualMemberReference">The actual member reference.</param>
		internal static MemberMapping CreateCodeMapping(
			this MethodDefinition member,
			List<MemberMapping> codeMappings,
			MemberReference actualMemberReference = null)
		{
			if (member == null || !member.HasBody)
				return null;
			
			if (codeMappings == null)
				return null;
			
			// create IL/CSharp code mappings - used in debugger
			MemberMapping currentMemberMapping = null;

            if (codeMappings.Any(map => map.MetadataToken == member.MetadataToken.ToInt32()))
            {
                currentMemberMapping = new MemberMapping()
                {
                    MetadataToken = member.MetadataToken.ToInt32(),
                    MemberCodeMappings = new List<SourceCodeMapping>(),
                    MemberReference = actualMemberReference ?? member,
                    CodeSize = member.Body.CodeSize
                };

                codeMappings.Add(currentMemberMapping);
            }
			
			return currentMemberMapping;
		}
コード例 #3
0
		void WriteStructureBody(ILStructure 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) {
					ILStructure child = s.Children[childIndex++];
					WriteStructureHeader(child);
					WriteStructureBody(child, branchTargets, ref inst, currentMethodMapping, codeSize);
					WriteStructureFooter(child);
				} else {
					if (!isFirstInstructionInStructure && (prevInstructionWasBranch || branchTargets.Contains(offset))) {
						output.WriteLine(); // put an empty line after branches, and in front of branch targets
					}
					inst.WriteTo(output);
					
					// add IL code mappings - used in debugger
					if (currentMethodMapping != null) {
						currentMethodMapping.MemberCodeMappings.Add(
							new SourceCodeMapping() {
								SourceCodeLine = output.CurrentLine,
								ILInstructionOffset = new ILRange { From = inst.Offset, To = inst.Next == null ? codeSize : inst.Next.Offset },
								MemberMapping = currentMethodMapping
							});
					}
					
					output.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;
			}
		}