250 lines
8 KiB
C
250 lines
8 KiB
C
|
/***************************************************************************************************
|
||
|
|
||
|
Zyan Disassembler Library (Zydis)
|
||
|
|
||
|
Original Author : Mappa
|
||
|
|
||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||
|
* of this software and associated documentation files (the "Software"), to deal
|
||
|
* in the Software without restriction, including without limitation the rights
|
||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||
|
* copies of the Software, and to permit persons to whom the Software is
|
||
|
* furnished to do so, subject to the following conditions:
|
||
|
*
|
||
|
* The above copyright notice and this permission notice shall be included in all
|
||
|
* copies or substantial portions of the Software.
|
||
|
*
|
||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||
|
* SOFTWARE.
|
||
|
|
||
|
***************************************************************************************************/
|
||
|
|
||
|
#ifndef ZYDIS_INTERNAL_ENCODERDATA_H
|
||
|
#define ZYDIS_INTERNAL_ENCODERDATA_H
|
||
|
|
||
|
#include <Zycore/Defines.h>
|
||
|
#include <Zydis/Mnemonic.h>
|
||
|
#include <Zydis/SharedTypes.h>
|
||
|
|
||
|
/**
|
||
|
* Used in encoder's table to represent standard ISA sizes in form of bit flags.
|
||
|
*/
|
||
|
typedef enum ZydisWidthFlag_
|
||
|
{
|
||
|
ZYDIS_WIDTH_INVALID = 0x00,
|
||
|
ZYDIS_WIDTH_16 = 0x01,
|
||
|
ZYDIS_WIDTH_32 = 0x02,
|
||
|
ZYDIS_WIDTH_64 = 0x04,
|
||
|
|
||
|
/**
|
||
|
* Maximum value of this enum.
|
||
|
*/
|
||
|
ZYDIS_WIDTH_MAX_VALUE = (ZYDIS_WIDTH_64 | (ZYDIS_WIDTH_64 - 1)),
|
||
|
/**
|
||
|
* The minimum number of bits required to represent all values of this enum.
|
||
|
*/
|
||
|
ZYDIS_WIDTH_REQUIRED_BITS = ZYAN_BITS_TO_REPRESENT(ZYDIS_WIDTH_MAX_VALUE)
|
||
|
} ZydisWidthFlag;
|
||
|
|
||
|
/**
|
||
|
* Used in encoder's table to represent mandatory instruction prefix. Using this enum instead of
|
||
|
* actual prefix value saves space.
|
||
|
*/
|
||
|
typedef enum ZydisMandatoryPrefix_
|
||
|
{
|
||
|
ZYDIS_MANDATORY_PREFIX_NONE,
|
||
|
ZYDIS_MANDATORY_PREFIX_66,
|
||
|
ZYDIS_MANDATORY_PREFIX_F2,
|
||
|
ZYDIS_MANDATORY_PREFIX_F3,
|
||
|
|
||
|
/**
|
||
|
* Maximum value of this enum.
|
||
|
*/
|
||
|
ZYDIS_MANDATORY_PREFIX_MAX_VALUE = ZYDIS_MANDATORY_PREFIX_F3,
|
||
|
/**
|
||
|
* The minimum number of bits required to represent all values of this enum.
|
||
|
*/
|
||
|
ZYDIS_MANDATORY_PREFIX_REQUIRED_BITS = ZYAN_BITS_TO_REPRESENT(ZYDIS_MANDATORY_PREFIX_MAX_VALUE)
|
||
|
} ZydisMandatoryPrefix;
|
||
|
|
||
|
/**
|
||
|
* Used in encoder's table to represent vector size supported by instruction definition.
|
||
|
*/
|
||
|
typedef enum ZydisVectorLength_
|
||
|
{
|
||
|
ZYDIS_VECTOR_LENGTH_INVALID,
|
||
|
ZYDIS_VECTOR_LENGTH_128,
|
||
|
ZYDIS_VECTOR_LENGTH_256,
|
||
|
ZYDIS_VECTOR_LENGTH_512,
|
||
|
|
||
|
/**
|
||
|
* Maximum value of this enum.
|
||
|
*/
|
||
|
ZYDIS_VECTOR_LENGTH_MAX_VALUE = ZYDIS_VECTOR_LENGTH_512,
|
||
|
/**
|
||
|
* The minimum number of bits required to represent all values of this enum.
|
||
|
*/
|
||
|
ZYDIS_VECTOR_LENGTH_REQUIRED_BITS = ZYAN_BITS_TO_REPRESENT(ZYDIS_VECTOR_LENGTH_MAX_VALUE)
|
||
|
} ZydisVectorLength;
|
||
|
|
||
|
/**
|
||
|
* Used in encoder's table to represent hint type supported by instruction definition.
|
||
|
*/
|
||
|
typedef enum ZydisSizeHint_
|
||
|
{
|
||
|
ZYDIS_SIZE_HINT_NONE,
|
||
|
ZYDIS_SIZE_HINT_ASZ,
|
||
|
ZYDIS_SIZE_HINT_OSZ,
|
||
|
|
||
|
/**
|
||
|
* Maximum value of this enum.
|
||
|
*/
|
||
|
ZYDIS_SIZE_HINT_MAX_VALUE = ZYDIS_SIZE_HINT_OSZ,
|
||
|
/**
|
||
|
* The minimum number of bits required to represent all values of this enum.
|
||
|
*/
|
||
|
ZYDIS_SIZE_HINT_REQUIRED_BITS = ZYAN_BITS_TO_REPRESENT(ZYDIS_SIZE_HINT_MAX_VALUE)
|
||
|
} ZydisSizeHint;
|
||
|
|
||
|
/**
|
||
|
* Used in encoder's primary lookup table which allows to access a set of instruction definitions
|
||
|
* for specified mnemonic in constant time.
|
||
|
*/
|
||
|
typedef struct ZydisEncoderLookupEntry_
|
||
|
{
|
||
|
/**
|
||
|
* Index to main array of `ZydisEncodableInstruction`.
|
||
|
*/
|
||
|
ZyanU16 encoder_reference;
|
||
|
/**
|
||
|
* The number of entries.
|
||
|
*/
|
||
|
ZyanU8 instruction_count;
|
||
|
} ZydisEncoderLookupEntry;
|
||
|
|
||
|
#pragma pack(push, 1)
|
||
|
|
||
|
/**
|
||
|
* This structure is encoder's internal representation of encodable instruction definition.
|
||
|
*/
|
||
|
typedef struct ZydisEncodableInstruction_
|
||
|
{
|
||
|
/**
|
||
|
* Index to one of decoder's instruction definition arrays.
|
||
|
*/
|
||
|
ZyanU16 instruction_reference;
|
||
|
/**
|
||
|
* Compressed information about operand count and types. Operand count is stored in lowest bits.
|
||
|
* Types of subsequent operands are stored in higher bits.
|
||
|
*/
|
||
|
ZyanU16 operand_mask;
|
||
|
/**
|
||
|
* The instruction-opcode.
|
||
|
*/
|
||
|
ZyanU8 opcode;
|
||
|
/**
|
||
|
* The mandatory ModR/M value.
|
||
|
*/
|
||
|
ZyanU8 modrm;
|
||
|
/**
|
||
|
* The instruction-encoding.
|
||
|
*/
|
||
|
ZyanU8 encoding ZYAN_BITFIELD(ZYDIS_INSTRUCTION_ENCODING_REQUIRED_BITS);
|
||
|
/**
|
||
|
* The opcode map.
|
||
|
*/
|
||
|
ZyanU8 opcode_map ZYAN_BITFIELD(ZYDIS_OPCODE_MAP_REQUIRED_BITS);
|
||
|
/**
|
||
|
* The combination of allowed processor modes.
|
||
|
*/
|
||
|
ZyanU8 modes ZYAN_BITFIELD(ZYDIS_WIDTH_REQUIRED_BITS);
|
||
|
/**
|
||
|
* The combination of allowed address sizes.
|
||
|
*/
|
||
|
ZyanU8 address_sizes ZYAN_BITFIELD(ZYDIS_WIDTH_REQUIRED_BITS);
|
||
|
/**
|
||
|
* The combination of allowed operand sizes.
|
||
|
*/
|
||
|
ZyanU8 operand_sizes ZYAN_BITFIELD(ZYDIS_WIDTH_REQUIRED_BITS);
|
||
|
/**
|
||
|
* The mandatory prefix.
|
||
|
*/
|
||
|
ZyanU8 mandatory_prefix ZYAN_BITFIELD(ZYDIS_MANDATORY_PREFIX_REQUIRED_BITS);
|
||
|
/**
|
||
|
* True if `REX.W` is required for this definition.
|
||
|
*/
|
||
|
ZyanU8 rex_w ZYAN_BITFIELD(1);
|
||
|
/**
|
||
|
* The vector length.
|
||
|
*/
|
||
|
ZyanU8 vector_length ZYAN_BITFIELD(ZYDIS_MANDATORY_PREFIX_REQUIRED_BITS);
|
||
|
/**
|
||
|
* The accepted sizing hint.
|
||
|
*/
|
||
|
ZyanU8 accepts_hint ZYAN_BITFIELD(ZYDIS_SIZE_HINT_REQUIRED_BITS);
|
||
|
/**
|
||
|
* Indicates that next instruction definition can be safely used instead of current one. This
|
||
|
* is used with some `VEX` instructions to take advantage of 2-byte `VEX` prefix when possible.
|
||
|
* 2-byte `VEX` allows to use high registers only when operand is encoded in `modrm_reg`
|
||
|
* (high bit in `REX.R`). Encoder uses swappable definitions to take advantage of this
|
||
|
* optimization opportunity.
|
||
|
*
|
||
|
* Second use of this field is to handle special case for `mov` instruction. This particular
|
||
|
* conflict is described in detail inside `ZydisHandleSwappableDefinition`.
|
||
|
*/
|
||
|
ZyanU8 swappable ZYAN_BITFIELD(1);
|
||
|
} ZydisEncodableInstruction;
|
||
|
|
||
|
#pragma pack(pop)
|
||
|
|
||
|
/**
|
||
|
* Contains information used by instruction size prediction algorithm inside
|
||
|
* `ZydisEncoderEncodeInstructionAbsolute`.
|
||
|
*/
|
||
|
typedef struct ZydisEncoderRelInfo_
|
||
|
{
|
||
|
/**
|
||
|
* Sizes of instruction variants. First index is effective address size. Second index is
|
||
|
* desired immediate size (8, 16 and 32 bits respectively).
|
||
|
*/
|
||
|
ZyanU8 size[3][3];
|
||
|
/**
|
||
|
* See `ZydisSizeHint`.
|
||
|
*/
|
||
|
ZyanU8 accepts_scaling_hints;
|
||
|
/**
|
||
|
* True if instruction accepts branch hint prefixes.
|
||
|
*/
|
||
|
ZyanBool accepts_branch_hints;
|
||
|
} ZydisEncoderRelInfo;
|
||
|
|
||
|
/**
|
||
|
* Fetches array of `ZydisEncodableInstruction` structures and its size for given instruction
|
||
|
* mnemonic.
|
||
|
*
|
||
|
* @param mnemonic Instruction mnemonic.
|
||
|
* @param instruction This variable will receive a pointer to the array of
|
||
|
* `ZydisEncodableInstruction` structures.
|
||
|
*
|
||
|
* @return Entry count (0 if function failed).
|
||
|
*/
|
||
|
ZyanU8 ZydisGetEncodableInstructions(ZydisMnemonic mnemonic,
|
||
|
const ZydisEncodableInstruction **instruction);
|
||
|
|
||
|
/**
|
||
|
* Fetches `ZydisEncoderRelInfo` record for given instruction mnemonic.
|
||
|
*
|
||
|
* @param mnemonic Instruction mnemonic.
|
||
|
*
|
||
|
* @return Pointer to `ZydisEncoderRelInfo` structure or `ZYAN_NULL` if instruction doesn't have
|
||
|
* relative operands.
|
||
|
*/
|
||
|
const ZydisEncoderRelInfo *ZydisGetRelInfo(ZydisMnemonic mnemonic);
|
||
|
|
||
|
#endif /* ZYDIS_INTERNAL_ENCODERDATA_H */
|