private Expression RewriteSrc(MachineOperand op) { var memOp = op as MemoryOperand; if (memOp != null) { var r = frame.EnsureRegister(memOp.Register); var tmp = frame.CreateTemporary(op.Width); switch (memOp.Mode) { default: throw new NotImplementedException(string.Format("Not implemented: addressing mode {0}.", memOp.Mode)); case AddressMode.RegDef: return(emitter.Load(this.instrs.Current.DataWidth, r)); case AddressMode.AutoIncr: emitter.Assign(tmp, emitter.Load(op.Width, r)); emitter.Assign(r, emitter.IAdd(r, memOp.Width.Size)); break; } return(tmp); } var regOp = op as RegisterOperand; if (regOp != null) { return(frame.EnsureRegister(regOp.Register)); } throw new NotImplementedException(); }
private Expression RewriteSrc(MachineOperand op) { var reg = op as RegisterOperand; if (reg != null) { return(binder.EnsureRegister(reg.Register)); } var addr = op as AddressOperand; if (addr != null) { return(addr.Address); } var imm = op as ImmediateOperand; if (imm != null) { return(imm.Value); } var mem = op as MemoryOperand; if (mem != null) { Expression ea = RewriteSrcEa(mem); var tmp = binder.CreateTemporary(mem.Width); m.Assign(tmp, m.Load(mem.Width, ea)); return(tmp); } throw new NotImplementedException(op.GetType().Name); }
private Expression Operand(ArmInstructionOperand op) { switch (op.Type) { case ArmInstructionOperandType.Register: var reg = frame.EnsureRegister(A32Registers.RegisterByCapstoneID[op.RegisterValue.Value]); return(MaybeShiftOperand(reg, op)); case ArmInstructionOperandType.SysRegister: var sysreg = frame.EnsureRegister(A32Registers.SysRegisterByCapstoneID[op.SysRegisterValue.Value]); return(sysreg); case ArmInstructionOperandType.Immediate: return(Constant.Word32(op.ImmediateValue.Value)); case ArmInstructionOperandType.CImmediate: case ArmInstructionOperandType.PImmediate: return(Constant.Byte((byte)op.ImmediateValue.Value)); case ArmInstructionOperandType.Memory: Expression baseReg = Reg(op.MemoryValue.BaseRegister); Expression ea = baseReg; if (op.MemoryValue.BaseRegister == ArmRegister.PC) // PC-relative address { var dst = (uint)((int)instrs.Current.Address.ToUInt32() + op.MemoryValue.Displacement) + 8u; ea = Address.Ptr32(dst); if (op.MemoryValue.IndexRegister != ArmRegister.Invalid) { var ireg = Reg(op.MemoryValue.IndexRegister); if (op.Shifter.Type == ArmShifterType.LSL) { ea = m.IAdd(ea, m.IMul(ireg, 1 << op.Shifter.Value)); } else { throw new NotImplementedException(); } } return(m.Load(SizeFromLoadStore(instr), ea)); } if (op.MemoryValue.Displacement != 0 && instrs.Current.IsLastOperand(op)) { var offset = Constant.Int32(op.MemoryValue.Displacement); ea = op.MemoryValue.IndexRegisterScale < 0 ? m.ISub(ea, offset) : m.IAdd(ea, offset); } if (instrs.Current.IsLastOperand(op) && instr.ArchitectureDetail.WriteBack) { m.Assign(baseReg, ea); ea = baseReg; } return(m.Load(SizeFromLoadStore(instr), ea)); case ArmInstructionOperandType.FloatingPoint: return(Constant.Real64(op.FloatingPointValue.Value)); } throw new NotImplementedException(op.Type.ToString()); }
private Expression RewriteOperand(Operand op) { Constant offset; switch (op.Mode) { default: throw new NotImplementedException("Unimplemented address mode " + op.Mode); case AddressMode.Accumulator: return(frame.EnsureRegister(Registers.a)); case AddressMode.Immediate: return(op.Offset); case AddressMode.IndirectIndexed: var y = frame.EnsureRegister(Registers.y); offset = Constant.Word16((ushort)op.Offset.ToByte()); return(emitter.LoadB( emitter.IAdd( emitter.Load(PrimitiveType.Ptr16, offset), emitter.Cast(PrimitiveType.UInt16, y)))); case AddressMode.IndexedIndirect: var x = frame.EnsureRegister(Registers.x); offset = Constant.Word16((ushort)op.Offset.ToByte()); return(emitter.LoadB( emitter.Load( PrimitiveType.Ptr16, emitter.IAdd( offset, emitter.Cast(PrimitiveType.UInt16, x))))); case AddressMode.Absolute: return(emitter.LoadB(op.Offset)); case AddressMode.AbsoluteX: return(emitter.LoadB(emitter.IAdd(op.Offset, frame.EnsureRegister(Registers.x)))); case AddressMode.ZeroPage: if (op.Register != null) { return(emitter.LoadB( emitter.IAdd( Constant.Create(PrimitiveType.Ptr16, op.Offset.ToUInt16()), frame.EnsureRegister(op.Register)))); } else { return(emitter.LoadB( Constant.Create(PrimitiveType.Ptr16, op.Offset.ToUInt16()))); } } }
private Expression RewriteSrc(MachineOperand op) { var reg = op as RegisterOperand; if (reg != null) { return(binder.EnsureRegister(reg.Register)); } var addr = op as AddressOperand; if (addr != null) { return(addr.Address); } var imm = op as ImmediateOperand; if (imm != null) { return(imm.Value); } var mem = op as MemoryOperand; if (mem != null) { Expression ea; if (mem.Base != null) { ea = binder.EnsureRegister(mem.Base); if (mem.Index != null) { var idx = binder.EnsureRegister(mem.Index); ea = m.IAdd( ea, m.Cast(PrimitiveType.Int16, idx)); } else if (mem.Offset != null) { ea = m.IAdd( ea, m.Int16((sbyte)mem.Offset.ToByte())); } } else { ea = arch.MakeAddressFromConstant(mem.Offset); } var tmp = binder.CreateTemporary(mem.Width); m.Assign(tmp, m.Load(mem.Width, ea)); return(tmp); } throw new NotImplementedException(op.GetType().Name); }
private Expression RewriteOp(ArmInstructionOperand op, DataType accessSize = null) { switch (op.Type) { case ArmInstructionOperandType.Register: return(GetReg(op.RegisterValue.Value)); case ArmInstructionOperandType.Immediate: if (accessSize != null) { return(Constant.Create(accessSize, op.ImmediateValue.Value)); } else { return(Constant.Int32(op.ImmediateValue.Value)); } case ArmInstructionOperandType.Memory: var mem = op.MemoryValue; var ea = EffectiveAddress(mem); return(emitter.Load(accessSize, ea)); default: throw new NotImplementedException(op.Type.ToString()); } }
private void RewriteMem(int iOp, Expression src, Action <Expression, Expression> write, Expression seg) { var op = instr.operands[iOp]; var mop = (MemoryOperand)op; var baseReg = frame.EnsureRegister(mop.Base); Expression ea = baseReg; if (mop.PreDecrement) { m.Assign(baseReg, m.ISub(baseReg, Constant.Int16(1))); } Expression val; if (seg != null) { val = m.SegMem(mop.Width, seg, ea); } else { val = m.Load(mop.Width, ea); } write(val, src); if (mop.PostIncrement) { m.Assign(baseReg, m.IAdd(baseReg, Constant.Int16(1))); } }
private Expression Rewrite(MachineOperand op, bool highWord = false) { var rop = op as RegisterOperand; if (rop != null) { if (rop.Register.Number == 31) { return(Constant.Word64(0)); } else if (rop.Register.Number == 63) { return(Constant.Real64(0.0)); } else { return(this.binder.EnsureRegister(rop.Register)); } } var imm = op as ImmediateOperand; if (imm != null) { return(imm.Value); } var addr = op as AddressOperand; if (addr != null) { return(addr.Address); } var mop = op as MemoryOperand; if (mop != null) { int offset = highWord ? (int)mop.Offset << 16 : mop.Offset; Expression ea; if (mop.Base.Number == ZeroRegister) { var dt = PrimitiveType.Create(Domain.Integer, arch.PointerType.Size); ea = Constant.Create(dt, offset); //$TODO should be platform size. } else { ea = binder.EnsureRegister(mop.Base); if (offset > 0) { ea = m.IAdd(ea, offset); } else if (offset < 0) { ea = m.ISub(ea, -offset); } } return(m.Load(mop.Width, ea)); } throw new NotImplementedException(string.Format("{0} ({1})", op, op.GetType().Name)); }
private Expression RewriteOperand(MachineOperand op) { var regOp = op as RegisterOperand; if (regOp != null) { return(binder.EnsureRegister(regOp.Register)); } var immOp = op as ImmediateOperand; if (immOp != null) { return(immOp.Value); } var indOp = op as IndirectOperand; if (indOp != null) { Expression ea; Identifier baseReg = binder.EnsureRegister(indOp.Base); if (indOp.Offset == 0) { ea = baseReg; } else if (indOp.Offset > 0) { ea = m.IAdd(baseReg, indOp.Offset); } else { ea = m.ISub(baseReg, -indOp.Offset); } return(m.Load(indOp.Width, ea)); } var addrOp = op as AddressOperand; if (addrOp != null) { return(addrOp.Address); } throw new NotImplementedException(string.Format("Rewriting of operand type {0} not implemented yet.", op.GetType().Name)); }
private Expression Operand(ArmInstructionOperand op) { switch (op.Type) { case ArmInstructionOperandType.Register: var reg = frame.EnsureRegister(A32Registers.RegisterByCapstoneID[op.RegisterValue.Value]); return(MaybeShiftOperand(reg, op)); case ArmInstructionOperandType.Immediate: return(Constant.Word32(op.ImmediateValue.Value)); case ArmInstructionOperandType.Memory: Expression baseReg = Reg(op.MemoryValue.BaseRegister); Expression ea = baseReg; if (op.MemoryValue.BaseRegister == ArmRegister.PC) // PC-relative address { if (op.MemoryValue.Displacement != 0) { var dst = (uint)((int)instrs.Current.Address.ToUInt32() + op.MemoryValue.Displacement) + 8u; return(emitter.Load(SizeFromLoadStore(instr), Address.Ptr32(dst))); } } if (op.MemoryValue.Displacement != 0 && instrs.Current.IsLastOperand(op)) { var offset = Constant.Int32(op.MemoryValue.Displacement); ea = op.MemoryValue.IndexRegisterScale < 0 ? emitter.ISub(ea, offset) : emitter.IAdd(ea, offset); } if (instrs.Current.IsLastOperand(op) && instr.ArchitectureDetail.WriteBack) { emitter.Assign(baseReg, ea); ea = baseReg; } return(emitter.Load(SizeFromLoadStore(instr), ea)); } throw new NotImplementedException(op.Type.ToString()); }
private Expression RewriteOp(MachineOperand op) { var rOp = op as RegisterOperand; if (rOp != null) { return(frame.EnsureRegister(rOp.Register)); } var immOp = op as ImmediateOperand; if (immOp != null) { return(immOp.Value); } var memOp = op as MemoryOperand; if (memOp != null) { Identifier bReg = null; if (memOp.Base != null) { bReg = frame.EnsureRegister(memOp.Base); } if (memOp.Offset == null) { return(emitter.Load(memOp.Width, bReg)); } else if (bReg == null) { return(emitter.Load(memOp.Width, memOp.Offset)); } else { int s = memOp.Offset.ToInt32(); if (s > 0) { return(emitter.Load(memOp.Width, emitter.IAdd(bReg, s))); } else if (s < 0) { return(emitter.Load(memOp.Width, emitter.ISub(bReg, -s))); } else { return(emitter.Load(memOp.Width, bReg)); } } } throw new NotImplementedException(string.Format("Rewriting of Z80 operand type {0} is not implemented yet.", op.GetType().FullName)); }
private Expression RewriteSrc(MachineOperand op) { var memOp = op as MemoryOperand; if (memOp != null) { var r = frame.EnsureRegister(memOp.Register); var tmp = frame.CreateTemporary(op.Width); if (memOp.Mode == AddressMode.AutoIncr) { emitter.Assign(tmp, emitter.Load(op.Width, r)); emitter.Assign(r, emitter.IAdd(r, memOp.Width.Size)); return(tmp); } return(tmp); } var regOp = op as RegisterOperand; if (regOp != null) { return(frame.EnsureRegister(regOp.Register)); } throw new NotImplementedException(); }
private Expression RewriteJmpSrc(MachineOperand op) { var memOp = op as MemoryOperand; if (memOp == null) { throw new AddressCorrelatedException( instrs.Current.Address, "Invalid addressing mode for transfer functions.", memOp.Mode); } var r = frame.EnsureRegister(memOp.Register); var tmp = frame.CreateTemporary(op.Width); switch (memOp.Mode) { default: throw new AddressCorrelatedException( instrs.Current.Address, "Not implemented: addressing mode {0}.", memOp.Mode); case AddressMode.RegDef: return(r); case AddressMode.Absolute: return(Address.Ptr16(memOp.EffectiveAddress)); case AddressMode.AutoIncr: m.Assign(tmp, m.Load(op.Width, m.Load(PrimitiveType.Ptr16, r))); m.Assign(r, m.IAdd(r, memOp.Width.Size)); break; case AddressMode.AutoIncrDef: m.Assign(tmp, m.Load(op.Width, r)); m.Assign(r, m.IAdd(r, memOp.Width.Size)); break; case AddressMode.AutoDecr: m.Assign(r, m.ISub(r, memOp.Width.Size)); return(m.Load(op.Width, r)); case AddressMode.AutoDecrDef: m.Assign(r, m.ISub(r, memOp.Width.Size)); m.Assign(tmp, m.Load(op.Width, m.Load(PrimitiveType.Ptr16, r))); return(tmp); case AddressMode.Indexed: if (memOp.Register == Registers.pc) { var offset = (short)memOp.EffectiveAddress; var addrBase = (long)rtlCluster.Address.ToLinear(); var addr = Address.Ptr16((ushort)(2 + addrBase + offset)); return(addr); } else { return(m.Load( this.instrs.Current.DataWidth, m.IAdd(r, Constant.Word16(memOp.EffectiveAddress)))); } case AddressMode.IndexedDef: if (memOp.Register == Registers.pc) { var offset = (short)memOp.EffectiveAddress; var addrBase = (long)rtlCluster.Address.ToLinear() + rtlCluster.Length; var addr = Constant.Word16((ushort)(addrBase + offset)); return(m.Load( PrimitiveType.Word16, addr)); } else { return(m.Load( PrimitiveType.Ptr16, m.IAdd(r, Constant.Word16(memOp.EffectiveAddress)))); } } return(tmp); /* * var immOp = op as ImmediateOperand; * if (immOp != null) * { * return immOp.Value; * } * var addrOp = op as AddressOperand; * if (addrOp != null) * { * return addrOp.Address; * } * throw new NotImplementedException(); */ }
} // the data width of the current instruction being rewritten. /// <summary> /// Rewrite operands being used as sources. /// </summary> /// <param name="operand"></param> /// <param name="addrInstr">Address of the current instruction</param> /// <returns></returns> public Expression RewriteSrc(MachineOperand operand, Address addrInstr, bool addressAsAddress = false) { var reg = operand as RegisterOperand; if (reg != null) { Expression r = binder.EnsureRegister(reg.Register); if (DataWidth != null && DataWidth.Size != reg.Width.Size) { r = m.Cast(DataWidth, r); } return(r); } var imm = operand as M68kImmediateOperand; if (imm != null) { if (imm.Width.Domain == Domain.Real) { return(imm.Constant.CloneExpression()); } if (DataWidth != null && DataWidth.BitSize > imm.Width.BitSize) { return(Constant.Create(DataWidth, imm.Constant.ToInt64())); } else { return(Constant.Create(imm.Width, imm.Constant.ToUInt32())); } } var mem = operand as MemoryOperand; if (mem != null) { return(RewriteMemoryAccess(mem, DataWidth, addrInstr)); } var addr = operand as M68kAddressOperand; if (addr != null) { if (addressAsAddress) { return(addr.Address); } else { return(m.Load(DataWidth, addr.Address)); } } var pre = operand as PredecrementMemoryOperand; if (pre != null) { var ea = binder.EnsureRegister(pre.Register); m.Assign(ea, m.ISub(ea, m.Int32(DataWidth.Size))); return(m.Load(DataWidth, ea)); } var post = operand as PostIncrementMemoryOperand; if (post != null) { var r = binder.EnsureRegister(post.Register); var tmp = binder.CreateTemporary(DataWidth); m.Assign(tmp, m.Load(DataWidth, r)); m.Assign(r, m.IAdd(r, m.Int32(DataWidth.Size))); return(tmp); } var indidx = operand as IndirectIndexedOperand; if (indidx != null) { Expression ea = RewriteIndirectBaseRegister(indidx, addrInstr); Expression ix = binder.EnsureRegister(indidx.XRegister); if (indidx.XWidth.Size != 4) { ix = m.Cast(PrimitiveType.Int32, m.Cast(PrimitiveType.Int16, ix)); } if (indidx.Scale > 1) { ix = m.IMul(ix, Constant.Int32(indidx.Scale)); } return(m.Load(DataWidth, m.IAdd(ea, ix))); } var indop = operand as IndexedOperand; if (indop != null) { Expression ea = Combine(indop.Base, indop.base_reg); if (indop.postindex) { ea = m.LoadDw(ea); } if (indop.index_reg != null) { var idx = Combine(null, indop.index_reg); if (indop.index_scale > 1) { idx = m.IMul(idx, indop.index_scale); } ea = Combine(ea, idx); } if (indop.preindex) { ea = m.LoadDw(ea); } ea = Combine(ea, indop.outer); return(m.Load(DataWidth, ea)); } throw new NotImplementedException("Unimplemented RewriteSrc for operand type " + operand.GetType().Name); }
private Expression Operand(MachineOperand op) { var rop = op as RegisterOperand; if (rop != null) { return(frame.EnsureRegister(rop.Register)); } var immOp = op as ImmediateOperand; if (immOp != null) { return(immOp.Value); } var shOp = op as ShiftOperand; if (shOp != null) { var r = Operand(shOp.Operand); var sh = Operand(shOp.Shift); switch (shOp.Opcode) { case Opcode.lsl: return(emitter.Shl(r, sh)); case Opcode.lsr: return(emitter.Shr(r, sh)); case Opcode.asr: return(emitter.Sar(r, sh)); case Opcode.ror: return(host.PseudoProcedure(PseudoProcedure.Ror, PrimitiveType.Word32, r, sh)); default: throw new NotSupportedException(string.Format("Unsupported shift operation {0}.", shOp.Opcode)); } } var memOp = op as ArmMemoryOperand; if (memOp != null) { Expression baseReg = frame.EnsureRegister(memOp.Base); Expression ea = baseReg; if (memOp.Base.Number == 0x0F) // PC-relative address { var imm = memOp.Offset as ArmImmediateOperand; if (imm != null) { if (memOp.Writeback) { throw new NotImplementedException(); } var dst = (uint)((int)instr.Address.ToUInt32() + imm.Value.ToInt32()) + 8u; return(emitter.Load(memOp.Width, Address.Ptr32(dst))); } } if (memOp.Offset != null && memOp.Preindexed) { var offset = Operand(memOp.Offset); ea = memOp.Subtract ? emitter.ISub(ea, offset) : emitter.IAdd(ea, offset); } if (memOp.Preindexed && memOp.Writeback) { emitter.Assign(baseReg, ea); ea = baseReg; } return(emitter.Load(memOp.Width, ea)); } throw new NotSupportedException(string.Format("Unsupported operand {0}.", op)); }
private Expression RewriteSrcOp(int iOp, PrimitiveType width) { var op = dasm.Current.Operands[iOp]; var regOp = op as RegisterOperand; if (regOp != null) { var reg = frame.EnsureRegister(regOp.Register); if (width.Size == 4) { return(reg); } else if (width.Size == 8) { var regHi = frame.EnsureRegister(arch.GetRegister(1 + (int)reg.Storage.Domain)); return(frame.EnsureSequence(regHi.Storage, reg.Storage, width)); } else if (width.Size == 16) { var regHi1 = frame.EnsureRegister(arch.GetRegister(1 + (int)reg.Storage.Domain)); var regHi2 = frame.EnsureRegister(arch.GetRegister(2 + (int)reg.Storage.Domain)); var regHi3 = frame.EnsureRegister(arch.GetRegister(3 + (int)reg.Storage.Domain)); var regLo = frame.EnsureSequence(regHi1.Storage, reg.Storage, PrimitiveType.Word64); var regHi = frame.EnsureSequence(regHi3.Storage, regHi2.Storage, PrimitiveType.Word64); return(frame.EnsureSequence(regHi.Storage, regLo.Storage, width)); } else { return(emitter.Cast(width, reg)); } } var immOp = op as ImmediateOperand; if (immOp != null) { return(immOp.Value); } var memOp = op as MemoryOperand; if (memOp != null) { Expression ea; if (memOp.Base != null) { var reg = frame.EnsureRegister(memOp.Base); if (memOp.AutoDecrement) { emitter.Assign(reg, emitter.ISub(reg, width.Size)); } else if (memOp.AutoIncrement) { var tmp = frame.CreateTemporary(reg.DataType); emitter.Assign(tmp, reg); reg = tmp; } ea = reg; if (memOp.Offset != null) { ea = emitter.IAdd(ea, memOp.Offset); } if (memOp.Index != null) { Expression idx = frame.EnsureRegister(memOp.Index); if (width.Size != 1) { idx = emitter.IMul(idx, Constant.Int32(width.Size)); } ea = emitter.IAdd(ea, idx); } Expression load; if (memOp.Deferred) { load = emitter.Load(width, emitter.LoadDw(ea)); } else { load = emitter.Load(width, ea); } if (memOp.AutoIncrement) { if (memOp.AutoIncrement) { reg = frame.EnsureRegister(memOp.Base); int inc = (memOp.Deferred) ? 4 : width.Size; emitter.Assign(reg, emitter.IAdd(reg, inc)); } } return(load); } else { } } var addrOp = op as AddressOperand; if (addrOp != null) { return(addrOp.Address); } throw new NotImplementedException(op.GetType().Name); }
private Expression SrcOp(MachineOperand op, Func <int, int> immediateFn = null) { var regOp = op as RegisterOperand; if (regOp != null) { var id = binder.EnsureRegister(regOp.Register); return(id); } var immOp = op as ImmediateOperand; if (immOp != null) { return(Constant.Word32(immediateFn(immOp.Value.ToInt32()))); } var addrOp = op as AddressOperand; if (addrOp != null) { return(addrOp.Address); } var mem = op as MemoryOperand; if (mem != null) { Identifier reg; switch (mem.mode) { default: throw new NotImplementedException(mem.mode.ToString()); case AddressingMode.Indirect: return(m.Load(mem.Width, binder.EnsureRegister(mem.reg))); case AddressingMode.IndirectPreDecr: reg = binder.EnsureRegister(mem.reg); m.Assign(reg, m.IAdd(reg, Constant.Int32(mem.Width.Size))); return(m.Load(mem.Width, reg)); case AddressingMode.IndirectPostIncr: var t = binder.CreateTemporary(mem.Width); reg = binder.EnsureRegister(mem.reg); m.Assign(t, m.Load(mem.Width, reg)); m.Assign(reg, m.IAdd(reg, Constant.Int32(t.DataType.Size))); return(t); case AddressingMode.IndirectDisplacement: reg = binder.EnsureRegister(mem.reg); return(m.Load( mem.Width, m.IAdd(reg, Constant.Int32(mem.disp)))); case AddressingMode.IndexedIndirect: return(m.Load(mem.Width, m.IAdd( binder.EnsureRegister(Registers.r0), binder.EnsureRegister(mem.reg)))); case AddressingMode.PcRelativeDisplacement: var addr = instr.Address.ToUInt32(); if (mem.Width.Size == 4) { addr &= ~3u; } addr += (uint)(mem.disp + 4); return(m.Load(mem.Width, Address.Ptr32(addr))); } } throw new NotImplementedException(op.GetType().Name); }