diff options
| author | Jim Ingham <jingham@apple.com> | 2013-03-13 01:55:16 +0000 |
|---|---|---|
| committer | Jim Ingham <jingham@apple.com> | 2013-03-13 01:55:16 +0000 |
| commit | 32ce20c5eed6336feed739a6903b0b6d351030c6 (patch) | |
| tree | 57eab8e76a0b1ce0363a5afc3d3e50923a76731c /lldb/source/Plugins/Disassembler | |
| parent | d19444c48b8dd5108d44a95ef23534f40fa3a7cf (diff) | |
| download | bcm5719-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.cpp | 60 |
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)) |

