-
Notifications
You must be signed in to change notification settings - Fork 15
/
Copy pathopcode_gen.h
161 lines (136 loc) · 4.06 KB
/
opcode_gen.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
#pragma once
// (c) Robert Muth - see LICENSE for more info
// NOTE: this file is PARTIALLY autogenerated via: ./opcode_tab.py gen_h
#include "BE/Elf/enum_gen.h" // for reloc types
#include <cstdint>
#include <string_view>
namespace cwerg::x64 {
constexpr const unsigned NA = 15;
using namespace cwerg;
#include "BE/CpuX64/opcode_gen_enum.h"
/* @AUTOGEN-START@ */
constexpr const unsigned MAX_OPERAND_COUNT = 6;
constexpr const unsigned MAX_INSTRUCTION_LENGTH = 11;
constexpr const unsigned MAX_INSTRUCTION_LENGTH_WITH_PREFIXES = 15;
constexpr const unsigned MAX_INSTRUCTION_NAME_LENGTH = 27;
constexpr const unsigned MAX_FINGERPRINT = 6000;
enum class MEM_WIDTH : uint8_t {
NONE = 1,
SIB = 2,
SIB_BP_DISP = 3,
RIP_DISP = 4,
};
enum class OK : uint8_t {
RIP_BASE = 1,
MODRM_RM_BASE = 2,
OFFABS8 = 3,
OFFABS32 = 4,
SIB_SCALE = 5,
SIB_INDEX = 6,
SIB_BASE = 7,
SIB_INDEX_AS_BASE = 8,
IMM8 = 10,
IMM16 = 11,
IMM32 = 12,
OFFPCREL8 = 13,
OFFPCREL32 = 14,
IMM8_16 = 17,
IMM8_32 = 18,
IMM8_64 = 19,
IMM32_64 = 20,
IMM64 = 21,
BYTE_WITH_REG8 = 24,
BYTE_WITH_REG16 = 25,
BYTE_WITH_REG32 = 26,
BYTE_WITH_REG64 = 27,
MODRM_RM_REG8 = 28,
MODRM_RM_REG16 = 29,
MODRM_RM_REG32 = 30,
MODRM_RM_REG64 = 31,
MODRM_RM_XREG32 = 32,
MODRM_RM_XREG64 = 33,
MODRM_RM_XREG128 = 34,
MODRM_REG8 = 35,
MODRM_REG16 = 36,
MODRM_REG32 = 37,
MODRM_REG64 = 38,
MODRM_XREG32 = 39,
MODRM_XREG64 = 40,
MODRM_XREG128 = 41,
IMPLICIT_AL = 50,
IMPLICIT_AX = 51,
IMPLICIT_EAX = 52,
IMPLICIT_RAX = 53,
IMPLICIT_DX = 54,
IMPLICIT_EDX = 55,
IMPLICIT_RDX = 56,
IMPLICIT_CL = 57,
IMPLICIT_1 = 68,
};
/* @AUTOGEN-END@ */
// Describes a class of instructions structurally (read-only data).
struct Opcode {
uint8_t num_fields : 4;
uint8_t num_bytes : 4;
uint8_t mem_width_log: 3; // 8 = 1, 16 = 2, 32 = 3, 64 = 4, 128 = 5
uint8_t rexw : 1;
// NA (15) == pos not set
uint8_t modrm_pos : 4;
uint8_t sib_pos : 4;
uint8_t offset_pos : 4;
uint8_t imm_pos : 4;
uint8_t byte_with_reg_pos : 4;
OK fields[MAX_OPERAND_COUNT]; // 6
uint8_t data[MAX_INSTRUCTION_LENGTH]; // 11
uint8_t mask[MAX_INSTRUCTION_LENGTH]; // 11
};
static_assert(sizeof(Opcode) == 32);
static_assert(MAX_INSTRUCTION_NAME_LENGTH < 32); // need null byte
// Indexed by OPC
extern const Opcode OpcodeTableEncodings[]; // see
extern const char OpcodeTableNames[][32]; // see
inline const char* OpcodeName(const Opcode* opcode) {
return OpcodeTableNames[opcode - OpcodeTableEncodings];
}
inline OPC OpcodeOPC(const Opcode* opcode) {
return OPC(opcode - OpcodeTableEncodings);
}
extern const Opcode* FindOpcode(std::string_view data);
// Find the Opcode or null with the given name
extern const Opcode* FindOpcodeForMnemonic(std::string_view name);
// Decoded representation of the instruction word
struct Ins {
const Opcode* opcode;
// number of used entries is ArmOpcode.num_fields
int64_t operands[MAX_OPERAND_COUNT];
// Relocation info
std::string_view reloc_symbol;
elf::RELOC_TYPE_X86_64 reloc_kind = elf::RELOC_TYPE_X86_64::NONE;
uint8_t reloc_pos; // index into operands
bool is_local_sym = false;
bool has_reloc() const { return reloc_kind != elf::RELOC_TYPE_X86_64::NONE; }
void clear_reloc() {
if (has_reloc()) {
reloc_kind = elf::RELOC_TYPE_X86_64::NONE;
operands[reloc_pos] = 0;
}
}
void set_reloc(elf::RELOC_TYPE_X86_64 kind,
bool is_local,
uint8_t pos,
std::string_view symbol) {
reloc_kind = kind;
is_local_sym = is_local;
reloc_pos = pos;
reloc_symbol = symbol;
}
};
// Decode the instruction word `data`
// Returns true if successful
extern bool Disassemble(Ins* ins, std::string_view data);
// Encode the instruction and put it into `data`
// `data` must be at least ins.opcode.num_bytes long
extern uint32_t Assemble(const Ins& ins, char* data);
extern bool UsesRex(const Ins& ins);
extern const char* EnumToString(OK x);
} // namespace cwerg::x64