summaryrefslogtreecommitdiffstats
path: root/lldb/source/Plugins/Disassembler
diff options
context:
space:
mode:
authorJim Ingham <jingham@apple.com>2013-03-13 01:55:16 +0000
committerJim Ingham <jingham@apple.com>2013-03-13 01:55:16 +0000
commit32ce20c5eed6336feed739a6903b0b6d351030c6 (patch)
tree57eab8e76a0b1ce0363a5afc3d3e50923a76731c /lldb/source/Plugins/Disassembler
parentd19444c48b8dd5108d44a95ef23534f40fa3a7cf (diff)
downloadbcm5719-llvm-32ce20c5eed6336feed739a6903b0b6d351030c6.tar.gz
bcm5719-llvm-32ce20c5eed6336feed739a6903b0b6d351030c6.zip
DoesBranch needs to compute the instruction if it isn't already done.
Handle the "alternate_isa" correctly. llvm-svn: 176922
Diffstat (limited to 'lldb/source/Plugins/Disassembler')
-rw-r--r--lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp60
1 files changed, 55 insertions, 5 deletions
diff --git a/lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp b/lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp
index f4192b18f4a..e358a1bb4bd 100644
--- a/lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp
+++ b/lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp
@@ -73,11 +73,61 @@ public:
}
virtual bool
- DoesBranch () const
+ DoesBranch ()
{
+ if (m_does_branch == eLazyBoolCalculate)
+ {
+ m_disasm.Lock(this, NULL);
+ DataExtractor data;
+ if (m_opcode.GetData(data))
+ {
+ bool is_alternate_isa;
+ lldb::addr_t pc = m_address.GetFileAddress();
+
+ DisassemblerLLVMC::LLVMCDisassembler *mc_disasm_ptr = GetDisasmToUse (is_alternate_isa);
+ uint8_t *opcode_data = const_cast<uint8_t *>(data.PeekData (0, 1));
+ const size_t opcode_data_len = data.GetByteSize();
+ llvm::MCInst inst;
+ size_t inst_size = mc_disasm_ptr->GetMCInst(opcode_data,
+ opcode_data_len,
+ pc,
+ inst);
+ // Be conservative, if we didn't understand the instruction, say it might branch...
+ if (inst_size == 0)
+ m_does_branch = eLazyBoolYes;
+ else
+ {
+ bool can_branch = mc_disasm_ptr->CanBranch(inst);
+ if (can_branch)
+ m_does_branch = eLazyBoolYes;
+ else
+ m_does_branch = eLazyBoolNo;
+ }
+ }
+ m_disasm.Unlock();
+ }
return m_does_branch == eLazyBoolYes;
}
+ DisassemblerLLVMC::LLVMCDisassembler *
+ GetDisasmToUse (bool &is_alternate_isa)
+ {
+ DisassemblerLLVMC::LLVMCDisassembler *mc_disasm_ptr = m_disasm.m_disasm_ap.get();
+
+ is_alternate_isa = false;
+ if (m_disasm.m_alternate_disasm_ap.get() != NULL)
+ {
+ const AddressClass address_class = GetAddressClass ();
+
+ if (address_class == eAddressClassCodeAlternateISA)
+ {
+ mc_disasm_ptr = m_disasm.m_alternate_disasm_ap.get();
+ is_alternate_isa = true;
+ }
+ }
+ return mc_disasm_ptr;
+ }
+
virtual size_t
Decode (const lldb_private::Disassembler &disassembler,
const lldb_private::DataExtractor &data,
@@ -126,9 +176,9 @@ public:
}
if (!got_op)
{
- DisassemblerLLVMC::LLVMCDisassembler *mc_disasm_ptr = m_disasm.m_disasm_ap.get();
+ bool is_alternate_isa = false;
+ DisassemblerLLVMC::LLVMCDisassembler *mc_disasm_ptr = GetDisasmToUse (is_alternate_isa);
- bool is_altnernate_isa = false;
if (m_disasm.m_alternate_disasm_ap.get() != NULL)
{
const AddressClass address_class = GetAddressClass ();
@@ -136,14 +186,14 @@ public:
if (address_class == eAddressClassCodeAlternateISA)
{
mc_disasm_ptr = m_disasm.m_alternate_disasm_ap.get();
- is_altnernate_isa = true;
+ is_alternate_isa = true;
}
}
const llvm::Triple::ArchType machine = arch.GetMachine();
if (machine == llvm::Triple::arm || machine == llvm::Triple::thumb)
{
- if (machine == llvm::Triple::thumb || is_altnernate_isa)
+ if (machine == llvm::Triple::thumb || is_alternate_isa)
{
uint32_t thumb_opcode = data.GetU16(&data_offset);
if ((thumb_opcode & 0xe000) != 0xe000 || ((thumb_opcode & 0x1800u) == 0))
OpenPOWER on IntegriCloud