protected ArrayAccess PushToHWStackAccess() { var stkptr = binder.EnsureRegister(arch.StackRegister); var slot = m.ARef(PrimitiveType.Ptr32, PICRegisters.GlobalStack, stkptr); m.Assign(stkptr, m.IAdd(stkptr, Constant.Byte(1))); return(slot); }
private void RewriteLoad() { var ea = Op(1); if (instrCur.Operands.Length == 3) { ea = m.IAdd(ea, Op(2)); } var dst = Op(0); m.Assign(dst, m.Mem(dst.DataType, ea)); }
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.Mem(mem.Width, ea)); return(tmp); } throw new NotImplementedException(op.GetType().Name); }
private Expression RewriteSrc(MachineOperand op) { switch (op) { case RegisterOperand rop: return(binder.EnsureRegister(rop.Register)); case ImmediateOperand iop: return(iop.Value); case AddressOperand aop: return(aop.Address); case MemoryOperand mop: Expression ea; if (mop.Base != null) { ea = binder.EnsureRegister(mop.Base); if (mop.Offset != 0) { ea = m.IAddS(ea, mop.Offset); } } else { ea = m.Ptr32((uint)mop.Offset); } if (mop.Index != null) { var idx = binder.EnsureRegister(mop.Index); ea = m.IAdd(ea, idx); } return(m.Mem(op.Width, ea)); case BitOperand bit: var bitSrc = RewriteSrc(bit.Operand); return(host.Intrinsic( "__bit", false, PrimitiveType.Bool, bitSrc, Constant.Byte((byte)bit.BitPosition))); case FlagGroupOperand fop: return(binder.EnsureFlagGroup(fop.FlagGroup)); default: throw new NotImplementedException($"Rl87Rewriter: operand type {op.GetType().Name} not implemented yet."); } }
private void RewriteAdc() { var dst = RewriteOp(dasm.Current.Op1); var src = RewriteOp(dasm.Current.Op2); emitter.Assign(dst, emitter.IAdd(emitter.IAdd(dst, src), FlagGroup(FlagM.CF))); AssignCond(FlagM.CF | FlagM.ZF | FlagM.SF | FlagM.PF, dst); }
private Expression Mem(MemoryOperand mem) { Expression ea; if (mem.Base != null) { var baseReg = binder.EnsureRegister(mem.Base); ea = baseReg; if (mem.Predecrement) { m.Assign(baseReg, m.ISubS(baseReg, mem.Width.Size)); } if (mem.Offset != 0) { ea = m.IAdd(ea, mem.Offset); } if (mem.Postincrement) { m.Assign(baseReg, m.IAddS(baseReg, mem.Width.Size)); } } else { ea = Address.Ptr16((ushort)mem.Offset); } return(m.Mem(mem.Width, ea)); }
private Expression EffectiveAddress(MachineOperand operand, RtlEmitter emitter) { var mop = (MemoryOperand) operand; var reg = binder.EnsureRegister(mop.BaseRegister); var offset = mop.Offset; return emitter.IAdd(reg, offset); }
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 { if (op.MemoryValue.Displacement != 0) { var dst = (uint)((int)instrs.Current.Address.ToUInt32() + op.MemoryValue.Displacement) + 8u; return(m.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 ? 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)); } throw new NotImplementedException(op.Type.ToString()); }
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.Mem(mop.Width, ea)); } throw new NotImplementedException(string.Format("{0} ({1})", op, op.GetType().Name)); }
private void Inc() { var mem = RewriteOperand(instrCur.Operands[0]); var tmp = binder.CreateTemporary(PrimitiveType.Byte); var c = FlagGroupStorage(FlagM.NF | FlagM.ZF); m.Assign(tmp, m.IAdd(mem, 1)); m.Assign(RewriteOperand(instrCur.Operands[0]), tmp); m.Assign(c, m.Cond(tmp)); }
private Expression EffectiveAddress_r0(MachineOperand op1, MachineOperand op2) { var e1 = RewriteOperand(op1, true); var e2 = RewriteOperand(op2); if (e1.IsZero) return e2; else return m.IAdd(e1, e2); }
private void RewritePush() { var src = OpSrc(instr.Operand1); var sp = binder.EnsureRegister(Registers.SP); m.Assign(sp, m.IAdd(sp, 1)); m.Assign(m.Mem8(sp), src); }
private Expression EffectiveAddress(ArmInstructionMemoryOperandValue mem) { var baseReg = GetReg(mem.BaseRegister); var ea = baseReg; if (mem.Displacement > 0) { ea = emitter.IAdd(ea, Constant.Int32(mem.Displacement)); } else if (mem.Displacement < 0) { ea = emitter.ISub(ea, Constant.Int32(-mem.Displacement)); } else if (mem.IndexRegister != ArmRegister.Invalid) { ea = emitter.IAdd(ea, GetReg(mem.IndexRegister)); } return(ea); }
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.Mem(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 RewriteSrc(MachineOperand op) { switch (op) { case RegisterOperand reg: return(binder.EnsureRegister(reg.Register)); case AddressOperand addr: return(addr.Address); case ImmediateOperand imm: return(imm.Value); case MemoryOperand mem: 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.Convert(idx, idx.DataType, PrimitiveType.Int16)); } else if (mem.Offset != null) { ea = m.IAdd( ea, m.Int16((sbyte)mem.Offset.ToByte())); } } else { ea = arch.MakeAddressFromConstant(mem.Offset, false); } var tmp = binder.CreateTemporary(mem.Width); m.Assign(tmp, m.Mem(mem.Width, ea)); return(tmp); } throw new NotImplementedException(op.GetType().Name); }
private Expression RewriteOp(int iOp) { switch (instr.Operands[iOp]) { case RegisterOperand r: if (r.Register == arch.Registers.GpRegs[0]) { return(Constant.Zero(r.Register.DataType)); } else { return(binder.EnsureRegister(r.Register)); } case ImmediateOperand i: return(i.Value); case LeftImmediateOperand l: return(l.Value); case AddressOperand a: return(a.Address); case MemoryOperand mem: Identifier rb = binder.EnsureRegister(mem.Base); Expression ea = rb; if (mem.Index != null) { if (mem.Index != arch.Registers.GpRegs[0]) { var idx = binder.EnsureRegister(mem.Index); ea = m.IAdd(ea, idx); } } else if (mem.Offset != 0) { ea = m.IAddS(ea, mem.Offset); } if (instr.BaseReg == AddrRegMod.mb) { m.Assign(rb, ea); ea = rb; } else if (instr.BaseReg == AddrRegMod.ma) { var tmp = binder.CreateTemporary(rb.DataType); m.Assign(tmp, ea); m.Assign(rb, tmp); ea = tmp; } return(m.Mem(mem.Width, ea)); } throw new NotImplementedException($"Unimplemented PA-RISC operand type {instr.Operands[iOp].GetType()}."); }
private void RewritePush() { var src = OpSrc(instr.Operands[0], arch.DataMemory); var sp = binder.EnsureRegister(Registers.SP); m.Assign(sp, m.IAdd(sp, 1)); var dataMemory = binder.EnsureRegister(arch.DataMemory); m.Assign(m.SegMem8(dataMemory, sp), src); }
private Expression EffectiveAddress(MemoryOperand mem) { if (mem.Base == null || mem.Base.Number == 0) { // Must be abs address. return(Address.Create(arch.PointerType, (uint)mem.Offset)); } Expression ea = binder.EnsureRegister(mem.Base); if (mem.Index != null && mem.Index.Number > 0) { var idx = binder.EnsureRegister(mem.Index); ea = m.IAdd(ea, idx); } if (mem.Offset != 0) { var off = Constant.Int(mem.Base.DataType, mem.Offset); ea = m.IAdd(ea, off); } return(ea); }
private Expression RewriteDecorator(DecoratorOperand dec) { var exp = OperandSrc(dec.Operand); if (dec.NewValue) { //$TODO; return(exp); } if (dec.Inverted) { exp = m.Not(exp); return(exp); } if (dec.Carry) { var app = (ApplicationOperand)dec.Operand; var p = binder.EnsureRegister(((RegisterOperand)app.Operands[2]).Register); exp = m.IAdd(exp, p); //$TODO: what about carry-out? it's in p. return(exp); } if (dec.Width.BitSize < (int)dec.Operand.Width.BitSize) { exp = m.Slice(dec.Width, exp, dec.BitOffset); return(exp); } throw new NotImplementedException(dec.ToString()); }
private void RewriteAdd(MipsInstruction instr, PrimitiveType size) { var opLeft = RewriteOperand(instr.op2); var opRight = RewriteOperand(instr.op3); Expression opSrc; if (opLeft.IsZero) { opSrc = opRight; } else if (opRight.IsZero) { opSrc = opLeft; } else { opSrc = emitter.IAdd(opLeft, opRight); } var opDst = RewriteOperand(instr.op1); emitter.Assign(opDst, opSrc); }
private void RewriteAdc() { var dst = RewriteOp(dasm.Current.Operands[0]); var src = RewriteOp(dasm.Current.Operands[1]); m.Assign(dst, m.IAdd(m.IAdd(dst, src), FlagGroup(FlagM.CF))); AssignCond(FlagM.CF | FlagM.ZF | FlagM.SF | FlagM.PF, dst); }
private Expression Operand(MachineOperand op) { switch (op) { case RegisterOperand rop: return(binder.EnsureRegister(rop.Register)); case ImmediateOperand imm: return(imm.Value); case MemoryOperand mem: Expression ea; if (mem.Address != null) { if (mem.Register != null) { ea = m.IAdd( mem.Address, m.Cast(PrimitiveType.UInt16, binder.EnsureRegister(mem.Register))); } else { ea = mem.Address; } } else { ea = RegisterPair(mem.Register); } return(m.Mem(mem.Width, ea)); case AddressOperand addr: return(addr.Address); default: throw new NotImplementedException(op.GetType().Name); } }
private Expression EffectiveAddress_r0(MachineOperand operand, RtlEmitter emitter) { var mop = (MemoryOperand) operand; if (mop.BaseRegister.Number == 0) { return Constant.Word32((int) mop.Offset.ToInt16()); } else { var reg = binder.EnsureRegister(mop.BaseRegister); var offset = mop.Offset; return emitter.IAdd(reg, offset); } }
/// <summary> /// Rewrites the effective address of a memory load. /// </summary> /// <param name="mem"></param> /// <returns></returns> private Expression RewriteSrcEa(MemoryOperand mem) { Expression ea; if (mem.Base != null) { if (mem.Increment < 0) { throw new NotImplementedException("predec"); } ea = binder.EnsureRegister(mem.Base); if (mem.Offset != null) { ea = m.IAdd(ea, mem.Offset); } } else { ea = arch.MakeAddressFromConstant(mem.Offset, false); } return(ea); }
public void AOS_LookupA6Call() { Given_Func("#1 512 0x200 Allocate( heap/a1, size/d0)\n"); When_Create_Platform(); m.Call(m.IAdd(binder.EnsureRegister(Registers.a6), -512), 4); var state = arch.CreateProcessorState(); var svc = platform.FindService(rtls.Last(), state); Assert.AreEqual("Allocate", svc.Name); Assert.AreEqual(2, svc.Signature.Parameters.Length); Assert.AreEqual("a1", svc.Signature.Parameters[0].Storage.ToString()); Assert.AreEqual("d0", svc.Signature.Parameters[1].Storage.ToString()); }
private Expression RewriteOp(MachineOperand op) { switch (op) { case RegisterOperand rop: return(binder.EnsureRegister(rop.Register)); case MemoryOperand mop: Expression ea = binder.EnsureRegister(mop.Base); if (mop.PostIncrement) { var tmp = binder.CreateTemporary(op.Width); m.Assign(tmp, m.Mem(op.Width, ea)); m.Assign(ea, m.IAdd(ea, m.Int16((short)op.Width.Size))); return(tmp); } else if (mop.Offset != 0) { var tmp = binder.CreateTemporary(op.Width); m.Assign(tmp, m.Mem(op.Width, m.IAdd(ea, m.Int16(mop.Offset)))); return(tmp); } else { var tmp = binder.CreateTemporary(op.Width); m.Assign(tmp, m.Mem(op.Width, ea)); return(tmp); } case ImmediateOperand iop: return(iop.Value); case AddressOperand aop: return(aop.Address); } throw new NotImplementedException(op.ToString()); }
private void RewriteAddc() { var dst = Reg(instrCur.Operands[0]); var src1 = Reg0(instrCur.Operands[1]); var src2 = Reg0(instrCur.Operands[2]); var c = binder.EnsureFlagGroup(arch.GetFlagGroup(Registers.sr, (uint)FlagM.CY)); m.Assign(dst, m.IAdd(m.IAdd(src1, src2), c)); CV(dst); }
private Expression SimplifySum(Expression srcLeft, Expression srcRight) { if (srcLeft == null && srcRight == null) { return(Constant.Zero(PrimitiveType.Ptr32)); } else if (srcLeft == null) { return(srcRight); } else if (srcRight == null) { return(srcLeft); } else { return(m.IAdd(srcLeft, srcRight)); } }
private MemoryAccess RewriteMemoryOperand(MemoryOperand memop) { if (memop.Base != null) { Expression baseReg; if (memop.Base == Registers.pc) { baseReg = instr.Address + instr.Length; } else { baseReg = binder.EnsureRegister(memop.Base); } Expression ea = baseReg; if (memop.Index != null) { Expression idx = binder.EnsureRegister(memop.Index); if (idx.DataType.BitSize < ea.DataType.BitSize) { idx = m.Cast(PrimitiveType.UInt16, idx); } ea = m.IAdd(baseReg, idx); } else if (memop.PreIncrement) { m.Assign(ea, m.IAddS(ea, memop.Offset.Value)); } else if (memop.PostIncrement) { var tmp = binder.CreateTemporary(baseReg.DataType); m.Assign(tmp, ea); m.Assign(baseReg, m.IAddS(baseReg, memop.Offset.Value)); ea = tmp; } else { ea = m.IAdd(baseReg, (ushort)memop.Offset.Value); } if (memop.Indirect) { ea = m.Mem(PrimitiveType.Ptr16, ea); } return(m.Mem(memop.Width, ea)); } else { Debug.Assert(memop.Offset != null); return(m.Mem(memop.Width, Address.Ptr16((ushort)memop.Offset.Value))); } }
public void MacOS_ResolveIndirectCall() { var macOS = new MacOSClassic(null, new M68kArchitecture("m68k")); var a5 = new Identifier(Registers.a5.Name, Registers.a5.DataType, Registers.a5); var a5world = new MemoryArea(Address.Ptr32(0x00100000), new byte[0x0300]); macOS.A5World = new ImageSegment("A5World", a5world, AccessMode.ReadWrite); macOS.A5Offset = 0x0100u; const int jumpTableOffset = 0x0032; const uint uAddrDirect = 0x00123400u; var w = new BeImageWriter(a5world, macOS.A5Offset + jumpTableOffset); w.WriteBeUInt16(0x4EF9); // jmp... (not really necessary for the test but hey....); w.WriteBeUInt32(uAddrDirect); var m = new RtlEmitter(null); var instr = new RtlCall(m.IAdd(a5, jumpTableOffset), 4, RtlClass.Call); var addr = macOS.ResolveIndirectCall(instr); Assert.AreEqual(uAddrDirect, addr.ToUInt32()); }