Index: lldb/trunk/include/lldb/API/SBAddress.h =================================================================== --- lldb/trunk/include/lldb/API/SBAddress.h +++ lldb/trunk/include/lldb/API/SBAddress.h @@ -103,6 +103,8 @@ const lldb_private::Address *operator->() const; + friend bool operator==(const SBAddress &lhs, const SBAddress &rhs); + lldb_private::Address *get(); lldb_private::Address &ref(); @@ -117,6 +119,8 @@ std::unique_ptr m_opaque_ap; }; +bool operator==(const SBAddress &lhs, const SBAddress &rhs); + } // namespace lldb #endif // LLDB_SBAddress_h_ Index: lldb/trunk/include/lldb/API/SBInstruction.h =================================================================== --- lldb/trunk/include/lldb/API/SBInstruction.h +++ lldb/trunk/include/lldb/API/SBInstruction.h @@ -53,6 +53,8 @@ bool HasDelaySlot(); + bool CanSetBreakpoint(); + void Print(FILE *out); bool GetDescription(lldb::SBStream &description); Index: lldb/trunk/include/lldb/API/SBInstructionList.h =================================================================== --- lldb/trunk/include/lldb/API/SBInstructionList.h +++ lldb/trunk/include/lldb/API/SBInstructionList.h @@ -32,6 +32,15 @@ lldb::SBInstruction GetInstructionAtIndex(uint32_t idx); + // ---------------------------------------------------------------------- + // Returns the number of instructions between the start and end address. + // If canSetBreakpoint is true then the count will be the number of + // instructions on which a breakpoint can be set. + // ---------------------------------------------------------------------- + size_t GetInstructionsCount(const SBAddress &start, + const SBAddress &end, + bool canSetBreakpoint = false); + void Clear(); void AppendInstruction(lldb::SBInstruction inst); Index: lldb/trunk/include/lldb/Core/Disassembler.h =================================================================== --- lldb/trunk/include/lldb/Core/Disassembler.h +++ lldb/trunk/include/lldb/Core/Disassembler.h @@ -173,6 +173,8 @@ virtual bool HasDelaySlot(); + bool CanSetBreakpoint (); + virtual size_t Decode(const Disassembler &disassembler, const DataExtractor &data, lldb::offset_t data_offset) = 0; Index: lldb/trunk/packages/Python/lldbsuite/test/functionalities/breakpoint/step_over_breakpoint/TestStepOverBreakpoint.py =================================================================== --- lldb/trunk/packages/Python/lldbsuite/test/functionalities/breakpoint/step_over_breakpoint/TestStepOverBreakpoint.py +++ lldb/trunk/packages/Python/lldbsuite/test/functionalities/breakpoint/step_over_breakpoint/TestStepOverBreakpoint.py @@ -62,12 +62,11 @@ instructions = function.GetInstructions(self.target) addr_1 = self.breakpoint1.GetLocationAtIndex(0).GetAddress() addr_4 = self.breakpoint4.GetLocationAtIndex(0).GetAddress() - for i in range(instructions.GetSize()) : - addr = instructions.GetInstructionAtIndex(i).GetAddress() - if (addr == addr_1) : index_1 = i - if (addr == addr_4) : index_4 = i - steps_expected = index_4 - index_1 + # if third argument is true then the count will be the number of + # instructions on which a breakpoint can be set. + # start = addr_1, end = addr_4, canSetBreakpoint = True + steps_expected = instructions.GetInstructionsCount(addr_1, addr_4, True) step_count = 0 # Step from breakpoint_1 to breakpoint_4 while True: Index: lldb/trunk/scripts/interface/SBInstruction.i =================================================================== --- lldb/trunk/scripts/interface/SBInstruction.i +++ lldb/trunk/scripts/interface/SBInstruction.i @@ -54,6 +54,9 @@ bool HasDelaySlot (); + bool + CanSetBreakpoint (); + void Print (FILE *out); Index: lldb/trunk/scripts/interface/SBInstructionList.i =================================================================== --- lldb/trunk/scripts/interface/SBInstructionList.i +++ lldb/trunk/scripts/interface/SBInstructionList.i @@ -44,6 +44,9 @@ lldb::SBInstruction GetInstructionAtIndex (uint32_t idx); + size_t GetInstructionsCount(const SBAddress &start, const SBAddress &end, + bool canSetBreakpoint); + void Clear (); Index: lldb/trunk/source/API/SBAddress.cpp =================================================================== --- lldb/trunk/source/API/SBAddress.cpp +++ lldb/trunk/source/API/SBAddress.cpp @@ -55,6 +55,12 @@ return *this; } +bool lldb::operator==(const SBAddress &lhs, const SBAddress &rhs) { + if (lhs.IsValid() && rhs.IsValid()) + return lhs.ref() == rhs.ref(); + return false; +} + bool SBAddress::IsValid() const { return m_opaque_ap.get() != NULL && m_opaque_ap->IsValid(); } Index: lldb/trunk/source/API/SBInstruction.cpp =================================================================== --- lldb/trunk/source/API/SBInstruction.cpp +++ lldb/trunk/source/API/SBInstruction.cpp @@ -176,6 +176,13 @@ return false; } +bool SBInstruction::CanSetBreakpoint () { + lldb::InstructionSP inst_sp(GetOpaque()); + if (inst_sp) + return inst_sp->CanSetBreakpoint(); + return false; +} + lldb::InstructionSP SBInstruction::GetOpaque() { if (m_opaque_sp) return m_opaque_sp->GetSP(); Index: lldb/trunk/source/API/SBInstructionList.cpp =================================================================== --- lldb/trunk/source/API/SBInstructionList.cpp +++ lldb/trunk/source/API/SBInstructionList.cpp @@ -9,6 +9,7 @@ #include "lldb/API/SBInstructionList.h" #include "lldb/API/SBInstruction.h" +#include "lldb/API/SBAddress.h" #include "lldb/API/SBStream.h" #include "lldb/Core/Disassembler.h" #include "lldb/Core/Module.h" @@ -49,6 +50,31 @@ return inst; } +size_t SBInstructionList::GetInstructionsCount(const SBAddress &start, + const SBAddress &end, + bool canSetBreakpoint) { + size_t num_instructions = GetSize(); + size_t i = 0; + SBAddress addr; + size_t lower_index = 0; + size_t upper_index = 0; + size_t instructions_to_skip = 0; + for (i = 0; i < num_instructions; ++i) { + addr = GetInstructionAtIndex(i).GetAddress(); + if (start == addr) + lower_index = i; + if (end == addr) + upper_index = i; + } + if (canSetBreakpoint) + for (i = lower_index; i <= upper_index; ++i) { + SBInstruction insn = GetInstructionAtIndex(i); + if (!insn.CanSetBreakpoint()) + ++instructions_to_skip; + } + return upper_index - lower_index - instructions_to_skip; +} + void SBInstructionList::Clear() { m_opaque_sp.reset(); } void SBInstructionList::AppendInstruction(SBInstruction insn) {} Index: lldb/trunk/source/Core/Disassembler.cpp =================================================================== --- lldb/trunk/source/Core/Disassembler.cpp +++ lldb/trunk/source/Core/Disassembler.cpp @@ -759,6 +759,10 @@ return false; } +bool Instruction::CanSetBreakpoint () { + return !HasDelaySlot(); +} + bool Instruction::HasDelaySlot() { // Default is false. return false;