diff options
author | Bhushan D. Attarde <Bhushan.Attarde@imgtec.com> | 2015-08-26 06:04:54 +0000 |
---|---|---|
committer | Bhushan D. Attarde <Bhushan.Attarde@imgtec.com> | 2015-08-26 06:04:54 +0000 |
commit | 7f3daeda9a1c8e2a7691954827c9ea886c8cfa62 (patch) | |
tree | 3b935ff9f79f0c5212abf7bd320757b70bff130e /lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp | |
parent | d39bcaed2122c23a44dad3dc94b9e2166f8a3035 (diff) | |
download | llvm-7f3daeda9a1c8e2a7691954827c9ea886c8cfa62.zip llvm-7f3daeda9a1c8e2a7691954827c9ea886c8cfa62.tar.gz llvm-7f3daeda9a1c8e2a7691954827c9ea886c8cfa62.tar.bz2 |
[MIPS] Avoid breakpoint in delay slot
SUMMARY:
This patch implements Target::GetBreakableLoadAddress() method that takes an address
and checks for any reason there is a better address than this to put a breakpoint on.
If there is then return that address.
MIPS uses this method to avoid breakpoint in delay slot.
Reviewers: clayborg, jingham
Subscribers: jingham, mohit.bhakkad, sagar, jaydeep, nitesh.jain, lldb-commits
Differential Revision: http://http://reviews.llvm.org/D12184
llvm-svn: 246015
Diffstat (limited to 'lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp')
-rw-r--r-- | lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp b/lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp index 02e39d3..19e2dbd 100644 --- a/lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp +++ b/lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp @@ -52,6 +52,7 @@ public: Instruction (address, addr_class), m_disasm_sp (disasm.shared_from_this()), m_does_branch (eLazyBoolCalculate), + m_has_delay_slot (eLazyBoolCalculate), m_is_valid (false), m_using_file_addr (false) { @@ -99,6 +100,43 @@ public: return m_does_branch == eLazyBoolYes; } + virtual bool + HasDelaySlot () + { + if (m_has_delay_slot == eLazyBoolCalculate) + { + GetDisassemblerLLVMC().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); + const uint8_t *opcode_data = data.GetDataStart(); + const size_t opcode_data_len = data.GetByteSize(); + llvm::MCInst inst; + const size_t inst_size = mc_disasm_ptr->GetMCInst (opcode_data, + opcode_data_len, + pc, + inst); + // if we didn't understand the instruction, say it doesn't have a delay slot... + if (inst_size == 0) + m_has_delay_slot = eLazyBoolNo; + else + { + const bool has_delay_slot = mc_disasm_ptr->HasDelaySlot(inst); + if (has_delay_slot) + m_has_delay_slot = eLazyBoolYes; + else + m_has_delay_slot = eLazyBoolNo; + } + } + GetDisassemblerLLVMC().Unlock(); + } + return m_has_delay_slot == eLazyBoolYes; + } + DisassemblerLLVMC::LLVMCDisassembler * GetDisasmToUse (bool &is_alternate_isa) { @@ -409,6 +447,7 @@ protected: DisassemblerSP m_disasm_sp; // for ownership LazyBool m_does_branch; + LazyBool m_has_delay_slot; bool m_is_valid; bool m_using_file_addr; }; @@ -543,6 +582,12 @@ DisassemblerLLVMC::LLVMCDisassembler::CanBranch (llvm::MCInst &mc_inst) } bool +DisassemblerLLVMC::LLVMCDisassembler::HasDelaySlot (llvm::MCInst &mc_inst) +{ + return m_instr_info_ap->get(mc_inst.getOpcode()).hasDelaySlot(); +} + +bool DisassemblerLLVMC::FlavorValidForArchSpec (const lldb_private::ArchSpec &arch, const char *flavor) { llvm::Triple triple = arch.GetTriple(); |