diff --git a/README.md b/README.md
index f25203a4..2b59d568 100644
--- a/README.md
+++ b/README.md
@@ -21,7 +21,7 @@
- Very small file-size overhead compared to other common disassembler libraries
- [Complete doxygen documentation](https://zydis.re/doc/3/)
- Absolutely no third party dependencies — not even libc
- - Should compile on any platform with a working C99 compiler
+ - Should compile on any platform with a working C11 compiler
- Tested on Windows, macOS, FreeBSD, Linux and UEFI, both user and kernel mode
## Decoder Example
@@ -140,7 +140,7 @@ The above example program generates the following output:
### Unix
-Zydis builds cleanly on most platforms without any external dependencies. You can use CMake to generate project files for your favorite C99 compiler.
+Zydis builds cleanly on most platforms without any external dependencies. You can use CMake to generate project files for your favorite C11 compiler.
```bash
git clone --recursive 'https://github.com/zyantific/zydis.git'
diff --git a/assets/porting-guide-v3-v4.md b/assets/porting-guide-v3-v4.md
index c840d4da..36cb77cc 100644
--- a/assets/porting-guide-v3-v4.md
+++ b/assets/porting-guide-v3-v4.md
@@ -1,5 +1,7 @@
# Porting Guide v3 -> v4
+- Zydis now requires a C11 capable compiler
+
## API changes
### ZydisDecodedInstruction
@@ -9,7 +11,7 @@
2. Added field `operand_count_visible`
- Contains the number of visible (explicit and implicit) operands
-### ZydisDecoder
+### Decoder
#### 1
@@ -63,3 +65,5 @@ ZYDIS_EXPORT ZyanStatus ZydisDecoderDecodeOperands(const ZydisDecoder* decoder,
- The `ZYDIS_ATTRIB_` defines were rebased (underlying bits were changed)
- New type: `ZydisDecodingFlags`
- New type: `ZydisDecoderContext`
+- `ZydisDecodedOperand::type` was moved to a different location in the struct
+- Unions were added around fields in `ZydisDecodedOperand` and `ZydisDecodedInstruction`
diff --git a/dependencies/zycore b/dependencies/zycore
index dd2211a0..c58d7fb5 160000
--- a/dependencies/zycore
+++ b/dependencies/zycore
@@ -1 +1 @@
-Subproject commit dd2211a023c2e6d383709fcb401a92943cb5e6b1
+Subproject commit c58d7fb524a7e0ef6cf30f594e4746441a4a2acf
diff --git a/include/Zydis/DecoderTypes.h b/include/Zydis/DecoderTypes.h
index 5cd5c77f..a90c840f 100644
--- a/include/Zydis/DecoderTypes.h
+++ b/include/Zydis/DecoderTypes.h
@@ -117,10 +117,6 @@ typedef struct ZydisDecodedOperand_
* The operand-id.
*/
ZyanU8 id;
- /**
- * The type of the operand.
- */
- ZydisOperandType type;
/**
* The visibility of the operand.
*/
@@ -154,86 +150,91 @@ typedef struct ZydisDecodedOperand_
*/
ZydisOperandAttributes attributes;
/**
- * Extended info for register-operands.
+ * The type of the operand.
*/
- struct ZydisDecodedOperandReg_
- {
- /**
- * The register value.
- */
- ZydisRegister value;
- } reg;
- /**
- * Extended info for memory-operands.
+ ZydisOperandType type;
+ /*
+ * Operand type specific information.
+ *
+ * The enabled union variant is determined by the `type` field.
*/
- struct ZydisDecodedOperandMem_
- {
- /**
- * The type of the memory operand.
- */
- ZydisMemoryOperandType type;
- /**
- * The segment register.
- */
- ZydisRegister segment;
- /**
- * The base register.
- */
- ZydisRegister base;
- /**
- * The index register.
- */
- ZydisRegister index;
+ union {
/**
- * The scale factor.
+ * Extended info for register-operands.
*/
- ZyanU8 scale;
+ struct ZydisDecodedOperandReg_ {
+ /**
+ * The register value.
+ */
+ ZydisRegister value;
+ } reg;
/**
- * Extended info for memory-operands with displacement.
+ * Extended info for memory-operands.
*/
- struct ZydisDecodedOperandMemDisp_
- {
+ struct ZydisDecodedOperandMem_ {
/**
- * Signals, if the displacement value is used.
+ * The type of the memory operand.
*/
- ZyanBool has_displacement;
+ ZydisMemoryOperandType type;
/**
- * The displacement value
+ * The segment register.
*/
- ZyanI64 value;
- } disp;
- } mem;
- /**
- * Extended info for pointer-operands.
- */
- struct ZydisDecodedOperandPtr_
- {
- ZyanU16 segment;
- ZyanU32 offset;
- } ptr;
- /**
- * Extended info for immediate-operands.
- */
- struct ZydisDecodedOperandImm_
- {
- /**
- * Signals, if the immediate value is signed.
- */
- ZyanBool is_signed;
+ ZydisRegister segment;
+ /**
+ * The base register.
+ */
+ ZydisRegister base;
+ /**
+ * The index register.
+ */
+ ZydisRegister index;
+ /**
+ * The scale factor.
+ */
+ ZyanU8 scale;
+ /**
+ * Extended info for memory-operands with displacement.
+ */
+ struct ZydisDecodedOperandMemDisp_ {
+ /**
+ * Signals, if the displacement value is used.
+ */
+ ZyanBool has_displacement;
+ /**
+ * The displacement value
+ */
+ ZyanI64 value;
+ } disp;
+ } mem;
/**
- * Signals, if the immediate value contains a relative offset. You can use
- * `ZydisCalcAbsoluteAddress` to determine the absolute address value.
+ * Extended info for pointer-operands.
*/
- ZyanBool is_relative;
+ struct ZydisDecodedOperandPtr_ {
+ ZyanU16 segment;
+ ZyanU32 offset;
+ } ptr;
/**
- * The immediate value.
+ * Extended info for immediate-operands.
*/
- union ZydisDecodedOperandImmValue_
- {
- ZyanU64 u;
- ZyanI64 s;
- } value;
- } imm;
+ struct ZydisDecodedOperandImm_ {
+ /**
+ * Signals, if the immediate value is signed.
+ */
+ ZyanBool is_signed;
+ /**
+ * Signals, if the immediate value contains a relative offset. You can use
+ * `ZydisCalcAbsoluteAddress` to determine the absolute address value.
+ */
+ ZyanBool is_relative;
+ /**
+ * The immediate value.
+ */
+ union ZydisDecodedOperandImmValue_ {
+ ZyanU64 u;
+ ZyanI64 s;
+ } value;
+ } imm;
+ };
} ZydisDecodedOperand;
/* ---------------------------------------------------------------------------------------------- */
@@ -913,226 +914,227 @@ typedef struct ZydisDecodedInstruction_
*/
ZyanU8 offset;
} rex;
- /**
- * Detailed info about the `XOP` prefix.
+ /*
+ * Union for things from various mutually exclusive vector extensions.
*/
- struct ZydisDecodedInstructionRawXop_
- {
- /**
- * Extension of the `ModRM.reg` field (inverted).
- */
- ZyanU8 R;
- /**
- * Extension of the `SIB.index` field (inverted).
- */
- ZyanU8 X;
- /**
- * Extension of the `ModRM.rm`, `SIB.base`, or `opcode.reg` field (inverted).
- */
- ZyanU8 B;
- /**
- * Opcode-map specifier.
- */
- ZyanU8 m_mmmm;
- /**
- * 64-bit operand-size promotion or opcode-extension.
- */
- ZyanU8 W;
- /**
- * `NDS`/`NDD` (non-destructive-source/destination) register
- * specifier (inverted).
- */
- ZyanU8 vvvv;
- /**
- * Vector-length specifier.
- */
- ZyanU8 L;
- /**
- * Compressed legacy prefix.
- */
- ZyanU8 pp;
- /**
- * The offset of the first xop byte, relative to the beginning of
- * the instruction, in bytes.
- */
- ZyanU8 offset;
- } xop;
- /**
- * Detailed info about the `VEX` prefix.
- */
- struct ZydisDecodedInstructionRawVex_
- {
- /**
- * Extension of the `ModRM.reg` field (inverted).
- */
- ZyanU8 R;
- /**
- * Extension of the `SIB.index` field (inverted).
- */
- ZyanU8 X;
- /**
- * Extension of the `ModRM.rm`, `SIB.base`, or `opcode.reg` field (inverted).
- */
- ZyanU8 B;
- /**
- * Opcode-map specifier.
- */
- ZyanU8 m_mmmm;
- /**
- * 64-bit operand-size promotion or opcode-extension.
- */
- ZyanU8 W;
- /**
- * `NDS`/`NDD` (non-destructive-source/destination) register specifier
- * (inverted).
- */
- ZyanU8 vvvv;
- /**
- * Vector-length specifier.
- */
- ZyanU8 L;
- /**
- * Compressed legacy prefix.
- */
- ZyanU8 pp;
- /**
- * The offset of the first `VEX` byte, relative to the beginning of the instruction, in
- * bytes.
- */
- ZyanU8 offset;
- /**
- * The size of the `VEX` prefix, in bytes.
- */
- ZyanU8 size;
- } vex;
- /**
- * Detailed info about the `EVEX` prefix.
- */
- struct ZydisDecodedInstructionRawEvex_
- {
- /**
- * Extension of the `ModRM.reg` field (inverted).
- */
- ZyanU8 R;
- /**
- * Extension of the `SIB.index/vidx` field (inverted).
- */
- ZyanU8 X;
- /**
- * Extension of the `ModRM.rm` or `SIB.base` field (inverted).
- */
- ZyanU8 B;
- /**
- * High-16 register specifier modifier (inverted).
- */
- ZyanU8 R2;
- /**
- * Opcode-map specifier.
- */
- ZyanU8 mmm;
- /**
- * 64-bit operand-size promotion or opcode-extension.
- */
- ZyanU8 W;
- /**
- * `NDS`/`NDD` (non-destructive-source/destination) register specifier
- * (inverted).
- */
- ZyanU8 vvvv;
- /**
- * Compressed legacy prefix.
- */
- ZyanU8 pp;
- /**
- * Zeroing/Merging.
- */
- ZyanU8 z;
- /**
- * Vector-length specifier or rounding-control (most significant bit).
- */
- ZyanU8 L2;
- /**
- * Vector-length specifier or rounding-control (least significant bit).
- */
- ZyanU8 L;
- /**
- * Broadcast/RC/SAE context.
- */
- ZyanU8 b;
- /**
- * High-16 `NDS`/`VIDX` register specifier.
- */
- ZyanU8 V2;
- /**
- * Embedded opmask register specifier.
- */
- ZyanU8 aaa;
- /**
- * The offset of the first evex byte, relative to the beginning of the
- * instruction, in bytes.
- */
- ZyanU8 offset;
- } evex;
- /**
- * Detailed info about the `MVEX` prefix.
- */
- struct ZydisDecodedInstructionRawMvex_
- {
- /**
- * Extension of the `ModRM.reg` field (inverted).
- */
- ZyanU8 R;
- /**
- * Extension of the `SIB.index/vidx` field (inverted).
- */
- ZyanU8 X;
- /**
- * Extension of the `ModRM.rm` or `SIB.base` field (inverted).
- */
- ZyanU8 B;
- /**
- * High-16 register specifier modifier (inverted).
- */
- ZyanU8 R2;
- /**
- * Opcode-map specifier.
- */
- ZyanU8 mmmm;
- /**
- * 64-bit operand-size promotion or opcode-extension.
- */
- ZyanU8 W;
- /**
- * `NDS`/`NDD` (non-destructive-source/destination) register specifier
- * (inverted).
- */
- ZyanU8 vvvv;
- /**
- * Compressed legacy prefix.
- */
- ZyanU8 pp;
- /**
- * Non-temporal/eviction hint.
- */
- ZyanU8 E;
- /**
- * Swizzle/broadcast/up-convert/down-convert/static-rounding controls.
- */
- ZyanU8 SSS;
- /**
- * High-16 `NDS`/`VIDX` register specifier.
- */
- ZyanU8 V2;
- /**
- * Embedded opmask register specifier.
- */
- ZyanU8 kkk;
- /**
- * The offset of the first mvex byte, relative to the beginning of the
- * instruction, in bytes.
- */
- ZyanU8 offset;
- } mvex;
+ union {
+ /**
+ * Detailed info about the `XOP` prefix.
+ */
+ struct ZydisDecodedInstructionRawXop_ {
+ /**
+ * Extension of the `ModRM.reg` field (inverted).
+ */
+ ZyanU8 R;
+ /**
+ * Extension of the `SIB.index` field (inverted).
+ */
+ ZyanU8 X;
+ /**
+ * Extension of the `ModRM.rm`, `SIB.base`, or `opcode.reg` field (inverted).
+ */
+ ZyanU8 B;
+ /**
+ * Opcode-map specifier.
+ */
+ ZyanU8 m_mmmm;
+ /**
+ * 64-bit operand-size promotion or opcode-extension.
+ */
+ ZyanU8 W;
+ /**
+ * `NDS`/`NDD` (non-destructive-source/destination) register
+ * specifier (inverted).
+ */
+ ZyanU8 vvvv;
+ /**
+ * Vector-length specifier.
+ */
+ ZyanU8 L;
+ /**
+ * Compressed legacy prefix.
+ */
+ ZyanU8 pp;
+ /**
+ * The offset of the first xop byte, relative to the beginning of
+ * the instruction, in bytes.
+ */
+ ZyanU8 offset;
+ } xop;
+ /**
+ * Detailed info about the `VEX` prefix.
+ */
+ struct ZydisDecodedInstructionRawVex_ {
+ /**
+ * Extension of the `ModRM.reg` field (inverted).
+ */
+ ZyanU8 R;
+ /**
+ * Extension of the `SIB.index` field (inverted).
+ */
+ ZyanU8 X;
+ /**
+ * Extension of the `ModRM.rm`, `SIB.base`, or `opcode.reg` field (inverted).
+ */
+ ZyanU8 B;
+ /**
+ * Opcode-map specifier.
+ */
+ ZyanU8 m_mmmm;
+ /**
+ * 64-bit operand-size promotion or opcode-extension.
+ */
+ ZyanU8 W;
+ /**
+ * `NDS`/`NDD` (non-destructive-source/destination) register specifier
+ * (inverted).
+ */
+ ZyanU8 vvvv;
+ /**
+ * Vector-length specifier.
+ */
+ ZyanU8 L;
+ /**
+ * Compressed legacy prefix.
+ */
+ ZyanU8 pp;
+ /**
+ * The offset of the first `VEX` byte, relative to the beginning of the instruction, in
+ * bytes.
+ */
+ ZyanU8 offset;
+ /**
+ * The size of the `VEX` prefix, in bytes.
+ */
+ ZyanU8 size;
+ } vex;
+ /**
+ * Detailed info about the `EVEX` prefix.
+ */
+ struct ZydisDecodedInstructionRawEvex_ {
+ /**
+ * Extension of the `ModRM.reg` field (inverted).
+ */
+ ZyanU8 R;
+ /**
+ * Extension of the `SIB.index/vidx` field (inverted).
+ */
+ ZyanU8 X;
+ /**
+ * Extension of the `ModRM.rm` or `SIB.base` field (inverted).
+ */
+ ZyanU8 B;
+ /**
+ * High-16 register specifier modifier (inverted).
+ */
+ ZyanU8 R2;
+ /**
+ * Opcode-map specifier.
+ */
+ ZyanU8 mmm;
+ /**
+ * 64-bit operand-size promotion or opcode-extension.
+ */
+ ZyanU8 W;
+ /**
+ * `NDS`/`NDD` (non-destructive-source/destination) register specifier
+ * (inverted).
+ */
+ ZyanU8 vvvv;
+ /**
+ * Compressed legacy prefix.
+ */
+ ZyanU8 pp;
+ /**
+ * Zeroing/Merging.
+ */
+ ZyanU8 z;
+ /**
+ * Vector-length specifier or rounding-control (most significant bit).
+ */
+ ZyanU8 L2;
+ /**
+ * Vector-length specifier or rounding-control (least significant bit).
+ */
+ ZyanU8 L;
+ /**
+ * Broadcast/RC/SAE context.
+ */
+ ZyanU8 b;
+ /**
+ * High-16 `NDS`/`VIDX` register specifier.
+ */
+ ZyanU8 V2;
+ /**
+ * Embedded opmask register specifier.
+ */
+ ZyanU8 aaa;
+ /**
+ * The offset of the first evex byte, relative to the beginning of the
+ * instruction, in bytes.
+ */
+ ZyanU8 offset;
+ } evex;
+ /**
+ * Detailed info about the `MVEX` prefix.
+ */
+ struct ZydisDecodedInstructionRawMvex_ {
+ /**
+ * Extension of the `ModRM.reg` field (inverted).
+ */
+ ZyanU8 R;
+ /**
+ * Extension of the `SIB.index/vidx` field (inverted).
+ */
+ ZyanU8 X;
+ /**
+ * Extension of the `ModRM.rm` or `SIB.base` field (inverted).
+ */
+ ZyanU8 B;
+ /**
+ * High-16 register specifier modifier (inverted).
+ */
+ ZyanU8 R2;
+ /**
+ * Opcode-map specifier.
+ */
+ ZyanU8 mmmm;
+ /**
+ * 64-bit operand-size promotion or opcode-extension.
+ */
+ ZyanU8 W;
+ /**
+ * `NDS`/`NDD` (non-destructive-source/destination) register specifier
+ * (inverted).
+ */
+ ZyanU8 vvvv;
+ /**
+ * Compressed legacy prefix.
+ */
+ ZyanU8 pp;
+ /**
+ * Non-temporal/eviction hint.
+ */
+ ZyanU8 E;
+ /**
+ * Swizzle/broadcast/up-convert/down-convert/static-rounding controls.
+ */
+ ZyanU8 SSS;
+ /**
+ * High-16 `NDS`/`VIDX` register specifier.
+ */
+ ZyanU8 V2;
+ /**
+ * Embedded opmask register specifier.
+ */
+ ZyanU8 kkk;
+ /**
+ * The offset of the first mvex byte, relative to the beginning of the
+ * instruction, in bytes.
+ */
+ ZyanU8 offset;
+ } mvex;
+ };
/**
* Detailed info about the `ModRM` byte.
*/
diff --git a/msvc/dependencies/zycore/Zycore.vcxproj b/msvc/dependencies/zycore/Zycore.vcxproj
index fc941189..3803b3fa 100644
--- a/msvc/dependencies/zycore/Zycore.vcxproj
+++ b/msvc/dependencies/zycore/Zycore.vcxproj
@@ -423,6 +423,7 @@
Disabled
true
true
+ 4201;4748;%(DisableSpecificWarnings)
Native
@@ -550,6 +551,7 @@
true
true
MaxSpeed
+ 4201;4603;4627;4986;4987;%(DisableSpecificWarnings)
Native
@@ -676,6 +678,7 @@
Disabled
true
true
+ 4201;4748;%(DisableSpecificWarnings)
Native
@@ -804,6 +807,7 @@
true
true
MaxSpeed
+ 4201;4603;4627;4986;4987;%(DisableSpecificWarnings)
Native
diff --git a/msvc/examples/ZydisWinKernel.vcxproj b/msvc/examples/ZydisWinKernel.vcxproj
index f5ae1908..20669b87 100644
--- a/msvc/examples/ZydisWinKernel.vcxproj
+++ b/msvc/examples/ZydisWinKernel.vcxproj
@@ -130,6 +130,7 @@
true
false
false
+ 4201;4748;%(DisableSpecificWarnings)
/NOVCFEATURE /NOCOFFGRPINFO %(AdditionalOptions)
@@ -156,6 +157,7 @@
true
false
MaxSpeed
+ 4201;4603;4627;4986;4987;%(DisableSpecificWarnings)
UseLinkTimeCodeGeneration
@@ -180,6 +182,7 @@
true
false
false
+ 4201;4748;%(DisableSpecificWarnings)
/NOVCFEATURE /NOCOFFGRPINFO %(AdditionalOptions)
@@ -206,6 +209,7 @@
true
false
MaxSpeed
+ 4201;4603;4627;4986;4987;%(DisableSpecificWarnings)
UseLinkTimeCodeGeneration
diff --git a/msvc/zydis/Zydis.vcxproj b/msvc/zydis/Zydis.vcxproj
index c3460895..06929d76 100644
--- a/msvc/zydis/Zydis.vcxproj
+++ b/msvc/zydis/Zydis.vcxproj
@@ -424,6 +424,7 @@
Disabled
true
true
+ 4201;4748;%(DisableSpecificWarnings)
Native
@@ -551,6 +552,7 @@
true
true
MaxSpeed
+ 4201;4603;4627;4986;4987;%(DisableSpecificWarnings)
Native
@@ -677,6 +679,7 @@
Disabled
true
true
+ 4201;4748;%(DisableSpecificWarnings)
Native
@@ -802,6 +805,7 @@
true
true
MaxSpeed
+ 4201;4603;4627;4986;4987;%(DisableSpecificWarnings)
Native
@@ -938,4 +942,4 @@
-
+
\ No newline at end of file
diff --git a/tools/ZydisFuzzShared.c b/tools/ZydisFuzzShared.c
index bcbb5c45..8a86b50a 100644
--- a/tools/ZydisFuzzShared.c
+++ b/tools/ZydisFuzzShared.c
@@ -153,14 +153,26 @@ void ZydisValidateEnumRanges(const ZydisDecodedInstruction* insn,
ZYDIS_CHECK_ENUM(op->visibility, ZYDIS_OPERAND_VISIBILITY_MAX_VALUE);
ZYDIS_CHECK_ENUM(op->encoding, ZYDIS_OPERAND_ENCODING_MAX_VALUE);
ZYDIS_CHECK_ENUM(op->element_type, ZYDIS_ELEMENT_TYPE_MAX_VALUE);
- ZYDIS_CHECK_ENUM(op->reg.value, ZYDIS_REGISTER_MAX_VALUE);
- ZYDIS_CHECK_ENUM(op->mem.type, ZYDIS_MEMOP_TYPE_MAX_VALUE);
- ZYDIS_CHECK_ENUM(op->mem.segment, ZYDIS_REGISTER_MAX_VALUE);
- ZYDIS_CHECK_ENUM(op->mem.base, ZYDIS_REGISTER_MAX_VALUE);
- ZYDIS_CHECK_ENUM(op->mem.index, ZYDIS_REGISTER_MAX_VALUE);
- ZYDIS_CHECK_ENUM(op->mem.disp.has_displacement, ZYAN_TRUE);
- ZYDIS_CHECK_ENUM(op->imm.is_signed, ZYAN_TRUE);
- ZYDIS_CHECK_ENUM(op->imm.is_relative, ZYAN_TRUE);
+
+ switch (op->type)
+ {
+ case ZYDIS_OPERAND_TYPE_REGISTER:
+ ZYDIS_CHECK_ENUM(op->reg.value, ZYDIS_REGISTER_MAX_VALUE);
+ break;
+ case ZYDIS_OPERAND_TYPE_MEMORY:
+ ZYDIS_CHECK_ENUM(op->mem.type, ZYDIS_MEMOP_TYPE_MAX_VALUE);
+ ZYDIS_CHECK_ENUM(op->mem.segment, ZYDIS_REGISTER_MAX_VALUE);
+ ZYDIS_CHECK_ENUM(op->mem.base, ZYDIS_REGISTER_MAX_VALUE);
+ ZYDIS_CHECK_ENUM(op->mem.index, ZYDIS_REGISTER_MAX_VALUE);
+ ZYDIS_CHECK_ENUM(op->mem.disp.has_displacement, ZYAN_TRUE);
+ break;
+ case ZYDIS_OPERAND_TYPE_IMMEDIATE:
+ ZYDIS_CHECK_ENUM(op->imm.is_signed, ZYAN_TRUE);
+ ZYDIS_CHECK_ENUM(op->imm.is_relative, ZYAN_TRUE);
+ break;
+ default:
+ break;
+ }
}
// AVX.