diff options
Diffstat (limited to 'lldb/tools/debugserver/source/DNBBreakpoint.cpp')
-rw-r--r-- | lldb/tools/debugserver/source/DNBBreakpoint.cpp | 329 |
1 files changed, 141 insertions, 188 deletions
diff --git a/lldb/tools/debugserver/source/DNBBreakpoint.cpp b/lldb/tools/debugserver/source/DNBBreakpoint.cpp index 2645f173306..89a91287f9e 100644 --- a/lldb/tools/debugserver/source/DNBBreakpoint.cpp +++ b/lldb/tools/debugserver/source/DNBBreakpoint.cpp @@ -12,214 +12,167 @@ //===----------------------------------------------------------------------===// #include "DNBBreakpoint.h" +#include "DNBLog.h" #include "MachProcess.h" -#include <assert.h> #include <algorithm> +#include <assert.h> #include <inttypes.h> -#include "DNBLog.h" - - -#pragma mark -- DNBBreakpoint -DNBBreakpoint::DNBBreakpoint(nub_addr_t addr, nub_size_t byte_size, bool hardware) : - m_retain_count (1), - m_byte_size (static_cast<uint32_t>(byte_size)), - m_opcode(), - m_addr(addr), - m_enabled(0), - m_hw_preferred(hardware), - m_is_watchpoint(0), - m_watch_read(0), - m_watch_write(0), - m_hw_index(INVALID_NUB_HW_INDEX) -{ -} - -DNBBreakpoint::~DNBBreakpoint() -{ -} - -void -DNBBreakpoint::Dump() const -{ - if (IsBreakpoint()) - { - DNBLog ("DNBBreakpoint addr = 0x%llx state = %s type = %s breakpoint hw_index = %i", - (uint64_t)m_addr, - m_enabled ? "enabled " : "disabled", - IsHardware() ? "hardware" : "software", - GetHardwareIndex()); - } - else - { - DNBLog ("DNBBreakpoint addr = 0x%llx size = %llu state = %s type = %s watchpoint (%s%s) hw_index = %i", - (uint64_t)m_addr, - (uint64_t)m_byte_size, - m_enabled ? "enabled " : "disabled", - IsHardware() ? "hardware" : "software", - m_watch_read ? "r" : "", - m_watch_write ? "w" : "", - GetHardwareIndex()); - } -} - -#pragma mark -- DNBBreakpointList - -DNBBreakpointList::DNBBreakpointList() -{ -} -DNBBreakpointList::~DNBBreakpointList() -{ -} - - -DNBBreakpoint * -DNBBreakpointList::Add(nub_addr_t addr, nub_size_t length, bool hardware) -{ - m_breakpoints.insert(std::make_pair(addr, DNBBreakpoint(addr, length, hardware))); - iterator pos = m_breakpoints.find (addr); +#pragma mark-- DNBBreakpoint +DNBBreakpoint::DNBBreakpoint(nub_addr_t addr, nub_size_t byte_size, + bool hardware) + : m_retain_count(1), m_byte_size(static_cast<uint32_t>(byte_size)), + m_opcode(), m_addr(addr), m_enabled(0), m_hw_preferred(hardware), + m_is_watchpoint(0), m_watch_read(0), m_watch_write(0), + m_hw_index(INVALID_NUB_HW_INDEX) {} + +DNBBreakpoint::~DNBBreakpoint() {} + +void DNBBreakpoint::Dump() const { + if (IsBreakpoint()) { + DNBLog("DNBBreakpoint addr = 0x%llx state = %s type = %s breakpoint " + "hw_index = %i", + (uint64_t)m_addr, m_enabled ? "enabled " : "disabled", + IsHardware() ? "hardware" : "software", GetHardwareIndex()); + } else { + DNBLog("DNBBreakpoint addr = 0x%llx size = %llu state = %s type = %s " + "watchpoint (%s%s) hw_index = %i", + (uint64_t)m_addr, (uint64_t)m_byte_size, + m_enabled ? "enabled " : "disabled", + IsHardware() ? "hardware" : "software", m_watch_read ? "r" : "", + m_watch_write ? "w" : "", GetHardwareIndex()); + } +} + +#pragma mark-- DNBBreakpointList + +DNBBreakpointList::DNBBreakpointList() {} + +DNBBreakpointList::~DNBBreakpointList() {} + +DNBBreakpoint *DNBBreakpointList::Add(nub_addr_t addr, nub_size_t length, + bool hardware) { + m_breakpoints.insert( + std::make_pair(addr, DNBBreakpoint(addr, length, hardware))); + iterator pos = m_breakpoints.find(addr); + return &pos->second; +} + +bool DNBBreakpointList::Remove(nub_addr_t addr) { + iterator pos = m_breakpoints.find(addr); + if (pos != m_breakpoints.end()) { + m_breakpoints.erase(pos); + return true; + } + return false; +} + +DNBBreakpoint *DNBBreakpointList::FindByAddress(nub_addr_t addr) { + iterator pos = m_breakpoints.find(addr); + if (pos != m_breakpoints.end()) return &pos->second; -} -bool -DNBBreakpointList::Remove (nub_addr_t addr) -{ - iterator pos = m_breakpoints.find(addr); - if (pos != m_breakpoints.end()) - { - m_breakpoints.erase(pos); - return true; - } - return false; + return NULL; } -DNBBreakpoint * -DNBBreakpointList::FindByAddress (nub_addr_t addr) -{ - iterator pos = m_breakpoints.find(addr); - if (pos != m_breakpoints.end()) - return &pos->second; - - return NULL; -} +const DNBBreakpoint *DNBBreakpointList::FindByAddress(nub_addr_t addr) const { + const_iterator pos = m_breakpoints.find(addr); + if (pos != m_breakpoints.end()) + return &pos->second; -const DNBBreakpoint * -DNBBreakpointList::FindByAddress (nub_addr_t addr) const -{ - const_iterator pos = m_breakpoints.find(addr); - if (pos != m_breakpoints.end()) - return &pos->second; - - return NULL; + return NULL; } // Finds the next breakpoint at an address greater than or equal to "addr" -size_t -DNBBreakpointList::FindBreakpointsThatOverlapRange (nub_addr_t addr, - nub_addr_t size, - std::vector<DNBBreakpoint *> &bps) -{ - bps.clear(); - iterator end = m_breakpoints.end(); - // Find the first breakpoint with an address >= to "addr" - iterator pos = m_breakpoints.lower_bound(addr); - if (pos != end) - { - if (pos != m_breakpoints.begin()) - { - // Watch out for a breakpoint at an address less than "addr" that might still overlap - iterator prev_pos = pos; - --prev_pos; - if (prev_pos->second.IntersectsRange (addr, size, NULL, NULL, NULL)) - bps.push_back (&pos->second); - - } - - while (pos != end) - { - // When we hit a breakpoint whose start address is greater than "addr + size" we are done. - // Do the math in a way that doesn't risk unsigned overflow with bad input. - if ((pos->second.Address() - addr) >= size) - break; - - // Check if this breakpoint overlaps, and if it does, add it to the list - if (pos->second.IntersectsRange (addr, size, NULL, NULL, NULL)) - { - bps.push_back (&pos->second); - ++pos; - } - } +size_t DNBBreakpointList::FindBreakpointsThatOverlapRange( + nub_addr_t addr, nub_addr_t size, std::vector<DNBBreakpoint *> &bps) { + bps.clear(); + iterator end = m_breakpoints.end(); + // Find the first breakpoint with an address >= to "addr" + iterator pos = m_breakpoints.lower_bound(addr); + if (pos != end) { + if (pos != m_breakpoints.begin()) { + // Watch out for a breakpoint at an address less than "addr" that might + // still overlap + iterator prev_pos = pos; + --prev_pos; + if (prev_pos->second.IntersectsRange(addr, size, NULL, NULL, NULL)) + bps.push_back(&pos->second); } - return bps.size(); -} -void -DNBBreakpointList::Dump() const -{ - const_iterator pos; - const_iterator end = m_breakpoints.end(); - for (pos = m_breakpoints.begin(); pos != end; ++pos) - pos->second.Dump(); -} - -void -DNBBreakpointList::DisableAll () -{ - iterator pos, end = m_breakpoints.end(); - for (pos = m_breakpoints.begin(); pos != end; ++pos) - pos->second.SetEnabled(false); -} - - -void -DNBBreakpointList::RemoveTrapsFromBuffer (nub_addr_t addr, nub_size_t size, void *p) const -{ - uint8_t *buf = (uint8_t *)p; - const_iterator end = m_breakpoints.end(); - const_iterator pos = m_breakpoints.lower_bound(addr); - while (pos != end && (pos->first < (addr + size))) - { - nub_addr_t intersect_addr; - nub_size_t intersect_size; - nub_size_t opcode_offset; - const DNBBreakpoint &bp = pos->second; - if (bp.IntersectsRange(addr, size, &intersect_addr, &intersect_size, &opcode_offset)) - { - assert(addr <= intersect_addr && intersect_addr < addr + size); - assert(addr < intersect_addr + intersect_size && intersect_addr + intersect_size <= addr + size); - assert(opcode_offset + intersect_size <= bp.ByteSize()); - nub_size_t buf_offset = intersect_addr - addr; - ::memcpy(buf + buf_offset, bp.SavedOpcodeBytes() + opcode_offset, intersect_size); - } + while (pos != end) { + // When we hit a breakpoint whose start address is greater than "addr + + // size" we are done. + // Do the math in a way that doesn't risk unsigned overflow with bad + // input. + if ((pos->second.Address() - addr) >= size) + break; + + // Check if this breakpoint overlaps, and if it does, add it to the list + if (pos->second.IntersectsRange(addr, size, NULL, NULL, NULL)) { + bps.push_back(&pos->second); ++pos; + } + } + } + return bps.size(); +} + +void DNBBreakpointList::Dump() const { + const_iterator pos; + const_iterator end = m_breakpoints.end(); + for (pos = m_breakpoints.begin(); pos != end; ++pos) + pos->second.Dump(); +} + +void DNBBreakpointList::DisableAll() { + iterator pos, end = m_breakpoints.end(); + for (pos = m_breakpoints.begin(); pos != end; ++pos) + pos->second.SetEnabled(false); +} + +void DNBBreakpointList::RemoveTrapsFromBuffer(nub_addr_t addr, nub_size_t size, + void *p) const { + uint8_t *buf = (uint8_t *)p; + const_iterator end = m_breakpoints.end(); + const_iterator pos = m_breakpoints.lower_bound(addr); + while (pos != end && (pos->first < (addr + size))) { + nub_addr_t intersect_addr; + nub_size_t intersect_size; + nub_size_t opcode_offset; + const DNBBreakpoint &bp = pos->second; + if (bp.IntersectsRange(addr, size, &intersect_addr, &intersect_size, + &opcode_offset)) { + assert(addr <= intersect_addr && intersect_addr < addr + size); + assert(addr < intersect_addr + intersect_size && + intersect_addr + intersect_size <= addr + size); + assert(opcode_offset + intersect_size <= bp.ByteSize()); + nub_size_t buf_offset = intersect_addr - addr; + ::memcpy(buf + buf_offset, bp.SavedOpcodeBytes() + opcode_offset, + intersect_size); } + ++pos; + } } -void -DNBBreakpointList::DisableAllBreakpoints(MachProcess *process) -{ - iterator pos, end = m_breakpoints.end(); - for (pos = m_breakpoints.begin(); pos != end; ++pos) - process->DisableBreakpoint(pos->second.Address(), false); +void DNBBreakpointList::DisableAllBreakpoints(MachProcess *process) { + iterator pos, end = m_breakpoints.end(); + for (pos = m_breakpoints.begin(); pos != end; ++pos) + process->DisableBreakpoint(pos->second.Address(), false); } -void -DNBBreakpointList::DisableAllWatchpoints(MachProcess *process) -{ - iterator pos, end = m_breakpoints.end(); - for (pos = m_breakpoints.begin(); pos != end; ++pos) - process->DisableWatchpoint(pos->second.Address(), false); +void DNBBreakpointList::DisableAllWatchpoints(MachProcess *process) { + iterator pos, end = m_breakpoints.end(); + for (pos = m_breakpoints.begin(); pos != end; ++pos) + process->DisableWatchpoint(pos->second.Address(), false); } -void -DNBBreakpointList::RemoveDisabled() -{ - iterator pos = m_breakpoints.begin(); - while (pos != m_breakpoints.end()) - { - if (!pos->second.IsEnabled()) - pos = m_breakpoints.erase(pos); - else - ++pos; - } +void DNBBreakpointList::RemoveDisabled() { + iterator pos = m_breakpoints.begin(); + while (pos != m_breakpoints.end()) { + if (!pos->second.IsEnabled()) + pos = m_breakpoints.erase(pos); + else + ++pos; + } } |