public DisassemblyFormatter(Program program, MachineInstruction instr, List<TextSpan> line) { this.program = program; this.instr = instr; this.line = line; this.Platform = program.Platform; }
private string BuildBytes(MachineInstruction instr) { var sb = new StringBuilder(); var rdr = program.CreateImageReader(instr.Address); for (int i = 0; i < instr.Length; ++i) { sb.AppendFormat("{0:X2} ", rdr.ReadByte()); } return sb.ToString(); }
public bool DumpAssemblerLine(LoadedImage image, MachineInstruction instr, TextWriter writer) { Address addrBegin = instr.Address; if (ShowAddresses) writer.Write("{0} ", addrBegin); if (ShowCodeBytes) { StringWriter sw = new StringWriter(); WriteByteRange(image, instr.Address, instr.Address + instr.Length, sw); writer.WriteLine("{0,-16}\t{1}", sw.ToString(), instr); } else { writer.WriteLine("\t{0}", instr.ToString()); } return true; }
//$PERF: could benefit from a binary search, but basic blocks // are so small it may not make a difference. public static int FindIndexOfInstructionAddress(MachineInstruction[] instrs, Address addr) { return Array.FindIndex( instrs, i => i.Contains(addr)); }
public AsmSpanifyer(Program program, MachineInstruction[] instrs, Address addr) { this.instrs = instrs; this.offset = FindIndexOfInstructionAddress(instrs, addr); this.program = program; }
public void Mcdm_FindInstructionIndex() { var instrs = new MachineInstruction[] { new FakeInstruction(Operation.Add) { Address = Address.Ptr32(0x1000), Length = 2 }, new FakeInstruction(Operation.Add) { Address = Address.Ptr32(0x1002), Length = 2 }, }; Func<uint, int> Idx = u => MixedCodeDataModel.FindIndexOfInstructionAddress( instrs, Address.Ptr32(u)); Assert.AreEqual(-1, Idx(0x0FFF)); Assert.AreEqual(0, Idx(0x1000)); Assert.AreEqual(0, Idx(0x1001)); Assert.AreEqual(1, Idx(0x1002)); Assert.AreEqual(1, Idx(0x1003)); Assert.AreEqual(-1, Idx(0x1004)); }
/// <summary> /// Find the constant destination of a transfer instruction. /// </summary> /// <param name="i"></param> /// <returns></returns> private Address DestinationAddress(MachineInstruction i) { var op = i.GetOperand(0) as AddressOperand; if (op == null) { // Z80 has JP Z,<dest> instructions... op = i.GetOperand(1) as AddressOperand; } if (op != null) { return op.Address; } return null; }
/// <summary> /// Returns true if this function might continue to the next instruction. /// </summary> /// <param name="i"></param> /// <returns></returns> private bool MayFallThrough(MachineInstruction i) { return (i.InstructionClass & (InstructionClass.Linear | InstructionClass.Conditional | InstructionClass.Call)) != 0; //$REVIEW: what if you call a terminating function? }
private bool IsInvalid(MemoryArea mem, MachineInstruction instr) { if (instr.InstructionClass == InstructionClass.Invalid) return true; // If an instruction straddles a relocation, it can't be // a real instruction. if (mem.Relocations.Overlaps(instr.Address, (uint)instr.Length)) return true; return false; }
public static LineSpan RenderAsmLine(Program program, MachineInstruction instr) { var line = new List<TextSpan>(); var addr = instr.Address; line.Add(new AddressSpan(addr.ToString() + " ", addr, "link")); line.Add(new InstructionTextSpan(instr, BuildBytes(program, instr), "dasm-bytes")); var dfmt = new DisassemblyFormatter(program, instr, line); instr.Render(dfmt); dfmt.NewLine(); return new LineSpan(addr, line.ToArray()); }
public InstructionTextSpan(MachineInstruction instr, string text, string style) { this.Tag = instr; this.text = text; this.Style = style; }
public IJumpTableDialog CreateJumpTableDialog(Program program, MachineInstruction instrIndirectJmp, Address addrVector, int stride) { return new JumpTableDialog() { Services = this.services, Program = program, Instruction = instrIndirectJmp, VectorAddress = addrVector, Stride = stride }; }
/// <summary> /// Implementation of IComparer.Compare. In reality, /// </summary> /// <param name="oInstrA"></param> /// <param name="oInstrB"></param> /// <returns></returns> public override bool CompareOperands(MachineInstruction a, MachineInstruction b) { var instrA = (X86Instruction)a; var instrB = (X86Instruction)b; if (instrA.code != instrB.code) return false; if (instrA.Operands != instrB.Operands) return false; bool retval = true; if (instrA.Operands > 0) { retval = CompareOperands(instrA.op1, instrB.op1); if (retval && instrA.Operands > 1) { retval = CompareOperands(instrA.op2, instrB.op2); if (retval && instrA.Operands > 2) { retval = CompareOperands(instrA.op3, instrB.op3); } } } return retval; }
public override int GetOperandsHash(MachineInstruction inst) { var instr = (X86Instruction)inst; int hash = instr.Operands.GetHashCode(); if (instr.Operands > 0) { hash = hash * 23 + GetHashCode(instr.op1); if (instr.Operands > 1) { hash = hash * 17 + GetHashCode(instr.op2); if (instr.Operands > 2) { hash = hash * 13 + GetHashCode(instr.op3); } } } return hash; }
public bool DumpAssemblerLine(MemoryArea mem, MachineInstruction instr, InstrWriter writer) { Address addrBegin = instr.Address; if (ShowAddresses) writer.Write("{0} ", addrBegin); if (ShowCodeBytes) { WriteByteRange(mem, instr.Address, instr.Address + instr.Length, writer); if (instr.Length * 3 < 16) { writer.Write(new string(' ', 16 - (instr.Length * 3))); } } writer.Write("\t"); instr.Render(writer); writer.WriteLine(); return true; }