LLDB mainline
Opcode.h
Go to the documentation of this file.
1//===-- Opcode.h ------------------------------------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef LLDB_CORE_OPCODE_H
10#define LLDB_CORE_OPCODE_H
11
12#include "lldb/Utility/Endian.h"
14
15#include "llvm/ADT/bit.h"
16
17#include <cassert>
18#include <cstdint>
19#include <cstring>
20
21namespace lldb {
22class SBInstruction;
23}
24
25namespace lldb_private {
26class DataExtractor;
27class Stream;
28
29class Opcode {
30public:
31 enum Type {
35 eType16_2, // a 32-bit Thumb instruction, made up of two words
36 eType16_32Tuples, // RISC-V that can have 2, 4, 6, 8 etc byte long
37 // instructions which will be printed in combinations of
38 // 16 & 32-bit words.
42 };
43
44 Opcode() = default;
45
46 Opcode(uint8_t inst, lldb::ByteOrder order)
47 : m_byte_order(order), m_type(eType8) {
48 m_data.inst8 = inst;
49 }
50
51 Opcode(uint16_t inst, lldb::ByteOrder order)
52 : m_byte_order(order), m_type(eType16) {
53 m_data.inst16 = inst;
54 }
55
56 Opcode(uint32_t inst, lldb::ByteOrder order)
57 : m_byte_order(order), m_type(eType32) {
58 m_data.inst32 = inst;
59 }
60
61 Opcode(uint64_t inst, lldb::ByteOrder order)
62 : m_byte_order(order), m_type(eType64) {
63 m_data.inst64 = inst;
64 }
65
66 Opcode(uint8_t *bytes, size_t length, Opcode::Type type,
67 lldb::ByteOrder order) {
68 DoSetOpcodeBytes(bytes, length, type, order);
69 }
70
75
76 Opcode::Type GetType() const { return m_type; }
77
78 uint8_t GetOpcode8(uint8_t invalid_opcode = UINT8_MAX) const {
79 switch (m_type) {
81 break;
82 case Opcode::eType8:
83 return m_data.inst8;
84 case Opcode::eType16:
85 break;
87 break;
89 break;
90 case Opcode::eType32:
91 break;
92 case Opcode::eType64:
93 break;
95 break;
96 }
97 return invalid_opcode;
98 }
99
100 uint16_t GetOpcode16(uint16_t invalid_opcode = UINT16_MAX) const {
101 switch (m_type) {
103 break;
104 case Opcode::eType8:
105 return m_data.inst8;
106 case Opcode::eType16:
107 return GetEndianSwap() ? llvm::byteswap<uint16_t>(m_data.inst16)
108 : m_data.inst16;
110 break;
112 break;
113 case Opcode::eType32:
114 break;
115 case Opcode::eType64:
116 break;
118 break;
119 }
120 return invalid_opcode;
121 }
122
123 uint32_t GetOpcode32(uint32_t invalid_opcode = UINT32_MAX) const {
124 switch (m_type) {
126 break;
127 case Opcode::eType8:
128 return m_data.inst8;
129 case Opcode::eType16:
130 return GetEndianSwap() ? llvm::byteswap<uint16_t>(m_data.inst16)
131 : m_data.inst16;
133 break;
134 case Opcode::eType16_2: // passthrough
135 case Opcode::eType32:
136 return GetEndianSwap() ? llvm::byteswap<uint32_t>(m_data.inst32)
137 : m_data.inst32;
138 case Opcode::eType64:
139 break;
141 break;
142 }
143 return invalid_opcode;
144 }
145
146 uint64_t GetOpcode64(uint64_t invalid_opcode = UINT64_MAX) const {
147 switch (m_type) {
149 break;
150 case Opcode::eType8:
151 return m_data.inst8;
152 case Opcode::eType16:
153 return GetEndianSwap() ? llvm::byteswap<uint16_t>(m_data.inst16)
154 : m_data.inst16;
156 break;
157 case Opcode::eType16_2: // passthrough
158 case Opcode::eType32:
159 return GetEndianSwap() ? llvm::byteswap<uint32_t>(m_data.inst32)
160 : m_data.inst32;
161 case Opcode::eType64:
162 return GetEndianSwap() ? llvm::byteswap<uint64_t>(m_data.inst64)
163 : m_data.inst64;
165 break;
166 }
167 return invalid_opcode;
168 }
169
170 void SetOpcode8(uint8_t inst, lldb::ByteOrder order) {
171 m_type = eType8;
172 m_data.inst8 = inst;
173 m_byte_order = order;
174 }
175
176 void SetOpcode16(uint16_t inst, lldb::ByteOrder order) {
177 m_type = eType16;
178 m_data.inst16 = inst;
179 m_byte_order = order;
180 }
181
182 void SetOpcode16_2(uint32_t inst, lldb::ByteOrder order) {
184 m_data.inst32 = inst;
185 m_byte_order = order;
186 }
187
188 void SetOpcode32(uint32_t inst, lldb::ByteOrder order) {
189 m_type = eType32;
190 m_data.inst32 = inst;
191 m_byte_order = order;
192 }
193
194 void SetOpcode64(uint64_t inst, lldb::ByteOrder order) {
195 m_type = eType64;
196 m_data.inst64 = inst;
197 m_byte_order = order;
198 }
199
200 void SetOpcode16_32TupleBytes(const void *bytes, size_t length,
201 lldb::ByteOrder order) {
203 }
204
208
209 void DoSetOpcodeBytes(const void *bytes, size_t length, Opcode::Type type,
210 lldb::ByteOrder order) {
211 if (bytes != nullptr && length > 0) {
212 m_type = type;
213 m_data.inst.length = length;
214 assert(length <= sizeof(m_data.inst.bytes));
215 memcpy(m_data.inst.bytes, bytes, length);
216 m_byte_order = order;
217 } else {
219 m_data.inst.length = 0;
220 }
221 }
222
223 int Dump(Stream *s, uint32_t min_byte_width) const;
224
225 const void *GetOpcodeBytes() const {
226 return ((m_type == Opcode::eTypeBytes) ? m_data.inst.bytes : nullptr);
227 }
228
229 uint32_t GetByteSize() const {
230 switch (m_type) {
232 break;
233 case Opcode::eType8:
234 return sizeof(m_data.inst8);
235 case Opcode::eType16:
236 return sizeof(m_data.inst16);
238 return m_data.inst.length;
239 case Opcode::eType16_2: // passthrough
240 case Opcode::eType32:
241 return sizeof(m_data.inst32);
242 case Opcode::eType64:
243 return sizeof(m_data.inst64);
245 return m_data.inst.length;
246 }
247 return 0;
248 }
249
250 // Get the opcode exactly as it would be laid out in memory.
251 uint32_t GetData(DataExtractor &data) const;
252
253protected:
255
256 const void *GetOpcodeDataBytes() const {
257 switch (m_type) {
259 break;
260 case Opcode::eType8:
261 return &m_data.inst8;
262 case Opcode::eType16:
263 return &m_data.inst16;
265 return m_data.inst.bytes;
266 case Opcode::eType16_2: // passthrough
267 case Opcode::eType32:
268 return &m_data.inst32;
269 case Opcode::eType64:
270 return &m_data.inst64;
272 return m_data.inst.bytes;
273 }
274 return nullptr;
275 }
276
278
285
287
289 union {
290 uint8_t inst8;
291 uint16_t inst16;
292 uint32_t inst32;
293 uint64_t inst64;
294 struct {
295 uint8_t bytes[16]; // This must be big enough to handle any opcode for any
296 // supported target.
297 uint8_t length;
298 } inst;
300};
301
302} // namespace lldb_private
303
304#endif // LLDB_CORE_OPCODE_H
An data extractor class.
void SetOpcode16(uint16_t inst, lldb::ByteOrder order)
Definition Opcode.h:176
void SetOpcodeBytes(const void *bytes, size_t length)
Definition Opcode.h:205
struct lldb_private::Opcode::@156232132041300233024301123342201147024264135026::@172330167001202032221076241015252223234141124150 inst
Opcode(uint16_t inst, lldb::ByteOrder order)
Definition Opcode.h:51
void DoSetOpcodeBytes(const void *bytes, size_t length, Opcode::Type type, lldb::ByteOrder order)
Definition Opcode.h:209
uint8_t GetOpcode8(uint8_t invalid_opcode=UINT8_MAX) const
Definition Opcode.h:78
void SetOpcode16_2(uint32_t inst, lldb::ByteOrder order)
Definition Opcode.h:182
Opcode(uint8_t inst, lldb::ByteOrder order)
Definition Opcode.h:46
uint32_t GetByteSize() const
Definition Opcode.h:229
bool GetEndianSwap() const
Definition Opcode.h:279
uint8_t bytes[16]
Definition Opcode.h:295
void SetOpcode64(uint64_t inst, lldb::ByteOrder order)
Definition Opcode.h:194
lldb::ByteOrder m_byte_order
Definition Opcode.h:286
Opcode::Type m_type
Definition Opcode.h:288
const void * GetOpcodeDataBytes() const
Definition Opcode.h:256
union lldb_private::Opcode::@156232132041300233024301123342201147024264135026 m_data
Opcode::Type GetType() const
Definition Opcode.h:76
int Dump(Stream *s, uint32_t min_byte_width) const
Definition Opcode.cpp:24
const void * GetOpcodeBytes() const
Definition Opcode.h:225
Opcode(uint32_t inst, lldb::ByteOrder order)
Definition Opcode.h:56
Opcode(uint64_t inst, lldb::ByteOrder order)
Definition Opcode.h:61
lldb::ByteOrder GetDataByteOrder() const
Definition Opcode.cpp:83
void SetOpcode8(uint8_t inst, lldb::ByteOrder order)
Definition Opcode.h:170
void SetOpcode16_32TupleBytes(const void *bytes, size_t length, lldb::ByteOrder order)
Definition Opcode.h:200
uint32_t GetData(DataExtractor &data) const
Definition Opcode.cpp:103
uint32_t GetOpcode32(uint32_t invalid_opcode=UINT32_MAX) const
Definition Opcode.h:123
uint16_t GetOpcode16(uint16_t invalid_opcode=UINT16_MAX) const
Definition Opcode.h:100
void SetOpcode32(uint32_t inst, lldb::ByteOrder order)
Definition Opcode.h:188
uint64_t GetOpcode64(uint64_t invalid_opcode=UINT64_MAX) const
Definition Opcode.h:146
Opcode(uint8_t *bytes, size_t length, Opcode::Type type, lldb::ByteOrder order)
Definition Opcode.h:66
A stream class that can stream formatted output to a file.
Definition Stream.h:28
#define UINT64_MAX
#define UINT32_MAX
lldb::ByteOrder InlHostByteOrder()
Definition Endian.h:25
A class that represents a running process on the host machine.
ByteOrder
Byte ordering definitions.