http://llvm-reviews.chandlerc.com/D1838
CHANGE SINCE LAST DIFF
http://llvm-reviews.chandlerc.com/D1838?vs=4677&id=4808#toc
Files:
include/lldb/Core/Opcode.h
source/Core/Opcode.cpp
source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp
Index: include/lldb/Core/Opcode.h
===================================================================
--- include/lldb/Core/Opcode.h
+++ include/lldb/Core/Opcode.h
@@ -15,7 +15,9 @@
// C++ Includes
// Other libraries and framework includes
+#include "llvm/Support/MathExtras.h"
// Project includes
+#include "lldb/Host/Endian.h"
#include "lldb/lldb-public.h"
namespace lldb
@@ -39,31 +41,31 @@
eTypeBytes
};
- Opcode () : m_type (eTypeInvalid)
+ Opcode () : m_byte_order (lldb::eByteOrderInvalid), m_type (eTypeInvalid)
{
}
- Opcode (uint8_t inst) : m_type (eType8)
+ Opcode (uint8_t inst) : m_byte_order (lldb::eByteOrderInvalid), m_type (eType8)
{
m_data.inst8 = inst;
}
- Opcode (uint16_t inst) : m_type (eType16)
+ Opcode (uint16_t inst) : m_byte_order (lldb::eByteOrderInvalid), m_type (eType16)
{
m_data.inst16 = inst;
}
- Opcode (uint32_t inst) : m_type (eType32)
+ Opcode (uint32_t inst) : m_byte_order (lldb::eByteOrderInvalid), m_type (eType32)
{
m_data.inst32 = inst;
}
- Opcode (uint64_t inst) : m_type (eType64)
+ Opcode (uint64_t inst) : m_byte_order (lldb::eByteOrderInvalid), m_type (eType64)
{
m_data.inst64 = inst;
}
- Opcode (uint8_t *bytes, size_t length)
+ Opcode (uint8_t *bytes, size_t length) : m_byte_order (lldb::eByteOrderInvalid)
{
SetOpcodeBytes (bytes, length);
}
@@ -71,6 +73,7 @@
void
Clear()
{
+ m_byte_order = lldb::eByteOrderInvalid;
m_type = Opcode::eTypeInvalid;
}
Opcode::Type
@@ -102,7 +105,7 @@
{
case Opcode::eTypeInvalid: break;
case Opcode::eType8: return m_data.inst8;
- case Opcode::eType16: return m_data.inst16;
+ 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;
@@ -118,9 +121,9 @@
{
case Opcode::eTypeInvalid: break;
case Opcode::eType8: return m_data.inst8;
- case Opcode::eType16: return m_data.inst16;
+ case Opcode::eType16: return GetEndianSwap() ? llvm::ByteSwap_16(m_data.inst16) : m_data.inst16;
case Opcode::eType16_2: // passthrough
- case Opcode::eType32: return m_data.inst32;
+ case Opcode::eType32: return GetEndianSwap() ? llvm::ByteSwap_32(m_data.inst32) : m_data.inst32;
case Opcode::eType64: break;
case Opcode::eTypeBytes: break;
}
@@ -134,10 +137,10 @@
{
case Opcode::eTypeInvalid: break;
case Opcode::eType8: return m_data.inst8;
- case Opcode::eType16: return m_data.inst16;
+ case Opcode::eType16: return GetEndianSwap() ? llvm::ByteSwap_16(m_data.inst16) : m_data.inst16;
case Opcode::eType16_2: // passthrough
- case Opcode::eType32: return m_data.inst32;
- case Opcode::eType64: return m_data.inst64;
+ 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;
@@ -187,6 +190,7 @@
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
{
@@ -195,6 +199,12 @@
}
}
+ void
+ SetByteOrder (lldb::ByteOrder byte_order)
+ {
+ m_byte_order = byte_order;
+ }
+
int
Dump (Stream *s, uint32_t min_byte_width);
@@ -249,6 +259,15 @@
lldb::ByteOrder
GetDataByteOrder () const;
+ bool
+ GetEndianSwap() const
+ {
+ return (m_byte_order == lldb::eByteOrderBig && lldb::endian::InlHostByteOrder() == lldb::eByteOrderLittle) ||
+ (m_byte_order == lldb::eByteOrderLittle && lldb::endian::InlHostByteOrder() == lldb::eByteOrderBig);
+ }
+
+ lldb::ByteOrder m_byte_order;
+
Opcode::Type m_type;
union
{
Index: source/Core/Opcode.cpp
===================================================================
--- source/Core/Opcode.cpp
+++ source/Core/Opcode.cpp
@@ -71,6 +71,10 @@
lldb::ByteOrder
Opcode::GetDataByteOrder () const
{
+ if (m_byte_order != eByteOrderInvalid)
+ {
+ return m_byte_order;
+ }
switch (m_type)
{
case Opcode::eTypeInvalid: break;
@@ -89,39 +93,66 @@
Opcode::GetData (DataExtractor &data) const
{
uint32_t byte_size = GetByteSize ();
+ uint8_t swap_buf[8];
+ const void *buf = NULL;
- DataBufferSP buffer_sp;
if (byte_size > 0)
{
- switch (m_type)
+ if (!GetEndianSwap())
+ {
+ if (m_type == Opcode::eType16_2)
+ {
+ // 32 bit thumb instruction, we need to sizzle this a bit
+ swap_buf[0] = m_data.inst.bytes[2];
+ swap_buf[1] = m_data.inst.bytes[3];
+ swap_buf[2] = m_data.inst.bytes[0];
+ swap_buf[3] = m_data.inst.bytes[1];
+ buf = swap_buf;
+ }
+ else
+ {
+ buf = GetOpcodeDataBytes();
+ }
+ }
+ else
{
- case Opcode::eTypeInvalid:
- break;
-
- case Opcode::eType8: buffer_sp.reset (new DataBufferHeap (&m_data.inst8, byte_size)); break;
- case Opcode::eType16: buffer_sp.reset (new DataBufferHeap (&m_data.inst16, byte_size)); break;
- case Opcode::eType16_2:
- {
- // 32 bit thumb instruction, we need to sizzle this a bit
- uint8_t buf[4];
- buf[0] = m_data.inst.bytes[2];
- buf[1] = m_data.inst.bytes[3];
- buf[2] = m_data.inst.bytes[0];
- buf[3] = m_data.inst.bytes[1];
- buffer_sp.reset (new DataBufferHeap (buf, byte_size));
- }
- break;
- case Opcode::eType32:
- buffer_sp.reset (new DataBufferHeap (&m_data.inst32, byte_size));
- break;
- case Opcode::eType64: buffer_sp.reset (new DataBufferHeap (&m_data.inst64, byte_size)); break;
- case Opcode::eTypeBytes:buffer_sp.reset (new DataBufferHeap (GetOpcodeBytes(), byte_size)); break;
- break;
+ switch (m_type)
+ {
+ case Opcode::eTypeInvalid:
+ break;
+ case Opcode::eType8:
+ buf = GetOpcodeDataBytes();
+ break;
+ case Opcode::eType16:
+ *(uint16_t *)swap_buf = llvm::ByteSwap_16(m_data.inst16);
+ buf = swap_buf;
+ break;
+ case Opcode::eType16_2:
+ swap_buf[0] = m_data.inst.bytes[1];
+ swap_buf[1] = m_data.inst.bytes[0];
+ swap_buf[2] = m_data.inst.bytes[3];
+ swap_buf[3] = m_data.inst.bytes[2];
+ buf = swap_buf;
+ break;
+ case Opcode::eType32:
+ *(uint32_t *)swap_buf = llvm::ByteSwap_32(m_data.inst32);
+ buf = swap_buf;
+ break;
+ case Opcode::eType64:
+ *(uint32_t *)swap_buf = llvm::ByteSwap_64(m_data.inst64);
+ buf = swap_buf;
+ break;
+ case Opcode::eTypeBytes:
+ buf = GetOpcodeDataBytes();
+ break;
+ }
}
}
-
- if (buffer_sp)
+ if (buf)
{
+ DataBufferSP buffer_sp;
+
+ buffer_sp.reset (new DataBufferHeap (buf, byte_size));
data.SetByteOrder(GetDataByteOrder());
data.SetData (buffer_sp);
return byte_size;
Index: source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp
===================================================================
--- source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp
+++ source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp
@@ -163,6 +163,7 @@
got_op = true;
break;
}
+ m_opcode.SetByteOrder (data.GetByteOrder());
}
if (!got_op)
{
@@ -193,6 +194,7 @@
m_opcode.SetOpcode32 (data.GetU32(&data_offset));
m_is_valid = true;
}
+ m_opcode.SetByteOrder (data.GetByteOrder());
}
else
{
_______________________________________________
lldb-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/lldb-commits