aboutsummaryrefslogtreecommitdiff
path: root/lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp
diff options
context:
space:
mode:
authorBhushan D. Attarde <Bhushan.Attarde@imgtec.com>2015-08-26 06:04:54 +0000
committerBhushan D. Attarde <Bhushan.Attarde@imgtec.com>2015-08-26 06:04:54 +0000
commit7f3daeda9a1c8e2a7691954827c9ea886c8cfa62 (patch)
tree3b935ff9f79f0c5212abf7bd320757b70bff130e /lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp
parentd39bcaed2122c23a44dad3dc94b9e2166f8a3035 (diff)
downloadllvm-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.cpp45
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();