public ThumbRewriter(ThumbProcessorArchitecture arch, EndianImageReader rdr, ArmProcessorState state, Frame frame, IRewriterHost host) { this.instrs = CreateInstructionStream(rdr); this.frame = frame; this.host = host; this.itState = 0; this.itStateCondition = ArmCodeCondition.AL; }
private void Predicate(ArmCodeCondition cond, Expression dst, Expression src) { RtlInstruction instr; if (dst is Identifier id && id.Storage == A32Registers.pc) { rtlc = RtlClass.Transfer; instr = new RtlGoto(src, RtlClass.Transfer); }
private void Predicate(ArmCodeCondition cond, RtlInstruction instr) { if (cond == ArmCodeCondition.AL) { emitter.Emit(instr); } else { emitter.If(TestCond(cond), instr); } }
private TestCondition TestCond(ArmCodeCondition cond) { switch (cond) { default: throw new NotImplementedException(string.Format("ARM condition code {0} not implemented.", cond)); case ArmCodeCondition.HS: return(new TestCondition(ConditionCode.UGE, FlagGroup(FlagM.CF, "C", PrimitiveType.Byte))); case ArmCodeCondition.LO: return(new TestCondition(ConditionCode.ULT, FlagGroup(FlagM.CF, "C", PrimitiveType.Byte))); case ArmCodeCondition.EQ: return(new TestCondition(ConditionCode.EQ, FlagGroup(FlagM.ZF, "Z", PrimitiveType.Byte))); case ArmCodeCondition.GE: return(new TestCondition(ConditionCode.GE, FlagGroup(FlagM.NF | FlagM.ZF | FlagM.VF, "NZV", PrimitiveType.Byte))); case ArmCodeCondition.GT: return(new TestCondition(ConditionCode.GT, FlagGroup(FlagM.NF | FlagM.ZF | FlagM.VF, "NZV", PrimitiveType.Byte))); case ArmCodeCondition.HI: return(new TestCondition(ConditionCode.UGT, FlagGroup(FlagM.ZF | FlagM.CF, "ZC", PrimitiveType.Byte))); case ArmCodeCondition.LE: return(new TestCondition(ConditionCode.LE, FlagGroup(FlagM.ZF | FlagM.CF | FlagM.VF, "NZV", PrimitiveType.Byte))); case ArmCodeCondition.LS: return(new TestCondition(ConditionCode.ULE, FlagGroup(FlagM.ZF | FlagM.CF, "ZC", PrimitiveType.Byte))); case ArmCodeCondition.LT: return(new TestCondition(ConditionCode.LT, FlagGroup(FlagM.NF | FlagM.VF, "NV", PrimitiveType.Byte))); case ArmCodeCondition.MI: return(new TestCondition(ConditionCode.LT, FlagGroup(FlagM.NF, "N", PrimitiveType.Byte))); case ArmCodeCondition.PL: return(new TestCondition(ConditionCode.GT, FlagGroup(FlagM.NF | FlagM.ZF, "NZ", PrimitiveType.Byte))); case ArmCodeCondition.NE: return(new TestCondition(ConditionCode.NE, FlagGroup(FlagM.ZF, "Z", PrimitiveType.Byte))); case ArmCodeCondition.VC: return(new TestCondition(ConditionCode.NO, FlagGroup(FlagM.VF, "V", PrimitiveType.Byte))); case ArmCodeCondition.VS: return(new TestCondition(ConditionCode.OV, FlagGroup(FlagM.VF, "V", PrimitiveType.Byte))); } }
private void Predicate(ArmCodeCondition cond, RtlInstruction instr) { if (cond == ArmCodeCondition.AL) { m.Emit(instr); } else { m.BranchInMiddleOfInstruction( TestCond(cond).Invert(), Address.Ptr32((uint)(this.instr.Address + this.instr.Bytes.Length)), RtlClass.ConditionalTransfer); m.Emit(instr); } }
private void Predicate(ArmCodeCondition cond, Expression dst, Expression src) { RtlInstruction instr; Identifier id; if (dst.As <Identifier>(out id) && id.Storage == A32Registers.pc) { rtlc = RtlClass.Transfer; instr = new RtlGoto(src, RtlClass.Transfer); } else { instr = new RtlAssignment(dst, src); } Predicate(cond, instr); }
private void Predicate(ArmCodeCondition cond, Expression dst, Expression src) { RtlInstruction instr; Identifier id; if (dst.As <Identifier>(out id) && id.Storage == A32Registers.pc) { ric.Class = RtlClass.Transfer; instr = new RtlGoto(src, RtlClass.Transfer); } else { instr = new RtlAssignment(dst, src); } if (cond == ArmCodeCondition.AL) { emitter.Emit(instr); } else { emitter.If(TestCond(cond), instr); } }
public IEnumerator <RtlInstructionCluster> GetEnumerator() { while (instrs.MoveNext()) { if (!instrs.Current.TryGetInternal(out this.instr)) { continue; throw new AddressCorrelatedException( instrs.Current.Address, "Invalid opcode cannot be rewritten to IR."); } this.ops = instr.ArchitectureDetail.Operands; this.ric = new RtlInstructionCluster(instrs.Current.Address, instr.Bytes.Length); this.ric.Class = RtlClass.Linear; this.emitter = new RtlEmitter(ric.Instructions); switch (instr.Id) { default: throw new AddressCorrelatedException( instrs.Current.Address, "Rewriting ARM Thumb opcode '{0}' ({1}) is not supported yet.", instr.Mnemonic, instr.Id); case ArmInstruction.ADD: RewriteBinop((a, b) => emitter.IAdd(a, b)); break; case ArmInstruction.ADDW: RewriteAddw(); break; case ArmInstruction.ADR: RewriteAdr(); break; case ArmInstruction.AND: RewriteAnd(); break; case ArmInstruction.ASR: RewriteShift(emitter.Sar); break; case ArmInstruction.B: RewriteB(); break; case ArmInstruction.BIC: RewriteBic(); break; case ArmInstruction.BL: RewriteBl(); break; case ArmInstruction.BLX: RewriteBlx(); break; case ArmInstruction.BX: RewriteBx(); break; case ArmInstruction.CBZ: RewriteCbnz(emitter.Eq0); break; case ArmInstruction.CBNZ: RewriteCbnz(emitter.Ne0); break; case ArmInstruction.CMP: RewriteCmp(); break; case ArmInstruction.DMB: RewriteDmb(); break; case ArmInstruction.EOR: RewriteEor(); break; case ArmInstruction.IT: RewriteIt(); continue; // Don't emit anything yet.; case ArmInstruction.LDR: RewriteLdr(PrimitiveType.Word32, PrimitiveType.Word32); break; case ArmInstruction.LDRB: RewriteLdr(PrimitiveType.UInt32, PrimitiveType.Byte); break; case ArmInstruction.LDRSB: RewriteLdr(PrimitiveType.Int32, PrimitiveType.SByte); break; case ArmInstruction.LDREX: RewriteLdrex(); break; case ArmInstruction.LDRH: RewriteLdr(PrimitiveType.UInt32, PrimitiveType.Word16); break; case ArmInstruction.LSL: RewriteShift(emitter.Shl); break; case ArmInstruction.LSR: RewriteShift(emitter.Shr); break; case ArmInstruction.MOV: RewriteMov(); break; case ArmInstruction.MOVT: RewriteMovt(); break; case ArmInstruction.MOVW: RewriteMovw(); break; case ArmInstruction.MRC: RewriteMrc(); break; case ArmInstruction.MVN: RewriteMvn(); break; case ArmInstruction.POP: RewritePop(); break; case ArmInstruction.PUSH: RewritePush(); break; case ArmInstruction.RSB: RewriteRsb(); break; case ArmInstruction.STM: RewriteStm(); break; case ArmInstruction.STR: RewriteStr(PrimitiveType.Word32); break; case ArmInstruction.STRH: RewriteStr(PrimitiveType.Word16); break; case ArmInstruction.STRB: RewriteStr(PrimitiveType.Byte); break; case ArmInstruction.STREX: RewriteStrex(); break; case ArmInstruction.SUB: RewriteBinop((a, b) => emitter.ISub(a, b)); break; case ArmInstruction.SUBW: RewriteSubw(); break; case ArmInstruction.TRAP: RewriteTrap(); break; case ArmInstruction.TST: RewriteTst(); break; case ArmInstruction.UDF: RewriteUdf(); break; case ArmInstruction.UXTH: RewriteUxth(); break; } itState = (itState << 1) & 0x0F; if (itState == 0) { itStateCondition = ArmCodeCondition.AL; } yield return(ric); } }