Ejemplo n.º 1
0
        public InstructionDef(EnumValue code, string opCodeString, string instructionString, EnumValue mnemonic,
                              EnumValue mem, EnumValue bcst, EnumValue decoderOption, InstructionDefFlags1 flags1, InstructionDefFlags2 flags2,
                              InstructionDefFlags3 flags3, InstrStrFmtOption instrStrFmtOption, InstructionStringFlags instrStrFlags,
                              InstrStrImpliedOp[] instrStrImpliedOps,
                              MandatoryPrefix mandatoryPrefix, OpCodeTableKind table, OpCodeL lBit, OpCodeW wBit, uint opCode, int opCodeLength,
                              int groupIndex, int rmGroupIndex, CodeSize operandSize, CodeSize addressSize, TupleType tupleType, OpCodeOperandKind[] opKinds,
                              PseudoOpsKind?pseudoOp, EnumValue encoding, EnumValue flowControl, ConditionCode conditionCode,
                              BranchKind branchKind, RflagsBits read, RflagsBits undefined, RflagsBits written, RflagsBits cleared, RflagsBits set,
                              EnumValue[] cpuid, OpInfo[] opInfo,
                              FastFmtInstructionDef fast, FmtInstructionDef gas, FmtInstructionDef intel, FmtInstructionDef masm, FmtInstructionDef nasm)
        {
            Code               = code;
            OpCodeString       = opCodeString;
            InstructionString  = instructionString;
            Mnemonic           = mnemonic;
            Memory             = mem;
            MemoryBroadcast    = bcst;
            DecoderOption      = decoderOption;
            EncodingValue      = encoding;
            Flags1             = flags1;
            Flags2             = flags2;
            Flags3             = flags3;
            InstrStrFmtOption  = instrStrFmtOption;
            InstrStrFlags      = instrStrFlags;
            InstrStrImpliedOps = instrStrImpliedOps;

            MandatoryPrefix = mandatoryPrefix;
            Table           = table;
            LBit            = lBit;
            WBit            = wBit;
            OpCode          = opCode;
            OpCodeLength    = opCodeLength;
            GroupIndex      = groupIndex;
            RmGroupIndex    = rmGroupIndex;
            TupleType       = tupleType;
            OperandSize     = operandSize;
            AddressSize     = addressSize;
            OpKinds         = opKinds;

            PseudoOp        = pseudoOp;
            ControlFlow     = flowControl;
            ConditionCode   = conditionCode;
            BranchKind      = branchKind;
            RflagsRead      = read;
            RflagsUndefined = undefined;
            RflagsWritten   = written;
            RflagsCleared   = cleared;
            RflagsSet       = set;
            RflagsInfo      = null;
            Cpuid           = cpuid;
            CpuidInternal   = null;
            OpInfo          = opInfo;
            OpInfoEnum      = new EnumValue[opInfo.Length];

            Fast  = fast;
            Gas   = gas;
            Intel = intel;
            Masm  = masm;
            Nasm  = nasm;
        }
Ejemplo n.º 2
0
 public XopOpCodeInfo(EnumValue code, MandatoryPrefix mandatoryPrefix, OpCodeTableKind table, uint opCode, int groupIndex, XopVectorLength vecLen, OpCodeFlags flags, XopOpKind[] opKinds)
 {
     Code            = code;
     MandatoryPrefix = mandatoryPrefix;
     Table           = table;
     OpCode          = opCode;
     GroupIndex      = groupIndex;
     Flags           = flags;
     VectorLength    = vecLen;
     OpKinds         = opKinds;
 }
Ejemplo n.º 3
0
 public VexHandler(uint dword1, uint dword2, uint dword3)
     : base(GetCode(dword1), GetOpCode(dword1), GetGroupIndex(dword2), (Encodable)((dword2 >> (int)VexFlags.EncodableShift) & (int)VexFlags.EncodableMask), OperandSize.None, AddressSize.None, null, CreateOps(dword3))
 {
     opCodeTable     = (OpCodeTable)((dword2 >> (int)VexFlags.OpCodeTableShift) & (int)VexFlags.OpCodeTableMask);
     mandatoryPrefix = (MandatoryPrefix)((dword2 >> (int)VexFlags.MandatoryPrefixShift) & (int)VexFlags.MandatoryPrefixMask);
     W1       = (dword2 & (uint)VexFlags.VEX_W1) != 0;
     lastByte = (dword2 >> ((int)VexFlags.VEX_LShift - 2)) & 4;
     if (W1)
     {
         lastByte |= 0x80;
     }
 }
Ejemplo n.º 4
0
 public EvexOpCodeInfo(EnumValue code, MandatoryPrefix mandatoryPrefix, OpCodeTableKind table, uint opCode, int groupIndex, EvexVectorLength vecLen, TupleType tupleType, OpCodeFlags flags, EvexOpKind[] opKinds)
 {
     Code            = code;
     MandatoryPrefix = mandatoryPrefix;
     Table           = table;
     OpCode          = opCode;
     GroupIndex      = groupIndex;
     Flags           = flags;
     VectorLength    = vecLen;
     OpKinds         = opKinds;
     TupleType       = tupleType;
 }
Ejemplo n.º 5
0
 public LegacyOpCodeInfo(EnumValue code, MandatoryPrefix mandatoryPrefix, OpCodeTableKind table, uint opCode, int groupIndex, OperandSize operandSize, AddressSize addressSize, OpCodeFlags flags, LegacyOpKind[] opKinds)
 {
     Code            = code;
     MandatoryPrefix = mandatoryPrefix;
     Table           = table;
     OpCode          = opCode;
     GroupIndex      = groupIndex;
     Flags           = flags;
     OperandSize     = operandSize;
     AddressSize     = addressSize;
     OpKinds         = opKinds;
 }
Ejemplo n.º 6
0
 public EvexOpCodeInfo(EnumValue code, MandatoryPrefix mandatoryPrefix, OpCodeTableKind table, uint opCode, int groupIndex, EvexVectorLength vecLen, TupleType tupleType, OpCodeFlags flags, EvexOpKind[] opKinds)
     : this(code, mandatoryPrefix, table, opCode, groupIndex, -1, vecLen, tupleType, flags, opKinds)
 {
 }
Ejemplo n.º 7
0
 public XopOpCodeInfo(EnumValue code, MandatoryPrefix mandatoryPrefix, OpCodeTableKind table, uint opCode, int groupIndex, XopVectorLength vecLen, OpCodeFlags flags, XopOpKind[] opKinds)
     : this(code, mandatoryPrefix, table, opCode, groupIndex, -1, vecLen, flags, opKinds)
 {
 }
Ejemplo n.º 8
0
 public LegacyOpCodeInfo(EnumValue code, MandatoryPrefix mandatoryPrefix, OpCodeTableKind table, uint opCode, int groupIndex, OperandSize operandSize, AddressSize addressSize, OpCodeFlags flags, LegacyOpKind[] opKinds)
     : this(code, mandatoryPrefix, table, opCode, groupIndex, -1, operandSize, addressSize, flags, opKinds)
 {
 }
Ejemplo n.º 9
0
        internal static FuzzerInstruction CreateValid(Code code, bool isModrmMemory, uint w, uint l, MandatoryPrefix mandatoryPrefix, int groupIndex, OpCode?opCode = null)
        {
            var opc        = code.ToOpCode();
            var table      = GetTable(opc.Encoding, opc.Table);
            var realOpCode = opCode ?? OpCode.CreateFromUInt32(opc.OpCode);
            const FuzzerInstructionFlags flags = FuzzerInstructionFlags.None;

            return(new FuzzerInstruction(code, flags, w, l, mandatoryPrefix, table, realOpCode, groupIndex, opc.RmGroupIndex, isModrmMemory, opc.OperandSize, opc.AddressSize));
        }
Ejemplo n.º 10
0
 internal static FuzzerInstruction CreateInvalidVec(FuzzerOpCodeTable table, OpCode opCode, int groupIndex, int rmGroupIndex, bool isModrmMemory, MandatoryPrefix mandatoryPrefix, uint w, uint l, FuzzerInstructionFlags flags) =>
 new FuzzerInstruction(Code.INVALID, flags, w, l, mandatoryPrefix, table, opCode, groupIndex, rmGroupIndex, isModrmMemory, 0, 0);
Ejemplo n.º 11
0
 internal static FuzzerInstruction CreateInvalidLegacy(FuzzerOpCodeTable table, OpCode opCode, int groupIndex, bool isModrmMemory, MandatoryPrefix mandatoryPrefix) =>
 new FuzzerInstruction(Code.INVALID, FuzzerInstructionFlags.None, 0, 0, mandatoryPrefix, table, opCode, groupIndex, -1, isModrmMemory, 0, 0);
Ejemplo n.º 12
0
        FuzzerInstruction(Code code, FuzzerInstructionFlags flags, uint w, uint l, MandatoryPrefix mandatoryPrefix, FuzzerOpCodeTable table, OpCode opCode, int groupIndex, int rmGroupIndex, bool isModrmMemory, int operandSize, int addressSize)
        {
            // Should be a 2-byte opcode instead (groupIndex = modrm.reg and rmGroupIndex = modrm.rm bits)
            Assert.True(groupIndex < 0 || rmGroupIndex < 0);
            Assert.True(groupIndex >= -1 && groupIndex <= 7);
            Assert.True(rmGroupIndex >= -1 && rmGroupIndex <= 7);
            var opc = code.ToOpCode();

            Assert.True(opc.IsInstruction || code == Code.INVALID);

            if (isModrmMemory)
            {
                if (opc.CanBroadcast)
                {
                    flags |= FuzzerInstructionFlags.CanBroadcast;
                }
                if (opc.CanUseLockPrefix)
                {
                    flags |= FuzzerInstructionFlags.CanUseLockPrefix;
                }
            }
            else
            {
                if (opc.CanUseRoundingControl)
                {
                    flags |= FuzzerInstructionFlags.CanUseRoundingControl;
                }
                if (opc.CanSuppressAllExceptions)
                {
                    flags |= FuzzerInstructionFlags.CanSuppressAllExceptions;
                }
            }
            if (opc.RequireNonZeroOpMaskRegister)
            {
                flags |= FuzzerInstructionFlags.RequireNonZeroOpMaskRegister;
            }
            if (opc.CanUseZeroingMasking)
            {
                flags |= FuzzerInstructionFlags.CanUseZeroingMasking;
            }
            if (opc.CanUseOpMaskRegister)
            {
                flags |= FuzzerInstructionFlags.CanUseOpMaskRegister;
            }
            switch (code)
            {
            case Code.Xchg_r16_AX:
            case Code.Xchg_r32_EAX:
            case Code.Xchg_r64_RAX:
                flags |= FuzzerInstructionFlags.IsXchgRegAcc;
                break;

            case Code.Nopw:
            case Code.Nopd:
            case Code.Nopq:
                flags |= FuzzerInstructionFlags.IsNop;
                break;

            case Code.Rdrand_r16:
            case Code.Rdrand_r32:
            case Code.Rdrand_r64:
            case Code.Rdseed_r16:
            case Code.Rdseed_r32:
            case Code.Rdseed_r64:
            case Code.Movbe_r16_m16:
            case Code.Movbe_r32_m32:
            case Code.Movbe_r64_m64:
            case Code.Movbe_m16_r16:
            case Code.Movbe_m32_r32:
            case Code.Movbe_m64_r64:
                Assert.True(mandatoryPrefix == MandatoryPrefix.None);
                mandatoryPrefix = MandatoryPrefix.PNP;
                flags          |= FuzzerInstructionFlags.IsNFx;
                break;
            }

            Code            = code;
            Flags           = flags;
            W               = w;
            L               = l;
            MandatoryPrefix = mandatoryPrefix;
            Table           = table;
            OpCode          = opCode;
            GroupIndex      = groupIndex;
            RmGroupIndex    = rmGroupIndex;
            IsModrmMemory   = isModrmMemory;
            OperandSize     = operandSize;
            AddressSize     = addressSize;

            if (MandatoryPrefix == MandatoryPrefix.P66 && operandSize != 64 && CodeUtils.IsReservedNop(Code))
            {
                MandatoryPrefix = MandatoryPrefix.None;
            }

            FuzzerOperand[]? operands = null;
            // Special support for reserved nop instructions since we may have transformed them to
            // a 2-byte opcode (no ops) or a reg or rm group (one operand).
            if (CodeUtils.IsReservedNop(code))
            {
                // Verify our assumptions
                Assert.True(opc.OpCount == 2);
                const int RM_INDEX  = 0;
                const int REG_INDEX = 1;
                switch (opc.GetOpKind(RM_INDEX))
                {
                case OpCodeOperandKind.r16_or_mem:
                case OpCodeOperandKind.r32_or_mem:
                case OpCodeOperandKind.r64_or_mem:
                    break;

                default:
                    throw ThrowHelpers.Unreachable;
                }
                switch (opc.GetOpKind(REG_INDEX))
                {
                case OpCodeOperandKind.r16_reg:
                case OpCodeOperandKind.r32_reg:
                case OpCodeOperandKind.r64_reg:
                    break;

                default:
                    throw ThrowHelpers.Unreachable;
                }

                if (OpCode.IsTwobyte)
                {
                    Assert.True(groupIndex < 0 && rmGroupIndex < 0);
                    operands = Array.Empty <FuzzerOperand>();
                }
                else if (groupIndex >= 0)
                {
                    Assert.True(rmGroupIndex < 0);
                    // reg bits are hard coded, rm bits can be used
                    operands = new FuzzerOperand[1] {
                        FuzzerOperands.GetOperand(opc.GetOpKind(RM_INDEX), isModrmMemory)
                    };
                }
                else if (rmGroupIndex >= 0)
                {
                    // rm bits are hard coded, reg bits can be used
                    operands = new FuzzerOperand[1] {
                        FuzzerOperands.GetOperand(opc.GetOpKind(REG_INDEX), isModrmMemory)
                    };
                }
            }
            if (operands is null)
            {
                int opCount = opc.OpCount + (opc.CanUseOpMaskRegister ? 1 : 0);
                operands = opCount == 0 ? Array.Empty <FuzzerOperand>() : new FuzzerOperand[opCount];
                int i;
                for (i = 0; i < opc.OpCount; i++)
                {
                    operands[i] = FuzzerOperands.GetOperand(opc.GetOpKind(i), isModrmMemory);
                }
                if (opc.CanUseOpMaskRegister)
                {
                    operands[i++] = FuzzerOperands.OpMaskRegister;
                }
                Assert.True(i == operands.Length);
            }
            operands = operands.Where(a => a.Kind != FuzzerOperandKind.None).ToArray();
            Operands = operands;
            Assert.True(!opc.CanUseOpMaskRegister || (operands.Length > 0 && operands[operands.Length - 1] == FuzzerOperands.OpMaskRegister));
            ImmediateOperands   = operands.OfType <ImmediateFuzzerOperand>().ToArray();
            MemOffsOperands     = operands.Where(a => a.Kind == FuzzerOperandKind.MemOffs).ToArray();
            ImpliedMemOperands  = operands.Where(a => a.Kind == FuzzerOperandKind.ImpliedMem).ToArray();
            ModrmMemoryOperands = operands.OfType <ModrmMemoryFuzzerOperand>().ToArray();
            RegisterOperands    = operands.OfType <RegisterFuzzerOperand>().ToArray();
            // There are fuzzers that test only some of these op kinds, so if there's a new op kind, a new fuzzer would need
            // to be added, see eg AllMemOffsFuzzerGen
            Assert.True(Operands.Length == ImmediateOperands.Length + MemOffsOperands.Length + ImpliedMemOperands.Length + ModrmMemoryOperands.Length + RegisterOperands.Length);

            foreach (var memOp in ModrmMemoryOperands)
            {
                if (memOp.IsVSIB)
                {
                    Flags |= FuzzerInstructionFlags.IsVsib;
                    break;
                }
            }
        }