Initial checkin of lldb code from internal Apple repo.

llvm-svn: 105619
diff --git a/lldb/tools/debugserver/source/DNBBreakpoint.cpp b/lldb/tools/debugserver/source/DNBBreakpoint.cpp
new file mode 100644
index 0000000..837f532
--- /dev/null
+++ b/lldb/tools/debugserver/source/DNBBreakpoint.cpp
@@ -0,0 +1,303 @@
+//===-- DNBBreakpoint.cpp ---------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  Created by Greg Clayton on 6/29/07.
+//
+//===----------------------------------------------------------------------===//
+
+#include "DNBBreakpoint.h"
+#include <algorithm>
+#include "DNBLog.h"
+
+
+#pragma mark -- DNBBreakpoint
+DNBBreakpoint::DNBBreakpoint(nub_addr_t addr, nub_size_t byte_size, nub_thread_t tid, bool hardware) :
+    m_breakID(GetNextID()),
+    m_tid(tid),
+    m_byte_size(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),
+    m_hit_count(0),
+    m_ignore_count(0),
+    m_callback(NULL),
+    m_callback_baton(NULL)
+{
+}
+
+DNBBreakpoint::~DNBBreakpoint()
+{
+}
+
+nub_break_t
+DNBBreakpoint::GetNextID()
+{
+    static uint32_t g_nextBreakID = 0;
+    return ++g_nextBreakID;
+}
+
+void
+DNBBreakpoint::SetCallback(DNBCallbackBreakpointHit callback, void *callback_baton)
+{
+    m_callback = callback;
+    m_callback_baton = callback_baton;
+}
+
+
+// RETURNS - true if we should stop at this breakpoint, false if we
+// should continue.
+
+bool
+DNBBreakpoint::BreakpointHit(nub_process_t pid, nub_thread_t tid)
+{
+    m_hit_count++;
+
+    if (m_hit_count > m_ignore_count)
+    {
+        if (m_callback)
+            return m_callback(pid, tid, GetID(), m_callback_baton);
+        return true;
+    }
+    return false;
+}
+
+void
+DNBBreakpoint::Dump() const
+{
+    if (IsBreakpoint())
+    {
+        DNBLog("DNBBreakpoint %u: tid = %4.4x  addr = %8.8p  state = %s  type = %s breakpoint  hw_index = %i  hit_count = %-4u  ignore_count = %-4u  callback = %8.8p baton = %8.8p",
+            m_breakID,
+            m_tid,
+            m_addr,
+            m_enabled ? "enabled " : "disabled",
+            IsHardware() ? "hardware" : "software",
+            GetHardwareIndex(),
+            GetHitCount(),
+            GetIgnoreCount(),
+            m_callback,
+            m_callback_baton);
+    }
+    else
+    {
+        DNBLog("DNBBreakpoint %u: tid = %4.4x  addr = %8.8p  size = %u  state = %s  type = %s watchpoint (%s%s)  hw_index = %i  hit_count = %-4u  ignore_count = %-4u  callback = %8.8p baton = %8.8p",
+            m_breakID,
+            m_tid,
+            m_addr,
+            m_byte_size,
+            m_enabled ? "enabled " : "disabled",
+            IsHardware() ? "hardware" : "software",
+            m_watch_read ? "r" : "",
+            m_watch_write ? "w" : "",
+            GetHardwareIndex(),
+            GetHitCount(),
+            GetIgnoreCount(),
+            m_callback,
+            m_callback_baton);
+    }
+}
+
+#pragma mark -- DNBBreakpointList
+
+DNBBreakpointList::DNBBreakpointList()
+{
+}
+
+DNBBreakpointList::~DNBBreakpointList()
+{
+}
+
+
+nub_break_t
+DNBBreakpointList::Add(const DNBBreakpoint& bp)
+{
+    m_breakpoints.push_back(bp);
+    return m_breakpoints.back().GetID();
+}
+
+bool
+DNBBreakpointList::ShouldStop(nub_process_t pid, nub_thread_t tid, nub_break_t breakID)
+{
+    DNBBreakpoint *bp = FindByID (breakID);
+    if (bp)
+    {
+        // Let the breakpoint decide if it should stop here (could not have
+        // reached it's target hit count yet, or it could have a callback
+        // that decided it shouldn't stop (shared library loads/unloads).
+        return bp->BreakpointHit(pid, tid);
+    }
+    // We should stop here since this breakpoint isn't valid anymore or it
+    // doesn't exist.
+    return true;
+}
+
+nub_break_t
+DNBBreakpointList::FindIDByAddress (nub_addr_t addr)
+{
+    DNBBreakpoint *bp = FindByAddress (addr);
+    if (bp)
+    {
+        DNBLogThreadedIf(LOG_BREAKPOINTS, "DNBBreakpointList::%s ( addr = 0x%8.8llx ) => %u", __FUNCTION__, (uint64_t)addr, bp->GetID());
+        return bp->GetID();
+    }
+    DNBLogThreadedIf(LOG_BREAKPOINTS, "DNBBreakpointList::%s ( addr = 0x%8.8llx ) => NONE", __FUNCTION__, (uint64_t)addr);
+    return INVALID_NUB_BREAK_ID;
+}
+
+bool
+DNBBreakpointList::Remove (nub_break_t breakID)
+{
+    iterator pos = GetBreakIDIterator(breakID);    // Predicate
+    if (pos != m_breakpoints.end())
+    {
+        m_breakpoints.erase(pos);
+        return true;
+    }
+    return false;
+}
+
+
+class BreakpointIDMatches
+{
+public:
+    BreakpointIDMatches (nub_break_t breakID) : m_breakID(breakID) {}
+    bool operator() (const DNBBreakpoint& bp) const
+    {
+        return m_breakID == bp.GetID();
+    }
+ private:
+   const nub_break_t m_breakID;
+};
+
+class BreakpointAddressMatches
+{
+public:
+    BreakpointAddressMatches (nub_addr_t addr) : m_addr(addr) {}
+    bool operator() (const DNBBreakpoint& bp) const
+    {
+        return m_addr == bp.Address();
+    }
+ private:
+   const nub_addr_t m_addr;
+};
+
+DNBBreakpointList::iterator
+DNBBreakpointList::GetBreakIDIterator (nub_break_t breakID)
+{
+    return std::find_if(m_breakpoints.begin(), m_breakpoints.end(), // Search full range
+                        BreakpointIDMatches(breakID));              // Predicate
+}
+
+DNBBreakpointList::const_iterator
+DNBBreakpointList::GetBreakIDConstIterator (nub_break_t breakID) const
+{
+    return std::find_if(m_breakpoints.begin(), m_breakpoints.end(), // Search full range
+                        BreakpointIDMatches(breakID));              // Predicate
+}
+
+DNBBreakpoint *
+DNBBreakpointList::FindByID (nub_break_t breakID)
+{
+    iterator pos = GetBreakIDIterator(breakID);
+    if (pos != m_breakpoints.end())
+        return &(*pos);
+
+    return NULL;
+}
+
+const DNBBreakpoint *
+DNBBreakpointList::FindByID (nub_break_t breakID) const
+{
+    const_iterator pos = GetBreakIDConstIterator(breakID);
+    if (pos != m_breakpoints.end())
+        return &(*pos);
+
+    return NULL;
+}
+
+DNBBreakpoint *
+DNBBreakpointList::FindByAddress (nub_addr_t addr)
+{
+    iterator end = m_breakpoints.end();
+    iterator pos = std::find_if(m_breakpoints.begin(), end,             // Search full range
+                                BreakpointAddressMatches(addr));        // Predicate
+    if (pos != end)
+        return &(*pos);
+
+    return NULL;
+}
+
+const DNBBreakpoint *
+DNBBreakpointList::FindByAddress (nub_addr_t addr) const
+{
+    const_iterator end = m_breakpoints.end();
+    const_iterator pos = std::find_if(m_breakpoints.begin(), end,       // Search full range
+                                      BreakpointAddressMatches(addr));  // Predicate
+    if (pos != end)
+        return &(*pos);
+
+    return NULL;
+}
+
+bool
+DNBBreakpointList::SetCallback(nub_break_t breakID, DNBCallbackBreakpointHit callback, void *callback_baton)
+{
+    DNBBreakpoint *bp = FindByID (breakID);
+    if (bp)
+    {
+        bp->SetCallback(callback, callback_baton);
+        return true;
+    }
+    return false;
+}
+
+
+void
+DNBBreakpointList::Dump() const
+{
+    const_iterator pos;
+    const_iterator end = m_breakpoints.end();
+    for (pos = m_breakpoints.begin(); pos != end; ++pos)
+        (*pos).Dump();
+}
+
+
+DNBBreakpoint *
+DNBBreakpointList::GetByIndex (uint32_t i)
+{
+    iterator end = m_breakpoints.end();
+    iterator pos;
+    uint32_t curr_i = 0;
+    for (pos = m_breakpoints.begin(), curr_i = 0; pos != end; ++pos, ++curr_i)
+    {
+        if (curr_i == i)
+            return &(*pos);
+    }
+    return NULL;
+}
+
+const DNBBreakpoint *
+DNBBreakpointList::GetByIndex (uint32_t i) const
+{
+    const_iterator end = m_breakpoints.end();
+    const_iterator pos;
+    uint32_t curr_i = 0;
+    for (pos = m_breakpoints.begin(), curr_i = 0; pos != end; ++pos, ++curr_i)
+    {
+        if (curr_i == i)
+            return &(*pos);
+    }
+    return NULL;
+}
+