diff options
| author | Greg Clayton <gclayton@apple.com> | 2012-08-07 01:29:29 +0000 |
|---|---|---|
| committer | Greg Clayton <gclayton@apple.com> | 2012-08-07 01:29:29 +0000 |
| commit | 79101b5cb01eda3c3b617314de23b78ea6abb702 (patch) | |
| tree | e57704756e0f797476063199c6db2545f1377a47 | |
| parent | c11a33a2bd8e999be50ffc78b9bb747112f5b1f8 (diff) | |
| download | bcm5719-llvm-79101b5cb01eda3c3b617314de23b78ea6abb702.tar.gz bcm5719-llvm-79101b5cb01eda3c3b617314de23b78ea6abb702.zip | |
Fixed an error in the thumb opcode encoding. We need the 32 bit thumb instructions to be encoded as a 32 bit value for the EmulateARM code.
llvm-svn: 161381
| -rw-r--r-- | lldb/source/Core/Opcode.cpp | 29 | ||||
| -rw-r--r-- | lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp | 7 |
2 files changed, 25 insertions, 11 deletions
diff --git a/lldb/source/Core/Opcode.cpp b/lldb/source/Core/Opcode.cpp index 4eb2ae01511..a4a96fdf1cd 100644 --- a/lldb/source/Core/Opcode.cpp +++ b/lldb/source/Core/Opcode.cpp @@ -41,12 +41,6 @@ Opcode::Dump (Stream *s, uint32_t min_byte_width) 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; @@ -106,8 +100,27 @@ 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::eType16_2: // passthrough - case Opcode::eType32: buffer_sp.reset (new DataBufferHeap (&m_data.inst32, byte_size)); break; + case Opcode::eType16_2: + 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 (m_type == Opcode::eType16_2 || 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)); + } + else + { + 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 b03b2af391b..349c16e12d1 100644 --- a/lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp +++ b/lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp @@ -130,7 +130,7 @@ public: { if (machine == llvm::Triple::thumb || is_altnernate_isa) { - uint16_t thumb_opcode = data.GetU16(&data_offset); + uint32_t thumb_opcode = data.GetU16(&data_offset); if ((thumb_opcode & 0xe000) != 0xe000 || ((thumb_opcode & 0x1800u) == 0)) { m_opcode.SetOpcode16 (thumb_opcode); @@ -138,8 +138,9 @@ public: } else { - data_offset -= 2; - m_opcode.SetOpcode16_2 (data.GetU32(&data_offset)); + thumb_opcode <<= 16; + thumb_opcode |= data.GetU16(&data_offset); + m_opcode.SetOpcode16_2 (thumb_opcode); m_is_valid = true; } } |

