diff options
-rw-r--r-- | lldb/include/lldb/Core/Opcode.h | 14 | ||||
-rw-r--r-- | lldb/source/Core/Opcode.cpp | 32 | ||||
-rw-r--r-- | lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp | 9 |
3 files changed, 29 insertions, 26 deletions
diff --git a/lldb/include/lldb/Core/Opcode.h b/lldb/include/lldb/Core/Opcode.h index 5761678d031..06f63f76285 100644 --- a/lldb/include/lldb/Core/Opcode.h +++ b/lldb/include/lldb/Core/Opcode.h @@ -33,6 +33,7 @@ namespace lldb_private { eTypeInvalid, eType8, eType16, + eType16_2, // a 32-bit Thumb instruction, made up of two words eType32, eType64, eTypeBytes @@ -86,6 +87,7 @@ namespace lldb_private { 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; @@ -102,6 +104,7 @@ namespace lldb_private { case Opcode::eTypeInvalid: break; case Opcode::eType8: return m_data.inst8; case Opcode::eType16: return m_data.inst16; + case Opcode::eType16_2: break; case Opcode::eType32: break; case Opcode::eType64: break; case Opcode::eTypeBytes: break; @@ -117,6 +120,7 @@ namespace lldb_private { 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: break; case Opcode::eTypeBytes: break; @@ -132,6 +136,7 @@ namespace lldb_private { 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: break; @@ -152,6 +157,13 @@ namespace lldb_private { m_type = eType16; m_data.inst16 = inst; } + + void + SetOpcode16_2 (uint32_t inst) + { + m_type = eType16_2; + m_data.inst32 = inst; + } void SetOpcode32 (uint32_t inst) @@ -203,6 +215,7 @@ namespace lldb_private { 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; @@ -227,6 +240,7 @@ namespace lldb_private { 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; diff --git a/lldb/source/Core/Opcode.cpp b/lldb/source/Core/Opcode.cpp index ffc42172f74..4eb2ae01511 100644 --- a/lldb/source/Core/Opcode.cpp +++ b/lldb/source/Core/Opcode.cpp @@ -40,7 +40,13 @@ Opcode::Dump (Stream *s, uint32_t min_byte_width) case Opcode::eType16: bytes_written = s->Printf ("0x%4.4x", m_data.inst16); break; - + case Opcode::eType16_2: + if (GetDataByteOrder() == eByteOrderLittle) + bytes_written = s->Printf ("0x%4.4x%4.4x", m_data.inst32 & 0xffff, m_data.inst32 >> 16); + else + bytes_written = s->Printf ("0x%2.2x%2.2x%2.2x%2.2x", (m_data.inst32 >> 16) & 0xff, (m_data.inst32 >> 24), + (m_data.inst32 & 0xff), (m_data.inst32 >> 8) & 0xff); + break; case Opcode::eType32: bytes_written = s->Printf ("0x%8.8x", m_data.inst32); break; @@ -76,6 +82,7 @@ Opcode::GetDataByteOrder () const case Opcode::eTypeInvalid: break; case Opcode::eType8: case Opcode::eType16: + case Opcode::eType16_2: case Opcode::eType32: case Opcode::eType64: return lldb::endian::InlHostByteOrder(); case Opcode::eTypeBytes: @@ -99,27 +106,8 @@ Opcode::GetData (DataExtractor &data, lldb::AddressClass address_class) const 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::eType32: - { - // The only thing that uses eAddressClassCodeAlternateISA currently - // is Thumb. If this ever changes, we will need to pass in more - // information like an additional "const ArchSpec &arch". For now - // this will do - if (address_class == eAddressClassCodeAlternateISA) - { - // 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; - } - buffer_sp.reset (new DataBufferHeap (&m_data.inst32, byte_size)); - } - break; - + case Opcode::eType16_2: // passthrough + 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; diff --git a/lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp b/lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp index a5284f11c8e..b03b2af391b 100644 --- a/lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp +++ b/lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp @@ -130,22 +130,23 @@ public: { if (machine == llvm::Triple::thumb || is_altnernate_isa) { - uint32_t thumb_opcode = data.GetU16(&data_offset); + uint16_t thumb_opcode = data.GetU16(&data_offset); if ((thumb_opcode & 0xe000) != 0xe000 || ((thumb_opcode & 0x1800u) == 0)) { m_opcode.SetOpcode16 (thumb_opcode); + m_is_valid = true; } else { - thumb_opcode <<= 16; - thumb_opcode |= data.GetU16(&data_offset); - m_opcode.SetOpcode32 (thumb_opcode); + data_offset -= 2; + m_opcode.SetOpcode16_2 (data.GetU32(&data_offset)); m_is_valid = true; } } else { m_opcode.SetOpcode32 (data.GetU32(&data_offset)); + m_is_valid = true; } } else |