예제 #1
0
 public MethodIL Add(OpCodeInfo opCodeInfo)
 {
     ArgumentValidator.ValidateNotNull("Op code info", opCodeInfo);
     this._opCodes.Add(opCodeInfo);
     this._branchTargetsCount += opCodeInfo.BranchTargetCount;
     return(this);
 }
예제 #2
0
        public override string ToString()
        {
            var op   = GET_OPCODE();
            var a    = GETARG_A();
            var b    = GETARG_B();
            var c    = GETARG_C();
            var ax   = GETARG_Ax();
            var bx   = GETARG_Bx();
            var sbx  = GETARG_sBx();
            var mode = OpCodeInfo.GetMode(op);

            switch (mode.OpMode)
            {
            case OpMode.iABC: {
                string ret = string.Format("{0,-9} {1}"
                                           , op
                                           , a);
                if (mode.BMode != OpArgMask.OpArgN)
                {
                    ret += " " + (ISK(b) ? MYK(INDEXK(b)) : b);
                }
                if (mode.CMode != OpArgMask.OpArgN)
                {
                    ret += " " + (ISK(c) ? MYK(INDEXK(c)) : c);
                }
                return(ret);
            }

            case OpMode.iABx: {
                string ret = string.Format("{0,-9} {1}"
                                           , op
                                           , a);
                if (mode.BMode == OpArgMask.OpArgK)
                {
                    ret += " " + MYK(bx);
                }
                else if (mode.BMode == OpArgMask.OpArgU)
                {
                    ret += " " + bx;
                }
                return(ret);
            }

            case OpMode.iAsBx: {
                return(string.Format("{0,-9} {1} {2}"
                                     , op
                                     , a
                                     , sbx));
            }

            case OpMode.iAx: {
                return(string.Format("{0,-9} {1}"
                                     , op
                                     , MYK(ax)));
            }

            default:
                throw new System.NotImplementedException();
            }
        }
예제 #3
0
        static void AppendTable(OpCodeInfo info, StringBuilder sb)
        {
            switch (info.Table)
            {
            case OpCodeTableKind.Normal:
                break;

            case OpCodeTableKind.T0F:
                AppendOpCode(sb, 0x0F);
                break;

            case OpCodeTableKind.T0F38:
                AppendOpCode(sb, 0x0F38);
                break;

            case OpCodeTableKind.T0F3A:
                AppendOpCode(sb, 0x0F3A);
                break;

            case OpCodeTableKind.XOP8:
                sb.Append("X8");
                break;

            case OpCodeTableKind.XOP9:
                sb.Append("X9");
                break;

            case OpCodeTableKind.XOPA:
                sb.Append("XA");
                break;

            default:
                throw new InvalidOperationException();
            }
        }
예제 #4
0
        /// <summary>
        /// Do all registers of the given instruction fit in the size that is available for them?
        /// </summary>
        private static bool AllRegistersFit(Instruction ins)
        {
            var registers = ins.Registers;
            var count     = registers.Count;

            if (count == 0)
            {
                return(true);
            }
            var info = OpCodeInfo.Get(ins.OpCode);

            for (var i = 0; i < count; i++)
            {
                var size = info.GetUsage(i) & RegisterFlags.SizeMask;
                switch (size)
                {
                case RegisterFlags.Bits4:
                    if (!registers[i].IsBits4)
                    {
                        return(false);
                    }
                    break;

                case RegisterFlags.Bits8:
                    if (!registers[i].IsBits8)
                    {
                        return(false);
                    }
                    break;
                }
            }
            return(true);
        }
예제 #5
0
        static string ToString_VEX_XOP_EVEX(OpCodeInfo info, StringBuilder sb, bool l0l1, string encodingName)
        {
            sb.Length = 0;

            sb.Append(encodingName);
            sb.Append('.');
            if (info.IsLIG)
            {
                sb.Append("LIG");
            }
            else if (l0l1)
            {
                sb.Append('L');
                sb.Append(info.L);
            }
            else
            {
                sb.Append(128U << (int)info.L);
            }
            switch (info.MandatoryPrefix)
            {
            case MandatoryPrefix.None:
            case MandatoryPrefix.PNP:
                break;

            case MandatoryPrefix.P66:
                sb.Append('.');
                AppendHexByte(sb, 0x66);
                break;

            case MandatoryPrefix.PF3:
                sb.Append('.');
                AppendHexByte(sb, 0xF3);
                break;

            case MandatoryPrefix.PF2:
                sb.Append('.');
                AppendHexByte(sb, 0xF2);
                break;

            default:
                throw new InvalidOperationException();
            }
            sb.Append('.');
            AppendTable(info, sb);
            if (info.IsWIG)
            {
                sb.Append(".WIG");
            }
            else
            {
                sb.Append(".W");
                sb.Append(info.W);
            }
            sb.Append(' ');
            AppendOpCode(sb, info.OpCode);
            AppendRest(info, sb);

            return(sb.ToString());
        }
예제 #6
0
 public OpCodeFormatter(OpCodeInfo opCode, StringBuilder sb, LKind lkind, bool hasModrmInfo)
 {
     this.opCode       = opCode;
     this.sb           = sb;
     this.lkind        = lkind;
     this.hasModrmInfo = hasModrmInfo;
 }
예제 #7
0
 static string GetMode(StringBuilder sb, OpCodeInfo opCode)
 {
     sb.Clear();
     if ((opCode.Flags & OpCodeFlags.Mode16) != 0)
     {
         sb.Append("16");
     }
     if ((opCode.Flags & OpCodeFlags.Mode32) != 0)
     {
         if (sb.Length > 0)
         {
             sb.Append('/');
         }
         sb.Append("32");
     }
     if ((opCode.Flags & OpCodeFlags.Mode64) != 0)
     {
         if (sb.Length > 0)
         {
             sb.Append('/');
         }
         sb.Append("64");
     }
     if (sb.Length == 0)
     {
         throw new InvalidOperationException();
     }
     sb.Append("-bit");
     return(sb.ToString());
 }
예제 #8
0
        public bool DisassembleMethod()
        {
            if (selectedMethod == null && selection.selectedMethod != null)
            {
                SelectMethod(selection.selectedMethod);
            }

            if (selectedMethod == null)
            {
                return(false);
            }
            var reader = new MethodBodyReader(selectedMethod);

            byteCount = reader.ilByteCount;
            ilCode    = reader.GetBodyCode();
            localVariables.Clear();
            if (string.IsNullOrWhiteSpace(ilCode))
            {
                instructionInfo.Clear();
                Updated?.Invoke(this);
                return(false);
            }

            if (reader.LocalVariables != null)
            {
                foreach (var local in reader.LocalVariables)
                {
                    localVariables.Add(local.LocalIndex, local);
                }
            }

            var lines = ilCode?.Split('\n').ToList();

            lines.RemoveAll(string.IsNullOrWhiteSpace);
            var ilCodeLines = lines.ToArray();

            var ilLinesInfos = new OpCodeInfo[ilCodeLines?.Length ?? 0];

            if (reader.instructions == null)
            {
                return(false);
            }
            for (var index = 0; index < reader.instructions.Count && index < ilLinesInfos.Length; index++)
            {
                var instruction = reader.instructions[index];
                var d           = TryGetOpCodeDescription(instruction.Code);
                if (d == null)
                {
                    continue;
                }
                ilLinesInfos[index] = d;
            }

            FindBlocks(ilCodeLines, reader.instructions, ilLinesInfos);

            Updated?.Invoke(this);
            DisassemblyChanged?.Invoke(this);
            return(true);
        }
예제 #9
0
        static string ToString_3DNow(OpCodeInfo info, StringBuilder sb)
        {
            sb.Length = 0;

            AppendOpCode(sb, 0x0F0F);
            sb.Append(" /r");
            sb.Append(' ');
            AppendOpCode(sb, info.OpCode);

            return(sb.ToString());
        }
예제 #10
0
            /// <summary>
            /// Add instructions that spill registers (when needed).
            /// </summary>
            internal void Generate(MethodBody body)
            {
                // Go over each instruction in the block.
                var instructions = block.Instructions.ToList();

                foreach (var ins in instructions)
                {
                    var registers = ins.Registers;
                    var count     = registers.Count;
                    if (count == 0)
                    {
                        // No registers, so no spilling
                        continue;
                    }

                    var isInvoke = ins.OpCode.IsInvoke();
                    if (isInvoke)
                    {
                        if (ins.RequiresInvokeRange())
                        {
                            ConvertInvoke(ins);
                        }
                    }
                    else
                    {
                        var info = OpCodeInfo.Get(ins.OpCode);
                        for (var i = 0; i < count; i++)
                        {
                            Register         r;
                            LowRegisterState state;
                            var spill = TryGetLowRegister(registers[i], out r, out state);
                            if (!spill)
                            {
                                var size = info.GetUsage(i) & RegisterFlags.SizeMask;
                                switch (size)
                                {
                                case RegisterFlags.Bits4:
                                    spill = !registers[i].IsBits4;
                                    break;

                                case RegisterFlags.Bits8:
                                    spill = !registers[i].IsBits8;
                                    break;
                                }
                            }
                            if (spill)
                            {
                                // Insert spilling code
                                AddCode(ins, registers[i], body);
                            }
                        }
                    }
                }
            }
예제 #11
0
 public InstructionDef(int opCount, EnumValue mnemonic, EnumValue mem, EnumValue bcst, OpCodeInfo opCodeInfo, InstrInfo instrInfo)
 {
     if (opCodeInfo.Code != instrInfo.Code)
     {
         throw new InvalidOperationException();
     }
     OpCount    = opCount;
     Mnemonic   = mnemonic;
     Mem        = mem;
     Bcst       = bcst;
     OpCodeInfo = opCodeInfo;
     InstrInfo  = instrInfo;
 }
예제 #12
0
        static OpCodeInfo[] CreateInfos()
        {
            var infos = new OpCodeInfo[IcedConstants.NumberOfCodeValues];
            var data  = OpCodeHandlers.GetData();

            Debug.Assert(data.Length == infos.Length * 3);
            var sb = new StringBuilder();

            for (int i = 0; i < infos.Length; i++)
            {
                infos[i] = new OpCodeInfo((Code)i, data[i * 3 + 2], data[i * 3 + 1], data[i * 3], sb);
            }
            return(infos);
        }
예제 #13
0
        public bool IsDestinationRegister(int index)
        {
            var info   = OpCodeInfo.Get(Instruction.Code.ToDex());
            var isDest = (info.GetUsage(index) & RegisterFlags.Destination) == RegisterFlags.Destination;

            // While not changing the value, check_cast changes the meaning of the
            // register. We treat it as a read-write instruction here. One should check if
            // check-cast should not always be treated as a read-write instruction.
            if (Instruction.Code == RCode.Check_cast)
            {
                isDest = true;
            }

            return(isDest);
        }
예제 #14
0
        public static ILMethodInfo Disassemble(MethodInfo method)
        {
            if (method == null)
            {
                return(null);
            }

            var reader = new MethodBodyReader(method);
            var ilCode = reader.GetBodyCode();

            if (string.IsNullOrWhiteSpace(ilCode))
            {
                return(null);
            }

            var localVariables = new List <LocalVariableInfo>();

            if (reader.LocalVariables != null)
            {
                localVariables.AddRange(reader.LocalVariables);
            }

            var lines = ilCode?.Split('\n').ToList();

            lines.RemoveAll(string.IsNullOrWhiteSpace);
            var ilCodeLines = lines.ToArray();

            var ilLinesInfos = new OpCodeInfo[ilCodeLines?.Length ?? 0];

            if (reader.instructions == null)
            {
                return(null);
            }
            for (var index = 0; index < reader.instructions.Count && index < ilLinesInfos.Length; index++)
            {
                var instruction = reader.instructions[index];
                var d           = ILNavigator.TryGetOpCodeDescription(instruction.Code);
                if (d == null)
                {
                    continue;
                }
                ilLinesInfos[index] = d;
            }

            var instructions = FindBlocks(ilCodeLines, reader.instructions, ilLinesInfos);

            return(new ILMethodInfo(localVariables, instructions));
        }
예제 #15
0
        static OpCodeInfo[] CreateInfos()
        {
            var infos     = new OpCodeInfo[IcedConstants.CodeEnumCount];
            var encFlags1 = EncoderData.EncFlags1;
            var encFlags2 = EncoderData.EncFlags2;
            var encFlags3 = EncoderData.EncFlags3;
            var opcFlags1 = OpCodeInfoData.OpcFlags1;
            var opcFlags2 = OpCodeInfoData.OpcFlags2;
            var sb        = new StringBuilder();

            for (int i = 0; i < infos.Length; i++)
            {
                infos[i] = new OpCodeInfo((Code)i, (EncFlags1)encFlags1[i], (EncFlags2)encFlags2[i], (EncFlags3)encFlags3[i], (OpCodeInfoFlags1)opcFlags1[i], (OpCodeInfoFlags2)opcFlags2[i], sb);
            }
            return(infos);
        }
예제 #16
0
        static OpCodeOperandKind GetOpCodeBitsOperand(OpCodeInfo info)
        {
            int opCount = info.OpCount;

            for (int i = 0; i < opCount; i++)
            {
                var opKind = info.GetOpKind(i);
                switch (opKind)
                {
                case OpCodeOperandKind.r8_opcode:
                case OpCodeOperandKind.r16_opcode:
                case OpCodeOperandKind.r32_opcode:
                case OpCodeOperandKind.r64_opcode:
                    return(opKind);
                }
            }
            return(OpCodeOperandKind.None);
        }
예제 #17
0
        /// <summary>
        /// Gets the lowest size (in bitsX) that is available for the given register in the given instruction.
        /// </summary>
        private static RegisterFlags GetLowestSize(Instruction instruction, Register r)
        {
            var result    = RegisterFlags.Bits16;
            var info      = OpCodeInfo.Get(instruction.Code.ToDex());
            var registers = instruction.Registers;

            for (var i = 0; i < registers.Count; i++)
            {
                if (registers[i] == r)
                {
                    var size = info.GetUsage(i) & RegisterFlags.SizeMask;
                    if (size < result)
                    {
                        result = size;
                    }
                }
            }
            return(result);
        }
예제 #18
0
        static bool HasVsib(OpCodeInfo info)
        {
            int opCount = info.OpCount;

            for (int i = 0; i < opCount; i++)
            {
                switch (info.GetOpKind(i))
                {
                case OpCodeOperandKind.mem_vsib32x:
                case OpCodeOperandKind.mem_vsib64x:
                case OpCodeOperandKind.mem_vsib32y:
                case OpCodeOperandKind.mem_vsib64y:
                case OpCodeOperandKind.mem_vsib32z:
                case OpCodeOperandKind.mem_vsib64z:
                    return(true);
                }
            }
            return(false);
        }
예제 #19
0
        public ILInstructionInfo(string line, ILInstruction instruction, OpCodeInfo opInfo)
        {
            this.Line              = line;
            this.OpInfo            = opInfo;
            this.instruction       = instruction;
            this.InstructionOffset = instruction.Offset;
            this.IsBrTarget        = instruction.IsBrTarget;

            if (this.IsBrTarget)
            {
                this.BranchTarget = (int)instruction.Operand;
            }
            else if (instruction.IsVariableAccess)
            {
                var list     = new List <int>();
                var varIndex = Convert.ToInt32(instruction.Operand);
//                Debug.Log(instruction.Operand + " -> " + varIndex);
                if (!list.Contains(varIndex))
                {
                    list.Add(varIndex);
                }
                LocalVariableAccesses = list;
            }
            else if (instruction.Code.ToString().ToLowerInvariant().Contains("loc."))
            {
                // getting local variable access in a hacky way:
                var str = instruction.Code.ToString().ToLowerInvariant();
//                Debug.Log(instruction.Code);
                var indexOfDot = str.IndexOf('.');
                var sub        = str.Substring(indexOfDot + 1);
                if (!string.IsNullOrWhiteSpace(sub))
                {
                    var num  = Convert.ToInt32(sub);
                    var list = new List <int>();
                    if (!list.Contains(num))
                    {
                        list.Add(num);
                    }
                    LocalVariableAccesses = list;
                }
            }
        }
예제 #20
0
        public static string ToString(OpCodeInfo info, StringBuilder sb, bool l0l1)
        {
            if (!info.IsInstruction)
            {
                switch (info.Code)
                {
                case Code.INVALID:              return("<invalid>");

                case Code.DeclareByte:  return("<db>");

                case Code.DeclareWord:  return("<dw>");

                case Code.DeclareDword: return("<dd>");

                case Code.DeclareQword: return("<dq>");

                default:                                throw new InvalidOperationException();
                }
            }

            switch (info.Encoding)
            {
            case EncodingKind.Legacy:
                return(ToString_Legacy(info, sb));

            case EncodingKind.VEX:
                return(ToString_VEX_XOP_EVEX(info, sb, l0l1, "VEX"));

            case EncodingKind.EVEX:
                return(ToString_VEX_XOP_EVEX(info, sb, l0l1, "EVEX"));

            case EncodingKind.XOP:
                return(ToString_VEX_XOP_EVEX(info, sb, l0l1, "XOP"));

            case EncodingKind.D3NOW:
                return(ToString_3DNow(info, sb));

            default:
                throw new InvalidOperationException();
            }
        }
예제 #21
0
        /// <summary>
        /// Is the given register used as source in the given instruction?
        /// </summary>
        public static bool IsSourceIn(this Register r, Instruction ins)
        {
            var registers = ins.Registers;
            var count     = registers.Count;

            if (count == 0)
            {
                return(false);
            }
            var info = OpCodeInfo.Get(ins.Code.ToDex());

            for (var i = 0; i < count; i++)
            {
                if (registers[i] == r)
                {
                    if ((info.GetUsage(i) & RegisterFlags.Source) == RegisterFlags.Source)
                    {
                        return(true);
                    }
                }
            }
            return(false);
        }
예제 #22
0
 public OpCodeFormatter(OpCodeInfo opCode, StringBuilder sb, LKind lkind)
 {
     this.opCode = opCode;
     this.sb     = sb;
     this.lkind  = lkind;
 }
예제 #23
0
        public InstructionFormatter(OpCodeInfo opCode, StringBuilder sb)
        {
            this.opCode    = opCode;
            this.sb        = sb;
            noVecIndex     = false;
            swapVecIndex12 = false;
            startOpIndex   = 0;
            bnd_count      = 0;
            r32_count      = 0;
            r64_count      = 0;
            r32_index      = 0;
            r64_index      = 0;
            k_index        = 0;
            vec_index      = 0;
            bnd_index      = 0;
            opCount        = opCode.OpCount;
            opMaskIsK1     = false;
            if ((opCode.Op0Kind == OpCodeOperandKind.k_reg || opCode.Op0Kind == OpCodeOperandKind.kp1_reg) && opCode.OpCount > 2)
            {
                vec_index++;
            }
            switch (opCode.Code)
            {
            case Code.EVEX_Vfpclassps_k_k1_xmmm128b32_imm8:
            case Code.EVEX_Vfpclassps_k_k1_ymmm256b32_imm8:
            case Code.EVEX_Vfpclassps_k_k1_zmmm512b32_imm8:
            case Code.EVEX_Vfpclasspd_k_k1_xmmm128b64_imm8:
            case Code.EVEX_Vfpclasspd_k_k1_ymmm256b64_imm8:
            case Code.EVEX_Vfpclasspd_k_k1_zmmm512b64_imm8:
            case Code.EVEX_Vfpclassss_k_k1_xmmm32_imm8:
            case Code.EVEX_Vfpclasssd_k_k1_xmmm64_imm8:
            case Code.EVEX_Vptestmb_k_k1_xmm_xmmm128:
            case Code.EVEX_Vptestmb_k_k1_ymm_ymmm256:
            case Code.EVEX_Vptestmb_k_k1_zmm_zmmm512:
            case Code.EVEX_Vptestmw_k_k1_xmm_xmmm128:
            case Code.EVEX_Vptestmw_k_k1_ymm_ymmm256:
            case Code.EVEX_Vptestmw_k_k1_zmm_zmmm512:
            case Code.EVEX_Vptestnmb_k_k1_xmm_xmmm128:
            case Code.EVEX_Vptestnmb_k_k1_ymm_ymmm256:
            case Code.EVEX_Vptestnmb_k_k1_zmm_zmmm512:
            case Code.EVEX_Vptestnmw_k_k1_xmm_xmmm128:
            case Code.EVEX_Vptestnmw_k_k1_ymm_ymmm256:
            case Code.EVEX_Vptestnmw_k_k1_zmm_zmmm512:
            case Code.EVEX_Vptestmd_k_k1_xmm_xmmm128b32:
            case Code.EVEX_Vptestmd_k_k1_ymm_ymmm256b32:
            case Code.EVEX_Vptestmd_k_k1_zmm_zmmm512b32:
            case Code.EVEX_Vptestmq_k_k1_xmm_xmmm128b64:
            case Code.EVEX_Vptestmq_k_k1_ymm_ymmm256b64:
            case Code.EVEX_Vptestmq_k_k1_zmm_zmmm512b64:
            case Code.EVEX_Vptestnmd_k_k1_xmm_xmmm128b32:
            case Code.EVEX_Vptestnmd_k_k1_ymm_ymmm256b32:
            case Code.EVEX_Vptestnmd_k_k1_zmm_zmmm512b32:
            case Code.EVEX_Vptestnmq_k_k1_xmm_xmmm128b64:
            case Code.EVEX_Vptestnmq_k_k1_ymm_ymmm256b64:
            case Code.EVEX_Vptestnmq_k_k1_zmm_zmmm512b64:
                opMaskIsK1 = true;
                break;

            case Code.VEX_Vpextrw_r32m16_xmm_imm8:
            case Code.VEX_Vpextrw_r64m16_xmm_imm8:
            case Code.EVEX_Vpextrw_r32m16_xmm_imm8:
            case Code.EVEX_Vpextrw_r64m16_xmm_imm8:
            case Code.VEX_Vmovmskpd_r32_xmm:
            case Code.VEX_Vmovmskpd_r64_xmm:
            case Code.VEX_Vmovmskpd_r32_ymm:
            case Code.VEX_Vmovmskpd_r64_ymm:
            case Code.VEX_Vmovmskps_r32_xmm:
            case Code.VEX_Vmovmskps_r64_xmm:
            case Code.VEX_Vmovmskps_r32_ymm:
            case Code.VEX_Vmovmskps_r64_ymm:
            case Code.Pextrb_r32m8_xmm_imm8:
            case Code.Pextrb_r64m8_xmm_imm8:
            case Code.Pextrd_rm32_xmm_imm8:
            case Code.Pextrq_rm64_xmm_imm8:
            case Code.VEX_Vpextrb_r32m8_xmm_imm8:
            case Code.VEX_Vpextrb_r64m8_xmm_imm8:
            case Code.VEX_Vpextrd_rm32_xmm_imm8:
            case Code.VEX_Vpextrq_rm64_xmm_imm8:
            case Code.EVEX_Vpextrb_r32m8_xmm_imm8:
            case Code.EVEX_Vpextrb_r64m8_xmm_imm8:
            case Code.EVEX_Vpextrd_rm32_xmm_imm8:
            case Code.EVEX_Vpextrq_rm64_xmm_imm8:
                vec_index++;
                break;

            case Code.Pxor_mm_mmm64:
            case Code.Punpckldq_mm_mmm32:
            case Code.Punpcklwd_mm_mmm32:
            case Code.Punpcklbw_mm_mmm32:
            case Code.Punpckhdq_mm_mmm64:
            case Code.Punpckhwd_mm_mmm64:
            case Code.Punpckhbw_mm_mmm64:
            case Code.Psubusb_mm_mmm64:
            case Code.Psubusw_mm_mmm64:
            case Code.Psubsw_mm_mmm64:
            case Code.Psubsb_mm_mmm64:
            case Code.Psubd_mm_mmm64:
            case Code.Psubw_mm_mmm64:
            case Code.Psubb_mm_mmm64:
            case Code.Psrlq_mm_imm8:
            case Code.Psrlq_mm_mmm64:
            case Code.Psrld_mm_imm8:
            case Code.Psrld_mm_mmm64:
            case Code.Psrlw_mm_imm8:
            case Code.Psrlw_mm_mmm64:
            case Code.Psrad_mm_imm8:
            case Code.Psrad_mm_mmm64:
            case Code.Psraw_mm_imm8:
            case Code.Psraw_mm_mmm64:
            case Code.Psllq_mm_imm8:
            case Code.Psllq_mm_mmm64:
            case Code.Pslld_mm_imm8:
            case Code.Pslld_mm_mmm64:
            case Code.Psllw_mm_mmm64:
            case Code.Por_mm_mmm64:
            case Code.Pmullw_mm_mmm64:
            case Code.Pmulhw_mm_mmm64:
            case Code.Pmovmskb_r32_mm:
            case Code.Pmovmskb_r64_mm:
            case Code.Pmovmskb_r32_xmm:
            case Code.Pmovmskb_r64_xmm:
            case Code.Pmaddwd_mm_mmm64:
            case Code.Pinsrw_mm_r32m16_imm8:
            case Code.Pinsrw_mm_r64m16_imm8:
            case Code.Pinsrw_xmm_r32m16_imm8:
            case Code.Pinsrw_xmm_r64m16_imm8:
            case Code.Pextrw_r32_xmm_imm8:
            case Code.Pextrw_r64_xmm_imm8:
            case Code.Pextrw_r32m16_xmm_imm8:
            case Code.Pextrw_r64m16_xmm_imm8:
            case Code.Pextrw_r32_mm_imm8:
            case Code.Pextrw_r64_mm_imm8:
            case Code.Cvtpd2pi_mm_xmmm128:
            case Code.Cvtpi2pd_xmm_mmm64:
            case Code.Cvtpi2ps_xmm_mmm64:
            case Code.Cvtps2pi_mm_xmmm64:
            case Code.Cvttpd2pi_mm_xmmm128:
            case Code.Cvttps2pi_mm_xmmm64:
            case Code.Movd_mm_rm32:
            case Code.Movq_mm_rm64:
            case Code.Movd_rm32_mm:
            case Code.Movq_rm64_mm:
            case Code.Movd_xmm_rm32:
            case Code.Movq_xmm_rm64:
            case Code.Movd_rm32_xmm:
            case Code.Movq_rm64_xmm:
            case Code.Movdq2q_mm_xmm:
            case Code.Movmskpd_r32_xmm:
            case Code.Movmskpd_r64_xmm:
            case Code.Movmskps_r32_xmm:
            case Code.Movmskps_r64_xmm:
            case Code.Movntq_m64_mm:
            case Code.Movq_mm_mmm64:
            case Code.Movq_mmm64_mm:
            case Code.Movq2dq_xmm_mm:
            case Code.Packuswb_mm_mmm64:
            case Code.Paddb_mm_mmm64:
            case Code.Paddw_mm_mmm64:
            case Code.Paddd_mm_mmm64:
            case Code.Paddq_mm_mmm64:
            case Code.Paddsb_mm_mmm64:
            case Code.Paddsw_mm_mmm64:
            case Code.Paddusb_mm_mmm64:
            case Code.Paddusw_mm_mmm64:
            case Code.Pand_mm_mmm64:
            case Code.Pandn_mm_mmm64:
            case Code.Pcmpeqb_mm_mmm64:
            case Code.Pcmpeqw_mm_mmm64:
            case Code.Pcmpeqd_mm_mmm64:
            case Code.Pcmpgtb_mm_mmm64:
            case Code.Pcmpgtw_mm_mmm64:
            case Code.Pcmpgtd_mm_mmm64:
                noVecIndex = true;
                break;

            case Code.Movapd_xmmm128_xmm:
            case Code.VEX_Vmovapd_xmmm128_xmm:
            case Code.VEX_Vmovapd_ymmm256_ymm:
            case Code.EVEX_Vmovapd_xmmm128_k1z_xmm:
            case Code.EVEX_Vmovapd_ymmm256_k1z_ymm:
            case Code.EVEX_Vmovapd_zmmm512_k1z_zmm:
            case Code.Movaps_xmmm128_xmm:
            case Code.VEX_Vmovaps_xmmm128_xmm:
            case Code.VEX_Vmovaps_ymmm256_ymm:
            case Code.EVEX_Vmovaps_xmmm128_k1z_xmm:
            case Code.EVEX_Vmovaps_ymmm256_k1z_ymm:
            case Code.EVEX_Vmovaps_zmmm512_k1z_zmm:
            case Code.Movdqa_xmmm128_xmm:
            case Code.VEX_Vmovdqa_xmmm128_xmm:
            case Code.VEX_Vmovdqa_ymmm256_ymm:
            case Code.EVEX_Vmovdqa32_xmmm128_k1z_xmm:
            case Code.EVEX_Vmovdqa32_ymmm256_k1z_ymm:
            case Code.EVEX_Vmovdqa32_zmmm512_k1z_zmm:
            case Code.EVEX_Vmovdqa64_xmmm128_k1z_xmm:
            case Code.EVEX_Vmovdqa64_ymmm256_k1z_ymm:
            case Code.EVEX_Vmovdqa64_zmmm512_k1z_zmm:
            case Code.Movdqu_xmmm128_xmm:
            case Code.VEX_Vmovdqu_xmmm128_xmm:
            case Code.VEX_Vmovdqu_ymmm256_ymm:
            case Code.EVEX_Vmovdqu8_xmmm128_k1z_xmm:
            case Code.EVEX_Vmovdqu8_ymmm256_k1z_ymm:
            case Code.EVEX_Vmovdqu8_zmmm512_k1z_zmm:
            case Code.EVEX_Vmovdqu16_xmmm128_k1z_xmm:
            case Code.EVEX_Vmovdqu16_ymmm256_k1z_ymm:
            case Code.EVEX_Vmovdqu16_zmmm512_k1z_zmm:
            case Code.EVEX_Vmovdqu32_xmmm128_k1z_xmm:
            case Code.EVEX_Vmovdqu32_ymmm256_k1z_ymm:
            case Code.EVEX_Vmovdqu32_zmmm512_k1z_zmm:
            case Code.EVEX_Vmovdqu64_xmmm128_k1z_xmm:
            case Code.EVEX_Vmovdqu64_ymmm256_k1z_ymm:
            case Code.EVEX_Vmovdqu64_zmmm512_k1z_zmm:
            case Code.VEX_Vmovhpd_xmm_xmm_m64:
            case Code.EVEX_Vmovhpd_xmm_xmm_m64:
            case Code.VEX_Vmovhps_xmm_xmm_m64:
            case Code.EVEX_Vmovhps_xmm_xmm_m64:
            case Code.VEX_Vmovlpd_xmm_xmm_m64:
            case Code.EVEX_Vmovlpd_xmm_xmm_m64:
            case Code.VEX_Vmovlps_xmm_xmm_m64:
            case Code.EVEX_Vmovlps_xmm_xmm_m64:
            case Code.Movq_xmmm64_xmm:
            case Code.Movss_xmmm32_xmm:
            case Code.Movupd_xmmm128_xmm:
            case Code.VEX_Vmovupd_xmmm128_xmm:
            case Code.VEX_Vmovupd_ymmm256_ymm:
            case Code.EVEX_Vmovupd_xmmm128_k1z_xmm:
            case Code.EVEX_Vmovupd_ymmm256_k1z_ymm:
            case Code.EVEX_Vmovupd_zmmm512_k1z_zmm:
            case Code.Movups_xmmm128_xmm:
            case Code.VEX_Vmovups_xmmm128_xmm:
            case Code.VEX_Vmovups_ymmm256_ymm:
            case Code.EVEX_Vmovups_xmmm128_k1z_xmm:
            case Code.EVEX_Vmovups_ymmm256_k1z_ymm:
            case Code.EVEX_Vmovups_zmmm512_k1z_zmm:
                swapVecIndex12 = true;
                break;
            }
            for (int i = 0; i < opCode.OpCount; i++)
            {
                switch (opCode.GetOpKind(i))
                {
                case OpCodeOperandKind.r32_reg:
                case OpCodeOperandKind.r32_rm:
                case OpCodeOperandKind.r32_opcode:
                case OpCodeOperandKind.r32_vvvv:
                    r32_count++;
                    break;

                case OpCodeOperandKind.r64_reg:
                case OpCodeOperandKind.r64_rm:
                case OpCodeOperandKind.r64_opcode:
                case OpCodeOperandKind.r64_vvvv:
                    r64_count++;
                    break;

                case OpCodeOperandKind.bnd_or_mem_mpx:
                case OpCodeOperandKind.bnd_reg:
                    bnd_count++;
                    break;

                case OpCodeOperandKind.st0:
                    if (i == 0)
                    {
                        switch (opCode.Code)
                        {
                        case Code.Fcom_st0_sti:
                        case Code.Fcomp_st0_sti:
                        case Code.Fld_st0_sti:
                        case Code.Fucom_st0_sti:
                        case Code.Fucomp_st0_sti:
                        case Code.Fxch_st0_sti:
                            startOpIndex = 1;
                            break;
                        }
                    }
                    break;

                case OpCodeOperandKind.None:
                case OpCodeOperandKind.farbr2_2:
                case OpCodeOperandKind.farbr4_2:
                case OpCodeOperandKind.mem_offs:
                case OpCodeOperandKind.mem:
                case OpCodeOperandKind.mem_mpx:
                case OpCodeOperandKind.mem_vsib32x:
                case OpCodeOperandKind.mem_vsib64x:
                case OpCodeOperandKind.mem_vsib32y:
                case OpCodeOperandKind.mem_vsib64y:
                case OpCodeOperandKind.mem_vsib32z:
                case OpCodeOperandKind.mem_vsib64z:
                case OpCodeOperandKind.r8_or_mem:
                case OpCodeOperandKind.r16_or_mem:
                case OpCodeOperandKind.r32_or_mem:
                case OpCodeOperandKind.r32_or_mem_mpx:
                case OpCodeOperandKind.r64_or_mem:
                case OpCodeOperandKind.r64_or_mem_mpx:
                case OpCodeOperandKind.mm_or_mem:
                case OpCodeOperandKind.xmm_or_mem:
                case OpCodeOperandKind.ymm_or_mem:
                case OpCodeOperandKind.zmm_or_mem:
                case OpCodeOperandKind.k_or_mem:
                case OpCodeOperandKind.r8_reg:
                case OpCodeOperandKind.r8_opcode:
                case OpCodeOperandKind.r16_reg:
                case OpCodeOperandKind.r16_rm:
                case OpCodeOperandKind.r16_opcode:
                case OpCodeOperandKind.seg_reg:
                case OpCodeOperandKind.k_reg:
                case OpCodeOperandKind.kp1_reg:
                case OpCodeOperandKind.k_rm:
                case OpCodeOperandKind.k_vvvv:
                case OpCodeOperandKind.mm_reg:
                case OpCodeOperandKind.mm_rm:
                case OpCodeOperandKind.xmm_reg:
                case OpCodeOperandKind.xmm_rm:
                case OpCodeOperandKind.xmm_vvvv:
                case OpCodeOperandKind.xmmp3_vvvv:
                case OpCodeOperandKind.xmm_is4:
                case OpCodeOperandKind.xmm_is5:
                case OpCodeOperandKind.ymm_reg:
                case OpCodeOperandKind.ymm_rm:
                case OpCodeOperandKind.ymm_vvvv:
                case OpCodeOperandKind.ymm_is4:
                case OpCodeOperandKind.ymm_is5:
                case OpCodeOperandKind.zmm_reg:
                case OpCodeOperandKind.zmm_rm:
                case OpCodeOperandKind.zmm_vvvv:
                case OpCodeOperandKind.zmmp3_vvvv:
                case OpCodeOperandKind.cr_reg:
                case OpCodeOperandKind.dr_reg:
                case OpCodeOperandKind.tr_reg:
                case OpCodeOperandKind.es:
                case OpCodeOperandKind.cs:
                case OpCodeOperandKind.ss:
                case OpCodeOperandKind.ds:
                case OpCodeOperandKind.fs:
                case OpCodeOperandKind.gs:
                case OpCodeOperandKind.al:
                case OpCodeOperandKind.cl:
                case OpCodeOperandKind.ax:
                case OpCodeOperandKind.dx:
                case OpCodeOperandKind.eax:
                case OpCodeOperandKind.rax:
                case OpCodeOperandKind.sti_opcode:
                case OpCodeOperandKind.imm2_m2z:
                case OpCodeOperandKind.imm8:
                case OpCodeOperandKind.imm8_const_1:
                case OpCodeOperandKind.imm8sex16:
                case OpCodeOperandKind.imm8sex32:
                case OpCodeOperandKind.imm8sex64:
                case OpCodeOperandKind.imm16:
                case OpCodeOperandKind.imm32:
                case OpCodeOperandKind.imm32sex64:
                case OpCodeOperandKind.imm64:
                case OpCodeOperandKind.seg_rDI:
                case OpCodeOperandKind.br16_1:
                case OpCodeOperandKind.br32_1:
                case OpCodeOperandKind.br64_1:
                case OpCodeOperandKind.br16_2:
                case OpCodeOperandKind.br32_4:
                case OpCodeOperandKind.br64_4:
                case OpCodeOperandKind.xbegin_2:
                case OpCodeOperandKind.xbegin_4:
                case OpCodeOperandKind.brdisp_2:
                case OpCodeOperandKind.brdisp_4:
                    break;

                case OpCodeOperandKind.seg_rSI:
                case OpCodeOperandKind.es_rDI:
                case OpCodeOperandKind.seg_rBX_al:
                    // string instructions, xlat
                    opCount = 0;
                    break;

                default:
                    throw new InvalidOperationException();
                }
            }
        }
예제 #24
0
        public ILStructure(MethodBody body)
            : this(ILStructureType.Root, 0, body.CodeSize)
        {
            // Build the tree of exception structures:
            for (int i = 0; i < body.ExceptionHandlers.Count; i++)
            {
                ExceptionHandler eh = body.ExceptionHandlers[i];
                if (!body.ExceptionHandlers.Take(i).Any(oldEh => oldEh.TryStart == eh.TryStart && oldEh.TryEnd == eh.TryEnd))
                {
                    AddNestedStructure(new ILStructure(ILStructureType.Try, eh.TryStart.Offset, eh.TryEnd.Offset, eh));
                }
                if (eh.HandlerType == ExceptionHandlerType.Filter)
                {
                    AddNestedStructure(new ILStructure(ILStructureType.Filter, eh.FilterStart.Offset, eh.HandlerStart.Offset, eh));
                }
                AddNestedStructure(new ILStructure(ILStructureType.Handler, eh.HandlerStart.Offset, eh.HandlerEnd == null ? body.CodeSize : eh.HandlerEnd.Offset, eh));
            }
            // Very simple loop detection: look for backward branches
            List <KeyValuePair <Instruction, Instruction> > allBranches = FindAllBranches(body);

            // We go through the branches in reverse so that we find the biggest possible loop boundary first (think loops with "continue;")
            for (int i = allBranches.Count - 1; i >= 0; i--)
            {
                int loopEnd   = allBranches[i].Key.GetEndOffset();
                int loopStart = allBranches[i].Value.Offset;
                if (loopStart < loopEnd)
                {
                    // We found a backward branch. This is a potential loop.
                    // Check that is has only one entry point:
                    Instruction entryPoint = null;

                    // entry point is first instruction in loop if prev inst isn't an unconditional branch
                    Instruction prev = allBranches[i].Value.Previous;
                    if (prev != null && !OpCodeInfo.IsUnconditionalBranch(prev.OpCode))
                    {
                        entryPoint = allBranches[i].Value;
                    }

                    bool multipleEntryPoints = false;
                    foreach (var pair in allBranches)
                    {
                        if (pair.Key.Offset < loopStart || pair.Key.Offset >= loopEnd)
                        {
                            if (loopStart <= pair.Value.Offset && pair.Value.Offset < loopEnd)
                            {
                                // jump from outside the loop into the loop
                                if (entryPoint == null)
                                {
                                    entryPoint = pair.Value;
                                }
                                else if (pair.Value != entryPoint)
                                {
                                    multipleEntryPoints = true;
                                }
                            }
                        }
                    }
                    if (!multipleEntryPoints)
                    {
                        AddNestedStructure(new ILStructure(ILStructureType.Loop, loopStart, loopEnd, entryPoint));
                    }
                }
            }
            SortChildren();
        }
예제 #25
0
        /// <summary>
        /// Is the register with the given index being assigned a value in this instruction?
        /// </summary>
        public bool IsDestinationRegister(int index)
        {
            var info = OpCodeInfo.Get(Code.ToDex());

            return((info.GetUsage(index) & RegisterFlags.Destination) == RegisterFlags.Destination);
        }
예제 #26
0
 public void WriteReference(OpCodeInfo opCode)
 {
     Write(opCode.Name);
 }
예제 #27
0
 public void WriteReference(OpCodeInfo opCode, bool omitSuffix = false)
 {
     actions.Add(target => target.WriteReference(opCode));
 }
        /// <summary>
        /// Transform the given body.
        /// </summary>
        public void Transform(Dex target, MethodBody body)
        {
            // Build the control flow graph
            var cfg = new ControlFlowGraph(body);

            // Go over each block to find registers that are initialized and may need initialization
            foreach (var iterator in cfg)
            {
                var block = iterator;
                var data  = new BasicBlockData(block);
                block.Tag = data;

                // Go over all instructions in the block, finding source/destination registers
                foreach (var ins in block.Instructions)
                {
                    var info  = OpCodeInfo.Get(ins.Code.ToDex());
                    var count = ins.Registers.Count;
                    for (var i = 0; i < count; i++)
                    {
                        var reg = ins.Registers[i];
                        if (reg.Category != RCategory.Argument)
                        {
                            var flags = info.GetUsage(i);
                            if (flags.HasFlag(RegisterFlags.Source))
                            {
                                // Must be initialize
                                if (!data.Initialized.Contains(reg))
                                {
                                    data.MayNeedInitialization.Add(reg);
                                }
                            }
                            if (flags.HasFlag(RegisterFlags.Destination))
                            {
                                // Destination
                                data.Initialized.Add(reg);
                            }
                        }
                    }
                }
            }

            // Go over all blocks to collect the register that really need initialization
            var needInitialization = new HashSet <Register>();

            foreach (var iterator in cfg)
            {
                var block = iterator;
                var data  = (BasicBlockData)block.Tag;

                foreach (var regIterator in data.MayNeedInitialization)
                {
                    // Short cut
                    var reg = regIterator;
                    if (needInitialization.Contains(reg))
                    {
                        continue;
                    }

                    // If the register is initialized in all entry blocks, we do not need to initialize it
                    if (block.EntryBlocks.Select(x => (BasicBlockData)x.Tag).Any(x => !x.IsInitialized(reg)))
                    {
                        // There is an entry block that does not initialize the register, so we have to initialize it
                        needInitialization.Add(reg);
                    }
                }
            }

            var      index               = 0;
            Register valueReg            = null;
            Register objectReg           = null;
            Register wideReg             = null;
            var      firstSourceLocation = body.Instructions[0].SequencePoint;

            foreach (var reg in needInitialization.OrderBy(x => x.Index))
            {
                switch (reg.Type)
                {
                case RType.Value:
                    if (valueReg == null)
                    {
                        body.Instructions.Insert(index++, new Instruction(RCode.Const, 0, new[] { reg })
                        {
                            SequencePoint = firstSourceLocation
                        });
                        valueReg = reg;
                    }
                    else if (valueReg != reg)
                    {
                        body.Instructions.Insert(index++, new Instruction(RCode.Move, reg, valueReg)
                        {
                            SequencePoint = firstSourceLocation
                        });
                    }
                    break;

                case RType.Object:
                    if (objectReg == null)
                    {
                        body.Instructions.Insert(index++, new Instruction(RCode.Const, 0, new[] { reg })
                        {
                            SequencePoint = firstSourceLocation
                        });
                        objectReg = reg;
                    }
                    else if (objectReg != reg)
                    {
                        body.Instructions.Insert(index++, new Instruction(RCode.Move_object, reg, objectReg)
                        {
                            SequencePoint = firstSourceLocation
                        });
                    }
                    break;

                case RType.Wide:
                    if (wideReg == null)
                    {
                        body.Instructions.Insert(index++, new Instruction(RCode.Const_wide, 0, new[] { reg })
                        {
                            SequencePoint = firstSourceLocation
                        });
                        wideReg = reg;
                    }
                    else if (wideReg != reg)
                    {
                        body.Instructions.Insert(index++, new Instruction(RCode.Move_wide, reg, wideReg)
                        {
                            SequencePoint = firstSourceLocation
                        });
                    }
                    break;
                }
            }
        }
예제 #29
0
        public InstructionFormatter(OpCodeInfo opCode, InstrStrFmtOption fmtOption, StringBuilder sb)
        {
            this.opCode    = opCode;
            this.sb        = sb;
            noVecIndex     = false;
            swapVecIndex12 = false;
            noGprSuffix    = false;
            startOpIndex   = 0;
            bnd_count      = 0;
            r32_count      = 0;
            r64_count      = 0;
            r32_index      = 0;
            r64_index      = 0;
            k_index        = 0;
            vec_index      = 0;
            tmm_index      = 0;
            bnd_index      = 0;
            opCount        = opCode.OpCount;
            opMaskIsK1     = false;
            switch (fmtOption)
            {
            case InstrStrFmtOption.None:
                break;

            case InstrStrFmtOption.OpMaskIsK1_or_NoGprSuffix:
                opMaskIsK1  = true;
                noGprSuffix = true;
                break;

            case InstrStrFmtOption.IncVecIndex:
                vec_index++;
                break;

            case InstrStrFmtOption.NoVecIndex:
                noVecIndex = true;
                break;

            case InstrStrFmtOption.SwapVecIndex12:
                swapVecIndex12 = true;
                break;

            case InstrStrFmtOption.SkipOp0:
                startOpIndex = 1;
                break;

            default:
                throw new InvalidOperationException();
            }
            if ((opCode.Op0Kind == OpCodeOperandKind.k_reg || opCode.Op0Kind == OpCodeOperandKind.kp1_reg) && opCode.OpCount > 2)
            {
                vec_index++;
            }
            for (int i = 0; i < opCode.OpCount; i++)
            {
                switch (opCode.GetOpKind(i))
                {
                case OpCodeOperandKind.r32_reg:
                case OpCodeOperandKind.r32_reg_mem:
                case OpCodeOperandKind.r32_rm:
                case OpCodeOperandKind.r32_opcode:
                case OpCodeOperandKind.r32_vvvv:
                    r32_count++;
                    break;

                case OpCodeOperandKind.r64_reg:
                case OpCodeOperandKind.r64_reg_mem:
                case OpCodeOperandKind.r64_rm:
                case OpCodeOperandKind.r64_opcode:
                case OpCodeOperandKind.r64_vvvv:
                    r64_count++;
                    break;

                case OpCodeOperandKind.bnd_or_mem_mpx:
                case OpCodeOperandKind.bnd_reg:
                    bnd_count++;
                    break;

                case OpCodeOperandKind.None:
                case OpCodeOperandKind.farbr2_2:
                case OpCodeOperandKind.farbr4_2:
                case OpCodeOperandKind.mem_offs:
                case OpCodeOperandKind.mem:
                case OpCodeOperandKind.mem_mpx:
                case OpCodeOperandKind.mem_mib:
                case OpCodeOperandKind.mem_vsib32x:
                case OpCodeOperandKind.mem_vsib64x:
                case OpCodeOperandKind.mem_vsib32y:
                case OpCodeOperandKind.mem_vsib64y:
                case OpCodeOperandKind.mem_vsib32z:
                case OpCodeOperandKind.mem_vsib64z:
                case OpCodeOperandKind.r8_or_mem:
                case OpCodeOperandKind.r16_or_mem:
                case OpCodeOperandKind.r32_or_mem:
                case OpCodeOperandKind.r32_or_mem_mpx:
                case OpCodeOperandKind.r64_or_mem:
                case OpCodeOperandKind.r64_or_mem_mpx:
                case OpCodeOperandKind.mm_or_mem:
                case OpCodeOperandKind.xmm_or_mem:
                case OpCodeOperandKind.ymm_or_mem:
                case OpCodeOperandKind.zmm_or_mem:
                case OpCodeOperandKind.k_or_mem:
                case OpCodeOperandKind.r8_reg:
                case OpCodeOperandKind.r8_opcode:
                case OpCodeOperandKind.r16_reg:
                case OpCodeOperandKind.r16_reg_mem:
                case OpCodeOperandKind.r16_rm:
                case OpCodeOperandKind.r16_opcode:
                case OpCodeOperandKind.seg_reg:
                case OpCodeOperandKind.k_reg:
                case OpCodeOperandKind.kp1_reg:
                case OpCodeOperandKind.k_rm:
                case OpCodeOperandKind.k_vvvv:
                case OpCodeOperandKind.mm_reg:
                case OpCodeOperandKind.mm_rm:
                case OpCodeOperandKind.xmm_reg:
                case OpCodeOperandKind.xmm_rm:
                case OpCodeOperandKind.xmm_vvvv:
                case OpCodeOperandKind.xmmp3_vvvv:
                case OpCodeOperandKind.xmm_is4:
                case OpCodeOperandKind.xmm_is5:
                case OpCodeOperandKind.ymm_reg:
                case OpCodeOperandKind.ymm_rm:
                case OpCodeOperandKind.ymm_vvvv:
                case OpCodeOperandKind.ymm_is4:
                case OpCodeOperandKind.ymm_is5:
                case OpCodeOperandKind.zmm_reg:
                case OpCodeOperandKind.zmm_rm:
                case OpCodeOperandKind.zmm_vvvv:
                case OpCodeOperandKind.zmmp3_vvvv:
                case OpCodeOperandKind.cr_reg:
                case OpCodeOperandKind.dr_reg:
                case OpCodeOperandKind.tr_reg:
                case OpCodeOperandKind.es:
                case OpCodeOperandKind.cs:
                case OpCodeOperandKind.ss:
                case OpCodeOperandKind.ds:
                case OpCodeOperandKind.fs:
                case OpCodeOperandKind.gs:
                case OpCodeOperandKind.al:
                case OpCodeOperandKind.cl:
                case OpCodeOperandKind.ax:
                case OpCodeOperandKind.dx:
                case OpCodeOperandKind.eax:
                case OpCodeOperandKind.rax:
                case OpCodeOperandKind.st0:
                case OpCodeOperandKind.sti_opcode:
                case OpCodeOperandKind.imm2_m2z:
                case OpCodeOperandKind.imm8:
                case OpCodeOperandKind.imm8_const_1:
                case OpCodeOperandKind.imm8sex16:
                case OpCodeOperandKind.imm8sex32:
                case OpCodeOperandKind.imm8sex64:
                case OpCodeOperandKind.imm16:
                case OpCodeOperandKind.imm32:
                case OpCodeOperandKind.imm32sex64:
                case OpCodeOperandKind.imm64:
                case OpCodeOperandKind.seg_rDI:
                case OpCodeOperandKind.br16_1:
                case OpCodeOperandKind.br32_1:
                case OpCodeOperandKind.br64_1:
                case OpCodeOperandKind.br16_2:
                case OpCodeOperandKind.br32_4:
                case OpCodeOperandKind.br64_4:
                case OpCodeOperandKind.xbegin_2:
                case OpCodeOperandKind.xbegin_4:
                case OpCodeOperandKind.brdisp_2:
                case OpCodeOperandKind.brdisp_4:
                case OpCodeOperandKind.sibmem:
                case OpCodeOperandKind.tmm_reg:
                case OpCodeOperandKind.tmm_rm:
                case OpCodeOperandKind.tmm_vvvv:
                    break;

                case OpCodeOperandKind.seg_rSI:
                case OpCodeOperandKind.es_rDI:
                case OpCodeOperandKind.seg_rBX_al:
                    // string instructions, xlat
                    opCount = 0;
                    break;

                default:
                    throw new InvalidOperationException();
                }
            }
        }
예제 #30
0
        /// <summary>
        /// Is the register with the given index being assigned a value in this instruction?
        /// </summary>
        public bool IsSourceRegister(int index)
        {
            var info = OpCodeInfo.Get(Code.ToDex());

            return((info.GetUsage(index) & RegisterFlags.Source) == RegisterFlags.Source);
        }