public MethodBodyDisassemblyFormatter(MethodDefinition methodDef, MapFileLookup mapFile) { _methodDef = methodDef; _mapFile = mapFile; TypeEntry typeEntry = null; MethodEntry methodEntry = null; if (mapFile != null) { typeEntry = mapFile.GetTypeByNewName(methodDef.Owner.Fullname); if (typeEntry != null) { methodEntry = typeEntry.FindDexMethod(methodDef.Name, methodDef.Prototype.ToSignature()); } } _dissassembly = new MethodDisassembly(methodDef, mapFile, typeEntry, methodEntry); _sourceDocument = new Lazy<string[]>(() => { if (_dissassembly.MethodEntry == null) return null; var pos = _mapFile.GetSourceCodePositions(_dissassembly.MethodEntry).FirstOrDefault(); if (pos == null) return null; try { return File.ReadAllLines(pos.Document.Path); } catch (Exception) { return null; } }); }
public DebugDisassemblyStream(DebugProgram program, DebugCodeContext documentContext) { _loc = documentContext.DocumentContext.DocumentLocation; _method = program.DisassemblyProvider.GetFromLocation(_loc); }
//private DalvikStackFrame GetUnwindStackFrame(DalvikThread thread, DebugCodeContext context) //{ // foreach (var stackFrame in thread.GetCallStack()) // { // bool isSameMethodEarlierOrSame = stackFrame.Location.IsSameMethod(context.Location) // && stackFrame.Location.Index >= context.Location.Index; // if (isSameMethodEarlierOrSame) // return stackFrame; // } // return null; //} /// <summary> /// Finds the next location with source starting from <paramref name="idx"/>. /// Will return null if no source is found. Will follow a single goto. /// Will return null if multiple gotos or if any other jump instruction is /// encountered. /// </summary> private int? FindNextLocationWithSource(MethodDisassembly disassembly, int idx) { var instructions = disassembly.Method.Body.Instructions; var ins = instructions[idx]; // find the next instruction with source code. var loc = disassembly.FindNextSourceCode(ins.Offset); if (loc == null) return null; int gotos = 0; for (; (ins = instructions[idx]).Offset < loc.Position.MethodOffset; ++idx) { // While working as expected, the following code as no effect on // foreach statements, since the target of the goto is a "IsSpecial" // branch instruction back to the very same goto. if (ins.OpCode == OpCodes.Goto || ins.OpCode == OpCodes.Goto_16 || ins.OpCode == OpCodes.Goto_32) { // follow a single goto. this is typically encountered // at the beginning of the loop of foreach statements. if (gotos++ > 0) return null; ins = (Instruction)ins.Operand; loc = disassembly.FindNextSourceCode(ins.Offset); if (loc == null) return null; idx = instructions.IndexOf(ins) - 1; continue; } if (ins.OpCode.IsJump()) return null; } return idx; }