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"
13 #include "lldb/lldb-enumerations.h"
14 
15 #include "llvm/Support/SwapByteOrder.h"
16 
17 #include <cassert>
18 #include <cstdint>
19 #include <cstring>
20 
21 namespace lldb {
22 class SBInstruction;
23 }
24 
25 namespace lldb_private {
26 class DataExtractor;
27 class Stream;
28 
29 class Opcode {
30 public:
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 
49  : m_byte_order(order), m_type(eType16) {
50  m_data.inst16 = inst;
51  }
52 
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)
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;
83  case Opcode::eType16_2:
84  break;
85  case Opcode::eType32:
86  break;
87  case Opcode::eType64:
88  break;
89  case Opcode::eTypeBytes:
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_16(m_data.inst16) : m_data.inst16;
103  case Opcode::eType16_2:
104  break;
105  case Opcode::eType32:
106  break;
107  case Opcode::eType64:
108  break;
109  case Opcode::eTypeBytes:
110  break;
111  }
112  return invalid_opcode;
113  }
114 
115  uint32_t GetOpcode32(uint32_t invalid_opcode = UINT32_MAX) const {
116  switch (m_type) {
118  break;
119  case Opcode::eType8:
120  return m_data.inst8;
121  case Opcode::eType16:
122  return GetEndianSwap() ? llvm::ByteSwap_16(m_data.inst16) : m_data.inst16;
123  case Opcode::eType16_2: // passthrough
124  case Opcode::eType32:
125  return GetEndianSwap() ? llvm::ByteSwap_32(m_data.inst32) : m_data.inst32;
126  case Opcode::eType64:
127  break;
128  case Opcode::eTypeBytes:
129  break;
130  }
131  return invalid_opcode;
132  }
133 
134  uint64_t GetOpcode64(uint64_t invalid_opcode = UINT64_MAX) const {
135  switch (m_type) {
137  break;
138  case Opcode::eType8:
139  return m_data.inst8;
140  case Opcode::eType16:
141  return GetEndianSwap() ? llvm::ByteSwap_16(m_data.inst16) : m_data.inst16;
142  case Opcode::eType16_2: // passthrough
143  case Opcode::eType32:
144  return GetEndianSwap() ? llvm::ByteSwap_32(m_data.inst32) : m_data.inst32;
145  case Opcode::eType64:
146  return GetEndianSwap() ? llvm::ByteSwap_64(m_data.inst64) : m_data.inst64;
147  case Opcode::eTypeBytes:
148  break;
149  }
150  return invalid_opcode;
151  }
152 
153  void SetOpcode8(uint8_t inst, lldb::ByteOrder order) {
154  m_type = eType8;
155  m_data.inst8 = inst;
156  m_byte_order = order;
157  }
158 
160  m_type = eType16;
161  m_data.inst16 = inst;
162  m_byte_order = order;
163  }
164 
166  m_type = eType16_2;
167  m_data.inst32 = inst;
168  m_byte_order = order;
169  }
170 
172  m_type = eType32;
173  m_data.inst32 = inst;
174  m_byte_order = order;
175  }
176 
177  void SetOpcode64(uint64_t inst, lldb::ByteOrder order) {
178  m_type = eType64;
179  m_data.inst64 = inst;
180  m_byte_order = order;
181  }
182 
183  void SetOpcodeBytes(const void *bytes, size_t length) {
184  if (bytes != nullptr && length > 0) {
185  m_type = eTypeBytes;
186  m_data.inst.length = length;
187  assert(length < sizeof(m_data.inst.bytes));
188  memcpy(m_data.inst.bytes, bytes, length);
190  } else {
192  m_data.inst.length = 0;
193  }
194  }
195 
196  int Dump(Stream *s, uint32_t min_byte_width);
197 
198  const void *GetOpcodeBytes() const {
199  return ((m_type == Opcode::eTypeBytes) ? m_data.inst.bytes : nullptr);
200  }
201 
203  switch (m_type) {
205  break;
206  case Opcode::eType8:
207  return sizeof(m_data.inst8);
208  case Opcode::eType16:
209  return sizeof(m_data.inst16);
210  case Opcode::eType16_2: // passthrough
211  case Opcode::eType32:
212  return sizeof(m_data.inst32);
213  case Opcode::eType64:
214  return sizeof(m_data.inst64);
215  case Opcode::eTypeBytes:
216  return m_data.inst.length;
217  }
218  return 0;
219  }
220 
221  // Get the opcode exactly as it would be laid out in memory.
222  uint32_t GetData(DataExtractor &data) const;
223 
224 protected:
225  friend class lldb::SBInstruction;
226 
227  const void *GetOpcodeDataBytes() const {
228  switch (m_type) {
230  break;
231  case Opcode::eType8:
232  return &m_data.inst8;
233  case Opcode::eType16:
234  return &m_data.inst16;
235  case Opcode::eType16_2: // passthrough
236  case Opcode::eType32:
237  return &m_data.inst32;
238  case Opcode::eType64:
239  return &m_data.inst64;
240  case Opcode::eTypeBytes:
241  return m_data.inst.bytes;
242  }
243  return nullptr;
244  }
245 
247 
248  bool GetEndianSwap() const {
249  return (m_byte_order == lldb::eByteOrderBig &&
253  }
254 
256 
258  union {
259  uint8_t inst8;
262  uint64_t inst64;
263  struct {
264  uint8_t bytes[16]; // This must be big enough to handle any opcode for any
265  // supported target.
266  uint8_t length;
267  } inst;
268  } m_data;
269 };
270 
271 } // namespace lldb_private
272 
273 #endif // LLDB_CORE_OPCODE_H
lldb_private::Opcode::inst8
uint8_t inst8
Definition: Opcode.h:259
lldb_private::Opcode::SetOpcode16_2
void SetOpcode16_2(uint32_t inst, lldb::ByteOrder order)
Definition: Opcode.h:165
lldb_private::Opcode::eType32
@ eType32
Definition: Opcode.h:36
lldb_private::Opcode::Opcode
Opcode()=default
lldb_private::Opcode::GetEndianSwap
bool GetEndianSwap() const
Definition: Opcode.h:248
lldb_private::Opcode::inst16
uint16_t inst16
Definition: Opcode.h:260
lldb_private::Opcode
Definition: Opcode.h:29
lldb_private::Opcode::eTypeInvalid
@ eTypeInvalid
Definition: Opcode.h:32
lldb_private::Opcode::SetOpcode8
void SetOpcode8(uint8_t inst, lldb::ByteOrder order)
Definition: Opcode.h:153
lldb_private::Opcode::Opcode
Opcode(uint16_t inst, lldb::ByteOrder order)
Definition: Opcode.h:48
lldb_private::Opcode::Opcode
Opcode(uint8_t *bytes, size_t length)
Definition: Opcode.h:63
lldb_private::Opcode::eType8
@ eType8
Definition: Opcode.h:33
lldb_private::Opcode::Opcode
Opcode(uint32_t inst, lldb::ByteOrder order)
Definition: Opcode.h:53
lldb_private::Opcode::inst64
uint64_t inst64
Definition: Opcode.h:262
lldb_private::Stream
Definition: Stream.h:28
lldb_private::Opcode::eTypeBytes
@ eTypeBytes
Definition: Opcode.h:38
lldb_private::Opcode::Opcode
Opcode(uint8_t inst, lldb::ByteOrder order)
Definition: Opcode.h:43
lldb_private::Opcode::SetOpcode32
void SetOpcode32(uint32_t inst, lldb::ByteOrder order)
Definition: Opcode.h:171
lldb_private::Opcode::SetOpcode16
void SetOpcode16(uint16_t inst, lldb::ByteOrder order)
Definition: Opcode.h:159
lldb_private::Opcode::GetOpcode16
uint16_t GetOpcode16(uint16_t invalid_opcode=UINT16_MAX) const
Definition: Opcode.h:95
lldb_private::Opcode::GetOpcodeBytes
const void * GetOpcodeBytes() const
Definition: Opcode.h:198
lldb_private::Opcode::eType16
@ eType16
Definition: Opcode.h:34
lldb_private::DataExtractor
Definition: DataExtractor.h:48
lldb_private::Opcode::GetOpcode8
uint8_t GetOpcode8(uint8_t invalid_opcode=UINT8_MAX) const
Definition: Opcode.h:75
lldb_private::Opcode::GetOpcode64
uint64_t GetOpcode64(uint64_t invalid_opcode=UINT64_MAX) const
Definition: Opcode.h:134
lldb-enumerations.h
lldb_private::Opcode::inst32
uint32_t inst32
Definition: Opcode.h:261
lldb_private::Opcode::GetData
uint32_t GetData(DataExtractor &data) const
Definition: Opcode.cpp:81
lldb::SBInstruction
class LLDB_API SBInstruction
Definition: SBDefines.h:51
lldb_private::Opcode::Opcode
Opcode(uint64_t inst, lldb::ByteOrder order)
Definition: Opcode.h:58
lldb_private::Opcode::bytes
uint8_t bytes[16]
Definition: Opcode.h:264
lldb::eByteOrderInvalid
@ eByteOrderInvalid
Definition: lldb-enumerations.h:139
uint32_t
lldb_private::Opcode::GetDataByteOrder
lldb::ByteOrder GetDataByteOrder() const
Definition: Opcode.cpp:62
lldb_private::Opcode::m_type
Opcode::Type m_type
Definition: Opcode.h:257
lldb_private::Opcode::SetOpcodeBytes
void SetOpcodeBytes(const void *bytes, size_t length)
Definition: Opcode.h:183
lldb_private::Opcode::GetOpcodeDataBytes
const void * GetOpcodeDataBytes() const
Definition: Opcode.h:227
lldb_private::endian::InlHostByteOrder
lldb::ByteOrder InlHostByteOrder()
Definition: Endian.h:25
lldb_private::Opcode::GetOpcode32
uint32_t GetOpcode32(uint32_t invalid_opcode=UINT32_MAX) const
Definition: Opcode.h:115
lldb_private::Opcode::m_data
union lldb_private::Opcode::@8 m_data
lldb_private::Opcode::Type
Type
Definition: Opcode.h:31
lldb_private::Opcode::GetByteSize
uint32_t GetByteSize() const
Definition: Opcode.h:202
UINT32_MAX
#define UINT32_MAX
Definition: lldb-defines.h:31
lldb_private::Opcode::inst
struct lldb_private::Opcode::@8::@9 inst
uint16_t
lldb::SBInstruction
Definition: SBInstruction.h:24
lldb_private::Opcode::SetOpcode64
void SetOpcode64(uint64_t inst, lldb::ByteOrder order)
Definition: Opcode.h:177
lldb_private::Opcode::GetType
Opcode::Type GetType() const
Definition: Opcode.h:73
lldb_private::Opcode::Dump
int Dump(Stream *s, uint32_t min_byte_width)
Definition: Opcode.cpp:24
lldb_private
A class that represents a running process on the host machine.
Definition: SBCommandInterpreterRunOptions.h:16
lldb::eByteOrderBig
@ eByteOrderBig
Definition: lldb-enumerations.h:140
lldb_private::Opcode::eType64
@ eType64
Definition: Opcode.h:37
lldb_private::Opcode::eType16_2
@ eType16_2
Definition: Opcode.h:35
lldb_private::Opcode::Clear
void Clear()
Definition: Opcode.h:68
lldb::eByteOrderLittle
@ eByteOrderLittle
Definition: lldb-enumerations.h:142
lldb_private::Opcode::m_byte_order
lldb::ByteOrder m_byte_order
Definition: Opcode.h:255
lldb
Definition: SBAddress.h:15
Endian.h
lldb_private::Opcode::length
uint8_t length
Definition: Opcode.h:266
UINT64_MAX
#define UINT64_MAX
Definition: lldb-defines.h:35
lldb::ByteOrder
ByteOrder
Byte ordering definitions.
Definition: lldb-enumerations.h:138