aboutsummaryrefslogtreecommitdiff
path: root/include/lldb/Core/Opcode.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/lldb/Core/Opcode.h')
-rw-r--r--include/lldb/Core/Opcode.h499
1 files changed, 243 insertions, 256 deletions
diff --git a/include/lldb/Core/Opcode.h b/include/lldb/Core/Opcode.h
index eac0746baba1..d5376d44b814 100644
--- a/include/lldb/Core/Opcode.h
+++ b/include/lldb/Core/Opcode.h
@@ -21,266 +21,253 @@
#include "lldb/Host/Endian.h"
#include "lldb/lldb-public.h"
-namespace lldb
-{
- class SBInstruction;
+namespace lldb {
+class SBInstruction;
} // namespace lldb
namespace lldb_private {
- class Opcode
- {
- public:
- enum Type
- {
- eTypeInvalid,
- eType8,
- eType16,
- eType16_2, // a 32-bit Thumb instruction, made up of two words
- eType32,
- eType64,
- eTypeBytes
- };
-
- Opcode () : m_byte_order (lldb::eByteOrderInvalid), m_type (eTypeInvalid)
- {
- }
-
- Opcode (uint8_t inst, lldb::ByteOrder order) : m_byte_order (order), m_type (eType8)
- {
- m_data.inst8 = inst;
- }
-
- Opcode (uint16_t inst, lldb::ByteOrder order) : m_byte_order (order), m_type (eType16)
- {
- m_data.inst16 = inst;
- }
-
- Opcode (uint32_t inst, lldb::ByteOrder order) : m_byte_order (order), m_type (eType32)
- {
- m_data.inst32 = inst;
- }
-
- Opcode (uint64_t inst, lldb::ByteOrder order) : m_byte_order (order), m_type (eType64)
- {
- m_data.inst64 = inst;
- }
-
- Opcode (uint8_t *bytes, size_t length) : m_byte_order (lldb::eByteOrderInvalid)
- {
- SetOpcodeBytes (bytes, length);
- }
-
- void
- Clear()
- {
- m_byte_order = lldb::eByteOrderInvalid;
- m_type = Opcode::eTypeInvalid;
- }
-
- Opcode::Type
- GetType () const
- {
- return m_type;
- }
-
- uint8_t
- GetOpcode8 (uint8_t invalid_opcode = UINT8_MAX) const
- {
- switch (m_type)
- {
- case Opcode::eTypeInvalid: break;
- case Opcode::eType8: return m_data.inst8;
- case Opcode::eType16: break;
- case Opcode::eType16_2: break;
- case Opcode::eType32: break;
- case Opcode::eType64: break;
- case Opcode::eTypeBytes: break;
- }
- return invalid_opcode;
- }
-
- uint16_t
- GetOpcode16 (uint16_t invalid_opcode = UINT16_MAX) const
- {
- switch (m_type)
- {
- case Opcode::eTypeInvalid: break;
- case Opcode::eType8: return m_data.inst8;
- case Opcode::eType16: return GetEndianSwap() ? llvm::ByteSwap_16(m_data.inst16) : m_data.inst16;
- case Opcode::eType16_2: break;
- case Opcode::eType32: break;
- case Opcode::eType64: break;
- case Opcode::eTypeBytes: break;
- }
- return invalid_opcode;
- }
-
- uint32_t
- GetOpcode32 (uint32_t invalid_opcode = UINT32_MAX) const
- {
- switch (m_type)
- {
- case Opcode::eTypeInvalid: break;
- case Opcode::eType8: return m_data.inst8;
- case Opcode::eType16: return GetEndianSwap() ? llvm::ByteSwap_16(m_data.inst16) : m_data.inst16;
- case Opcode::eType16_2: // passthrough
- case Opcode::eType32: return GetEndianSwap() ? llvm::ByteSwap_32(m_data.inst32) : m_data.inst32;
- case Opcode::eType64: break;
- case Opcode::eTypeBytes: break;
- }
- return invalid_opcode;
- }
-
- uint64_t
- GetOpcode64 (uint64_t invalid_opcode = UINT64_MAX) const
- {
- switch (m_type)
- {
- case Opcode::eTypeInvalid: break;
- case Opcode::eType8: return m_data.inst8;
- case Opcode::eType16: return GetEndianSwap() ? llvm::ByteSwap_16(m_data.inst16) : m_data.inst16;
- case Opcode::eType16_2: // passthrough
- case Opcode::eType32: return GetEndianSwap() ? llvm::ByteSwap_32(m_data.inst32) : m_data.inst32;
- case Opcode::eType64: return GetEndianSwap() ? llvm::ByteSwap_64(m_data.inst64) : m_data.inst64;
- case Opcode::eTypeBytes: break;
- }
- return invalid_opcode;
- }
-
- void
- SetOpcode8 (uint8_t inst, lldb::ByteOrder order)
- {
- m_type = eType8;
- m_data.inst8 = inst;
- m_byte_order = order;
- }
-
- void
- SetOpcode16 (uint16_t inst, lldb::ByteOrder order)
- {
- m_type = eType16;
- m_data.inst16 = inst;
- m_byte_order = order;
- }
-
- void
- SetOpcode16_2 (uint32_t inst, lldb::ByteOrder order)
- {
- m_type = eType16_2;
- m_data.inst32 = inst;
- m_byte_order = order;
- }
-
- void
- SetOpcode32 (uint32_t inst, lldb::ByteOrder order)
- {
- m_type = eType32;
- m_data.inst32 = inst;
- m_byte_order = order;
- }
-
- void
- SetOpcode64 (uint64_t inst, lldb::ByteOrder order)
- {
- m_type = eType64;
- m_data.inst64 = inst;
- m_byte_order = order;
- }
-
- void
- SetOpcodeBytes (const void *bytes, size_t length)
- {
- if (bytes != nullptr && length > 0)
- {
- m_type = eTypeBytes;
- m_data.inst.length = length;
- assert (length < sizeof (m_data.inst.bytes));
- memcpy (m_data.inst.bytes, bytes, length);
- m_byte_order = lldb::eByteOrderInvalid;
- }
- else
- {
- m_type = eTypeInvalid;
- m_data.inst.length = 0;
- }
- }
-
- int
- Dump (Stream *s, uint32_t min_byte_width);
-
- const void *
- GetOpcodeBytes () const
- {
- return ((m_type == Opcode::eTypeBytes) ? m_data.inst.bytes : nullptr);
- }
-
- uint32_t
- GetByteSize () const
- {
- switch (m_type)
- {
- case Opcode::eTypeInvalid: break;
- case Opcode::eType8: return sizeof(m_data.inst8);
- case Opcode::eType16: return sizeof(m_data.inst16);
- case Opcode::eType16_2: // passthrough
- case Opcode::eType32: return sizeof(m_data.inst32);
- case Opcode::eType64: return sizeof(m_data.inst64);
- case Opcode::eTypeBytes: return m_data.inst.length;
- }
- return 0;
- }
-
- // Get the opcode exactly as it would be laid out in memory.
- uint32_t
- GetData (DataExtractor &data) const;
-
- protected:
-
- friend class lldb::SBInstruction;
-
- const void *
- GetOpcodeDataBytes () const
- {
- switch (m_type)
- {
- case Opcode::eTypeInvalid: break;
- case Opcode::eType8: return &m_data.inst8;
- case Opcode::eType16: return &m_data.inst16;
- case Opcode::eType16_2: // passthrough
- case Opcode::eType32: return &m_data.inst32;
- case Opcode::eType64: return &m_data.inst64;
- case Opcode::eTypeBytes: return m_data.inst.bytes;
- }
- return nullptr;
- }
-
- lldb::ByteOrder
- GetDataByteOrder () const;
-
- bool
- GetEndianSwap() const
- {
- return (m_byte_order == lldb::eByteOrderBig && endian::InlHostByteOrder() == lldb::eByteOrderLittle) ||
- (m_byte_order == lldb::eByteOrderLittle && endian::InlHostByteOrder() == lldb::eByteOrderBig);
- }
-
- lldb::ByteOrder m_byte_order;
-
- Opcode::Type m_type;
- union
- {
- uint8_t inst8;
- uint16_t inst16;
- uint32_t inst32;
- uint64_t inst64;
- struct
- {
- uint8_t bytes[16]; // This must be big enough to handle any opcode for any supported target.
- uint8_t length;
- } inst;
- } m_data;
- };
+class Opcode {
+public:
+ enum Type {
+ eTypeInvalid,
+ eType8,
+ eType16,
+ eType16_2, // a 32-bit Thumb instruction, made up of two words
+ eType32,
+ eType64,
+ eTypeBytes
+ };
+
+ Opcode() : m_byte_order(lldb::eByteOrderInvalid), m_type(eTypeInvalid) {}
+
+ Opcode(uint8_t inst, lldb::ByteOrder order)
+ : m_byte_order(order), m_type(eType8) {
+ m_data.inst8 = inst;
+ }
+
+ Opcode(uint16_t inst, lldb::ByteOrder order)
+ : m_byte_order(order), m_type(eType16) {
+ m_data.inst16 = inst;
+ }
+
+ Opcode(uint32_t inst, lldb::ByteOrder order)
+ : m_byte_order(order), m_type(eType32) {
+ m_data.inst32 = inst;
+ }
+
+ Opcode(uint64_t inst, lldb::ByteOrder order)
+ : m_byte_order(order), m_type(eType64) {
+ m_data.inst64 = inst;
+ }
+
+ Opcode(uint8_t *bytes, size_t length)
+ : m_byte_order(lldb::eByteOrderInvalid) {
+ SetOpcodeBytes(bytes, length);
+ }
+
+ void Clear() {
+ m_byte_order = lldb::eByteOrderInvalid;
+ m_type = Opcode::eTypeInvalid;
+ }
+
+ Opcode::Type GetType() const { return m_type; }
+
+ uint8_t GetOpcode8(uint8_t invalid_opcode = UINT8_MAX) const {
+ switch (m_type) {
+ case Opcode::eTypeInvalid:
+ break;
+ case Opcode::eType8:
+ return m_data.inst8;
+ case Opcode::eType16:
+ break;
+ case Opcode::eType16_2:
+ break;
+ case Opcode::eType32:
+ break;
+ case Opcode::eType64:
+ break;
+ case Opcode::eTypeBytes:
+ break;
+ }
+ return invalid_opcode;
+ }
+
+ uint16_t GetOpcode16(uint16_t invalid_opcode = UINT16_MAX) const {
+ switch (m_type) {
+ case Opcode::eTypeInvalid:
+ break;
+ case Opcode::eType8:
+ return m_data.inst8;
+ case Opcode::eType16:
+ return GetEndianSwap() ? llvm::ByteSwap_16(m_data.inst16) : m_data.inst16;
+ case Opcode::eType16_2:
+ break;
+ case Opcode::eType32:
+ break;
+ case Opcode::eType64:
+ break;
+ case Opcode::eTypeBytes:
+ break;
+ }
+ return invalid_opcode;
+ }
+
+ uint32_t GetOpcode32(uint32_t invalid_opcode = UINT32_MAX) const {
+ switch (m_type) {
+ case Opcode::eTypeInvalid:
+ break;
+ case Opcode::eType8:
+ return m_data.inst8;
+ case Opcode::eType16:
+ return GetEndianSwap() ? llvm::ByteSwap_16(m_data.inst16) : m_data.inst16;
+ case Opcode::eType16_2: // passthrough
+ case Opcode::eType32:
+ return GetEndianSwap() ? llvm::ByteSwap_32(m_data.inst32) : m_data.inst32;
+ case Opcode::eType64:
+ break;
+ case Opcode::eTypeBytes:
+ break;
+ }
+ return invalid_opcode;
+ }
+
+ uint64_t GetOpcode64(uint64_t invalid_opcode = UINT64_MAX) const {
+ switch (m_type) {
+ case Opcode::eTypeInvalid:
+ break;
+ case Opcode::eType8:
+ return m_data.inst8;
+ case Opcode::eType16:
+ return GetEndianSwap() ? llvm::ByteSwap_16(m_data.inst16) : m_data.inst16;
+ case Opcode::eType16_2: // passthrough
+ case Opcode::eType32:
+ return GetEndianSwap() ? llvm::ByteSwap_32(m_data.inst32) : m_data.inst32;
+ case Opcode::eType64:
+ return GetEndianSwap() ? llvm::ByteSwap_64(m_data.inst64) : m_data.inst64;
+ case Opcode::eTypeBytes:
+ break;
+ }
+ return invalid_opcode;
+ }
+
+ void SetOpcode8(uint8_t inst, lldb::ByteOrder order) {
+ m_type = eType8;
+ m_data.inst8 = inst;
+ m_byte_order = order;
+ }
+
+ void SetOpcode16(uint16_t inst, lldb::ByteOrder order) {
+ m_type = eType16;
+ m_data.inst16 = inst;
+ m_byte_order = order;
+ }
+
+ void SetOpcode16_2(uint32_t inst, lldb::ByteOrder order) {
+ m_type = eType16_2;
+ m_data.inst32 = inst;
+ m_byte_order = order;
+ }
+
+ void SetOpcode32(uint32_t inst, lldb::ByteOrder order) {
+ m_type = eType32;
+ m_data.inst32 = inst;
+ m_byte_order = order;
+ }
+
+ void SetOpcode64(uint64_t inst, lldb::ByteOrder order) {
+ m_type = eType64;
+ m_data.inst64 = inst;
+ m_byte_order = order;
+ }
+
+ void SetOpcodeBytes(const void *bytes, size_t length) {
+ if (bytes != nullptr && length > 0) {
+ m_type = eTypeBytes;
+ m_data.inst.length = length;
+ assert(length < sizeof(m_data.inst.bytes));
+ memcpy(m_data.inst.bytes, bytes, length);
+ m_byte_order = lldb::eByteOrderInvalid;
+ } else {
+ m_type = eTypeInvalid;
+ m_data.inst.length = 0;
+ }
+ }
+
+ int Dump(Stream *s, uint32_t min_byte_width);
+
+ const void *GetOpcodeBytes() const {
+ return ((m_type == Opcode::eTypeBytes) ? m_data.inst.bytes : nullptr);
+ }
+
+ uint32_t GetByteSize() const {
+ switch (m_type) {
+ case Opcode::eTypeInvalid:
+ break;
+ case Opcode::eType8:
+ return sizeof(m_data.inst8);
+ case Opcode::eType16:
+ return sizeof(m_data.inst16);
+ case Opcode::eType16_2: // passthrough
+ case Opcode::eType32:
+ return sizeof(m_data.inst32);
+ case Opcode::eType64:
+ return sizeof(m_data.inst64);
+ case Opcode::eTypeBytes:
+ return m_data.inst.length;
+ }
+ return 0;
+ }
+
+ // Get the opcode exactly as it would be laid out in memory.
+ uint32_t GetData(DataExtractor &data) const;
+
+protected:
+ friend class lldb::SBInstruction;
+
+ const void *GetOpcodeDataBytes() const {
+ switch (m_type) {
+ case Opcode::eTypeInvalid:
+ break;
+ case Opcode::eType8:
+ return &m_data.inst8;
+ case Opcode::eType16:
+ return &m_data.inst16;
+ case Opcode::eType16_2: // passthrough
+ case Opcode::eType32:
+ return &m_data.inst32;
+ case Opcode::eType64:
+ return &m_data.inst64;
+ case Opcode::eTypeBytes:
+ return m_data.inst.bytes;
+ }
+ return nullptr;
+ }
+
+ lldb::ByteOrder GetDataByteOrder() const;
+
+ bool GetEndianSwap() const {
+ return (m_byte_order == lldb::eByteOrderBig &&
+ endian::InlHostByteOrder() == lldb::eByteOrderLittle) ||
+ (m_byte_order == lldb::eByteOrderLittle &&
+ endian::InlHostByteOrder() == lldb::eByteOrderBig);
+ }
+
+ lldb::ByteOrder m_byte_order;
+
+ Opcode::Type m_type;
+ union {
+ uint8_t inst8;
+ uint16_t inst16;
+ uint32_t inst32;
+ uint64_t inst64;
+ struct {
+ uint8_t bytes[16]; // This must be big enough to handle any opcode for any
+ // supported target.
+ uint8_t length;
+ } inst;
+ } m_data;
+};
} // namespace lldb_private