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/Support/SwapByteOrder.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
39 };
40
41 Opcode() = default;
42
43 Opcode(uint8_t inst, lldb::ByteOrder order)
44 : m_byte_order(order), m_type(eType8) {
45 m_data.inst8 = inst;
46 }
47
48 Opcode(uint16_t inst, lldb::ByteOrder order)
49 : m_byte_order(order), m_type(eType16) {
50 m_data.inst16 = inst;
51 }
52
53 Opcode(uint32_t inst, lldb::ByteOrder order)
54 : m_byte_order(order), m_type(eType32) {
55 m_data.inst32 = inst;
56 }
57
58 Opcode(uint64_t inst, lldb::ByteOrder order)
59 : m_byte_order(order), m_type(eType64) {
60 m_data.inst64 = inst;
61 }
62
63 Opcode(uint8_t *bytes, size_t length)
64 : m_byte_order(lldb::eByteOrderInvalid) {
66 }
67
68 void Clear() {
71 }
72
73 Opcode::Type GetType() const { return m_type; }
74
75 uint8_t GetOpcode8(uint8_t invalid_opcode = UINT8_MAX) const {
76 switch (m_type) {
78 break;
79 case Opcode::eType8:
80 return m_data.inst8;
81 case Opcode::eType16:
82 break;
84 break;
85 case Opcode::eType32:
86 break;
87 case Opcode::eType64:
88 break;
90 break;
91 }
92 return invalid_opcode;
93 }
94
95 uint16_t GetOpcode16(uint16_t invalid_opcode = UINT16_MAX) const {
96 switch (m_type) {
98 break;
99 case Opcode::eType8:
100 return m_data.inst8;
101 case Opcode::eType16:
102 return GetEndianSwap() ? llvm::byteswap<uint16_t>(m_data.inst16)
103 : m_data.inst16;
105 break;
106 case Opcode::eType32:
107 break;
108 case Opcode::eType64:
109 break;
111 break;
112 }
113 return invalid_opcode;
114 }
115
116 uint32_t GetOpcode32(uint32_t invalid_opcode = UINT32_MAX) const {
117 switch (m_type) {
119 break;
120 case Opcode::eType8:
121 return m_data.inst8;
122 case Opcode::eType16:
123 return GetEndianSwap() ? llvm::byteswap<uint16_t>(m_data.inst16)
124 : m_data.inst16;
125 case Opcode::eType16_2: // passthrough
126 case Opcode::eType32:
127 return GetEndianSwap() ? llvm::byteswap<uint32_t>(m_data.inst32)
128 : m_data.inst32;
129 case Opcode::eType64:
130 break;
132 break;
133 }
134 return invalid_opcode;
135 }
136
137 uint64_t GetOpcode64(uint64_t invalid_opcode = UINT64_MAX) const {
138 switch (m_type) {
140 break;
141 case Opcode::eType8:
142 return m_data.inst8;
143 case Opcode::eType16:
144 return GetEndianSwap() ? llvm::byteswap<uint16_t>(m_data.inst16)
145 : m_data.inst16;
146 case Opcode::eType16_2: // passthrough
147 case Opcode::eType32:
148 return GetEndianSwap() ? llvm::byteswap<uint32_t>(m_data.inst32)
149 : m_data.inst32;
150 case Opcode::eType64:
151 return GetEndianSwap() ? llvm::byteswap<uint64_t>(m_data.inst64)
152 : m_data.inst64;
154 break;
155 }
156 return invalid_opcode;
157 }
158
159 void SetOpcode8(uint8_t inst, lldb::ByteOrder order) {
160 m_type = eType8;
161 m_data.inst8 = inst;
162 m_byte_order = order;
163 }
164
165 void SetOpcode16(uint16_t inst, lldb::ByteOrder order) {
166 m_type = eType16;
167 m_data.inst16 = inst;
168 m_byte_order = order;
169 }
170
171 void SetOpcode16_2(uint32_t inst, lldb::ByteOrder order) {
173 m_data.inst32 = inst;
174 m_byte_order = order;
175 }
176
177 void SetOpcode32(uint32_t inst, lldb::ByteOrder order) {
178 m_type = eType32;
179 m_data.inst32 = inst;
180 m_byte_order = order;
181 }
182
183 void SetOpcode64(uint64_t inst, lldb::ByteOrder order) {
184 m_type = eType64;
185 m_data.inst64 = inst;
186 m_byte_order = order;
187 }
188
189 void SetOpcodeBytes(const void *bytes, size_t length) {
190 if (bytes != nullptr && length > 0) {
192 m_data.inst.length = length;
193 assert(length < sizeof(m_data.inst.bytes));
194 memcpy(m_data.inst.bytes, bytes, length);
196 } else {
198 m_data.inst.length = 0;
199 }
200 }
201
202 int Dump(Stream *s, uint32_t min_byte_width);
203
204 const void *GetOpcodeBytes() const {
205 return ((m_type == Opcode::eTypeBytes) ? m_data.inst.bytes : nullptr);
206 }
207
208 uint32_t GetByteSize() const {
209 switch (m_type) {
211 break;
212 case Opcode::eType8:
213 return sizeof(m_data.inst8);
214 case Opcode::eType16:
215 return sizeof(m_data.inst16);
216 case Opcode::eType16_2: // passthrough
217 case Opcode::eType32:
218 return sizeof(m_data.inst32);
219 case Opcode::eType64:
220 return sizeof(m_data.inst64);
222 return m_data.inst.length;
223 }
224 return 0;
225 }
226
227 // Get the opcode exactly as it would be laid out in memory.
228 uint32_t GetData(DataExtractor &data) const;
229
230protected:
232
233 const void *GetOpcodeDataBytes() const {
234 switch (m_type) {
236 break;
237 case Opcode::eType8:
238 return &m_data.inst8;
239 case Opcode::eType16:
240 return &m_data.inst16;
241 case Opcode::eType16_2: // passthrough
242 case Opcode::eType32:
243 return &m_data.inst32;
244 case Opcode::eType64:
245 return &m_data.inst64;
247 return m_data.inst.bytes;
248 }
249 return nullptr;
250 }
251
253
254 bool GetEndianSwap() const {
259 }
260
262
264 union {
265 uint8_t inst8;
266 uint16_t inst16;
267 uint32_t inst32;
268 uint64_t inst64;
269 struct {
270 uint8_t bytes[16]; // This must be big enough to handle any opcode for any
271 // supported target.
272 uint8_t length;
273 } inst;
275};
276
277} // namespace lldb_private
278
279#endif // LLDB_CORE_OPCODE_H
An data extractor class.
Definition: DataExtractor.h:48
void SetOpcode16(uint16_t inst, lldb::ByteOrder order)
Definition: Opcode.h:165
void SetOpcodeBytes(const void *bytes, size_t length)
Definition: Opcode.h:189
int Dump(Stream *s, uint32_t min_byte_width)
Definition: Opcode.cpp:24
Opcode(uint16_t inst, lldb::ByteOrder order)
Definition: Opcode.h:48
uint8_t GetOpcode8(uint8_t invalid_opcode=UINT8_MAX) const
Definition: Opcode.h:75
void SetOpcode16_2(uint32_t inst, lldb::ByteOrder order)
Definition: Opcode.h:171
Opcode(uint8_t inst, lldb::ByteOrder order)
Definition: Opcode.h:43
struct lldb_private::Opcode::@6::@7 inst
uint32_t inst32
Definition: Opcode.h:267
uint32_t GetByteSize() const
Definition: Opcode.h:208
union lldb_private::Opcode::@6 m_data
bool GetEndianSwap() const
Definition: Opcode.h:254
uint64_t inst64
Definition: Opcode.h:268
uint8_t bytes[16]
Definition: Opcode.h:270
void SetOpcode64(uint64_t inst, lldb::ByteOrder order)
Definition: Opcode.h:183
lldb::ByteOrder m_byte_order
Definition: Opcode.h:261
Opcode::Type m_type
Definition: Opcode.h:263
Opcode(uint8_t *bytes, size_t length)
Definition: Opcode.h:63
const void * GetOpcodeDataBytes() const
Definition: Opcode.h:233
Opcode::Type GetType() const
Definition: Opcode.h:73
const void * GetOpcodeBytes() const
Definition: Opcode.h:204
Opcode(uint32_t inst, lldb::ByteOrder order)
Definition: Opcode.h:53
Opcode(uint64_t inst, lldb::ByteOrder order)
Definition: Opcode.h:58
lldb::ByteOrder GetDataByteOrder() const
Definition: Opcode.cpp:62
void SetOpcode8(uint8_t inst, lldb::ByteOrder order)
Definition: Opcode.h:159
uint32_t GetData(DataExtractor &data) const
Definition: Opcode.cpp:81
uint32_t GetOpcode32(uint32_t invalid_opcode=UINT32_MAX) const
Definition: Opcode.h:116
uint16_t inst16
Definition: Opcode.h:266
uint16_t GetOpcode16(uint16_t invalid_opcode=UINT16_MAX) const
Definition: Opcode.h:95
void SetOpcode32(uint32_t inst, lldb::ByteOrder order)
Definition: Opcode.h:177
uint64_t GetOpcode64(uint64_t invalid_opcode=UINT64_MAX) const
Definition: Opcode.h:137
A stream class that can stream formatted output to a file.
Definition: Stream.h:28
#define UINT64_MAX
Definition: lldb-defines.h:23
#define UINT32_MAX
Definition: lldb-defines.h:19
lldb::ByteOrder InlHostByteOrder()
Definition: Endian.h:25
A class that represents a running process on the host machine.
Definition: SBAddress.h:15
ByteOrder
Byte ordering definitions.
@ eByteOrderInvalid
@ eByteOrderLittle
class LLDB_API SBInstruction
Definition: SBDefines.h:81