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);
			}
		}
Example #6
0
		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;
		}