Beispiel #1
0
 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;
 }
Beispiel #2
0
        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);
            }
Beispiel #3
0
 private void Predicate(ArmCodeCondition cond, RtlInstruction instr)
 {
     if (cond == ArmCodeCondition.AL)
     {
         emitter.Emit(instr);
     }
     else
     {
         emitter.If(TestCond(cond), instr);
     }
 }
Beispiel #4
0
        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)));
            }
        }
Beispiel #5
0
 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);
     }
 }
Beispiel #6
0
        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);
        }
Beispiel #7
0
        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);
            }
        }
Beispiel #8
0
        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);
            }
        }