コード例 #1
0
#pragma warning disable xUnit1026 // Theory methods should use all of their parameters
        void Test_all_OpCodeInfos(int lineNo, Code code, string opCodeString, OpCodeInfoTestCase tc)
        {
#pragma warning restore xUnit1026 // Theory methods should use all of their parameters
            var info = tc.Code.ToOpCode();
            Assert.Equal(tc.Code, info.Code);
#pragma warning disable xUnit2006 // Do not use invalid string equality check
            // Show the full string without ellipses by using Equal<string>() instead of Equal()
            Assert.Equal <string>(tc.OpCodeString, info.ToString());
#pragma warning restore xUnit2006 // Do not use invalid string equality check
            Assert.Equal(tc.Encoding, info.Encoding);
            Assert.Equal(tc.IsInstruction, info.IsInstruction);
            Assert.Equal(tc.Mode16, info.Mode16);
            Assert.Equal(tc.Mode32, info.Mode32);
            Assert.Equal(tc.Mode64, info.Mode64);
            Assert.Equal(tc.Fwait, info.Fwait);
            Assert.Equal(tc.OperandSize, info.OperandSize);
            Assert.Equal(tc.AddressSize, info.AddressSize);
            Assert.Equal(tc.L, info.L);
            Assert.Equal(tc.W, info.W);
            Assert.Equal(tc.IsLIG, info.IsLIG);
            Assert.Equal(tc.IsWIG, info.IsWIG);
            Assert.Equal(tc.IsWIG32, info.IsWIG32);
            Assert.Equal(tc.TupleType, info.TupleType);
            Assert.Equal(tc.CanBroadcast, info.CanBroadcast);
            Assert.Equal(tc.CanUseRoundingControl, info.CanUseRoundingControl);
            Assert.Equal(tc.CanSuppressAllExceptions, info.CanSuppressAllExceptions);
            Assert.Equal(tc.CanUseOpMaskRegister, info.CanUseOpMaskRegister);
            Assert.Equal(tc.CanUseZeroingMasking, info.CanUseZeroingMasking);
            Assert.Equal(tc.CanUseLockPrefix, info.CanUseLockPrefix);
            Assert.Equal(tc.CanUseXacquirePrefix, info.CanUseXacquirePrefix);
            Assert.Equal(tc.CanUseXreleasePrefix, info.CanUseXreleasePrefix);
            Assert.Equal(tc.CanUseRepPrefix, info.CanUseRepPrefix);
            Assert.Equal(tc.CanUseRepnePrefix, info.CanUseRepnePrefix);
            Assert.Equal(tc.CanUseBndPrefix, info.CanUseBndPrefix);
            Assert.Equal(tc.CanUseHintTakenPrefix, info.CanUseHintTakenPrefix);
            Assert.Equal(tc.CanUseNotrackPrefix, info.CanUseNotrackPrefix);
            Assert.Equal(tc.Table, info.Table);
            Assert.Equal(tc.MandatoryPrefix, info.MandatoryPrefix);
            Assert.Equal(tc.OpCode, info.OpCode);
            Assert.Equal(tc.IsGroup, info.IsGroup);
            Assert.Equal(tc.GroupIndex, info.GroupIndex);
            Assert.Equal(tc.OpCount, info.OpCount);
            Assert.Equal(tc.Op0Kind, info.Op0Kind);
            Assert.Equal(tc.Op1Kind, info.Op1Kind);
            Assert.Equal(tc.Op2Kind, info.Op2Kind);
            Assert.Equal(tc.Op3Kind, info.Op3Kind);
            Assert.Equal(tc.Op4Kind, info.Op4Kind);
            Assert.Equal(tc.Op0Kind, info.GetOpKind(0));
            Assert.Equal(tc.Op1Kind, info.GetOpKind(1));
            Assert.Equal(tc.Op2Kind, info.GetOpKind(2));
            Assert.Equal(tc.Op3Kind, info.GetOpKind(3));
            Assert.Equal(tc.Op4Kind, info.GetOpKind(4));
            Assert.Equal(5, Iced.Intel.DecoderConstants.MaxOpCount);
            for (int i = tc.OpCount; i < Iced.Intel.DecoderConstants.MaxOpCount; i++)
            {
                Assert.Equal(OpCodeOperandKind.None, info.GetOpKind(i));
            }
        }
コード例 #2
0
        static OpCodeInfoTestCase ReadTestCase(string line, int lineNo)
        {
            var parts = line.Split(seps);

            if (parts.Length != 8)
            {
                throw new InvalidOperationException($"Invalid number of commas ({parts.Length - 1} commas)");
            }

            var tc = new OpCodeInfoTestCase();

            tc.LineNumber    = lineNo;
            tc.IsInstruction = true;
            tc.GroupIndex    = -1;

            var code = parts[0].Trim();

            if (CodeUtils.IsIgnored(code))
            {
                return(null);
            }
            tc.Code              = ToCode(code);
            tc.Encoding          = ToEncoding(parts[1].Trim());
            tc.MandatoryPrefix   = ToMandatoryPrefix(parts[2].Trim());
            tc.Table             = ToTable(parts[3].Trim());
            tc.OpCode            = ToOpCode(parts[4].Trim(), out tc.OpCodeLength);
            tc.OpCodeString      = parts[5].Trim();
            tc.InstructionString = parts[6].Trim().Replace('|', ',');

            bool gotVectorLength = false;
            bool gotW            = false;

            foreach (var part in parts[7].Split(optsseps))
            {
                var key = part.Trim();
                if (key.Length == 0)
                {
                    continue;
                }
                int index = key.IndexOf('=');
                if (index >= 0)
                {
                    var value = key.Substring(index + 1);
                    key = key.Substring(0, index);
                    switch (key)
                    {
                    case OpCodeInfoKeys.GroupIndex:
                        if (!uint.TryParse(value, out uint groupIndex) || groupIndex > 7)
                        {
                            throw new InvalidOperationException($"Invalid group index: {value}");
                        }
                        tc.GroupIndex = (int)groupIndex;
                        tc.IsGroup    = true;
                        break;

                    case OpCodeInfoKeys.RmGroupIndex:
                        if (!uint.TryParse(value, out uint rmGroupIndex) || rmGroupIndex > 7)
                        {
                            throw new InvalidOperationException($"Invalid group index: {value}");
                        }
                        tc.RmGroupIndex = (int)rmGroupIndex;
                        tc.IsRmGroup    = true;
                        break;

                    case OpCodeInfoKeys.OpCodeOperandKind:
                        var opParts = value.Split(opseps);
                        tc.OpCount = opParts.Length;
                        if (opParts.Length >= 1)
                        {
                            tc.Op0Kind = ToOpCodeOperandKind(opParts[0]);
                        }
                        if (opParts.Length >= 2)
                        {
                            tc.Op1Kind = ToOpCodeOperandKind(opParts[1]);
                        }
                        if (opParts.Length >= 3)
                        {
                            tc.Op2Kind = ToOpCodeOperandKind(opParts[2]);
                        }
                        if (opParts.Length >= 4)
                        {
                            tc.Op3Kind = ToOpCodeOperandKind(opParts[3]);
                        }
                        if (opParts.Length >= 5)
                        {
                            tc.Op4Kind = ToOpCodeOperandKind(opParts[4]);
                        }
                        Static.Assert(IcedConstants.MaxOpCount == 5 ? 0 : -1);
                        if (opParts.Length >= 6)
                        {
                            throw new InvalidOperationException($"Invalid number of operands: '{value}'");
                        }
                        break;

                    case OpCodeInfoKeys.TupleType:
                        tc.TupleType = ToTupleType(value.Trim());
                        break;

                    case OpCodeInfoKeys.DecoderOption:
                        tc.DecoderOption = ToDecoderOptions(value.Trim());
                        break;

                    default:
                        throw new InvalidOperationException($"Invalid key: '{key}'");
                    }
                }
                else
                {
                    switch (key)
                    {
                    case OpCodeInfoFlags.NoInstruction:
                        tc.IsInstruction = false;
                        break;

                    case OpCodeInfoFlags.Bit16:
                        tc.Mode16 = true;
                        break;

                    case OpCodeInfoFlags.Bit32:
                        tc.Mode32 = true;
                        break;

                    case OpCodeInfoFlags.Bit64:
                        tc.Mode64 = true;
                        break;

                    case OpCodeInfoFlags.Fwait:
                        tc.Fwait = true;
                        break;

                    case OpCodeInfoFlags.OperandSize16:
                        tc.OperandSize = 16;
                        break;

                    case OpCodeInfoFlags.OperandSize32:
                        tc.OperandSize = 32;
                        break;

                    case OpCodeInfoFlags.OperandSize64:
                        tc.OperandSize = 64;
                        break;

                    case OpCodeInfoFlags.AddressSize16:
                        tc.AddressSize = 16;
                        break;

                    case OpCodeInfoFlags.AddressSize32:
                        tc.AddressSize = 32;
                        break;

                    case OpCodeInfoFlags.AddressSize64:
                        tc.AddressSize = 64;
                        break;

                    case OpCodeInfoFlags.LIG:
                        tc.IsLIG        = true;
                        gotVectorLength = true;
                        break;

                    case OpCodeInfoFlags.L0:
                        tc.L            = 0;
                        gotVectorLength = true;
                        break;

                    case OpCodeInfoFlags.L1:
                        tc.L            = 1;
                        gotVectorLength = true;
                        break;

                    case OpCodeInfoFlags.L128:
                        tc.L            = 0;
                        gotVectorLength = true;
                        break;

                    case OpCodeInfoFlags.L256:
                        tc.L            = 1;
                        gotVectorLength = true;
                        break;

                    case OpCodeInfoFlags.L512:
                        tc.L            = 2;
                        gotVectorLength = true;
                        break;

                    case OpCodeInfoFlags.WIG:
                        tc.IsWIG = true;
                        gotW     = true;
                        break;

                    case OpCodeInfoFlags.WIG32:
                        tc.W       = 0;
                        tc.IsWIG32 = true;
                        gotW       = true;
                        break;

                    case OpCodeInfoFlags.W0:
                        tc.W = 0;
                        gotW = true;
                        break;

                    case OpCodeInfoFlags.W1:
                        tc.W = 1;
                        gotW = true;
                        break;

                    case OpCodeInfoFlags.Broadcast:
                        tc.CanBroadcast = true;
                        break;

                    case OpCodeInfoFlags.RoundingControl:
                        tc.CanUseRoundingControl = true;
                        break;

                    case OpCodeInfoFlags.SuppressAllExceptions:
                        tc.CanSuppressAllExceptions = true;
                        break;

                    case OpCodeInfoFlags.OpMaskRegister:
                        tc.CanUseOpMaskRegister = true;
                        break;

                    case OpCodeInfoFlags.RequireOpMaskRegister:
                        tc.CanUseOpMaskRegister  = true;
                        tc.RequireOpMaskRegister = true;
                        break;

                    case OpCodeInfoFlags.ZeroingMasking:
                        tc.CanUseZeroingMasking = true;
                        break;

                    case OpCodeInfoFlags.Lock:
                        tc.CanUseLockPrefix = true;
                        break;

                    case OpCodeInfoFlags.Xacquire:
                        tc.CanUseXacquirePrefix = true;
                        break;

                    case OpCodeInfoFlags.Xrelease:
                        tc.CanUseXreleasePrefix = true;
                        break;

                    case OpCodeInfoFlags.Rep:
                    case OpCodeInfoFlags.Repe:
                        tc.CanUseRepPrefix = true;
                        break;

                    case OpCodeInfoFlags.Repne:
                        tc.CanUseRepnePrefix = true;
                        break;

                    case OpCodeInfoFlags.Bnd:
                        tc.CanUseBndPrefix = true;
                        break;

                    case OpCodeInfoFlags.HintTaken:
                        tc.CanUseHintTakenPrefix = true;
                        break;

                    case OpCodeInfoFlags.Notrack:
                        tc.CanUseNotrackPrefix = true;
                        break;

                    case OpCodeInfoFlags.IgnoresRoundingControl:
                        tc.IgnoresRoundingControl = true;
                        break;

                    case OpCodeInfoFlags.AmdLockRegBit:
                        tc.AmdLockRegBit = true;
                        break;

                    case OpCodeInfoFlags.DefaultOpSize64:
                        tc.DefaultOpSize64 = true;
                        break;

                    case OpCodeInfoFlags.ForceOpSize64:
                        tc.ForceOpSize64 = true;
                        break;

                    case OpCodeInfoFlags.IntelForceOpSize64:
                        tc.IntelForceOpSize64 = true;
                        break;

                    case OpCodeInfoFlags.Cpl0:
                        tc.Cpl0 = true;
                        break;

                    case OpCodeInfoFlags.Cpl1:
                        tc.Cpl1 = true;
                        break;

                    case OpCodeInfoFlags.Cpl2:
                        tc.Cpl2 = true;
                        break;

                    case OpCodeInfoFlags.Cpl3:
                        tc.Cpl3 = true;
                        break;

                    case OpCodeInfoFlags.InputOutput:
                        tc.IsInputOutput = true;
                        break;

                    case OpCodeInfoFlags.Nop:
                        tc.IsNop = true;
                        break;

                    case OpCodeInfoFlags.ReservedNop:
                        tc.IsReservedNop = true;
                        break;

                    case OpCodeInfoFlags.SerializingIntel:
                        tc.IsSerializingIntel = true;
                        break;

                    case OpCodeInfoFlags.SerializingAmd:
                        tc.IsSerializingAmd = true;
                        break;

                    case OpCodeInfoFlags.MayRequireCpl0:
                        tc.MayRequireCpl0 = true;
                        break;

                    case OpCodeInfoFlags.CetTracked:
                        tc.IsCetTracked = true;
                        break;

                    case OpCodeInfoFlags.NonTemporal:
                        tc.IsNonTemporal = true;
                        break;

                    case OpCodeInfoFlags.FpuNoWait:
                        tc.IsFpuNoWait = true;
                        break;

                    case OpCodeInfoFlags.IgnoresModBits:
                        tc.IgnoresModBits = true;
                        break;

                    case OpCodeInfoFlags.No66:
                        tc.No66 = true;
                        break;

                    case OpCodeInfoFlags.NFx:
                        tc.NFx = true;
                        break;

                    case OpCodeInfoFlags.RequiresUniqueRegNums:
                        tc.RequiresUniqueRegNums = true;
                        break;

                    case OpCodeInfoFlags.Privileged:
                        tc.IsPrivileged = true;
                        break;

                    case OpCodeInfoFlags.SaveRestore:
                        tc.IsSaveRestore = true;
                        break;

                    case OpCodeInfoFlags.StackInstruction:
                        tc.IsStackInstruction = true;
                        break;

                    case OpCodeInfoFlags.IgnoresSegment:
                        tc.IgnoresSegment = true;
                        break;

                    case OpCodeInfoFlags.OpMaskReadWrite:
                        tc.IsOpMaskReadWrite = true;
                        break;

                    case OpCodeInfoFlags.RealMode:
                        tc.RealMode = true;
                        break;

                    case OpCodeInfoFlags.ProtectedMode:
                        tc.ProtectedMode = true;
                        break;

                    case OpCodeInfoFlags.Virtual8086Mode:
                        tc.Virtual8086Mode = true;
                        break;

                    case OpCodeInfoFlags.CompatibilityMode:
                        tc.CompatibilityMode = true;
                        break;

                    case OpCodeInfoFlags.LongMode:
                        tc.LongMode = true;
                        break;

                    case OpCodeInfoFlags.UseOutsideSmm:
                        tc.UseOutsideSmm = true;
                        break;

                    case OpCodeInfoFlags.UseInSmm:
                        tc.UseInSmm = true;
                        break;

                    case OpCodeInfoFlags.UseOutsideEnclaveSgx:
                        tc.UseOutsideEnclaveSgx = true;
                        break;

                    case OpCodeInfoFlags.UseInEnclaveSgx1:
                        tc.UseInEnclaveSgx1 = true;
                        break;

                    case OpCodeInfoFlags.UseInEnclaveSgx2:
                        tc.UseInEnclaveSgx2 = true;
                        break;

                    case OpCodeInfoFlags.UseOutsideVmxOp:
                        tc.UseOutsideVmxOp = true;
                        break;

                    case OpCodeInfoFlags.UseInVmxRootOp:
                        tc.UseInVmxRootOp = true;
                        break;

                    case OpCodeInfoFlags.UseInVmxNonRootOp:
                        tc.UseInVmxNonRootOp = true;
                        break;

                    case OpCodeInfoFlags.UseOutsideSeam:
                        tc.UseOutsideSeam = true;
                        break;

                    case OpCodeInfoFlags.UseInSeam:
                        tc.UseInSeam = true;
                        break;

                    case OpCodeInfoFlags.TdxNonRootGenUd:
                        tc.TdxNonRootGenUd = true;
                        break;

                    case OpCodeInfoFlags.TdxNonRootGenVe:
                        tc.TdxNonRootGenVe = true;
                        break;

                    case OpCodeInfoFlags.TdxNonRootMayGenEx:
                        tc.TdxNonRootMayGenEx = true;
                        break;

                    case OpCodeInfoFlags.IntelVmExit:
                        tc.IntelVmExit = true;
                        break;

                    case OpCodeInfoFlags.IntelMayVmExit:
                        tc.IntelMayVmExit = true;
                        break;

                    case OpCodeInfoFlags.IntelSmmVmExit:
                        tc.IntelSmmVmExit = true;
                        break;

                    case OpCodeInfoFlags.AmdVmExit:
                        tc.AmdVmExit = true;
                        break;

                    case OpCodeInfoFlags.AmdMayVmExit:
                        tc.AmdMayVmExit = true;
                        break;

                    case OpCodeInfoFlags.TsxAbort:
                        tc.TsxAbort = true;
                        break;

                    case OpCodeInfoFlags.TsxImplAbort:
                        tc.TsxImplAbort = true;
                        break;

                    case OpCodeInfoFlags.TsxMayAbort:
                        tc.TsxMayAbort = true;
                        break;

                    case OpCodeInfoFlags.IntelDecoder16:
                        tc.IntelDecoder16 = true;
                        break;

                    case OpCodeInfoFlags.IntelDecoder32:
                        tc.IntelDecoder32 = true;
                        break;

                    case OpCodeInfoFlags.IntelDecoder64:
                        tc.IntelDecoder64 = true;
                        break;

                    case OpCodeInfoFlags.AmdDecoder16:
                        tc.AmdDecoder16 = true;
                        break;

                    case OpCodeInfoFlags.AmdDecoder32:
                        tc.AmdDecoder32 = true;
                        break;

                    case OpCodeInfoFlags.AmdDecoder64:
                        tc.AmdDecoder64 = true;
                        break;

                    default:
                        throw new InvalidOperationException($"Invalid key: '{key}'");
                    }
                }
            }
            switch (tc.Encoding)
            {
            case EncodingKind.Legacy:
            case EncodingKind.D3NOW:
                break;

            case EncodingKind.VEX:
            case EncodingKind.EVEX:
            case EncodingKind.XOP:
                if (!gotVectorLength)
                {
                    throw new InvalidOperationException("Missing vector length: L0/L1/L128/L256/L512/LIG");
                }
                if (!gotW)
                {
                    throw new InvalidOperationException("Missing W bit: W0/W1/WIG/WIG32");
                }
                break;

            default:
                throw new InvalidOperationException();
            }

            return(tc);
        }
コード例 #3
0
ファイル: OpCodeInfoTests.cs プロジェクト: 34736384/iced
#pragma warning disable xUnit1026 // Theory methods should use all of their parameters
        void Test_all_OpCodeInfos(int lineNo, Code code, string opCodeString, string instructionString, OpCodeInfoTestCase tc)
        {
#pragma warning restore xUnit1026 // Theory methods should use all of their parameters
            var info = tc.Code.ToOpCode();
            Assert.Equal(tc.Code, info.Code);
#pragma warning disable xUnit2006 // Do not use invalid string equality check
            // Show the full string without ellipses by using Equal<string>() instead of Equal()
            Assert.Equal <string>(tc.OpCodeString, info.ToOpCodeString());
            Assert.Equal <string>(tc.InstructionString, info.ToInstructionString());
#pragma warning restore xUnit2006 // Do not use invalid string equality check
            Assert.True((object)info.ToInstructionString() == info.ToString());
            Assert.Equal(tc.Mnemonic, info.Mnemonic);
            Assert.Equal(tc.Encoding, info.Encoding);
            Assert.Equal(tc.IsInstruction, info.IsInstruction);
            Assert.Equal(tc.Mode16, info.Mode16);
            Assert.Equal(tc.Mode16, info.IsAvailableInMode(16));
            Assert.Equal(tc.Mode32, info.Mode32);
            Assert.Equal(tc.Mode32, info.IsAvailableInMode(32));
            Assert.Equal(tc.Mode64, info.Mode64);
            Assert.Equal(tc.Mode64, info.IsAvailableInMode(64));
            Assert.Equal(tc.Fwait, info.Fwait);
            Assert.Equal(tc.OperandSize, info.OperandSize);
            Assert.Equal(tc.AddressSize, info.AddressSize);
            Assert.Equal(tc.L, info.L);
            Assert.Equal(tc.W, info.W);
            Assert.Equal(tc.IsLIG, info.IsLIG);
            Assert.Equal(tc.IsWIG, info.IsWIG);
            Assert.Equal(tc.IsWIG32, info.IsWIG32);
            Assert.Equal(tc.TupleType, info.TupleType);
            Assert.Equal(tc.MemorySize, info.MemorySize);
            Assert.Equal(tc.BroadcastMemorySize, info.BroadcastMemorySize);
            Assert.Equal(tc.DecoderOption, info.DecoderOption);
            Assert.Equal(tc.CanBroadcast, info.CanBroadcast);
            Assert.Equal(tc.CanUseRoundingControl, info.CanUseRoundingControl);
            Assert.Equal(tc.CanSuppressAllExceptions, info.CanSuppressAllExceptions);
            Assert.Equal(tc.CanUseOpMaskRegister, info.CanUseOpMaskRegister);
            Assert.Equal(tc.RequireOpMaskRegister, info.RequireOpMaskRegister);
            if (tc.RequireOpMaskRegister)
            {
                Assert.True(info.CanUseOpMaskRegister);
                Assert.False(info.CanUseZeroingMasking);
            }
            Assert.Equal(tc.CanUseZeroingMasking, info.CanUseZeroingMasking);
            Assert.Equal(tc.CanUseLockPrefix, info.CanUseLockPrefix);
            Assert.Equal(tc.CanUseXacquirePrefix, info.CanUseXacquirePrefix);
            Assert.Equal(tc.CanUseXreleasePrefix, info.CanUseXreleasePrefix);
            Assert.Equal(tc.CanUseRepPrefix, info.CanUseRepPrefix);
            Assert.Equal(tc.CanUseRepnePrefix, info.CanUseRepnePrefix);
            Assert.Equal(tc.CanUseBndPrefix, info.CanUseBndPrefix);
            Assert.Equal(tc.CanUseHintTakenPrefix, info.CanUseHintTakenPrefix);
            Assert.Equal(tc.CanUseNotrackPrefix, info.CanUseNotrackPrefix);
            Assert.Equal(tc.IgnoresRoundingControl, info.IgnoresRoundingControl);
            Assert.Equal(tc.AmdLockRegBit, info.AmdLockRegBit);
            Assert.Equal(tc.DefaultOpSize64, info.DefaultOpSize64);
            Assert.Equal(tc.ForceOpSize64, info.ForceOpSize64);
            Assert.Equal(tc.IntelForceOpSize64, info.IntelForceOpSize64);
            Assert.Equal(tc.Cpl0 && !tc.Cpl1 && !tc.Cpl2 && !tc.Cpl3, info.MustBeCpl0);
            Assert.Equal(tc.Cpl0, info.Cpl0);
            Assert.Equal(tc.Cpl1, info.Cpl1);
            Assert.Equal(tc.Cpl2, info.Cpl2);
            Assert.Equal(tc.Cpl3, info.Cpl3);
            Assert.Equal(tc.IsInputOutput, info.IsInputOutput);
            Assert.Equal(tc.IsNop, info.IsNop);
            Assert.Equal(tc.IsReservedNop, info.IsReservedNop);
            Assert.Equal(tc.IsSerializingIntel, info.IsSerializingIntel);
            Assert.Equal(tc.IsSerializingAmd, info.IsSerializingAmd);
            Assert.Equal(tc.MayRequireCpl0, info.MayRequireCpl0);
            Assert.Equal(tc.IsCetTracked, info.IsCetTracked);
            Assert.Equal(tc.IsNonTemporal, info.IsNonTemporal);
            Assert.Equal(tc.IsFpuNoWait, info.IsFpuNoWait);
            Assert.Equal(tc.IgnoresModBits, info.IgnoresModBits);
            Assert.Equal(tc.No66, info.No66);
            Assert.Equal(tc.NFx, info.NFx);
            Assert.Equal(tc.RequiresUniqueRegNums, info.RequiresUniqueRegNums);
            Assert.Equal(tc.RequiresUniqueDestRegNum, info.RequiresUniqueDestRegNum);
            Assert.Equal(tc.IsPrivileged, info.IsPrivileged);
            Assert.Equal(tc.IsSaveRestore, info.IsSaveRestore);
            Assert.Equal(tc.IsStackInstruction, info.IsStackInstruction);
            Assert.Equal(tc.IgnoresSegment, info.IgnoresSegment);
            Assert.Equal(tc.IsOpMaskReadWrite, info.IsOpMaskReadWrite);
            Assert.Equal(tc.RealMode, info.RealMode);
            Assert.Equal(tc.ProtectedMode, info.ProtectedMode);
            Assert.Equal(tc.Virtual8086Mode, info.Virtual8086Mode);
            Assert.Equal(tc.CompatibilityMode, info.CompatibilityMode);
            Assert.Equal(tc.LongMode, info.LongMode);
            Assert.Equal(tc.UseOutsideSmm, info.UseOutsideSmm);
            Assert.Equal(tc.UseInSmm, info.UseInSmm);
            Assert.Equal(tc.UseOutsideEnclaveSgx, info.UseOutsideEnclaveSgx);
            Assert.Equal(tc.UseInEnclaveSgx1, info.UseInEnclaveSgx1);
            Assert.Equal(tc.UseInEnclaveSgx2, info.UseInEnclaveSgx2);
            Assert.Equal(tc.UseOutsideVmxOp, info.UseOutsideVmxOp);
            Assert.Equal(tc.UseInVmxRootOp, info.UseInVmxRootOp);
            Assert.Equal(tc.UseInVmxNonRootOp, info.UseInVmxNonRootOp);
            Assert.Equal(tc.UseOutsideSeam, info.UseOutsideSeam);
            Assert.Equal(tc.UseInSeam, info.UseInSeam);
            Assert.Equal(tc.TdxNonRootGenUd, info.TdxNonRootGenUd);
            Assert.Equal(tc.TdxNonRootGenVe, info.TdxNonRootGenVe);
            Assert.Equal(tc.TdxNonRootMayGenEx, info.TdxNonRootMayGenEx);
            Assert.Equal(tc.IntelVmExit, info.IntelVmExit);
            Assert.Equal(tc.IntelMayVmExit, info.IntelMayVmExit);
            Assert.Equal(tc.IntelSmmVmExit, info.IntelSmmVmExit);
            Assert.Equal(tc.AmdVmExit, info.AmdVmExit);
            Assert.Equal(tc.AmdMayVmExit, info.AmdMayVmExit);
            Assert.Equal(tc.TsxAbort, info.TsxAbort);
            Assert.Equal(tc.TsxImplAbort, info.TsxImplAbort);
            Assert.Equal(tc.TsxMayAbort, info.TsxMayAbort);
            Assert.Equal(tc.IntelDecoder16, info.IntelDecoder16);
            Assert.Equal(tc.IntelDecoder32, info.IntelDecoder32);
            Assert.Equal(tc.IntelDecoder64, info.IntelDecoder64);
            Assert.Equal(tc.AmdDecoder16, info.AmdDecoder16);
            Assert.Equal(tc.AmdDecoder32, info.AmdDecoder32);
            Assert.Equal(tc.AmdDecoder64, info.AmdDecoder64);
            Assert.Equal(tc.Table, info.Table);
            Assert.Equal(tc.MandatoryPrefix, info.MandatoryPrefix);
            Assert.Equal(tc.OpCode, info.OpCode);
            Assert.Equal(tc.OpCodeLength, info.OpCodeLength);
            Assert.Equal(tc.IsGroup, info.IsGroup);
            Assert.Equal(tc.GroupIndex, info.GroupIndex);
            Assert.Equal(tc.IsRmGroup, info.IsRmGroup);
            Assert.Equal(tc.RmGroupIndex, info.RmGroupIndex);
            Assert.Equal(tc.OpCount, info.OpCount);
            Assert.Equal(tc.Op0Kind, info.Op0Kind);
            Assert.Equal(tc.Op1Kind, info.Op1Kind);
            Assert.Equal(tc.Op2Kind, info.Op2Kind);
            Assert.Equal(tc.Op3Kind, info.Op3Kind);
            Assert.Equal(tc.Op4Kind, info.Op4Kind);
            Assert.Equal(tc.Op0Kind, info.GetOpKind(0));
            Assert.Equal(tc.Op1Kind, info.GetOpKind(1));
            Assert.Equal(tc.Op2Kind, info.GetOpKind(2));
            Assert.Equal(tc.Op3Kind, info.GetOpKind(3));
            Assert.Equal(tc.Op4Kind, info.GetOpKind(4));
            Static.Assert(IcedConstants.MaxOpCount == 5 ? 0 : -1);
            for (int i = tc.OpCount; i < IcedConstants.MaxOpCount; i++)
            {
                Assert.Equal(OpCodeOperandKind.None, info.GetOpKind(i));
            }
        }
コード例 #4
0
        static OpCodeInfoTestCase ReadTestCase(string line, int lineNo)
        {
            var parts = line.Split(seps);

            if (parts.Length != 8)
            {
                throw new InvalidOperationException($"Invalid number of commas ({parts.Length - 1} commas)");
            }

            var tc = new OpCodeInfoTestCase();

            tc.LineNumber    = lineNo;
            tc.IsInstruction = true;
            tc.GroupIndex    = -1;

            tc.Code              = ToCode(parts[0].Trim());
            tc.Encoding          = ToEncoding(parts[1].Trim());
            tc.MandatoryPrefix   = ToMandatoryPrefix(parts[2].Trim());
            tc.Table             = ToTable(parts[3].Trim());
            tc.OpCode            = ToOpCode(parts[4].Trim());
            tc.OpCodeString      = parts[5].Trim();
            tc.InstructionString = parts[6].Trim().Replace('|', ',');

            bool gotVectorLength = false;
            bool gotW            = false;

            foreach (var part in parts[7].Split(optsseps))
            {
                var key = part.Trim();
                if (key.Length == 0)
                {
                    continue;
                }
                int index = key.IndexOf('=');
                if (index >= 0)
                {
                    var value = key.Substring(index + 1);
                    key = key.Substring(0, index);
                    switch (key)
                    {
                    case "g":
                        if (!uint.TryParse(value, out uint groupIndex) || groupIndex > 7)
                        {
                            throw new InvalidOperationException($"Invalid group index: {value}");
                        }
                        tc.GroupIndex = (int)groupIndex;
                        tc.IsGroup    = true;
                        break;

                    case "op":
                        var opParts = value.Split(opseps);
                        tc.OpCount = opParts.Length;
                        if (opParts.Length >= 1)
                        {
                            tc.Op0Kind = ToOpCodeOperandKind(opParts[0]);
                        }
                        if (opParts.Length >= 2)
                        {
                            tc.Op1Kind = ToOpCodeOperandKind(opParts[1]);
                        }
                        if (opParts.Length >= 3)
                        {
                            tc.Op2Kind = ToOpCodeOperandKind(opParts[2]);
                        }
                        if (opParts.Length >= 4)
                        {
                            tc.Op3Kind = ToOpCodeOperandKind(opParts[3]);
                        }
                        if (opParts.Length >= 5)
                        {
                            tc.Op4Kind = ToOpCodeOperandKind(opParts[4]);
                        }
                        if (Iced.Intel.DecoderConstants.MaxOpCount != 5)
                        {
                            throw new InvalidOperationException("Invalid MaxOpCount value");
                        }
                        if (opParts.Length >= 6)
                        {
                            throw new InvalidOperationException($"Invalid number of operands: '{value}'");
                        }
                        break;

                    case "tt":
                        tc.TupleType = ToTupleType(value.Trim());
                        break;

                    default:
                        throw new InvalidOperationException($"Invalid key: '{key}'");
                    }
                }
                else
                {
                    switch (key)
                    {
                    case "notinstr":
                        tc.IsInstruction = false;
                        break;

                    case "16b":
                        tc.Mode16 = true;
                        break;

                    case "32b":
                        tc.Mode32 = true;
                        break;

                    case "64b":
                        tc.Mode64 = true;
                        break;

                    case "fwait":
                        tc.Fwait = true;
                        break;

                    case "o16":
                        tc.OperandSize = 16;
                        break;

                    case "o32":
                        tc.OperandSize = 32;
                        break;

                    case "o64":
                        tc.OperandSize = 64;
                        break;

                    case "a16":
                        tc.AddressSize = 16;
                        break;

                    case "a32":
                        tc.AddressSize = 32;
                        break;

                    case "a64":
                        tc.AddressSize = 64;
                        break;

                    case "LIG":
                        tc.IsLIG        = true;
                        gotVectorLength = true;
                        break;

                    case "L0":
                        tc.L            = 0;
                        gotVectorLength = true;
                        break;

                    case "L1":
                        tc.L            = 1;
                        gotVectorLength = true;
                        break;

                    case "L128":
                        tc.L            = 0;
                        gotVectorLength = true;
                        break;

                    case "L256":
                        tc.L            = 1;
                        gotVectorLength = true;
                        break;

                    case "L512":
                        tc.L            = 2;
                        gotVectorLength = true;
                        break;

                    case "WIG":
                        tc.IsWIG = true;
                        gotW     = true;
                        break;

                    case "WIG32":
                        tc.W       = 0;
                        tc.IsWIG32 = true;
                        gotW       = true;
                        break;

                    case "W0":
                        tc.W = 0;
                        gotW = true;
                        break;

                    case "W1":
                        tc.W = 1;
                        gotW = true;
                        break;

                    case "b":
                        tc.CanBroadcast = true;
                        break;

                    case "er":
                        tc.CanUseRoundingControl = true;
                        break;

                    case "sae":
                        tc.CanSuppressAllExceptions = true;
                        break;

                    case "k":
                        tc.CanUseOpMaskRegister = true;
                        break;

                    case "z":
                        tc.CanUseZeroingMasking = true;
                        break;

                    case "lock":
                        tc.CanUseLockPrefix = true;
                        break;

                    case "xacquire":
                        tc.CanUseXacquirePrefix = true;
                        break;

                    case "xrelease":
                        tc.CanUseXreleasePrefix = true;
                        break;

                    case "rep":
                    case "repe":
                        tc.CanUseRepPrefix = true;
                        break;

                    case "repne":
                        tc.CanUseRepnePrefix = true;
                        break;

                    case "bnd":
                        tc.CanUseBndPrefix = true;
                        break;

                    case "ht":
                        tc.CanUseHintTakenPrefix = true;
                        break;

                    case "notrack":
                        tc.CanUseNotrackPrefix = true;
                        break;

                    default:
                        throw new InvalidOperationException($"Invalid key: '{key}'");
                    }
                }
            }
            switch (tc.Encoding)
            {
            case EncodingKind.Legacy:
            case EncodingKind.D3NOW:
                break;

            case EncodingKind.VEX:
            case EncodingKind.EVEX:
            case EncodingKind.XOP:
                if (!gotVectorLength)
                {
                    throw new InvalidOperationException($"Missing vector length: L0/L1/L128/L256/L512/LIG");
                }
                if (!gotW)
                {
                    throw new InvalidOperationException($"Missing W bit: W0/W1/WIG");
                }
                break;

            default:
                throw new InvalidOperationException();
            }

            return(tc);
        }
コード例 #5
0
        static OpCodeInfoTestCase ReadTestCase(string line, int lineNo)
        {
            var parts = line.Split(seps);

            if (parts.Length != 8)
            {
                throw new InvalidOperationException($"Invalid number of commas ({parts.Length - 1} commas)");
            }

            var tc = new OpCodeInfoTestCase();

            tc.LineNumber    = lineNo;
            tc.IsInstruction = true;
            tc.GroupIndex    = -1;

            tc.Code              = ToCode(parts[0].Trim());
            tc.Encoding          = ToEncoding(parts[1].Trim());
            tc.MandatoryPrefix   = ToMandatoryPrefix(parts[2].Trim());
            tc.Table             = ToTable(parts[3].Trim());
            tc.OpCode            = ToOpCode(parts[4].Trim());
            tc.OpCodeString      = parts[5].Trim();
            tc.InstructionString = parts[6].Trim().Replace('|', ',');

            bool gotVectorLength = false;
            bool gotW            = false;

            foreach (var part in parts[7].Split(optsseps))
            {
                var key = part.Trim();
                if (key.Length == 0)
                {
                    continue;
                }
                int index = key.IndexOf('=');
                if (index >= 0)
                {
                    var value = key.Substring(index + 1);
                    key = key.Substring(0, index);
                    switch (key)
                    {
                    case OpCodeInfoKeys.GroupIndex:
                        if (!uint.TryParse(value, out uint groupIndex) || groupIndex > 7)
                        {
                            throw new InvalidOperationException($"Invalid group index: {value}");
                        }
                        tc.GroupIndex = (int)groupIndex;
                        tc.IsGroup    = true;
                        break;

                    case OpCodeInfoKeys.OpCodeOperandKind:
                        var opParts = value.Split(opseps);
                        tc.OpCount = opParts.Length;
                        if (opParts.Length >= 1)
                        {
                            tc.Op0Kind = ToOpCodeOperandKind(opParts[0]);
                        }
                        if (opParts.Length >= 2)
                        {
                            tc.Op1Kind = ToOpCodeOperandKind(opParts[1]);
                        }
                        if (opParts.Length >= 3)
                        {
                            tc.Op2Kind = ToOpCodeOperandKind(opParts[2]);
                        }
                        if (opParts.Length >= 4)
                        {
                            tc.Op3Kind = ToOpCodeOperandKind(opParts[3]);
                        }
                        if (opParts.Length >= 5)
                        {
                            tc.Op4Kind = ToOpCodeOperandKind(opParts[4]);
                        }
                        Static.Assert(IcedConstants.MaxOpCount == 5 ? 0 : -1);
                        if (opParts.Length >= 6)
                        {
                            throw new InvalidOperationException($"Invalid number of operands: '{value}'");
                        }
                        break;

                    case OpCodeInfoKeys.TupleType:
                        tc.TupleType = ToTupleType(value.Trim());
                        break;

                    default:
                        throw new InvalidOperationException($"Invalid key: '{key}'");
                    }
                }
                else
                {
                    switch (key)
                    {
                    case OpCodeInfoFlags.NotInstruction:
                        tc.IsInstruction = false;
                        break;

                    case OpCodeInfoFlags.Bit16:
                        tc.Mode16 = true;
                        break;

                    case OpCodeInfoFlags.Bit32:
                        tc.Mode32 = true;
                        break;

                    case OpCodeInfoFlags.Bit64:
                        tc.Mode64 = true;
                        break;

                    case OpCodeInfoFlags.Fwait:
                        tc.Fwait = true;
                        break;

                    case OpCodeInfoFlags.OperandSize16:
                        tc.OperandSize = 16;
                        break;

                    case OpCodeInfoFlags.OperandSize32:
                        tc.OperandSize = 32;
                        break;

                    case OpCodeInfoFlags.OperandSize64:
                        tc.OperandSize = 64;
                        break;

                    case OpCodeInfoFlags.AddressSize16:
                        tc.AddressSize = 16;
                        break;

                    case OpCodeInfoFlags.AddressSize32:
                        tc.AddressSize = 32;
                        break;

                    case OpCodeInfoFlags.AddressSize64:
                        tc.AddressSize = 64;
                        break;

                    case OpCodeInfoFlags.LIG:
                        tc.IsLIG        = true;
                        gotVectorLength = true;
                        break;

                    case OpCodeInfoFlags.L0:
                        tc.L            = 0;
                        gotVectorLength = true;
                        break;

                    case OpCodeInfoFlags.L1:
                        tc.L            = 1;
                        gotVectorLength = true;
                        break;

                    case OpCodeInfoFlags.L128:
                        tc.L            = 0;
                        gotVectorLength = true;
                        break;

                    case OpCodeInfoFlags.L256:
                        tc.L            = 1;
                        gotVectorLength = true;
                        break;

                    case OpCodeInfoFlags.L512:
                        tc.L            = 2;
                        gotVectorLength = true;
                        break;

                    case OpCodeInfoFlags.WIG:
                        tc.IsWIG = true;
                        gotW     = true;
                        break;

                    case OpCodeInfoFlags.WIG32:
                        tc.W       = 0;
                        tc.IsWIG32 = true;
                        gotW       = true;
                        break;

                    case OpCodeInfoFlags.W0:
                        tc.W = 0;
                        gotW = true;
                        break;

                    case OpCodeInfoFlags.W1:
                        tc.W = 1;
                        gotW = true;
                        break;

                    case OpCodeInfoFlags.Broadcast:
                        tc.CanBroadcast = true;
                        break;

                    case OpCodeInfoFlags.RoundingControl:
                        tc.CanUseRoundingControl = true;
                        break;

                    case OpCodeInfoFlags.SuppressAllExceptions:
                        tc.CanSuppressAllExceptions = true;
                        break;

                    case OpCodeInfoFlags.OpMaskRegister:
                        tc.CanUseOpMaskRegister = true;
                        break;

                    case OpCodeInfoFlags.RequireNonZeroOpMaskRegister:
                        tc.CanUseOpMaskRegister         = true;
                        tc.RequireNonZeroOpMaskRegister = true;
                        break;

                    case OpCodeInfoFlags.ZeroingMasking:
                        tc.CanUseZeroingMasking = true;
                        break;

                    case OpCodeInfoFlags.LockPrefix:
                        tc.CanUseLockPrefix = true;
                        break;

                    case OpCodeInfoFlags.XacquirePrefix:
                        tc.CanUseXacquirePrefix = true;
                        break;

                    case OpCodeInfoFlags.XreleasePrefix:
                        tc.CanUseXreleasePrefix = true;
                        break;

                    case OpCodeInfoFlags.RepPrefix:
                    case OpCodeInfoFlags.RepePrefix:
                        tc.CanUseRepPrefix = true;
                        break;

                    case OpCodeInfoFlags.RepnePrefix:
                        tc.CanUseRepnePrefix = true;
                        break;

                    case OpCodeInfoFlags.BndPrefix:
                        tc.CanUseBndPrefix = true;
                        break;

                    case OpCodeInfoFlags.HintTakenPrefix:
                        tc.CanUseHintTakenPrefix = true;
                        break;

                    case OpCodeInfoFlags.NotrackPrefix:
                        tc.CanUseNotrackPrefix = true;
                        break;

                    default:
                        throw new InvalidOperationException($"Invalid key: '{key}'");
                    }
                }
            }
            switch (tc.Encoding)
            {
            case EncodingKind.Legacy:
            case EncodingKind.D3NOW:
                break;

            case EncodingKind.VEX:
            case EncodingKind.EVEX:
            case EncodingKind.XOP:
                if (!gotVectorLength)
                {
                    throw new InvalidOperationException("Missing vector length: L0/L1/L128/L256/L512/LIG");
                }
                if (!gotW)
                {
                    throw new InvalidOperationException("Missing W bit: W0/W1/WIG/WIG32");
                }
                break;

            default:
                throw new InvalidOperationException();
            }

            return(tc);
        }