public AssemblyLine[] GetLines (int firstIndex, int lastIndex) { //Console.WriteLine ("pp GET LINES: " + firstIndex + " " + lastIndex + " " + baseIndex); if (lastIndex >= 0) FillDown (lastIndex); if (firstIndex < 0) FillUp (firstIndex); AssemblyLine[] array = new AssemblyLine [lastIndex - firstIndex + 1]; lines.CopyTo (baseIndex + firstIndex, array, 0, lastIndex - firstIndex + 1); return array; }
void InsertAssemblerLine (StringBuilder sb, int line, AssemblyLine asm) { sb.AppendFormat ("{0:x8} {1}\n", asm.Address, asm.Code); addressLines [GetAddrId (asm.Address, asm.AddressSpace)] = line; }
protected override AssemblyLine[] OnDisassembleFile (string file) { List<TypeMirror> types; if (!source_to_type.TryGetValue (file, out types)) return new AssemblyLine [0]; var lines = new List<AssemblyLine> (); foreach (TypeMirror type in types) { foreach (MethodMirror met in type.GetMethods ()) { string srcFile = met.SourceFile != null ? NormalizePath (met.SourceFile) : null; if (srcFile == null || !PathsAreEqual (srcFile, file)) continue; var body = met.GetMethodBody (); int lastLine = -1; int firstPos = lines.Count; string addrSpace = met.FullName; foreach (var ins in body.Instructions) { Location loc = met.LocationAtILOffset (ins.Offset); if (loc != null && lastLine == -1) { lastLine = loc.LineNumber; for (int n=firstPos; n<lines.Count; n++) { AssemblyLine old = lines [n]; lines [n] = new AssemblyLine (old.Address, old.AddressSpace, old.Code, loc.LineNumber); } } lines.Add (new AssemblyLine (ins.Offset, addrSpace, Disassemble (ins), loc != null ? loc.LineNumber : lastLine)); } } } lines.Sort (delegate (AssemblyLine a1, AssemblyLine a2) { int res = a1.SourceLine.CompareTo (a2.SourceLine); if (res != 0) return res; else return a1.Address.CompareTo (a2.Address); }); return lines.ToArray (); }
public void FillUp (int targetLine) { if (baseIndex + targetLine >= 0) return; // Lines we are missing int linesReq = -(baseIndex + targetLine); //Console.WriteLine ("pp FILLUP: " + linesReq); // Last known valid address long lastAddr = lines.Count > 0 ? lines [0].Address : baseAddress; // Addresses we are going to query to get the required lines long addr = lastAddr - (linesReq + ExtraUpLines) * AddrPerLine; // 4 is just a guess int lastCount = 0; bool limitFound = false; AssemblyLine[] alines; do { alines = GetLines (addr, lastAddr); if (alines.Length <= lastCount) { limitFound = true; break; } addr -= (linesReq + ExtraUpLines - alines.Length) * AddrPerLine; lastCount = alines.Length; } while (alines.Length < linesReq + ExtraUpLines); int max = limitFound ? alines.Length : alines.Length - ExtraUpLines; if (max < 0) max = 0; // Fill the lines for (int n=0; n < max; n++) lines.Insert (n, alines [n + (alines.Length - max)]); long firstAddr = lines [0].Address; for (int n=0; n < (linesReq - max); n++) { AssemblyLine line = new AssemblyLine (--firstAddr, ""); lines.Insert (0, line); max++; } baseIndex += max; }
public void FillDown (int targetLine) { if (baseIndex + targetLine < lines.Count) return; // Lines we are missing int linesReq = (baseIndex + targetLine) - lines.Count + 1; //Console.WriteLine ("pp FILLDOWN: " + linesReq); // Last known valid address long lastAddr = lines.Count > 0 ? lines [lines.Count - 1].Address : baseAddress; // Addresses we are going to query to get the required lines long addr = lastAddr + (linesReq + ExtraDownLines) * AddrPerLine; // 4 is just a guess int lastCount = 0; bool limitFound = false; AssemblyLine[] alines; do { alines = GetLines (lastAddr, addr); if (alines.Length <= lastCount) { limitFound = true; break; } addr += (linesReq + ExtraDownLines - alines.Length) * AddrPerLine; lastCount = alines.Length; } while (alines.Length < linesReq + ExtraDownLines); int max = limitFound ? alines.Length : alines.Length - ExtraDownLines; // Fill the lines for (int n=0; n < max; n++) lines.Add (alines [n]); lastAddr = lines [lines.Count - 1].Address; for (int n=0; n < (linesReq - max); n++) { AssemblyLine line = new AssemblyLine (++lastAddr, ""); lines.Add (line); } }
public override AssemblyLine[] GetLines (long startAddr, long endAddr) { try { ResultData data = session.RunCommand ("-data-disassemble", "-s", startAddr.ToString (), "-e", endAddr.ToString (), "--", "0"); ResultData ins = data.GetObject ("asm_insns"); AssemblyLine[] alines = new AssemblyLine [ins.Count]; for (int n=0; n<ins.Count; n++) { ResultData aline = ins.GetObject (n); long addr = long.Parse (aline.GetValue ("address").Substring (2), NumberStyles.HexNumber); AssemblyLine line = new AssemblyLine (addr, aline.GetValue ("inst")); alines [n] = line; } return alines; } catch { return new AssemblyLine [0]; } }
void InsertAssemblerLine (StringBuilder sb, int line, AssemblyLine asm) { sb.AppendFormat ("0x{0:x} {1}\n", asm.Address, asm.Code); addressLines [asm.Address] = line; }