mirror of https://github.com/x64dbg/zydis
Internal changes and optimizations of the generated tables and the InstructionEditor
This commit is contained in:
parent
be56ef937d
commit
7f7cbd8dcd
Binary file not shown.
|
@ -158,7 +158,7 @@ const
|
||||||
FILENAME_MNEMONICSTRINGS = 'MnemonicStrings.inc';
|
FILENAME_MNEMONICSTRINGS = 'MnemonicStrings.inc';
|
||||||
FILENAME_INSTRUCTIONDEFINITIONS = 'InstructionDefinitions.inc';
|
FILENAME_INSTRUCTIONDEFINITIONS = 'InstructionDefinitions.inc';
|
||||||
FILENAME_OPERANDDEFINITIONS = 'OperandDefinitions.inc';
|
FILENAME_OPERANDDEFINITIONS = 'OperandDefinitions.inc';
|
||||||
FILENAME_INTERNALSTRUCTS = 'InternalStructs.inc';
|
FILENAME_GENERATEDTYPES = 'GeneratedTypes.inc';
|
||||||
|
|
||||||
{ TCodeGenerator }
|
{ TCodeGenerator }
|
||||||
|
|
||||||
|
@ -562,8 +562,15 @@ begin
|
||||||
if (ifHasEvexSAE in Definition.Flags) then U := 'ZYDIS_EVEXB_FUNCTIONALITY_SAE';
|
if (ifHasEvexSAE in Definition.Flags) then U := 'ZYDIS_EVEXB_FUNCTIONALITY_SAE';
|
||||||
|
|
||||||
Buffer.Append(Format(' /*%.4x*/ ', [Index]));
|
Buffer.Append(Format(' /*%.4x*/ ', [Index]));
|
||||||
Buffer.Append(Format('ZYDIS_MAKE_INSTRUCTIONDEFINITION(ZYDIS_MNEMONIC_%s, 0x%.4x, %s, %s, %s)', [
|
Buffer.Append(Format('{ ZYDIS_MNEMONIC_%s, 0x%.4x, %s, %s, %s, %d, %d, %d, %d, %d, %d, %d }', [
|
||||||
AnsiUpperCase(Definition.Mnemonic), O, U, S, T]));
|
AnsiUpperCase(Definition.Mnemonic), O, U, S, T,
|
||||||
|
Byte(pfAcceptsLock in Definition.PrefixFlags),
|
||||||
|
Byte(pfAcceptsREP in Definition.PrefixFlags),
|
||||||
|
Byte(pfAcceptsREPEREPNE in Definition.PrefixFlags),
|
||||||
|
Byte(pfAcceptsXACQUIRE in Definition.PrefixFlags),
|
||||||
|
Byte(pfAcceptsXRELEASE in Definition.PrefixFlags),
|
||||||
|
Byte(pfAcceptsHLEWithoutLock in Definition.PrefixFlags),
|
||||||
|
Byte(pfAcceptsBranchHints in Definition.PrefixFlags)]));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
var
|
var
|
||||||
|
@ -573,7 +580,7 @@ var
|
||||||
begin
|
begin
|
||||||
Buffer := TStringBuffer.Create;
|
Buffer := TStringBuffer.Create;
|
||||||
try
|
try
|
||||||
Buffer.AppendLn('const ZydisInternalInstructionDefinition instructionDefinitions[] =');
|
Buffer.AppendLn('const ZydisInstructionDefinition instructionDefinitions[] =');
|
||||||
Buffer.AppendLn('{');
|
Buffer.AppendLn('{');
|
||||||
WorkStart('Generating instruction definitions', 0, Length(DefinitionList));
|
WorkStart('Generating instruction definitions', 0, Length(DefinitionList));
|
||||||
for I := Low(DefinitionList) to High(DefinitionList) do
|
for I := Low(DefinitionList) to High(DefinitionList) do
|
||||||
|
@ -637,7 +644,7 @@ begin
|
||||||
end;
|
end;
|
||||||
|
|
||||||
// Open the filter-array
|
// Open the filter-array
|
||||||
Buffer.AppendLn(Format('const ZydisInternalInstructionTableNode filter%s[][%d] = ', [
|
Buffer.AppendLn(Format('const ZydisInstructionTableNode filter%s[][%d] = ', [
|
||||||
InstructionFilterClasses[I].GetDescription,
|
InstructionFilterClasses[I].GetDescription,
|
||||||
Integer(InstructionFilterClasses[I].GetCapacity) - IndexShift]));
|
Integer(InstructionFilterClasses[I].GetCapacity) - IndexShift]));
|
||||||
Buffer.AppendLn('{');
|
Buffer.AppendLn('{');
|
||||||
|
@ -943,7 +950,7 @@ begin
|
||||||
opaWrite : OperandAccessMode := 'WRITE';
|
opaWrite : OperandAccessMode := 'WRITE';
|
||||||
opaReadWrite : OperandAccessMode := 'READWRITE';
|
opaReadWrite : OperandAccessMode := 'READWRITE';
|
||||||
end;
|
end;
|
||||||
Buffer.Append(Format('ZYDIS_MAKE_OPERANDDEFINITION(ZYDIS_SEM_OPERAND_TYPE_%s, ' +
|
Buffer.Append(Format('ZYDIS_OPERAND_DEFINITION(ZYDIS_SEM_OPERAND_TYPE_%s, ' +
|
||||||
'ZYDIS_OPERAND_ENCODING_%s, ZYDIS_OPERAND_ACCESS_%s)', [
|
'ZYDIS_OPERAND_ENCODING_%s, ZYDIS_OPERAND_ACCESS_%s)', [
|
||||||
OperandType, OperandEncoding, OperandAccessMode]));
|
OperandType, OperandEncoding, OperandAccessMode]));
|
||||||
end;
|
end;
|
||||||
|
@ -966,7 +973,7 @@ begin
|
||||||
// Generate operand-definition tables
|
// Generate operand-definition tables
|
||||||
for I := Low(OperandMapping) to High(OperandMapping) do
|
for I := Low(OperandMapping) to High(OperandMapping) do
|
||||||
begin
|
begin
|
||||||
Buffer.AppendLn(Format('const ZydisInternalOperandDefinition operandDefinitions%d[][%d] =',
|
Buffer.AppendLn(Format('const ZydisOperandDefinition operandDefinitions%d[][%d] =',
|
||||||
[I, I]));
|
[I, I]));
|
||||||
Buffer.AppendLn('{');
|
Buffer.AppendLn('{');
|
||||||
for J := Low(OperandMapping[I]) to High(OperandMapping[I]) do
|
for J := Low(OperandMapping[I]) to High(OperandMapping[I]) do
|
||||||
|
@ -996,7 +1003,7 @@ begin
|
||||||
Buffer.Append(Format(' /*%.4x*/ { ', [0]));
|
Buffer.Append(Format(' /*%.4x*/ { ', [0]));
|
||||||
for K := 1 to I do
|
for K := 1 to I do
|
||||||
begin
|
begin
|
||||||
Buffer.Append('ZYDIS_MAKE_OPERANDDEFINITION(ZYDIS_SEM_OPERAND_TYPE_UNUSED, ' +
|
Buffer.Append('ZYDIS_OPERAND_DEFINITION(ZYDIS_SEM_OPERAND_TYPE_UNUSED, ' +
|
||||||
'ZYDIS_OPERAND_ENCODING_NONE, ZYDIS_OPERAND_ACCESS_READ)');
|
'ZYDIS_OPERAND_ENCODING_NONE, ZYDIS_OPERAND_ACCESS_READ)');
|
||||||
if (K <> I) then
|
if (K <> I) then
|
||||||
begin
|
begin
|
||||||
|
|
|
@ -355,6 +355,38 @@ type
|
||||||
property FlagID: TX86FlagValue read FID write SetID default fvUnused;
|
property FlagID: TX86FlagValue read FID write SetID default fvUnused;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{TEVEXEncodingContext = (
|
||||||
|
ecNone,
|
||||||
|
ecBroadcast,
|
||||||
|
ecRoundingControl,
|
||||||
|
ecSuppressAllExceptions
|
||||||
|
);
|
||||||
|
|
||||||
|
TEVEXInformation = class(TPersistent)
|
||||||
|
strict private
|
||||||
|
FDefinition: TInstructionDefinition;
|
||||||
|
strict private
|
||||||
|
procedure Changed; inline;
|
||||||
|
strict private
|
||||||
|
function GetConflictState: Boolean;
|
||||||
|
private
|
||||||
|
procedure LoadFromJSON(JSON: PJSONVariantData; const FieldName: String);
|
||||||
|
procedure SaveToJSON(JSON: PJSONVariantData; const FieldName: String);
|
||||||
|
protected
|
||||||
|
procedure AssignTo(Dest: TPersistent); override;
|
||||||
|
protected
|
||||||
|
constructor Create(Definition: TInstructionDefinition);
|
||||||
|
public
|
||||||
|
function Equals(const Value: TX86Flags): Boolean; reintroduce;
|
||||||
|
public
|
||||||
|
property HasConflicts: Boolean read GetConflictState;
|
||||||
|
published
|
||||||
|
property EncodingContext: TEVEXEncodingContext;
|
||||||
|
property HasEvexAAA: Boolean;
|
||||||
|
property HasEvexZ: Boolean;
|
||||||
|
property CD8Scale: Cardinal;
|
||||||
|
end;}
|
||||||
|
|
||||||
TInstructionOperands = class;
|
TInstructionOperands = class;
|
||||||
|
|
||||||
TOperandType = (
|
TOperandType = (
|
||||||
|
@ -542,6 +574,8 @@ type
|
||||||
idcForcedConflict,
|
idcForcedConflict,
|
||||||
// The instruction-operands configuration is invalid
|
// The instruction-operands configuration is invalid
|
||||||
idcOperands,
|
idcOperands,
|
||||||
|
// The prefix-flags are invalid
|
||||||
|
idcPrefixFlags,
|
||||||
// The FLAGS/EFLAGS/RFLAGS registers in the ImplicitRead or ImplicitWrite property do not
|
// The FLAGS/EFLAGS/RFLAGS registers in the ImplicitRead or ImplicitWrite property do not
|
||||||
// match the given X86Flags configuration
|
// match the given X86Flags configuration
|
||||||
idcX86Flags
|
idcX86Flags
|
||||||
|
@ -568,13 +602,19 @@ type
|
||||||
|
|
||||||
TOpcodeByte = type Byte;
|
TOpcodeByte = type Byte;
|
||||||
|
|
||||||
|
TPrefixFlag = (
|
||||||
|
pfAcceptsLock,
|
||||||
|
pfAcceptsREP,
|
||||||
|
pfAcceptsREPEREPNE,
|
||||||
|
pfAcceptsXACQUIRE,
|
||||||
|
pfAcceptsXRELEASE,
|
||||||
|
pfAcceptsHLEWithoutLock,
|
||||||
|
pfAcceptsBranchHints
|
||||||
|
);
|
||||||
|
TPrefixFlags = set of TPrefixFlag;
|
||||||
|
|
||||||
TInstructionDefinitionFlag = (
|
TInstructionDefinitionFlag = (
|
||||||
ifForceConflict,
|
ifForceConflict,
|
||||||
ifAcceptsLock,
|
|
||||||
ifAcceptsREP,
|
|
||||||
ifAcceptsXACQUIRE,
|
|
||||||
ifAcceptsXRELEASE,
|
|
||||||
ifAcceptsBranchHints,
|
|
||||||
ifAcceptsEVEXAAA,
|
ifAcceptsEVEXAAA,
|
||||||
ifAcceptsEVEXZ,
|
ifAcceptsEVEXZ,
|
||||||
ifIsPrivileged,
|
ifIsPrivileged,
|
||||||
|
@ -601,6 +641,7 @@ type
|
||||||
FExtensions: TOpcodeExtensions;
|
FExtensions: TOpcodeExtensions;
|
||||||
FCPUID: TCPUIDFeatureFlags;
|
FCPUID: TCPUIDFeatureFlags;
|
||||||
FOperands: TInstructionOperands;
|
FOperands: TInstructionOperands;
|
||||||
|
FPrefixFlags: TPrefixFlags;
|
||||||
FFlags: TInstructionDefinitionFlags;
|
FFlags: TInstructionDefinitionFlags;
|
||||||
FImplicitRead: TX86Registers;
|
FImplicitRead: TX86Registers;
|
||||||
FImplicitWrite: TX86Registers;
|
FImplicitWrite: TX86Registers;
|
||||||
|
@ -613,6 +654,7 @@ type
|
||||||
procedure SetEncoding(const Value: TInstructionEncoding); inline;
|
procedure SetEncoding(const Value: TInstructionEncoding); inline;
|
||||||
procedure SetOpcodeMap(const Value: TOpcodeMap); inline;
|
procedure SetOpcodeMap(const Value: TOpcodeMap); inline;
|
||||||
procedure SetOpcode(const Value: TOpcodeByte); inline;
|
procedure SetOpcode(const Value: TOpcodeByte); inline;
|
||||||
|
procedure SetPrefixFlags(const Value: TPrefixFlags); inline;
|
||||||
procedure SetFlags(const Value: TInstructionDefinitionFlags); inline;
|
procedure SetFlags(const Value: TInstructionDefinitionFlags); inline;
|
||||||
procedure SetComment(const Value: String); inline;
|
procedure SetComment(const Value: String); inline;
|
||||||
strict private
|
strict private
|
||||||
|
@ -650,7 +692,8 @@ type
|
||||||
property OpcodeExtensions: TOpcodeExtensions read FExtensions;
|
property OpcodeExtensions: TOpcodeExtensions read FExtensions;
|
||||||
property CPUID: TCPUIDFeatureFlags read FCPUID;
|
property CPUID: TCPUIDFeatureFlags read FCPUID;
|
||||||
property Operands: TInstructionOperands read FOperands;
|
property Operands: TInstructionOperands read FOperands;
|
||||||
property Flags: TInstructionDefinitionFlags read FFlags write SetFlags;
|
property PrefixFlags: TPrefixFlags read FPrefixFlags write SetPrefixFlags default [];
|
||||||
|
property Flags: TInstructionDefinitionFlags read FFlags write SetFlags default [];
|
||||||
property ImplicitRead: TX86Registers read FImplicitRead;
|
property ImplicitRead: TX86Registers read FImplicitRead;
|
||||||
property ImplicitWrite: TX86Registers read FImplicitWrite;
|
property ImplicitWrite: TX86Registers read FImplicitWrite;
|
||||||
property X86Flags: TX86Flags read FX86Flags;
|
property X86Flags: TX86Flags read FX86Flags;
|
||||||
|
@ -1204,13 +1247,18 @@ const
|
||||||
'xopa'
|
'xopa'
|
||||||
);
|
);
|
||||||
|
|
||||||
SInstructionDefinitionFlag: array[TInstructionDefinitionFlag] of String = (
|
SPrefixFlag: array[TPrefixFlag] of String = (
|
||||||
'conflict',
|
|
||||||
'accepts_lock',
|
'accepts_lock',
|
||||||
'accepts_rep',
|
'accepts_rep',
|
||||||
|
'accepts_reperepne',
|
||||||
'accepts_xacquire',
|
'accepts_xacquire',
|
||||||
'accepts_xrelease',
|
'accepts_xrelease',
|
||||||
'accepts_branch_hints',
|
'accepts_hle_without_lock',
|
||||||
|
'accepts_branch_hints'
|
||||||
|
);
|
||||||
|
|
||||||
|
SInstructionDefinitionFlag: array[TInstructionDefinitionFlag] of String = (
|
||||||
|
'conflict',
|
||||||
'accepts_evex_aaa',
|
'accepts_evex_aaa',
|
||||||
'accepts_evex_z',
|
'accepts_evex_z',
|
||||||
'privileged',
|
'privileged',
|
||||||
|
@ -1223,7 +1271,7 @@ const
|
||||||
{$REGION 'Class: TJSONEnumHelper'}
|
{$REGION 'Class: TJSONEnumHelper'}
|
||||||
type
|
type
|
||||||
TJSONEnumHelper = record
|
TJSONEnumHelper = record
|
||||||
private
|
strict private
|
||||||
class function ReadString(JSON: PJSONVariantData; const Name, Default: String;
|
class function ReadString(JSON: PJSONVariantData; const Name, Default: String;
|
||||||
const LowerCase: Boolean = true): String; static; inline;
|
const LowerCase: Boolean = true): String; static; inline;
|
||||||
public
|
public
|
||||||
|
@ -1259,6 +1307,116 @@ begin
|
||||||
end;
|
end;
|
||||||
{$ENDREGION}
|
{$ENDREGION}
|
||||||
|
|
||||||
|
{$REGION 'Class: TJSONSetHelper'}
|
||||||
|
type
|
||||||
|
TJSONSetHelper<TSet> = record
|
||||||
|
strict private
|
||||||
|
class procedure GetEnumBounds(var MinValue, MaxValue: Integer); static; inline;
|
||||||
|
public
|
||||||
|
class function ReadValue(JSON: PJSONVariantData; const Name: String;
|
||||||
|
const ElementStrings: array of String): TSet; static;
|
||||||
|
class procedure WriteValue(JSON: PJSONVariantData; const Name: String;
|
||||||
|
const ElementStrings: array of String; Value: TSet); static;
|
||||||
|
end;
|
||||||
|
|
||||||
|
class procedure TJSONSetHelper<TSet>.GetEnumBounds(var MinValue, MaxValue: Integer);
|
||||||
|
var
|
||||||
|
TypInfo: PTypeInfo;
|
||||||
|
TypData: PTypeData;
|
||||||
|
begin
|
||||||
|
TypInfo := TypeInfo(TSet);
|
||||||
|
{$IFDEF DEBUG}
|
||||||
|
if (TypInfo^.Kind <> tkSet) then
|
||||||
|
begin
|
||||||
|
raise Exception.Create('Invalid generic type.');
|
||||||
|
end;
|
||||||
|
{$ENDIF}
|
||||||
|
TypData := GetTypeData(GetTypeData(TypInfo)^.CompType^);
|
||||||
|
{$IFDEF DEBUG}
|
||||||
|
if (TypData^.MinValue <> 0) then
|
||||||
|
begin
|
||||||
|
raise Exception.Create('The enum-type needs to be zero-based.');
|
||||||
|
end;
|
||||||
|
if (TypData^.MaxValue > 255) then
|
||||||
|
begin
|
||||||
|
raise Exception.Create('The enum-type''s maximum value needs the be lower than 256.');
|
||||||
|
end;
|
||||||
|
{$ENDIF}
|
||||||
|
MinValue := TypData^.MinValue;
|
||||||
|
MaxValue := TypData^.MaxValue;
|
||||||
|
end;
|
||||||
|
|
||||||
|
class function TJSONSetHelper<TSet>.ReadValue(JSON: PJSONVariantData; const Name: String;
|
||||||
|
const ElementStrings: array of String): TSet;
|
||||||
|
type
|
||||||
|
TSetType = set of 0..255;
|
||||||
|
var
|
||||||
|
A: PJSONVariantData;
|
||||||
|
MinValue,
|
||||||
|
MaxValue: Integer;
|
||||||
|
I, J: Integer;
|
||||||
|
begin
|
||||||
|
GetEnumBounds(MinValue, MaxValue);
|
||||||
|
{$IFDEF DEBUG}
|
||||||
|
if (MaxValue <> High(ElementStrings)) then
|
||||||
|
begin
|
||||||
|
raise Exception.Create('The size of the string-array does not match the size of the enum-type');
|
||||||
|
end;
|
||||||
|
{$ENDIF}
|
||||||
|
FillChar(Pointer(@Result)^, SizeOf(TSet), #0);
|
||||||
|
A := JSON^.Data(Name);
|
||||||
|
if (Assigned(A)) then
|
||||||
|
begin
|
||||||
|
if (A^.Kind <> jvArray) then
|
||||||
|
begin
|
||||||
|
raise Exception.CreateFmt('The "%s" field is not a valid JSON array.', [Name]);
|
||||||
|
end;
|
||||||
|
for I := 0 to A^.Count - 1 do
|
||||||
|
begin
|
||||||
|
for J := MinValue to MaxValue do
|
||||||
|
begin
|
||||||
|
if (LowerCase(A^.Item[I]) = ElementStrings[J]) then
|
||||||
|
begin
|
||||||
|
Include(TSetType(Pointer(@Result)^), J);
|
||||||
|
Break;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
class procedure TJSONSetHelper<TSet>.WriteValue(JSON: PJSONVariantData; const Name: String;
|
||||||
|
const ElementStrings: array of String; Value: TSet);
|
||||||
|
type
|
||||||
|
TSetType = set of 0..255;
|
||||||
|
var
|
||||||
|
A: TJSONVariantData;
|
||||||
|
MinValue,
|
||||||
|
MaxValue: Integer;
|
||||||
|
I: Integer;
|
||||||
|
begin
|
||||||
|
GetEnumBounds(MinValue, MaxValue);
|
||||||
|
{$IFDEF DEBUG}
|
||||||
|
if (MaxValue <> High(ElementStrings)) then
|
||||||
|
begin
|
||||||
|
raise Exception.Create('The size of the string-array does not match the size of the enum-type');
|
||||||
|
end;
|
||||||
|
{$ENDIF}
|
||||||
|
A.Init;
|
||||||
|
for I := MinValue to MaxValue do
|
||||||
|
begin
|
||||||
|
if (I in TSetType(Pointer(@Value)^)) then
|
||||||
|
begin
|
||||||
|
A.AddValue(ElementStrings[I]);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
if (A.Count > 0) then
|
||||||
|
begin
|
||||||
|
JSON^.AddNameValue(Name, Variant(A));
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
{$ENDREGION}
|
||||||
|
|
||||||
{$REGION 'Class: TOpcodeExtensions'}
|
{$REGION 'Class: TOpcodeExtensions'}
|
||||||
procedure TOpcodeExtensions.AssignTo(Dest: TPersistent);
|
procedure TOpcodeExtensions.AssignTo(Dest: TPersistent);
|
||||||
var
|
var
|
||||||
|
@ -1301,10 +1459,8 @@ end;
|
||||||
|
|
||||||
procedure TOpcodeExtensions.LoadFromJSON(JSON: PJSONVariantData; const FieldName: String);
|
procedure TOpcodeExtensions.LoadFromJSON(JSON: PJSONVariantData; const FieldName: String);
|
||||||
var
|
var
|
||||||
V, A: PJSONVariantData;
|
V: PJSONVariantData;
|
||||||
I: Integer;
|
I: Integer;
|
||||||
F: TExtBitFilter;
|
|
||||||
BitFilters: TExtBitFilters;
|
|
||||||
begin
|
begin
|
||||||
V := JSON.Data(FieldName);
|
V := JSON.Data(FieldName);
|
||||||
if (Assigned(V)) then
|
if (Assigned(V)) then
|
||||||
|
@ -1327,34 +1483,13 @@ begin
|
||||||
SetOperandSize(TExtOperandSize(I));
|
SetOperandSize(TExtOperandSize(I));
|
||||||
I := TJSONEnumHelper.ReadEnumValueFromString(V, 'adsize', SExtAddressSize);
|
I := TJSONEnumHelper.ReadEnumValueFromString(V, 'adsize', SExtAddressSize);
|
||||||
SetAddressSize(TExtAddressSize(I));
|
SetAddressSize(TExtAddressSize(I));
|
||||||
A := V^.Data('bitfilters');
|
SetBitFilters(TJSONSetHelper<TExtBitFilters>.ReadValue(V, 'bitfilters', SExtBitFilter));
|
||||||
if (Assigned(A)) then
|
|
||||||
begin
|
|
||||||
if (A^.Kind <> jvArray) then
|
|
||||||
begin
|
|
||||||
raise Exception.Create('The "prefix_flags" field is not a valid JSON array.');
|
|
||||||
end;
|
|
||||||
BitFilters := [];
|
|
||||||
for I := 0 to A^.Count - 1 do
|
|
||||||
begin
|
|
||||||
for F := Low(SExtBitFilter) to High(SExtBitFilter) do
|
|
||||||
begin
|
|
||||||
if (LowerCase(A^.Item[I]) = SExtBitFilter[F]) then
|
|
||||||
begin
|
|
||||||
BitFilters := BitFilters + [F];
|
|
||||||
Break;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
SetBitFilters(BitFilters);
|
|
||||||
end;
|
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TOpcodeExtensions.SaveToJSON(JSON: PJSONVariantData; const FieldName: String);
|
procedure TOpcodeExtensions.SaveToJSON(JSON: PJSONVariantData; const FieldName: String);
|
||||||
var
|
var
|
||||||
V, A: TJSONVariantData;
|
V: TJSONVariantData;
|
||||||
F: TExtBitFilter;
|
|
||||||
begin
|
begin
|
||||||
V.Init;
|
V.Init;
|
||||||
if (FMode <> imNeutral) then
|
if (FMode <> imNeutral) then
|
||||||
|
@ -1371,15 +1506,7 @@ begin
|
||||||
V.AddNameValue('opsize', SExtOperandSize[FOperandSize]);
|
V.AddNameValue('opsize', SExtOperandSize[FOperandSize]);
|
||||||
if (FAddressSize <> asNeutral) then
|
if (FAddressSize <> asNeutral) then
|
||||||
V.AddNameValue('adsize', SExtAddressSize[FAddressSize]);
|
V.AddNameValue('adsize', SExtAddressSize[FAddressSize]);
|
||||||
A.Init;
|
TJSONSetHelper<TExtBitFilters>.WriteValue(@V, 'bitfilters', SExtBitFilter, FBitFilters);
|
||||||
for F in FBitFilters do
|
|
||||||
begin
|
|
||||||
A.AddValue(SExtBitFilter[F]);
|
|
||||||
end;
|
|
||||||
if (A.Count > 0) then
|
|
||||||
begin
|
|
||||||
V.AddNameValue('bitfilters', Variant(A));
|
|
||||||
end;
|
|
||||||
if (V.Count > 0) then
|
if (V.Count > 0) then
|
||||||
begin
|
begin
|
||||||
JSON^.AddNameValue(FieldName, Variant(V));
|
JSON^.AddNameValue(FieldName, Variant(V));
|
||||||
|
@ -1493,49 +1620,15 @@ begin
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TCPUIDFeatureFlags.LoadFromJSON(JSON: PJSONVariantData; const FieldName: String);
|
procedure TCPUIDFeatureFlags.LoadFromJSON(JSON: PJSONVariantData; const FieldName: String);
|
||||||
var
|
|
||||||
A: PJSONVariantData;
|
|
||||||
I: Integer;
|
|
||||||
C: TCPUIDFeatureFlag;
|
|
||||||
Value: TCPUIDFeatureFlagSet;
|
|
||||||
begin
|
begin
|
||||||
A := JSON.Data(FieldName);
|
SetFeatureFlags(
|
||||||
if (Assigned(A)) then
|
TJSONSetHelper<TCPUIDFeatureFlagSet>.ReadValue(JSON, FieldName, SCPUIDFeatureFlag));
|
||||||
begin
|
|
||||||
if (A^.Kind <> jvArray) then
|
|
||||||
begin
|
|
||||||
raise Exception.CreateFmt('The "%s" field is not a valid JSON array.', [FieldName]);
|
|
||||||
end;
|
|
||||||
Value := [];
|
|
||||||
for I := 0 to A^.Count - 1 do
|
|
||||||
begin
|
|
||||||
for C := Low(SCPUIDFeatureFlag) to High(SCPUIDFeatureFlag) do
|
|
||||||
begin
|
|
||||||
if (LowerCase(A^.Item[I]) = SCPUIDFeatureFlag[C]) then
|
|
||||||
begin
|
|
||||||
Value := Value + [C];
|
|
||||||
Break;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
SetFeatureFlags(Value);
|
|
||||||
end;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TCPUIDFeatureFlags.SaveToJSON(JSON: PJSONVariantData; const FieldName: String);
|
procedure TCPUIDFeatureFlags.SaveToJSON(JSON: PJSONVariantData; const FieldName: String);
|
||||||
var
|
|
||||||
A: TJSONVariantData;
|
|
||||||
C: TCPUIDFeatureFlag;
|
|
||||||
begin
|
begin
|
||||||
A.Init;
|
TJSONSetHelper<TCPUIDFeatureFlagSet>.WriteValue(
|
||||||
for C in FFeatureFlags do
|
JSON, FieldName, SCPUIDFeatureFlag, FFeatureFlags);
|
||||||
begin
|
|
||||||
A.AddValue(SCPUIDFeatureFlag[C]);
|
|
||||||
end;
|
|
||||||
if (A.Count > 0) then
|
|
||||||
begin
|
|
||||||
JSON.AddNameValue(FieldName, Variant(A));
|
|
||||||
end;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TCPUIDFeatureFlags.SetFeatureFlags(const Value: TCPUIDFeatureFlagSet);
|
procedure TCPUIDFeatureFlags.SetFeatureFlags(const Value: TCPUIDFeatureFlagSet);
|
||||||
|
@ -1577,49 +1670,13 @@ begin
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TX86Registers.LoadFromJSON(JSON: PJSONVariantData; const FieldName: String);
|
procedure TX86Registers.LoadFromJSON(JSON: PJSONVariantData; const FieldName: String);
|
||||||
var
|
|
||||||
A: PJSONVariantData;
|
|
||||||
I: Integer;
|
|
||||||
R: TX86Register;
|
|
||||||
Value: TX86RegisterSet;
|
|
||||||
begin
|
begin
|
||||||
A := JSON^.Data(FieldName);
|
SetRegisters(TJSONSetHelper<TX86RegisterSet>.ReadValue(JSON, FieldName, SX86Register));
|
||||||
if (Assigned(A)) then
|
|
||||||
begin
|
|
||||||
if (A^.Kind <> jvArray) then
|
|
||||||
begin
|
|
||||||
raise Exception.CreateFmt('The "%s" field is not a valid JSON array.', [FieldName]);
|
|
||||||
end;
|
|
||||||
Value := [];
|
|
||||||
for I := 0 to A^.Count - 1 do
|
|
||||||
begin
|
|
||||||
for R := Low(SX86Register) to High(SX86Register) do
|
|
||||||
begin
|
|
||||||
if (LowerCase(A^.Item[I]) = SX86Register[R]) then
|
|
||||||
begin
|
|
||||||
Value := Value + [R];
|
|
||||||
Break;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
SetRegisters(Value);
|
|
||||||
end;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TX86Registers.SaveToJSON(JSON: PJSONVariantData; const FieldName: String);
|
procedure TX86Registers.SaveToJSON(JSON: PJSONVariantData; const FieldName: String);
|
||||||
var
|
|
||||||
A: TJSONVariantData;
|
|
||||||
R: TX86Register;
|
|
||||||
begin
|
begin
|
||||||
A.Init;
|
TJSONSetHelper<TX86RegisterSet>.WriteValue(JSON, FieldName, SX86Register, FRegisters);
|
||||||
for R in FRegisters do
|
|
||||||
begin
|
|
||||||
A.AddValue(SX86Register[R]);
|
|
||||||
end;
|
|
||||||
if (A.Count > 0) then
|
|
||||||
begin
|
|
||||||
JSON.AddNameValue(FieldName, Variant(A));
|
|
||||||
end;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TX86Registers.SetRegisters(const Value: TX86RegisterSet);
|
procedure TX86Registers.SetRegisters(const Value: TX86RegisterSet);
|
||||||
|
@ -2480,7 +2537,7 @@ var
|
||||||
begin
|
begin
|
||||||
for I := Low(FOperands) to High(FOperands) do
|
for I := Low(FOperands) to High(FOperands) do
|
||||||
begin
|
begin
|
||||||
if (Assigned(FOperands[I])) then FOperands[I].Free;
|
FOperands[I].Free;
|
||||||
end;
|
end;
|
||||||
inherited;
|
inherited;
|
||||||
end;
|
end;
|
||||||
|
@ -2683,12 +2740,12 @@ begin
|
||||||
end;
|
end;
|
||||||
// Remove definition from the definition list
|
// Remove definition from the definition list
|
||||||
FEditor.UnregisterDefinition(Self);
|
FEditor.UnregisterDefinition(Self);
|
||||||
if (Assigned(FExtensions)) then FExtensions.Free;
|
FExtensions.Free;
|
||||||
if (Assigned(FCPUID)) then FCPUID.Free;
|
FCPUID.Free;
|
||||||
if (Assigned(FOperands)) then FOperands.Free;
|
FOperands.Free;
|
||||||
if (Assigned(FImplicitRead)) then FImplicitRead.Free;
|
FImplicitRead.Free;
|
||||||
if (Assigned(FImplicitWrite)) then FImplicitWrite.Free;
|
FImplicitWrite.Free;
|
||||||
if (Assigned(FX86Flags)) then FX86Flags.Free;
|
FX86Flags.Free;
|
||||||
inherited;
|
inherited;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
@ -2735,9 +2792,6 @@ end;
|
||||||
procedure TInstructionDefinition.LoadFromJSON(JSON: PJSONVariantData);
|
procedure TInstructionDefinition.LoadFromJSON(JSON: PJSONVariantData);
|
||||||
var
|
var
|
||||||
I: Integer;
|
I: Integer;
|
||||||
A: PJSONVariantData;
|
|
||||||
F: TInstructionDefinitionFlag;
|
|
||||||
Flags: TInstructionDefinitionFlags;
|
|
||||||
begin
|
begin
|
||||||
BeginUpdate;
|
BeginUpdate;
|
||||||
try
|
try
|
||||||
|
@ -2764,27 +2818,9 @@ begin
|
||||||
FOperands.LoadFromJSON(JSON, 'operands');
|
FOperands.LoadFromJSON(JSON, 'operands');
|
||||||
FImplicitRead.LoadFromJSON(JSON, 'implicit_read');
|
FImplicitRead.LoadFromJSON(JSON, 'implicit_read');
|
||||||
FImplicitWrite.LoadFromJSON(JSON, 'implicit_write');
|
FImplicitWrite.LoadFromJSON(JSON, 'implicit_write');
|
||||||
A := JSON.Data('flags');
|
SetFlags(TJSONSetHelper<TInstructionDefinitionFlags>.ReadValue(
|
||||||
if (Assigned(A)) then
|
JSON, 'flags', SInstructionDefinitionFlag));
|
||||||
begin
|
SetPrefixFlags(TJSONSetHelper<TPrefixFlags>.ReadValue(JSON, 'prefix_flags', SPrefixFlag));
|
||||||
if (A^.Kind <> jvArray) then
|
|
||||||
begin
|
|
||||||
raise Exception.Create('The "flags" field is not a valid JSON array.');
|
|
||||||
end;
|
|
||||||
Flags := [];
|
|
||||||
for I := 0 to A^.Count - 1 do
|
|
||||||
begin
|
|
||||||
for F := Low(SInstructionDefinitionFlag) to High(SInstructionDefinitionFlag) do
|
|
||||||
begin
|
|
||||||
if (LowerCase(A^.Item[I]) = SInstructionDefinitionFlag[F]) then
|
|
||||||
begin
|
|
||||||
Flags := Flags + [F];
|
|
||||||
Break;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
SetFlags(Flags);
|
|
||||||
end;
|
|
||||||
FX86Flags.LoadFromJSON(JSON, 'x86flags');
|
FX86Flags.LoadFromJSON(JSON, 'x86flags');
|
||||||
FComment := JSON^.Value['comment'];
|
FComment := JSON^.Value['comment'];
|
||||||
finally
|
finally
|
||||||
|
@ -2793,9 +2829,6 @@ begin
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TInstructionDefinition.SaveToJSON(JSON: PJSONVariantData);
|
procedure TInstructionDefinition.SaveToJSON(JSON: PJSONVariantData);
|
||||||
var
|
|
||||||
A: TJSONVariantData;
|
|
||||||
F: TInstructionDefinitionFlag;
|
|
||||||
begin
|
begin
|
||||||
JSON^.AddNameValue('mnemonic', FMnemonic);
|
JSON^.AddNameValue('mnemonic', FMnemonic);
|
||||||
JSON^.AddNameValue('opcode', LowerCase(IntToHex(FOpcode, 2)));
|
JSON^.AddNameValue('opcode', LowerCase(IntToHex(FOpcode, 2)));
|
||||||
|
@ -2806,15 +2839,9 @@ begin
|
||||||
FOperands.SaveToJSON(JSON, 'operands');
|
FOperands.SaveToJSON(JSON, 'operands');
|
||||||
FImplicitRead.SaveToJSON(JSON, 'implicit_read');
|
FImplicitRead.SaveToJSON(JSON, 'implicit_read');
|
||||||
FImplicitWrite.SaveToJSON(JSON, 'implicit_write');
|
FImplicitWrite.SaveToJSON(JSON, 'implicit_write');
|
||||||
A.Init;
|
TJSONSetHelper<TInstructionDefinitionFlags>.WriteValue(JSON, 'flags',
|
||||||
for F in FFlags do
|
SInstructionDefinitionFlag, FFlags);
|
||||||
begin
|
TJSONSetHelper<TPrefixFlags>.WriteValue(JSON, 'prefix_flags', SPrefixFlag, FPrefixFlags);
|
||||||
A.AddValue(SInstructionDefinitionFlag[F]);
|
|
||||||
end;
|
|
||||||
if (A.Count > 0) then
|
|
||||||
begin
|
|
||||||
JSON^.AddNameValue('flags', Variant(A));
|
|
||||||
end;
|
|
||||||
FX86Flags.SaveToJSON(JSON, 'x86flags');
|
FX86Flags.SaveToJSON(JSON, 'x86flags');
|
||||||
if (FComment <> '') then
|
if (FComment <> '') then
|
||||||
begin
|
begin
|
||||||
|
@ -2946,6 +2973,15 @@ begin
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TInstructionDefinition.SetPrefixFlags(const Value: TPrefixFlags);
|
||||||
|
begin
|
||||||
|
if (FPrefixFlags <> Value) then
|
||||||
|
begin
|
||||||
|
FPrefixFlags := Value;
|
||||||
|
UpdateValues;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TInstructionDefinition.Update;
|
procedure TInstructionDefinition.Update;
|
||||||
begin
|
begin
|
||||||
UpdatePosition;
|
UpdatePosition;
|
||||||
|
@ -2965,6 +3001,33 @@ begin
|
||||||
begin
|
begin
|
||||||
Include(Conflicts, idcOperands);
|
Include(Conflicts, idcOperands);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
if ((pfAcceptsXACQUIRE in FPrefixFlags) or (pfAcceptsXRELEASE in FPrefixFlags)) and
|
||||||
|
(not ((pfAcceptsLock in FPrefixFlags) or (pfAcceptsHLEWithoutLock in FPrefixFlags))) then
|
||||||
|
begin
|
||||||
|
Include(Conflicts, idcPrefixFlags);
|
||||||
|
end;
|
||||||
|
if ((pfAcceptsXACQUIRE in FPrefixFlags) or (pfAcceptsXRELEASE in FPrefixFlags)) and
|
||||||
|
((pfAcceptsREP in FPrefixFlags) or (pfAcceptsREPEREPNE in FPrefixFlags)) then
|
||||||
|
begin
|
||||||
|
Include(Conflicts, idcPrefixFlags);
|
||||||
|
end;
|
||||||
|
if ((pfAcceptsLock in FPrefixFlags) or (pfAcceptsXACQUIRE in FPrefixFlags) or
|
||||||
|
(pfAcceptsXRELEASE in FPrefixFlags)) and (not (FOperands.Operands[0].OperandType in [
|
||||||
|
optMem8, optMem16, optMem32, optMem64, optMem128])) then
|
||||||
|
begin
|
||||||
|
Include(Conflicts, idcPrefixFlags);
|
||||||
|
end;
|
||||||
|
if ((pfAcceptsREP in FPrefixFlags) and (pfAcceptsREPEREPNE in FPrefixFlags)) then
|
||||||
|
begin
|
||||||
|
Include(Conflicts, idcPrefixFlags);
|
||||||
|
end;
|
||||||
|
if (pfAcceptsBranchHints in FPrefixFlags) and (not (FOperands.Operands[0].OperandType in [
|
||||||
|
optRel8, optRel16, optRel32, optRel64])) then
|
||||||
|
begin
|
||||||
|
Include(Conflicts, idcPrefixFlags);
|
||||||
|
end;
|
||||||
|
|
||||||
if (FX86Flags.HasConflicts) then
|
if (FX86Flags.HasConflicts) then
|
||||||
begin
|
begin
|
||||||
Include(Conflicts, idcX86Flags);
|
Include(Conflicts, idcX86Flags);
|
||||||
|
@ -3071,7 +3134,7 @@ end;
|
||||||
destructor TInstructionFilter.Destroy;
|
destructor TInstructionFilter.Destroy;
|
||||||
begin
|
begin
|
||||||
Assert((FItemCount = 0) and (FParent = nil));
|
Assert((FItemCount = 0) and (FParent = nil));
|
||||||
if Assigned(FDefinitions) then
|
if (Assigned(FDefinitions)) then
|
||||||
begin
|
begin
|
||||||
Assert(FDefinitions.Count = 0);
|
Assert(FDefinitions.Count = 0);
|
||||||
FDefinitions.Free;
|
FDefinitions.Free;
|
||||||
|
@ -3865,11 +3928,23 @@ var
|
||||||
I: Integer;
|
I: Integer;
|
||||||
JSONDefinitionList, JSONDefinition: TJSONVariantData;
|
JSONDefinitionList, JSONDefinition: TJSONVariantData;
|
||||||
begin
|
begin
|
||||||
// Sort definitions by mnemonic
|
// Sort definitions
|
||||||
Comparison :=
|
Comparison :=
|
||||||
function(const Left, Right: TInstructionDefinition): Integer
|
function(const Left, Right: TInstructionDefinition): Integer
|
||||||
begin
|
begin
|
||||||
Result := CompareStr(Left.Mnemonic, Right.Mnemonic);
|
Result := CompareStr(Left.Mnemonic, Right.Mnemonic);
|
||||||
|
if (Result = 0) then
|
||||||
|
begin
|
||||||
|
Result := Ord(Left.Encoding) - Ord(Right.Encoding);
|
||||||
|
end;
|
||||||
|
if (Result = 0) then
|
||||||
|
begin
|
||||||
|
Result := Ord(Left.OpcodeMap) - Ord(Right.OpcodeMap);
|
||||||
|
end;
|
||||||
|
if (Result = 0) then
|
||||||
|
begin
|
||||||
|
Result := Left.Opcode - Right.Opcode;
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
FDefinitions.Sort(TComparer<TInstructionDefinition>.Construct(Comparison));
|
FDefinitions.Sort(TComparer<TInstructionDefinition>.Construct(Comparison));
|
||||||
// Save to JSON
|
// Save to JSON
|
||||||
|
|
188341
assets/instructions.json
188341
assets/instructions.json
File diff suppressed because it is too large
Load Diff
|
@ -247,36 +247,36 @@ typedef uint32_t ZydisPrefixFlags;
|
||||||
/**
|
/**
|
||||||
* @brief The instruction accepts the string prefixes (rep/repe/repz/repne/repnz).
|
* @brief The instruction accepts the string prefixes (rep/repe/repz/repne/repnz).
|
||||||
*/
|
*/
|
||||||
#define ZYDIS_PREFIXFLAG_ACCEPTS_REPE 0x00400000
|
#define ZYDIS_PREFIXFLAG_ACCEPTS_REPE 0x00800000
|
||||||
/**
|
/**
|
||||||
* @brief The instruction accepts the string prefixes (rep/repe/repz/repne/repnz).
|
* @brief The instruction accepts the string prefixes (rep/repe/repz/repne/repnz).
|
||||||
*/
|
*/
|
||||||
#define ZYDIS_PREFIXFLAG_ACCEPTS_REPZ 0x00400000
|
#define ZYDIS_PREFIXFLAG_ACCEPTS_REPZ 0x00800000
|
||||||
/**
|
/**
|
||||||
* @brief The instruction accepts the string prefixes (rep/repe/repz/repne/repnz).
|
* @brief The instruction accepts the string prefixes (rep/repe/repz/repne/repnz).
|
||||||
*/
|
*/
|
||||||
#define ZYDIS_PREFIXFLAG_ACCEPTS_REPNE 0x00400000
|
#define ZYDIS_PREFIXFLAG_ACCEPTS_REPNE 0x01000000
|
||||||
/**
|
/**
|
||||||
* @brief The instruction accepts the string prefixes (rep/repe/repz/repne/repnz).
|
* @brief The instruction accepts the string prefixes (rep/repe/repz/repne/repnz).
|
||||||
*/
|
*/
|
||||||
#define ZYDIS_PREFIXFLAG_ACCEPTS_REPNZ 0x00400000
|
#define ZYDIS_PREFIXFLAG_ACCEPTS_REPNZ 0x01000000
|
||||||
/**
|
/**
|
||||||
* @brief The instruction has multiple prefixes of the first prefix-group (0x0F, 0xF3, 0xF2).
|
* @brief The instruction has multiple prefixes of the first prefix-group (0x0F, 0xF3, 0xF2).
|
||||||
*/
|
*/
|
||||||
#define ZYDIS_PREFIXFLAG_MULTIPLE_GRP1 0x00800000
|
#define ZYDIS_PREFIXFLAG_MULTIPLE_GRP1 0x02000000
|
||||||
/**
|
/**
|
||||||
* @brief The instruction has multiple prefixes of the second prefix-group (0x2E, 0x36,
|
* @brief The instruction has multiple prefixes of the second prefix-group (0x2E, 0x36,
|
||||||
* 0x3E, 0x26, 0x64, 0x65).
|
* 0x3E, 0x26, 0x64, 0x65).
|
||||||
*/
|
*/
|
||||||
#define ZYDIS_PREFIXFLAG_MULTIPLE_GRP2 0x01000000
|
#define ZYDIS_PREFIXFLAG_MULTIPLE_GRP2 0x04000000
|
||||||
/**
|
/**
|
||||||
* @brief The instruction has multiple prefixes of the third prefix-group (0x66).
|
* @brief The instruction has multiple prefixes of the third prefix-group (0x66).
|
||||||
*/
|
*/
|
||||||
#define ZYDIS_PREFIXFLAG_MULTIPLE_GRP3 0x02000000
|
#define ZYDIS_PREFIXFLAG_MULTIPLE_GRP3 0x08000000
|
||||||
/**
|
/**
|
||||||
* @brief The instruction has multiple prefixes of the fourth prefix-group (0x67).
|
* @brief The instruction has multiple prefixes of the fourth prefix-group (0x67).
|
||||||
*/
|
*/
|
||||||
#define ZYDIS_PREFIXFLAG_MULTIPLE_GRP4 0x04000000
|
#define ZYDIS_PREFIXFLAG_MULTIPLE_GRP4 0x10000000
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------------------------------- */
|
||||||
/* Instruction encoding */
|
/* Instruction encoding */
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
typedef struct ZydisInstructionDefinition_
|
||||||
|
{
|
||||||
|
uint32_t mnemonic : 11;
|
||||||
|
uint32_t operandsId : 9;
|
||||||
|
uint32_t evexBFunctionality : 2;
|
||||||
|
uint32_t hasEvexAAA : 1;
|
||||||
|
uint32_t hasEvexZ : 1;
|
||||||
|
uint32_t acceptsLock : 1;
|
||||||
|
uint32_t acceptsREP : 1;
|
||||||
|
uint32_t acceptsREPEREPNE : 1;
|
||||||
|
uint32_t acceptsXACQUIRE : 1;
|
||||||
|
uint32_t acceptsXRELEASE : 1;
|
||||||
|
uint32_t acceptsHLEWithoutLock : 1;
|
||||||
|
uint32_t acceptsBranchHints : 1;
|
||||||
|
} ZydisInstructionDefinition;
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -41,21 +41,69 @@ extern "C" {
|
||||||
/* ============================================================================================== */
|
/* ============================================================================================== */
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------------------------------- */
|
||||||
/* Instruction table */
|
/* Generated types */
|
||||||
/* ---------------------------------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
/**
|
// MSVC does not like types other than (un-)signed int for bitfields
|
||||||
* @brief Defines the @c ZydisInstructionTableNode datatype.
|
#ifdef ZYDIS_MSVC
|
||||||
*/
|
# pragma warning(push)
|
||||||
typedef void* ZydisInstructionTableNode;
|
# pragma warning(disable:4214)
|
||||||
|
#endif
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------------------------------- */
|
#pragma pack(push, 1)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Defines the @c ZydisInstructionTableNodeType datatype.
|
* @brief Defines the @c ZydisInstructionTableNodeType datatype.
|
||||||
*/
|
*/
|
||||||
typedef uint8_t ZydisInstructionTableNodeType;
|
typedef uint8_t ZydisInstructionTableNodeType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Defines the @c ZydisInstructionTableNodeValue datatype.
|
||||||
|
*/
|
||||||
|
typedef uint16_t ZydisInstructionTableNodeValue;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Defines the @c ZydisInstructionTableNode struct.
|
||||||
|
*
|
||||||
|
* This struct is static for now, because its size is sufficient to encode up to 65535
|
||||||
|
* instruction filters (what is about 10 times more than we currently need).
|
||||||
|
*/
|
||||||
|
typedef struct ZydisInstructionTableNode_
|
||||||
|
{
|
||||||
|
ZydisInstructionTableNodeType type;
|
||||||
|
ZydisInstructionTableNodeValue value;
|
||||||
|
} ZydisInstructionTableNode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Defines the @c ZydisSemanticOperandType datatype.
|
||||||
|
*/
|
||||||
|
typedef uint8_t ZydisSemanticOperandType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Defines the @c ZydisOperandDefinition struct.
|
||||||
|
*
|
||||||
|
* This struct is static for now, because adding more operand-types oder encodings requires
|
||||||
|
* code changes anyways.
|
||||||
|
*/
|
||||||
|
typedef struct ZydisOperandDefinition_
|
||||||
|
{
|
||||||
|
ZydisSemanticOperandType type : 7;
|
||||||
|
ZydisOperandEncoding encoding : 5;
|
||||||
|
ZydisOperandAccess access : 2;
|
||||||
|
} ZydisOperandDefinition;
|
||||||
|
|
||||||
|
#include <Zydis/Internal/GeneratedTypes.inc>
|
||||||
|
|
||||||
|
#pragma pack(pop)
|
||||||
|
|
||||||
|
#ifdef ZYDIS_MSVC
|
||||||
|
# pragma warning(pop)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------------------------------------- */
|
||||||
|
/* Instruction Table */
|
||||||
|
/* ---------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Values that represent zydis instruction table node types.
|
* @brief Values that represent zydis instruction table node types.
|
||||||
*/
|
*/
|
||||||
|
@ -144,20 +192,10 @@ enum ZydisInstructionTableNodeTypes
|
||||||
ZYDIS_NODETYPE_FILTER_EVEXB = 0x14
|
ZYDIS_NODETYPE_FILTER_EVEXB = 0x14
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Defines the @c ZydisInstructionTableNodeValue datatype.
|
|
||||||
*/
|
|
||||||
typedef uint16_t ZydisInstructionTableNodeValue;
|
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------------------------------- */
|
||||||
/* Operand definition */
|
/* Operand definition */
|
||||||
/* ---------------------------------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Defines the @c ZydisSemanticOperandType datatype.
|
|
||||||
*/
|
|
||||||
typedef uint8_t ZydisSemanticOperandType;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Values that represent semantic operand types.
|
* @brief Values that represent semantic operand types.
|
||||||
*/
|
*/
|
||||||
|
@ -246,34 +284,10 @@ enum ZydisSemanticOperandTypes
|
||||||
ZYDIS_SEM_OPERAND_TYPE_ST0
|
ZYDIS_SEM_OPERAND_TYPE_ST0
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Defines the @c ZydisOperandDefinition struct.
|
|
||||||
*/
|
|
||||||
typedef struct ZydisOperandDefinition_
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* @brief The semantic operand type.
|
|
||||||
*/
|
|
||||||
ZydisSemanticOperandType type;
|
|
||||||
/**
|
|
||||||
* @brief The operand encoding.
|
|
||||||
*/
|
|
||||||
ZydisOperandEncoding encoding;
|
|
||||||
/**
|
|
||||||
* @brief The operand access-mode.
|
|
||||||
*/
|
|
||||||
ZydisOperandAccess access;
|
|
||||||
} ZydisOperandDefinition;
|
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------------------------------- */
|
||||||
/* Instruction definition */
|
/* Instruction definition */
|
||||||
/* ---------------------------------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Defines the @c ZydisEvexBFunctionality datatype .
|
|
||||||
*/
|
|
||||||
typedef uint8_t ZydisEvexBFunctionality;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Values that represent zydis evex.b-functionalities.
|
* @brief Values that represent zydis evex.b-functionalities.
|
||||||
*/
|
*/
|
||||||
|
@ -285,66 +299,18 @@ enum ZydisEvexBFunctionalities
|
||||||
ZYDIS_EVEXB_FUNCTIONALITY_SAE
|
ZYDIS_EVEXB_FUNCTIONALITY_SAE
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Defines the @c ZydisInstructionDefinition struct.
|
|
||||||
*/
|
|
||||||
typedef struct ZydisInstructionDefinition_
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* @brief The instruction mnemonic.
|
|
||||||
*/
|
|
||||||
ZydisInstructionMnemonic mnemonic;
|
|
||||||
/**
|
|
||||||
* @brief The number of used operands.
|
|
||||||
*/
|
|
||||||
uint8_t operandCount;
|
|
||||||
/**
|
|
||||||
* @brief The operand-definitions.
|
|
||||||
*/
|
|
||||||
ZydisOperandDefinition operands[5];
|
|
||||||
/**
|
|
||||||
* @brief The evex.b functionality.
|
|
||||||
*/
|
|
||||||
ZydisEvexBFunctionality evexBFunctionality;
|
|
||||||
|
|
||||||
bool hasEvexAAA;
|
|
||||||
bool hasEvexZ;
|
|
||||||
} ZydisInstructionDefinition;
|
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
/* ============================================================================================== */
|
/* ============================================================================================== */
|
||||||
/* Functions */
|
/* Functions */
|
||||||
/* ============================================================================================== */
|
/* ============================================================================================== */
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Returns the type of the specified instruction table node.
|
|
||||||
*
|
|
||||||
* @param node The node.
|
|
||||||
*
|
|
||||||
* @return The type of the specified instruction table node.
|
|
||||||
*/
|
|
||||||
ZYDIS_NO_EXPORT ZydisInstructionTableNodeType ZydisInstructionTableGetNodeType(
|
|
||||||
const ZydisInstructionTableNode node);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Returns the value of the specified instruction table node.
|
|
||||||
*
|
|
||||||
* @param node The node.
|
|
||||||
*
|
|
||||||
* @return The value of the specified instruction table node.
|
|
||||||
*/
|
|
||||||
ZYDIS_NO_EXPORT ZydisInstructionTableNodeValue ZydisInstructionTableGetNodeValue(
|
|
||||||
const ZydisInstructionTableNode* node);
|
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Returns the root node of the instruction table.
|
* @brief Returns the root node of the instruction table.
|
||||||
*
|
*
|
||||||
* @return The root node of the instruction table.
|
* @return The root node of the instruction table.
|
||||||
*/
|
*/
|
||||||
ZYDIS_NO_EXPORT ZydisInstructionTableNode ZydisInstructionTableGetRootNode();
|
ZYDIS_NO_EXPORT const ZydisInstructionTableNode* ZydisInstructionTableGetRootNode();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Returns the child node of @c parent specified by @c index.
|
* @brief Returns the child node of @c parent specified by @c index.
|
||||||
|
@ -354,18 +320,25 @@ ZYDIS_NO_EXPORT ZydisInstructionTableNode ZydisInstructionTableGetRootNode();
|
||||||
*
|
*
|
||||||
* @return The specified child node.
|
* @return The specified child node.
|
||||||
*/
|
*/
|
||||||
ZYDIS_NO_EXPORT ZydisInstructionTableNode ZydisInstructionTableGetChildNode(
|
ZYDIS_NO_EXPORT const ZydisInstructionTableNode* ZydisInstructionTableGetChildNode(
|
||||||
const ZydisInstructionTableNode parent, uint16_t index);
|
const ZydisInstructionTableNode* parent, uint16_t index);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Returns the instruction definition that is linked to the given @c node.
|
* @brief Returns the instruction- and operand-definition that is linked to the given @c node.
|
||||||
*
|
*
|
||||||
* @param node The instruction definition node.
|
* @param node The instruction definition node.
|
||||||
|
* @param definition A pointer to a variable that receives a pointer to the
|
||||||
|
* instruction-definition.
|
||||||
|
* @param operands A pointer to a variable that receives a pointer to the first
|
||||||
|
* operand-definition of the instruction.
|
||||||
|
* @param operandCount A pointer to a variable that receives the number of operand-definitions
|
||||||
|
* for the instruction.
|
||||||
*
|
*
|
||||||
* @return Pointer to the instruction definition.
|
* @return @c TRUE, if @c node contained a valid instruction-definition, @c FALSE if not.
|
||||||
*/
|
*/
|
||||||
ZYDIS_NO_EXPORT ZydisInstructionDefinition ZydisInstructionDefinitionByNode(
|
ZYDIS_NO_EXPORT bool ZydisInstructionTableGetDefinition(const ZydisInstructionTableNode* node,
|
||||||
const ZydisInstructionTableNode node);
|
const ZydisInstructionDefinition** definition, const ZydisOperandDefinition** operands,
|
||||||
|
uint8_t* operandCount);
|
||||||
|
|
||||||
/* ============================================================================================== */
|
/* ============================================================================================== */
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
249
src/Decoder.c
249
src/Decoder.c
|
@ -1527,33 +1527,34 @@ static ZydisDecoderStatus ZydisDecodeOperand(ZydisInstructionDecoder* decoder,
|
||||||
/**
|
/**
|
||||||
* @brief Decodes all instruction-operands.
|
* @brief Decodes all instruction-operands.
|
||||||
*
|
*
|
||||||
* @param decoder A pointer to the @c ZydisInstructionDecoder decoder instance.
|
* @param decoder A pointer to the @c ZydisInstructionDecoder decoder instance.
|
||||||
* @param info A pointer to the @c ZydisInstructionInfo struct.
|
* @param info A pointer to the @c ZydisInstructionInfo struct.
|
||||||
* @param definition A pointer to the @c ZydisInstructionDefinition struct.
|
* @param operands A pointer to the first operand-definition of the instruction.
|
||||||
|
* @param operandCount The number of operands.
|
||||||
*
|
*
|
||||||
* @return A zydis decoder status code.
|
* @return A zydis decoder status code.
|
||||||
*/
|
*/
|
||||||
static ZydisDecoderStatus ZydisDecodeOperands(ZydisInstructionDecoder* decoder,
|
static ZydisDecoderStatus ZydisDecodeOperands(ZydisInstructionDecoder* decoder,
|
||||||
ZydisInstructionInfo* info, const ZydisInstructionDefinition* definition)
|
ZydisInstructionInfo* info, const ZydisOperandDefinition* operands, uint8_t operandCount)
|
||||||
{
|
{
|
||||||
ZYDIS_ASSERT(decoder);
|
ZYDIS_ASSERT(decoder);
|
||||||
ZYDIS_ASSERT(info);
|
ZYDIS_ASSERT(info);
|
||||||
ZYDIS_ASSERT(definition);
|
ZYDIS_ASSERT(operands);
|
||||||
ZYDIS_ASSERT(definition->operandCount <= 6);
|
ZYDIS_ASSERT(operandCount < 6);
|
||||||
|
|
||||||
info->operandCount = definition->operandCount;
|
info->operandCount = operandCount;
|
||||||
for (int i = 0; i < definition->operandCount; ++i)
|
for (int i = 0; i < operandCount; ++i)
|
||||||
{
|
{
|
||||||
ZydisSemanticOperandType type = definition->operands[i].type;
|
ZydisSemanticOperandType type = operands[i].type;
|
||||||
if (type == ZYDIS_SEM_OPERAND_TYPE_UNUSED)
|
if (type == ZYDIS_SEM_OPERAND_TYPE_UNUSED)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
ZydisInstructionEncoding encoding = definition->operands[i].encoding;
|
ZydisInstructionEncoding encoding = operands[i].encoding;
|
||||||
ZydisDecoderStatus status =
|
ZydisDecoderStatus status =
|
||||||
ZydisDecodeOperand(decoder, info, &info->operand[i], type, encoding);
|
ZydisDecodeOperand(decoder, info, &info->operand[i], type, encoding);
|
||||||
info->operand[i].encoding = encoding;
|
info->operand[i].encoding = encoding;
|
||||||
info->operand[i].access = definition->operands[i].access;
|
info->operand[i].access = operands[i].access;
|
||||||
if (status != ZYDIS_STATUS_DECODER_SUCCESS)
|
if (status != ZYDIS_STATUS_DECODER_SUCCESS)
|
||||||
{
|
{
|
||||||
info->instrFlags |= ZYDIS_INSTRFLAG_ERROR_OPERANDS;
|
info->instrFlags |= ZYDIS_INSTRFLAG_ERROR_OPERANDS;
|
||||||
|
@ -1607,129 +1608,86 @@ static ZydisDecoderStatus ZydisDecodeOperands(ZydisInstructionDecoder* decoder,
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
static void ZydisFinalizeInstructionInfo(ZydisInstructionInfo* info)
|
/**
|
||||||
|
* @brief Finalizes the @c ZydisInstructionInfo struct by adding additional information.
|
||||||
|
*
|
||||||
|
* @param info A pointer to the @c ZydisInstructionInfo struct.
|
||||||
|
* @param definition A pointer to the @c ZydisInstructionDefinition struct.
|
||||||
|
*/
|
||||||
|
static void ZydisFinalizeInstructionInfo(ZydisInstructionInfo* info,
|
||||||
|
const ZydisInstructionDefinition* definition)
|
||||||
{
|
{
|
||||||
ZYDIS_ASSERT(info);
|
ZYDIS_ASSERT(info);
|
||||||
|
ZYDIS_ASSERT(definition);
|
||||||
|
|
||||||
// TODO: Encode all these things in the instruction definition
|
// Set prefix-flags
|
||||||
|
if (definition->acceptsLock)
|
||||||
// Adjust prefix flags
|
|
||||||
switch (info->mnemonic)
|
|
||||||
{
|
{
|
||||||
case ZYDIS_MNEMONIC_ADD:
|
info->prefixFlags |= ZYDIS_PREFIXFLAG_ACCEPTS_LOCK;
|
||||||
case ZYDIS_MNEMONIC_ADC:
|
}
|
||||||
case ZYDIS_MNEMONIC_AND:
|
if (definition->acceptsREP)
|
||||||
case ZYDIS_MNEMONIC_BTC:
|
{
|
||||||
case ZYDIS_MNEMONIC_BTR:
|
info->prefixFlags |= ZYDIS_PREFIXFLAG_ACCEPTS_REP;
|
||||||
case ZYDIS_MNEMONIC_BTS:
|
} else if (definition->acceptsREPEREPNE)
|
||||||
case ZYDIS_MNEMONIC_CMPXCHG:
|
{
|
||||||
case ZYDIS_MNEMONIC_CMPXCHG8B:
|
info->prefixFlags |= ZYDIS_PREFIXFLAG_ACCEPTS_REPE | ZYDIS_PREFIXFLAG_ACCEPTS_REPNE;
|
||||||
case ZYDIS_MNEMONIC_CMPXCHG16B:
|
}
|
||||||
case ZYDIS_MNEMONIC_DEC:
|
if ((info->prefixFlags & ZYDIS_PREFIXFLAG_HAS_LOCK) || (definition->acceptsHLEWithoutLock))
|
||||||
case ZYDIS_MNEMONIC_INC:
|
{
|
||||||
case ZYDIS_MNEMONIC_NEG:
|
if (definition->acceptsXACQUIRE && (info->prefixFlags & ZYDIS_PREFIXFLAG_HAS_REPE))
|
||||||
case ZYDIS_MNEMONIC_NOT:
|
|
||||||
case ZYDIS_MNEMONIC_OR:
|
|
||||||
case ZYDIS_MNEMONIC_SBB:
|
|
||||||
case ZYDIS_MNEMONIC_SUB:
|
|
||||||
case ZYDIS_MNEMONIC_XOR:
|
|
||||||
case ZYDIS_MNEMONIC_XADD:
|
|
||||||
case ZYDIS_MNEMONIC_XCHG:
|
|
||||||
if (info->operand[0].type == ZYDIS_OPERAND_TYPE_MEMORY)
|
|
||||||
{
|
{
|
||||||
info->prefixFlags |= ZYDIS_PREFIXFLAG_ACCEPTS_LOCK;
|
info->prefixFlags |= ZYDIS_PREFIXFLAG_HAS_XACQUIRE;
|
||||||
|
info->prefixFlags &= ~ZYDIS_PREFIXFLAG_HAS_REPE;
|
||||||
|
}
|
||||||
|
if (definition->acceptsXRELEASE && (info->prefixFlags & ZYDIS_PREFIXFLAG_HAS_REPNE))
|
||||||
|
{
|
||||||
|
info->prefixFlags |= ZYDIS_PREFIXFLAG_HAS_XRELEASE;
|
||||||
|
info->prefixFlags &= ~ZYDIS_PREFIXFLAG_HAS_REPNE;
|
||||||
}
|
}
|
||||||
break;
|
}
|
||||||
case ZYDIS_MNEMONIC_MOVSB:
|
if (definition->acceptsBranchHints)
|
||||||
case ZYDIS_MNEMONIC_MOVSW:
|
{
|
||||||
case ZYDIS_MNEMONIC_MOVSD:
|
|
||||||
case ZYDIS_MNEMONIC_MOVSQ:
|
|
||||||
case ZYDIS_MNEMONIC_CMPS: // TODO: Only the string-instruction! We will use flags later.
|
|
||||||
case ZYDIS_MNEMONIC_SCASB:
|
|
||||||
case ZYDIS_MNEMONIC_SCASW:
|
|
||||||
case ZYDIS_MNEMONIC_SCASD:
|
|
||||||
case ZYDIS_MNEMONIC_SCASQ:
|
|
||||||
case ZYDIS_MNEMONIC_LODSB:
|
|
||||||
case ZYDIS_MNEMONIC_LODSW:
|
|
||||||
case ZYDIS_MNEMONIC_LODSD:
|
|
||||||
case ZYDIS_MNEMONIC_LODSQ:
|
|
||||||
case ZYDIS_MNEMONIC_STOSB:
|
|
||||||
case ZYDIS_MNEMONIC_STOSW:
|
|
||||||
case ZYDIS_MNEMONIC_STOSD:
|
|
||||||
case ZYDIS_MNEMONIC_STOSQ:
|
|
||||||
case ZYDIS_MNEMONIC_INSB:
|
|
||||||
case ZYDIS_MNEMONIC_INSW:
|
|
||||||
case ZYDIS_MNEMONIC_INSD:
|
|
||||||
case ZYDIS_MNEMONIC_OUTSB:
|
|
||||||
case ZYDIS_MNEMONIC_OUTSW:
|
|
||||||
case ZYDIS_MNEMONIC_OUTSD:
|
|
||||||
info->prefixFlags |= ZYDIS_PREFIXFLAG_ACCEPTS_REP | ZYDIS_PREFIXFLAG_ACCEPTS_REPNE;
|
|
||||||
break;
|
|
||||||
case ZYDIS_MNEMONIC_JO:
|
|
||||||
case ZYDIS_MNEMONIC_JNO:
|
|
||||||
case ZYDIS_MNEMONIC_JS:
|
|
||||||
case ZYDIS_MNEMONIC_JNS:
|
|
||||||
case ZYDIS_MNEMONIC_JE:
|
|
||||||
case ZYDIS_MNEMONIC_JNE:
|
|
||||||
case ZYDIS_MNEMONIC_JB:
|
|
||||||
case ZYDIS_MNEMONIC_JAE:
|
|
||||||
case ZYDIS_MNEMONIC_JBE:
|
|
||||||
case ZYDIS_MNEMONIC_JA:
|
|
||||||
case ZYDIS_MNEMONIC_JL:
|
|
||||||
case ZYDIS_MNEMONIC_JGE:
|
|
||||||
case ZYDIS_MNEMONIC_JLE:
|
|
||||||
case ZYDIS_MNEMONIC_JG:
|
|
||||||
case ZYDIS_MNEMONIC_JP:
|
|
||||||
case ZYDIS_MNEMONIC_JNP:
|
|
||||||
case ZYDIS_MNEMONIC_JCXZ:
|
|
||||||
case ZYDIS_MNEMONIC_JECXZ:
|
|
||||||
case ZYDIS_MNEMONIC_JRCXZ:
|
|
||||||
if (info->prefixFlags & ZYDIS_PREFIXFLAG_HAS_SEGMENT_CS)
|
if (info->prefixFlags & ZYDIS_PREFIXFLAG_HAS_SEGMENT_CS)
|
||||||
{
|
{
|
||||||
info->prefixFlags &= ~ZYDIS_PREFIXFLAG_HAS_SEGMENT_CS;
|
|
||||||
info->prefixFlags |= ZYDIS_PREFIXFLAG_HAS_BRANCH_NOT_TAKEN;
|
info->prefixFlags |= ZYDIS_PREFIXFLAG_HAS_BRANCH_NOT_TAKEN;
|
||||||
} else
|
info->prefixFlags &= ~ZYDIS_PREFIXFLAG_HAS_SEGMENT_CS;
|
||||||
|
}
|
||||||
if (info->prefixFlags & ZYDIS_PREFIXFLAG_HAS_SEGMENT_DS)
|
if (info->prefixFlags & ZYDIS_PREFIXFLAG_HAS_SEGMENT_DS)
|
||||||
{
|
{
|
||||||
|
info->prefixFlags |= ZYDIS_PREFIXFLAG_HAS_BRANCH_TAKEN;
|
||||||
info->prefixFlags &= ~ZYDIS_PREFIXFLAG_HAS_SEGMENT_DS;
|
info->prefixFlags &= ~ZYDIS_PREFIXFLAG_HAS_SEGMENT_DS;
|
||||||
info->prefixFlags |= ZYDIS_PREFIXFLAG_HAS_BRANCH_TAKEN;
|
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
if ((info->prefixFlags & ZYDIS_PREFIXFLAG_ACCEPTS_LOCK) &&
|
|
||||||
((info->prefixFlags & ZYDIS_PREFIXFLAG_HAS_REP) ||
|
// Set AVX-512 info
|
||||||
(info->prefixFlags & ZYDIS_PREFIXFLAG_HAS_REPNE)))
|
if (info->encoding == ZYDIS_INSTRUCTION_ENCODING_EVEX)
|
||||||
{
|
{
|
||||||
if (info->mnemonic != ZYDIS_MNEMONIC_CMPXCHG16B)
|
if (definition->hasEvexAAA && info->details.evex.aaa)
|
||||||
{
|
{
|
||||||
if ((info->prefixFlags & ZYDIS_PREFIXFLAG_HAS_LOCK) ||
|
info->avx.maskRegister = ZYDIS_REGISTER_K0 + info->details.evex.aaa;
|
||||||
(info->mnemonic == ZYDIS_MNEMONIC_XCHG))
|
}
|
||||||
{
|
if (definition->hasEvexZ && info->details.evex.z)
|
||||||
if (info->prefixFlags & ZYDIS_PREFIXFLAG_HAS_REPNE)
|
{
|
||||||
{
|
info->avx.maskMode = ZYDIS_AVX_MASKMODE_ZERO;
|
||||||
info->prefixFlags &= ~ZYDIS_PREFIXFLAG_HAS_REPNE;
|
} else
|
||||||
info->prefixFlags |= ZYDIS_PREFIXFLAG_HAS_XACQUIRE;
|
{
|
||||||
}
|
info->avx.maskMode = ZYDIS_AVX_MASKMODE_MERGE;
|
||||||
{
|
}
|
||||||
info->prefixFlags &= ~ZYDIS_PREFIXFLAG_HAS_REP;
|
switch (definition->evexBFunctionality)
|
||||||
info->prefixFlags |= ZYDIS_PREFIXFLAG_HAS_XRELEASE;
|
{
|
||||||
}
|
case ZYDIS_EVEXB_FUNCTIONALITY_BC:
|
||||||
} else
|
break;
|
||||||
if ((info->mnemonic == ZYDIS_MNEMONIC_MOV) && ((info->opcode == 0x88) ||
|
case ZYDIS_EVEXB_FUNCTIONALITY_RC:
|
||||||
(info->opcode == 0x89) || (info->opcode == 0xC6) || (info->opcode == 0xC7)))
|
info->avx.roundingMode =
|
||||||
{
|
(((info->details.evex.l2 & 0x01) << 1) | info->details.evex.l) + 1;
|
||||||
if (info->prefixFlags & ZYDIS_PREFIXFLAG_HAS_REP)
|
case ZYDIS_EVEXB_FUNCTIONALITY_SAE:
|
||||||
{
|
info->avx.sae = true;
|
||||||
info->prefixFlags &= ~ZYDIS_PREFIXFLAG_HAS_REP;
|
default:
|
||||||
info->prefixFlags |= ZYDIS_PREFIXFLAG_HAS_XRELEASE;
|
info->avx.broadcast = ZYDIS_AVX_BCSTMODE_INVALID;
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adjust instruction mnemonics
|
// Replace XCHG rAX, rAX with NOP alias
|
||||||
if (info->mnemonic == ZYDIS_MNEMONIC_XCHG)
|
if (info->mnemonic == ZYDIS_MNEMONIC_XCHG)
|
||||||
{
|
{
|
||||||
if (((info->operand[0].reg == ZYDIS_REGISTER_RAX) &&
|
if (((info->operand[0].reg == ZYDIS_REGISTER_RAX) &&
|
||||||
|
@ -2199,11 +2157,11 @@ static ZydisDecoderStatus ZydisDecodeOpcode(ZydisInstructionDecoder* decoder,
|
||||||
ZYDIS_ASSERT(info);
|
ZYDIS_ASSERT(info);
|
||||||
|
|
||||||
// Iterate through the instruction table
|
// Iterate through the instruction table
|
||||||
ZydisInstructionTableNode node = ZydisInstructionTableGetRootNode();
|
const ZydisInstructionTableNode* node = ZydisInstructionTableGetRootNode();
|
||||||
ZydisInstructionTableNodeType nodeType;
|
ZydisInstructionTableNodeType nodeType;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
nodeType = ZydisInstructionTableGetNodeType(node);
|
nodeType = node->type;
|
||||||
uint16_t index = 0;
|
uint16_t index = 0;
|
||||||
ZydisDecoderStatus status = 0;
|
ZydisDecoderStatus status = 0;
|
||||||
switch (nodeType)
|
switch (nodeType)
|
||||||
|
@ -2220,16 +2178,22 @@ static ZydisDecoderStatus ZydisDecodeOpcode(ZydisInstructionDecoder* decoder,
|
||||||
case ZYDIS_NODETYPE_DEFINITION_4OP:
|
case ZYDIS_NODETYPE_DEFINITION_4OP:
|
||||||
case ZYDIS_NODETYPE_DEFINITION_5OP:
|
case ZYDIS_NODETYPE_DEFINITION_5OP:
|
||||||
{
|
{
|
||||||
const ZydisInstructionDefinition definition = ZydisInstructionDefinitionByNode(node);
|
const ZydisInstructionDefinition* definition = NULL;
|
||||||
//ZYDIS_ASSERT(definition); // TODO: Pointer?
|
const ZydisOperandDefinition* operands = NULL;
|
||||||
info->mnemonic = definition.mnemonic;
|
uint8_t operandCount;
|
||||||
|
ZydisInstructionTableGetDefinition(node, &definition, &operands, &operandCount);
|
||||||
|
|
||||||
|
ZYDIS_ASSERT(definition);
|
||||||
|
ZYDIS_ASSERT(operands);
|
||||||
|
|
||||||
|
info->mnemonic = (ZydisInstructionMnemonic)definition->mnemonic;
|
||||||
|
|
||||||
if (info->encoding == ZYDIS_INSTRUCTION_ENCODING_3DNOW)
|
if (info->encoding == ZYDIS_INSTRUCTION_ENCODING_3DNOW)
|
||||||
{
|
{
|
||||||
// Save input-buffer state and decode dummy operands
|
// Save input-buffer state and decode dummy operands
|
||||||
uint8_t bufferPosRead = decoder->buffer.posRead;
|
uint8_t bufferPosRead = decoder->buffer.posRead;
|
||||||
uint8_t length = info->length;
|
uint8_t length = info->length;
|
||||||
ZYDIS_CHECK(ZydisDecodeOperands(decoder, info, &definition)); // TODO: Reference?
|
ZYDIS_CHECK(ZydisDecodeOperands(decoder, info, operands, operandCount));
|
||||||
// Read actual 3dnow opcode
|
// Read actual 3dnow opcode
|
||||||
ZYDIS_CHECK(ZydisInputNext(decoder, info, &info->opcode));
|
ZYDIS_CHECK(ZydisInputNext(decoder, info, &info->opcode));
|
||||||
// Restore input-buffer state
|
// Restore input-buffer state
|
||||||
|
@ -2247,7 +2211,7 @@ static ZydisDecoderStatus ZydisDecodeOpcode(ZydisInstructionDecoder* decoder,
|
||||||
node = ZydisInstructionTableGetChildNode(node, 0x0F);
|
node = ZydisInstructionTableGetChildNode(node, 0x0F);
|
||||||
node = ZydisInstructionTableGetChildNode(node, 0x0F);
|
node = ZydisInstructionTableGetChildNode(node, 0x0F);
|
||||||
node = ZydisInstructionTableGetChildNode(node, info->opcode);
|
node = ZydisInstructionTableGetChildNode(node, info->opcode);
|
||||||
if (ZydisInstructionTableGetNodeType(node) == ZYDIS_NODETYPE_INVALID)
|
if (node->type == ZYDIS_NODETYPE_INVALID)
|
||||||
{
|
{
|
||||||
info->instrFlags |= ZYDIS_INSTRFLAG_ERROR_UNDEFINED;
|
info->instrFlags |= ZYDIS_INSTRFLAG_ERROR_UNDEFINED;
|
||||||
return ZYDIS_STATUS_DECODER_UNDEFINED_INSTRUCTION;
|
return ZYDIS_STATUS_DECODER_UNDEFINED_INSTRUCTION;
|
||||||
|
@ -2255,43 +2219,18 @@ static ZydisDecoderStatus ZydisDecodeOpcode(ZydisInstructionDecoder* decoder,
|
||||||
node = ZydisInstructionTableGetChildNode(node,
|
node = ZydisInstructionTableGetChildNode(node,
|
||||||
(info->details.modrm.mod == 0x3) ? 1 : 0);
|
(info->details.modrm.mod == 0x3) ? 1 : 0);
|
||||||
// Decode actual operands and fix the instruction-info
|
// Decode actual operands and fix the instruction-info
|
||||||
ZydisInstructionDefinition definition2 = ZydisInstructionDefinitionByNode(node);
|
ZydisInstructionTableGetDefinition(node, &definition, &operands, &operandCount);
|
||||||
//ZYDIS_ASSERT(definition); // TODO: Pointer
|
ZYDIS_ASSERT(definition);
|
||||||
ZYDIS_CHECK(ZydisDecodeOperands(decoder, info, &definition2)); // TODO: Reference
|
ZYDIS_ASSERT(operands);
|
||||||
info->mnemonic = definition2.mnemonic;
|
ZYDIS_CHECK(ZydisDecodeOperands(decoder, info, operands, operandCount));
|
||||||
ZydisFinalizeInstructionInfo(info);
|
info->mnemonic = (ZydisInstructionMnemonic)definition->mnemonic;
|
||||||
|
ZydisFinalizeInstructionInfo(info, definition);
|
||||||
return ZydisInputNext(decoder, info, &info->opcode);
|
return ZydisInputNext(decoder, info, &info->opcode);
|
||||||
}
|
}
|
||||||
|
|
||||||
ZYDIS_CHECK(ZydisDecodeOperands(decoder, info, &definition)); // TODO: Reference
|
ZYDIS_CHECK(ZydisDecodeOperands(decoder, info, operands, operandCount));
|
||||||
ZydisFinalizeInstructionInfo(info);
|
ZydisFinalizeInstructionInfo(info, definition);
|
||||||
|
|
||||||
if (info->encoding == ZYDIS_INSTRUCTION_ENCODING_EVEX)
|
|
||||||
{
|
|
||||||
if (definition.hasEvexAAA && info->details.evex.aaa)
|
|
||||||
{
|
|
||||||
info->avx.maskRegister = ZYDIS_REGISTER_K0 + info->details.evex.aaa;
|
|
||||||
}
|
|
||||||
if (definition.hasEvexZ && info->details.evex.z)
|
|
||||||
{
|
|
||||||
info->avx.maskMode = ZYDIS_AVX_MASKMODE_ZERO;
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
info->avx.maskMode = ZYDIS_AVX_MASKMODE_MERGE;
|
|
||||||
}
|
|
||||||
switch (definition.evexBFunctionality)
|
|
||||||
{
|
|
||||||
case ZYDIS_EVEXB_FUNCTIONALITY_BC:
|
|
||||||
break;
|
|
||||||
case ZYDIS_EVEXB_FUNCTIONALITY_RC:
|
|
||||||
info->avx.roundingMode =
|
|
||||||
(((info->details.evex.l2 & 0x01) << 1) | info->details.evex.l) + 1;
|
|
||||||
case ZYDIS_EVEXB_FUNCTIONALITY_SAE:
|
|
||||||
info->avx.sae = true;
|
|
||||||
default:
|
|
||||||
info->avx.broadcast = ZYDIS_AVX_BCSTMODE_INVALID;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ZYDIS_STATUS_DECODER_SUCCESS;
|
return ZYDIS_STATUS_DECODER_SUCCESS;
|
||||||
}
|
}
|
||||||
case ZYDIS_NODETYPE_FILTER_OPCODE:
|
case ZYDIS_NODETYPE_FILTER_OPCODE:
|
||||||
|
|
|
@ -440,18 +440,26 @@ static ZydisStatus ZydisFormatterFormatInstructionIntel(ZydisInstructionFormatte
|
||||||
{
|
{
|
||||||
size_t offset = 0;
|
size_t offset = 0;
|
||||||
|
|
||||||
|
if ((info->prefixFlags & ZYDIS_PREFIXFLAG_ACCEPTS_REP) &&
|
||||||
|
(info->prefixFlags & ZYDIS_PREFIXFLAG_HAS_REP))
|
||||||
|
{
|
||||||
|
ZYDIS_CHECK(ZydisBufferAppend(buffer, bufferLen, &offset,
|
||||||
|
(formatter->flags & ZYDIS_FORMATTER_FLAG_UPPERCASE), "rep "));
|
||||||
|
}
|
||||||
|
if ((info->prefixFlags & ZYDIS_PREFIXFLAG_ACCEPTS_REPE) &&
|
||||||
|
(info->prefixFlags & ZYDIS_PREFIXFLAG_HAS_REPE))
|
||||||
|
{
|
||||||
|
ZYDIS_CHECK(ZydisBufferAppend(buffer, bufferLen, &offset,
|
||||||
|
(formatter->flags & ZYDIS_FORMATTER_FLAG_UPPERCASE), "repe "));
|
||||||
|
}
|
||||||
if ((info->prefixFlags & ZYDIS_PREFIXFLAG_ACCEPTS_REPNE) &&
|
if ((info->prefixFlags & ZYDIS_PREFIXFLAG_ACCEPTS_REPNE) &&
|
||||||
(info->prefixFlags & ZYDIS_PREFIXFLAG_HAS_REPNE))
|
(info->prefixFlags & ZYDIS_PREFIXFLAG_HAS_REPNE))
|
||||||
{
|
{
|
||||||
ZYDIS_CHECK(ZydisBufferAppend(buffer, bufferLen, &offset,
|
ZYDIS_CHECK(ZydisBufferAppend(buffer, bufferLen, &offset,
|
||||||
(formatter->flags & ZYDIS_FORMATTER_FLAG_UPPERCASE), "repne "));
|
(formatter->flags & ZYDIS_FORMATTER_FLAG_UPPERCASE), "repne "));
|
||||||
}
|
}
|
||||||
if ((info->prefixFlags & ZYDIS_PREFIXFLAG_ACCEPTS_REP) && (info->prefixFlags & ZYDIS_PREFIXFLAG_HAS_REP))
|
if ((info->prefixFlags & ZYDIS_PREFIXFLAG_ACCEPTS_LOCK) &&
|
||||||
{
|
(info->prefixFlags & ZYDIS_PREFIXFLAG_HAS_LOCK))
|
||||||
ZYDIS_CHECK(ZydisBufferAppend(buffer, bufferLen, &offset,
|
|
||||||
(formatter->flags & ZYDIS_FORMATTER_FLAG_UPPERCASE), "rep "));
|
|
||||||
}
|
|
||||||
if ((info->prefixFlags & ZYDIS_PREFIXFLAG_ACCEPTS_LOCK) && (info->prefixFlags & ZYDIS_PREFIXFLAG_HAS_LOCK))
|
|
||||||
{
|
{
|
||||||
ZYDIS_CHECK(ZydisBufferAppend(buffer, bufferLen, &offset,
|
ZYDIS_CHECK(ZydisBufferAppend(buffer, bufferLen, &offset,
|
||||||
(formatter->flags & ZYDIS_FORMATTER_FLAG_UPPERCASE), "lock "));
|
(formatter->flags & ZYDIS_FORMATTER_FLAG_UPPERCASE), "lock "));
|
||||||
|
|
|
@ -25,81 +25,12 @@
|
||||||
***************************************************************************************************/
|
***************************************************************************************************/
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <string.h>
|
|
||||||
#include <Zydis/Internal/InstructionTable.h>
|
#include <Zydis/Internal/InstructionTable.h>
|
||||||
|
|
||||||
/* ============================================================================================== */
|
/* ============================================================================================== */
|
||||||
/* Data tables */
|
/* Data tables */
|
||||||
/* ============================================================================================== */
|
/* ============================================================================================== */
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------------------------------- */
|
|
||||||
/* Generated types & Macros */
|
|
||||||
/* ---------------------------------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
// TODO: Auto generate these structs and macros
|
|
||||||
|
|
||||||
typedef struct ZydisInternalInstructionTableNode_
|
|
||||||
{
|
|
||||||
ZydisInstructionTableNodeType type;
|
|
||||||
ZydisInstructionTableNodeValue value;
|
|
||||||
} ZydisInternalInstructionTableNode;
|
|
||||||
|
|
||||||
#define ZYDIS_MAKE_INSTRUCTIONTABLENODE(type, value) \
|
|
||||||
{ type, value }
|
|
||||||
#define ZYDIS_GET_INSTRUCTIONTABLENODE_TYPE(node) \
|
|
||||||
node.type
|
|
||||||
#define ZYDIS_GET_INSTRUCTIONTABLENODE_VALUE(node) \
|
|
||||||
node.value
|
|
||||||
|
|
||||||
//typedef struct ZydisInternalOperandDefinition_
|
|
||||||
//{
|
|
||||||
// unsigned int type : 8;
|
|
||||||
// unsigned int encoding : 8;
|
|
||||||
// unsigned int access : 2;
|
|
||||||
//} ZydisInternalOperandDefinition;
|
|
||||||
//
|
|
||||||
//#define ZYDIS_MAKE_OPERANDDEFINITION(type, encoding, access) \
|
|
||||||
// { type, encoding, access }
|
|
||||||
//#define ZYDIS_GET_OPERANDDEFINITION_TYPE(def) \
|
|
||||||
// (ZydisSemanticOperandType)def.type
|
|
||||||
//#define ZYDIS_GET_OPERANDDEFINITION_ENCODING(def) \
|
|
||||||
// (ZydisOperandEncoding)def.encoding
|
|
||||||
//#define ZYDIS_GET_OPERANDDEFINITION_ACCESS(def) \
|
|
||||||
// (ZydisOperandAccess)def.access
|
|
||||||
|
|
||||||
typedef uint8_t ZydisInternalOperandDefinition[2];
|
|
||||||
|
|
||||||
#define ZYDIS_MAKE_OPERANDDEFINITION(type, encoding, access) \
|
|
||||||
{ type, ((encoding & 0x3F) << 2) | (access & 0x03) }
|
|
||||||
#define ZYDIS_GET_OPERANDDEFINITION_TYPE(def) \
|
|
||||||
def[0]
|
|
||||||
#define ZYDIS_GET_OPERANDDEFINITION_ENCODING(def) \
|
|
||||||
((def[1] >> 2) & 0x3F)
|
|
||||||
#define ZYDIS_GET_OPERANDDEFINITION_ACCESS(def) \
|
|
||||||
(def[1] & 0x03)
|
|
||||||
|
|
||||||
typedef struct ZydisInternalInstructionDefinition_
|
|
||||||
{
|
|
||||||
unsigned int mnemonic : 11;
|
|
||||||
unsigned int operandRef : 9;
|
|
||||||
unsigned int evexBFunctionality : 2;
|
|
||||||
unsigned int hasEvexAAA : 1;
|
|
||||||
unsigned int hasEvexZ : 1;
|
|
||||||
} ZydisInternalInstructionDefinition;
|
|
||||||
|
|
||||||
#define ZYDIS_MAKE_INSTRUCTIONDEFINITION(mnemonic, operandRef, evexBFunctionality, hasEvexAAA, hasEvexZ) \
|
|
||||||
{ mnemonic, operandRef, evexBFunctionality, hasEvexAAA, hasEvexZ }
|
|
||||||
#define ZYDIS_GET_INSTRUCTIONDEFINITION_MNEMONIC(def) \
|
|
||||||
(ZydisInstructionMnemonic)def.mnemonic
|
|
||||||
#define ZYDIS_GET_INSTRUCTIONDEFINITION_OPERANDREF(def) \
|
|
||||||
def.operandRef
|
|
||||||
#define ZYDIS_GET_INSTRUCTIONDEFINITION_EVEXBFUNCTIONALITY(def) \
|
|
||||||
(ZydisEvexBFunctionality)def.evexBFunctionality
|
|
||||||
#define ZYDIS_GET_INSTRUCTIONDEFINITION_HASEVEXAAA(def) \
|
|
||||||
def.hasEvexAAA
|
|
||||||
#define ZYDIS_GET_INSTRUCTIONDEFINITION_HASEVEXZ(def) \
|
|
||||||
def.hasEvexZ
|
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------------------------------- */
|
||||||
/* Forward declarations */
|
/* Forward declarations */
|
||||||
/* ---------------------------------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------------------------------- */
|
||||||
|
@ -109,7 +40,7 @@ typedef struct ZydisInternalInstructionDefinition_
|
||||||
*
|
*
|
||||||
* Indexed by the numeric value of the opcode.
|
* Indexed by the numeric value of the opcode.
|
||||||
*/
|
*/
|
||||||
extern const ZydisInternalInstructionTableNode filterOpcode[][256];
|
extern const ZydisInstructionTableNode filterOpcode[][256];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Contains all vex-map filters.
|
* @brief Contains all vex-map filters.
|
||||||
|
@ -132,7 +63,7 @@ extern const ZydisInternalInstructionTableNode filterOpcode[][256];
|
||||||
* E = F2_0F38
|
* E = F2_0F38
|
||||||
* F = F2_0F3A
|
* F = F2_0F3A
|
||||||
*/
|
*/
|
||||||
extern const ZydisInternalInstructionTableNode filterVEX[][16];
|
extern const ZydisInstructionTableNode filterVEX[][16];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Contains all xop-map filters.
|
* @brief Contains all xop-map filters.
|
||||||
|
@ -143,7 +74,7 @@ extern const ZydisInternalInstructionTableNode filterVEX[][16];
|
||||||
* 2 = xop9
|
* 2 = xop9
|
||||||
* 3 = xopA
|
* 3 = xopA
|
||||||
*/
|
*/
|
||||||
extern const ZydisInternalInstructionTableNode filterXOP[][4];
|
extern const ZydisInstructionTableNode filterXOP[][4];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Contains all instruction-mode filters.
|
* @brief Contains all instruction-mode filters.
|
||||||
|
@ -152,7 +83,7 @@ extern const ZydisInternalInstructionTableNode filterXOP[][4];
|
||||||
* 0 = 64 bit mode required
|
* 0 = 64 bit mode required
|
||||||
* 1 = 64 bit mode excluded
|
* 1 = 64 bit mode excluded
|
||||||
*/
|
*/
|
||||||
extern const ZydisInternalInstructionTableNode filterMode[][2];
|
extern const ZydisInstructionTableNode filterMode[][2];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Contains all mandatory-prefix switch tables.
|
* @brief Contains all mandatory-prefix switch tables.
|
||||||
|
@ -163,7 +94,7 @@ extern const ZydisInternalInstructionTableNode filterMode[][2];
|
||||||
* 2 = F3
|
* 2 = F3
|
||||||
* 3 = F2
|
* 3 = F2
|
||||||
*/
|
*/
|
||||||
extern const ZydisInternalInstructionTableNode filterMandatoryPrefix[][4];
|
extern const ZydisInstructionTableNode filterMandatoryPrefix[][4];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Contains all modrm.mod filters.
|
* @brief Contains all modrm.mod filters.
|
||||||
|
@ -172,21 +103,21 @@ extern const ZydisInternalInstructionTableNode filterMandatoryPrefix[][4];
|
||||||
* 0 = [modrm_mod == !11] = memory
|
* 0 = [modrm_mod == !11] = memory
|
||||||
* 1 = [modrm_mod == 11] = register
|
* 1 = [modrm_mod == 11] = register
|
||||||
*/
|
*/
|
||||||
extern const ZydisInternalInstructionTableNode filterModrmMod[][2];
|
extern const ZydisInstructionTableNode filterModrmMod[][2];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Contains all modrm.reg filters.
|
* @brief Contains all modrm.reg filters.
|
||||||
*
|
*
|
||||||
* Indexed by the numeric value of the modrm_reg field.
|
* Indexed by the numeric value of the modrm_reg field.
|
||||||
*/
|
*/
|
||||||
extern const ZydisInternalInstructionTableNode filterModrmReg[][8];
|
extern const ZydisInstructionTableNode filterModrmReg[][8];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Contains all modrm.rm filters.
|
* @brief Contains all modrm.rm filters.
|
||||||
*
|
*
|
||||||
* Indexed by the numeric value of the modrm_rm field.
|
* Indexed by the numeric value of the modrm_rm field.
|
||||||
*/
|
*/
|
||||||
extern const ZydisInternalInstructionTableNode filterModrmRm[][8];
|
extern const ZydisInstructionTableNode filterModrmRm[][8];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Contains all operand-size filters.
|
* @brief Contains all operand-size filters.
|
||||||
|
@ -195,7 +126,7 @@ extern const ZydisInternalInstructionTableNode filterModrmRm[][8];
|
||||||
* 0 = 16bit = 0x66 prefix in 32 bit mode
|
* 0 = 16bit = 0x66 prefix in 32 bit mode
|
||||||
* 1 = 32bit = 0x66 prefix in 16 bit mode
|
* 1 = 32bit = 0x66 prefix in 16 bit mode
|
||||||
*/
|
*/
|
||||||
extern const ZydisInternalInstructionTableNode filterOperandSize[][2];
|
extern const ZydisInstructionTableNode filterOperandSize[][2];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Contains all address-size filters.
|
* @brief Contains all address-size filters.
|
||||||
|
@ -205,207 +136,169 @@ extern const ZydisInternalInstructionTableNode filterOperandSize[][2];
|
||||||
* 1 = 32
|
* 1 = 32
|
||||||
* 2 = 64
|
* 2 = 64
|
||||||
*/
|
*/
|
||||||
extern const ZydisInternalInstructionTableNode filterAddressSize[][3];
|
extern const ZydisInstructionTableNode filterAddressSize[][3];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Contains all rex/vex/evex.w filters.
|
* @brief Contains all rex/vex/evex.w filters.
|
||||||
*
|
*
|
||||||
* Indexed by the numeric value of the rex/vex/evex.w field.
|
* Indexed by the numeric value of the rex/vex/evex.w field.
|
||||||
*/
|
*/
|
||||||
extern const ZydisInternalInstructionTableNode filterREXW[][2];
|
extern const ZydisInstructionTableNode filterREXW[][2];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Contains all vex.l filters.
|
* @brief Contains all vex.l filters.
|
||||||
*
|
*
|
||||||
* Indexed by the numeric value of the vex/evex.l field.
|
* Indexed by the numeric value of the vex/evex.l field.
|
||||||
*/
|
*/
|
||||||
extern const ZydisInternalInstructionTableNode filterVEXL[][2];
|
extern const ZydisInstructionTableNode filterVEXL[][2];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Contains all evex.l' filters.
|
* @brief Contains all evex.l' filters.
|
||||||
*
|
*
|
||||||
* Indexed by the numeric value of the evex.l' field.
|
* Indexed by the numeric value of the evex.l' field.
|
||||||
*/
|
*/
|
||||||
extern const ZydisInternalInstructionTableNode filterEVEXL2[][2];
|
extern const ZydisInstructionTableNode filterEVEXL2[][2];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Contains all evex.b filters.
|
* @brief Contains all evex.b filters.
|
||||||
*
|
*
|
||||||
* Indexed by the numeric value of the evex.b field.
|
* Indexed by the numeric value of the evex.b field.
|
||||||
*/
|
*/
|
||||||
extern const ZydisInternalInstructionTableNode filterEVEXB[][2];
|
extern const ZydisInstructionTableNode filterEVEXB[][2];
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Contains all operand-definitions with 1 operand.
|
* @brief Contains all operand-definitions with 1 operand.
|
||||||
*/
|
*/
|
||||||
extern const ZydisInternalOperandDefinition operandDefinitions1[][1];
|
extern const ZydisOperandDefinition operandDefinitions1[][1];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Contains all operand-definitions with 2 operands.
|
* @brief Contains all operand-definitions with 2 operands.
|
||||||
*/
|
*/
|
||||||
extern const ZydisInternalOperandDefinition operandDefinitions2[][2];
|
extern const ZydisOperandDefinition operandDefinitions2[][2];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Contains all operand-definitions with 3 operands.
|
* @brief Contains all operand-definitions with 3 operands.
|
||||||
*/
|
*/
|
||||||
extern const ZydisInternalOperandDefinition operandDefinitions3[][3];
|
extern const ZydisOperandDefinition operandDefinitions3[][3];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Contains all operand-definitions with 4 operands.
|
* @brief Contains all operand-definitions with 4 operands.
|
||||||
*/
|
*/
|
||||||
extern const ZydisInternalOperandDefinition operandDefinitions4[][4];
|
extern const ZydisOperandDefinition operandDefinitions4[][4];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Contains all operand-definitions with 5 operands.
|
* @brief Contains all operand-definitions with 5 operands.
|
||||||
*/
|
*/
|
||||||
extern const ZydisInternalOperandDefinition operandDefinitions5[][5];
|
extern const ZydisOperandDefinition operandDefinitions5[][5];
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Contains all instruction-definitions.
|
* @brief Contains all instruction-definitions.
|
||||||
*/
|
*/
|
||||||
extern const ZydisInternalInstructionDefinition instructionDefinitions[];
|
extern const ZydisInstructionDefinition instructionDefinitions[];
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------------------------------- */
|
||||||
/* Functions */
|
/* Functions */
|
||||||
/* ---------------------------------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
ZydisInstructionTableNodeType ZydisInstructionTableGetNodeType(
|
const ZydisInstructionTableNode* ZydisInstructionTableGetRootNode()
|
||||||
const ZydisInstructionTableNode node)
|
|
||||||
{
|
{
|
||||||
return (ZydisInstructionTableNodeType)
|
static const ZydisInstructionTableNode root = { ZYDIS_NODETYPE_FILTER_OPCODE, 0x00000000 };
|
||||||
ZYDIS_GET_INSTRUCTIONTABLENODE_TYPE((*(ZydisInternalInstructionTableNode*)node));
|
return &root;
|
||||||
}
|
}
|
||||||
|
|
||||||
ZydisInstructionTableNodeValue ZydisInstructionTableGetNodeValue(
|
const ZydisInstructionTableNode* ZydisInstructionTableGetChildNode(
|
||||||
const ZydisInstructionTableNode* node)
|
const ZydisInstructionTableNode* parent, uint16_t index)
|
||||||
{
|
{
|
||||||
return (ZydisInstructionTableNodeValue)
|
switch (parent->type)
|
||||||
ZYDIS_GET_INSTRUCTIONTABLENODE_VALUE((*(ZydisInternalInstructionTableNode*)node));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
ZydisInstructionTableNode ZydisInstructionTableGetRootNode()
|
|
||||||
{
|
|
||||||
static const ZydisInternalInstructionTableNode root =
|
|
||||||
ZYDIS_MAKE_INSTRUCTIONTABLENODE(ZYDIS_NODETYPE_FILTER_OPCODE, 0x00000000);
|
|
||||||
return (ZydisInstructionTableNode)&root;
|
|
||||||
}
|
|
||||||
|
|
||||||
ZydisInstructionTableNode ZydisInstructionTableGetChildNode(
|
|
||||||
const ZydisInstructionTableNode parent, uint16_t index)
|
|
||||||
{
|
|
||||||
ZydisInstructionTableNodeType nodeType = ZydisInstructionTableGetNodeType(parent);
|
|
||||||
uint16_t tableIndex = ZydisInstructionTableGetNodeValue(parent);
|
|
||||||
switch (nodeType)
|
|
||||||
{
|
{
|
||||||
case ZYDIS_NODETYPE_FILTER_OPCODE:
|
case ZYDIS_NODETYPE_FILTER_OPCODE:
|
||||||
ZYDIS_ASSERT(index < 256);
|
ZYDIS_ASSERT(index < 256);
|
||||||
return (ZydisInstructionTableNode*)&filterOpcode[tableIndex][index];
|
return &filterOpcode[parent->value][index];
|
||||||
case ZYDIS_NODETYPE_FILTER_VEX:
|
case ZYDIS_NODETYPE_FILTER_VEX:
|
||||||
ZYDIS_ASSERT(index < 16);
|
ZYDIS_ASSERT(index < 16);
|
||||||
return (ZydisInstructionTableNode*)&filterVEX[tableIndex][index];
|
return &filterVEX[parent->value][index];
|
||||||
case ZYDIS_NODETYPE_FILTER_XOP:
|
case ZYDIS_NODETYPE_FILTER_XOP:
|
||||||
ZYDIS_ASSERT(index < 4);
|
ZYDIS_ASSERT(index < 4);
|
||||||
return (ZydisInstructionTableNode*)&filterXOP[tableIndex][index];
|
return &filterXOP[parent->value][index];
|
||||||
case ZYDIS_NODETYPE_FILTER_MODE:
|
case ZYDIS_NODETYPE_FILTER_MODE:
|
||||||
ZYDIS_ASSERT(index < 3);
|
ZYDIS_ASSERT(index < 3);
|
||||||
return (ZydisInstructionTableNode*)&filterMode[tableIndex][index];
|
return &filterMode[parent->value][index];
|
||||||
case ZYDIS_NODETYPE_FILTER_MANDATORYPREFIX:
|
case ZYDIS_NODETYPE_FILTER_MANDATORYPREFIX:
|
||||||
ZYDIS_ASSERT(index < 4);
|
ZYDIS_ASSERT(index < 4);
|
||||||
return (ZydisInstructionTableNode*)&filterMandatoryPrefix[tableIndex][index];
|
return &filterMandatoryPrefix[parent->value][index];
|
||||||
case ZYDIS_NODETYPE_FILTER_MODRMMOD:
|
case ZYDIS_NODETYPE_FILTER_MODRMMOD:
|
||||||
ZYDIS_ASSERT(index < 2);
|
ZYDIS_ASSERT(index < 2);
|
||||||
return (ZydisInstructionTableNode*)&filterModrmMod[tableIndex][index];
|
return &filterModrmMod[parent->value][index];
|
||||||
case ZYDIS_NODETYPE_FILTER_MODRMREG:
|
case ZYDIS_NODETYPE_FILTER_MODRMREG:
|
||||||
ZYDIS_ASSERT(index < 8);
|
ZYDIS_ASSERT(index < 8);
|
||||||
return (ZydisInstructionTableNode*)&filterModrmReg[tableIndex][index];
|
return &filterModrmReg[parent->value][index];
|
||||||
case ZYDIS_NODETYPE_FILTER_MODRMRM:
|
case ZYDIS_NODETYPE_FILTER_MODRMRM:
|
||||||
ZYDIS_ASSERT(index < 8);
|
ZYDIS_ASSERT(index < 8);
|
||||||
return (ZydisInstructionTableNode*)&filterModrmRm[tableIndex][index];
|
return &filterModrmRm[parent->value][index];
|
||||||
case ZYDIS_NODETYPE_FILTER_OPERANDSIZE:
|
case ZYDIS_NODETYPE_FILTER_OPERANDSIZE:
|
||||||
ZYDIS_ASSERT(index < 2);
|
ZYDIS_ASSERT(index < 2);
|
||||||
return (ZydisInstructionTableNode*)&filterOperandSize[tableIndex][index];
|
return &filterOperandSize[parent->value][index];
|
||||||
case ZYDIS_NODETYPE_FILTER_ADDRESSSIZE:
|
case ZYDIS_NODETYPE_FILTER_ADDRESSSIZE:
|
||||||
ZYDIS_ASSERT(index < 3);
|
ZYDIS_ASSERT(index < 3);
|
||||||
return (ZydisInstructionTableNode*)&filterAddressSize[tableIndex][index];
|
return &filterAddressSize[parent->value][index];
|
||||||
case ZYDIS_NODETYPE_FILTER_REXW:
|
case ZYDIS_NODETYPE_FILTER_REXW:
|
||||||
ZYDIS_ASSERT(index < 2);
|
ZYDIS_ASSERT(index < 2);
|
||||||
return (ZydisInstructionTableNode*)&filterREXW[tableIndex][index];
|
return &filterREXW[parent->value][index];
|
||||||
case ZYDIS_NODETYPE_FILTER_VEXL:
|
case ZYDIS_NODETYPE_FILTER_VEXL:
|
||||||
ZYDIS_ASSERT(index < 2);
|
ZYDIS_ASSERT(index < 2);
|
||||||
return (ZydisInstructionTableNode*)&filterVEXL[tableIndex][index];
|
return &filterVEXL[parent->value][index];
|
||||||
case ZYDIS_NODETYPE_FILTER_EVEXL2:
|
case ZYDIS_NODETYPE_FILTER_EVEXL2:
|
||||||
ZYDIS_ASSERT(index < 2);
|
ZYDIS_ASSERT(index < 2);
|
||||||
return (ZydisInstructionTableNode*)&filterEVEXL2[tableIndex][index];
|
return &filterEVEXL2[parent->value][index];
|
||||||
case ZYDIS_NODETYPE_FILTER_EVEXB:
|
case ZYDIS_NODETYPE_FILTER_EVEXB:
|
||||||
ZYDIS_ASSERT(index < 2);
|
ZYDIS_ASSERT(index < 2);
|
||||||
return (ZydisInstructionTableNode*)&filterEVEXB[tableIndex][index];
|
return &filterEVEXB[parent->value][index];
|
||||||
default:
|
default:
|
||||||
ZYDIS_UNREACHABLE;
|
ZYDIS_UNREACHABLE;
|
||||||
}
|
}
|
||||||
static const ZydisInternalInstructionTableNode invalid =
|
static const ZydisInstructionTableNode invalid = { ZYDIS_NODETYPE_INVALID, 0x00000000 };
|
||||||
ZYDIS_MAKE_INSTRUCTIONTABLENODE(ZYDIS_NODETYPE_INVALID, 0x00000000);
|
return &invalid;
|
||||||
return (ZydisInstructionTableNode)&invalid;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ZydisInstructionDefinition ZydisInstructionDefinitionByNode(
|
bool ZydisInstructionTableGetDefinition(const ZydisInstructionTableNode* node,
|
||||||
const ZydisInstructionTableNode node)
|
const ZydisInstructionDefinition** definition, const ZydisOperandDefinition** operands,
|
||||||
|
uint8_t* operandCount)
|
||||||
{
|
{
|
||||||
ZydisInstructionDefinition result;
|
*definition = &instructionDefinitions[node->value];
|
||||||
memset(&result, 0, sizeof(result));
|
switch (node->type)
|
||||||
|
|
||||||
const ZydisInternalInstructionDefinition* definition =
|
|
||||||
&instructionDefinitions[ZydisInstructionTableGetNodeValue(node)];
|
|
||||||
result.mnemonic = ZYDIS_GET_INSTRUCTIONDEFINITION_MNEMONIC((*definition));
|
|
||||||
result.evexBFunctionality = ZYDIS_GET_INSTRUCTIONDEFINITION_EVEXBFUNCTIONALITY((*definition));
|
|
||||||
result.hasEvexAAA = ZYDIS_GET_INSTRUCTIONDEFINITION_HASEVEXAAA((*definition));
|
|
||||||
result.hasEvexZ = ZYDIS_GET_INSTRUCTIONDEFINITION_HASEVEXZ((*definition));
|
|
||||||
|
|
||||||
const ZydisInternalOperandDefinition* operand = NULL;
|
|
||||||
switch (ZydisInstructionTableGetNodeType(node))
|
|
||||||
{
|
{
|
||||||
case ZYDIS_NODETYPE_DEFINITION_0OP:
|
case ZYDIS_NODETYPE_DEFINITION_0OP:
|
||||||
result.operandCount = 0;
|
*operandCount = 0;
|
||||||
break;
|
break;
|
||||||
case ZYDIS_NODETYPE_DEFINITION_1OP:
|
case ZYDIS_NODETYPE_DEFINITION_1OP:
|
||||||
result.operandCount = 1;
|
*operandCount = 1;
|
||||||
operand = operandDefinitions1[ZYDIS_GET_INSTRUCTIONDEFINITION_OPERANDREF((*definition))];
|
*operands = operandDefinitions1[(*definition)->operandsId];
|
||||||
break;
|
break;
|
||||||
case ZYDIS_NODETYPE_DEFINITION_2OP:
|
case ZYDIS_NODETYPE_DEFINITION_2OP:
|
||||||
result.operandCount = 2;
|
*operandCount = 2;
|
||||||
operand = operandDefinitions2[ZYDIS_GET_INSTRUCTIONDEFINITION_OPERANDREF((*definition))];
|
*operands = operandDefinitions2[(*definition)->operandsId];
|
||||||
break;
|
break;
|
||||||
case ZYDIS_NODETYPE_DEFINITION_3OP:
|
case ZYDIS_NODETYPE_DEFINITION_3OP:
|
||||||
result.operandCount = 3;
|
*operandCount = 3;
|
||||||
operand = operandDefinitions3[ZYDIS_GET_INSTRUCTIONDEFINITION_OPERANDREF((*definition))];
|
*operands = operandDefinitions3[(*definition)->operandsId];
|
||||||
break;
|
break;
|
||||||
case ZYDIS_NODETYPE_DEFINITION_4OP:
|
case ZYDIS_NODETYPE_DEFINITION_4OP:
|
||||||
result.operandCount = 4;
|
*operandCount = 4;
|
||||||
operand = operandDefinitions4[ZYDIS_GET_INSTRUCTIONDEFINITION_OPERANDREF((*definition))];
|
*operands = operandDefinitions4[(*definition)->operandsId];
|
||||||
break;
|
break;
|
||||||
case ZYDIS_NODETYPE_DEFINITION_5OP:
|
case ZYDIS_NODETYPE_DEFINITION_5OP:
|
||||||
result.operandCount = 5;
|
*operandCount = 5;
|
||||||
operand = operandDefinitions5[ZYDIS_GET_INSTRUCTIONDEFINITION_OPERANDREF((*definition))];
|
*operands = operandDefinitions5[(*definition)->operandsId];
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ZYDIS_UNREACHABLE;
|
ZYDIS_UNREACHABLE;
|
||||||
}
|
return false;
|
||||||
if (result.operandCount > 0)
|
}
|
||||||
{
|
return true;
|
||||||
for (int i = 0; i < result.operandCount; ++i)
|
|
||||||
{
|
|
||||||
result.operands[i].type = ZYDIS_GET_OPERANDDEFINITION_TYPE((*operand));
|
|
||||||
result.operands[i].encoding = ZYDIS_GET_OPERANDDEFINITION_ENCODING((*operand));
|
|
||||||
result.operands[i].access = ZYDIS_GET_OPERANDDEFINITION_ACCESS((*operand));
|
|
||||||
++operand;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------------------------------- */
|
||||||
|
@ -413,7 +306,7 @@ ZydisInstructionDefinition ZydisInstructionDefinitionByNode(
|
||||||
/* ---------------------------------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
#define ZYDIS_INVALID \
|
#define ZYDIS_INVALID \
|
||||||
ZYDIS_MAKE_INSTRUCTIONTABLENODE(ZYDIS_NODETYPE_INVALID, 0x00000000)
|
{ ZYDIS_NODETYPE_INVALID, 0x00000000 }
|
||||||
#define ZYDIS_FILTER(type, id) \
|
#define ZYDIS_FILTER(type, id) \
|
||||||
{ type, id }
|
{ type, id }
|
||||||
#define ZYDIS_DEFINITION_0OP(id) \
|
#define ZYDIS_DEFINITION_0OP(id) \
|
||||||
|
@ -440,15 +333,16 @@ ZydisInstructionDefinition ZydisInstructionDefinitionByNode(
|
||||||
#undef ZYDIS_DEFINITION_4OP
|
#undef ZYDIS_DEFINITION_4OP
|
||||||
#undef ZYDIS_DEFINITION_5OP
|
#undef ZYDIS_DEFINITION_5OP
|
||||||
|
|
||||||
#undef ZYDIS_MAKE_INSTRUCTIONTABLENODE
|
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------------------------------- */
|
||||||
/* Operand definitions */
|
/* Operand definitions */
|
||||||
/* ---------------------------------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
#define ZYDIS_OPERAND_DEFINITION(type, encoding, access) \
|
||||||
|
{ type, encoding, access }
|
||||||
|
|
||||||
#include <Zydis/Internal/OperandDefinitions.inc>
|
#include <Zydis/Internal/OperandDefinitions.inc>
|
||||||
|
|
||||||
#undef ZYDIS_MAKE_OPERANDDEFINITION
|
#undef ZYDIS_OPERAND_DEFINITION
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------------------------------- */
|
||||||
/* Instruction definitions */
|
/* Instruction definitions */
|
||||||
|
@ -456,7 +350,4 @@ ZydisInstructionDefinition ZydisInstructionDefinitionByNode(
|
||||||
|
|
||||||
#include <Zydis/Internal/InstructionDefinitions.inc>
|
#include <Zydis/Internal/InstructionDefinitions.inc>
|
||||||
|
|
||||||
#undef ZYDIS_MAKE_AVX512INFO
|
|
||||||
#undef ZYDIS_MAKE_INSTRUCTIONDEFINITION
|
|
||||||
|
|
||||||
/* ============================================================================================== */
|
/* ============================================================================================== */
|
||||||
|
|
Loading…
Reference in New Issue