llvm-project/lldb/source/Breakpoint/BreakpointLocationList.cpp
Greg Clayton c982c768d2 Merged Eli Friedman's linux build changes where he added Makefile files that
enabled LLVM make style building and made this compile LLDB on Mac OS X. We
can now iterate on this to make the build work on both linux and macosx.

llvm-svn: 108009
2010-07-09 20:39:50 +00:00

299 lines
7.5 KiB
C++

//===-- BreakpointLocationList.cpp ------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes
#include "lldb/Breakpoint/BreakpointLocationList.h"
#include "lldb/Breakpoint/BreakpointLocation.h"
#include "lldb/Core/ModuleList.h"
#include "lldb/Target/Target.h"
using namespace lldb;
using namespace lldb_private;
BreakpointLocationList::BreakpointLocationList() :
m_locations(),
m_address_to_location (),
m_mutex (Mutex::eMutexTypeRecursive),
m_next_id (0)
{
}
BreakpointLocationList::~BreakpointLocationList()
{
}
lldb::break_id_t
BreakpointLocationList::Add (BreakpointLocationSP &bp_loc_sp)
{
if (bp_loc_sp)
{
Mutex::Locker locker (m_mutex);
m_locations.push_back (bp_loc_sp);
m_address_to_location[bp_loc_sp->GetAddress()] = bp_loc_sp;
return bp_loc_sp->GetID();
}
return LLDB_INVALID_BREAK_ID;
}
bool
BreakpointLocationList::ShouldStop (StoppointCallbackContext *context, lldb::break_id_t break_id)
{
BreakpointLocationSP bp = FindByID (break_id);
if (bp)
{
// Let the BreakpointLocation 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->ShouldStop (context);
}
// We should stop here since this BreakpointLocation isn't valid anymore or it
// doesn't exist.
return true;
}
lldb::break_id_t
BreakpointLocationList::FindIDByAddress (Address &addr)
{
BreakpointLocationSP bp_loc_sp = FindByAddress (addr);
if (bp_loc_sp)
{
return bp_loc_sp->GetID();
}
return LLDB_INVALID_BREAK_ID;
}
bool
BreakpointLocationList::Remove (lldb::break_id_t break_id)
{
Mutex::Locker locker (m_mutex);
collection::iterator pos = GetIDIterator(break_id); // Predicate
if (pos != m_locations.end())
{
m_address_to_location.erase ((*pos)->GetAddress());
m_locations.erase(pos);
return true;
}
return false;
}
class BreakpointLocationIDMatches
{
public:
BreakpointLocationIDMatches (lldb::break_id_t break_id) :
m_break_id(break_id)
{
}
bool operator() (const BreakpointLocationSP &bp_loc_sp) const
{
return m_break_id == bp_loc_sp->GetID();
}
private:
const lldb::break_id_t m_break_id;
};
class BreakpointLocationAddressMatches
{
public:
BreakpointLocationAddressMatches (Address& addr) :
m_addr(addr)
{
}
bool operator() (const BreakpointLocationSP& bp_loc_sp) const
{
return Address::CompareFileAddress(m_addr, bp_loc_sp->GetAddress()) == 0;
}
private:
const Address &m_addr;
};
BreakpointLocationList::collection::iterator
BreakpointLocationList::GetIDIterator (lldb::break_id_t break_id)
{
Mutex::Locker locker (m_mutex);
return std::find_if (m_locations.begin(),
m_locations.end(),
BreakpointLocationIDMatches(break_id));
}
BreakpointLocationList::collection::const_iterator
BreakpointLocationList::GetIDConstIterator (lldb::break_id_t break_id) const
{
Mutex::Locker locker (m_mutex);
return std::find_if (m_locations.begin(),
m_locations.end(),
BreakpointLocationIDMatches(break_id));
}
BreakpointLocationSP
BreakpointLocationList::FindByID (lldb::break_id_t break_id)
{
Mutex::Locker locker (m_mutex);
BreakpointLocationSP stop_sp;
collection::iterator pos = GetIDIterator(break_id);
if (pos != m_locations.end())
stop_sp = *pos;
return stop_sp;
}
const BreakpointLocationSP
BreakpointLocationList::FindByID (lldb::break_id_t break_id) const
{
Mutex::Locker locker (m_mutex);
BreakpointLocationSP stop_sp;
collection::const_iterator pos = GetIDConstIterator(break_id);
if (pos != m_locations.end())
stop_sp = *pos;
return stop_sp;
}
size_t
BreakpointLocationList::FindInModule (Module *module,
BreakpointLocationCollection& bp_loc_list)
{
Mutex::Locker locker (m_mutex);
const size_t orig_size = bp_loc_list.GetSize();
collection::iterator pos, end = m_locations.end();
for (pos = m_locations.begin(); pos != end; ++pos)
{
bool seen = false;
BreakpointLocationSP break_loc = (*pos);
const Section *section = break_loc->GetAddress().GetSection();
if (section)
{
if (section->GetModule() == module)
{
if (!seen)
{
seen = true;
bp_loc_list.Add (break_loc);
}
}
}
}
return bp_loc_list.GetSize() - orig_size;
}
const BreakpointLocationSP
BreakpointLocationList::FindByAddress (Address &addr) const
{
Mutex::Locker locker (m_mutex);
BreakpointLocationSP stop_sp;
if (!m_locations.empty())
{
addr_map::const_iterator pos = m_address_to_location.find (addr);
if (pos != m_address_to_location.end())
stop_sp = pos->second;
}
return stop_sp;
}
void
BreakpointLocationList::Dump (Stream *s) const
{
s->Printf("%.*p: ", (int)sizeof(void*) * 2, this);
s->Indent();
Mutex::Locker locker (m_mutex);
s->Printf("BreakpointLocationList with %zu BreakpointLocations:\n", m_locations.size());
s->IndentMore();
collection::const_iterator pos, end = m_locations.end();
for (pos = m_locations.begin(); pos != end; ++pos)
(*pos).get()->Dump(s);
s->IndentLess();
}
BreakpointLocationSP
BreakpointLocationList::GetByIndex (uint32_t i)
{
Mutex::Locker locker (m_mutex);
BreakpointLocationSP stop_sp;
if (i < m_locations.size())
stop_sp = m_locations[i];
return stop_sp;
}
const BreakpointLocationSP
BreakpointLocationList::GetByIndex (uint32_t i) const
{
Mutex::Locker locker (m_mutex);
BreakpointLocationSP stop_sp;
if (i < m_locations.size())
stop_sp = m_locations[i];
return stop_sp;
}
void
BreakpointLocationList::ClearAllBreakpointSites ()
{
Mutex::Locker locker (m_mutex);
collection::iterator pos, end = m_locations.end();
for (pos = m_locations.begin(); pos != end; ++pos)
(*pos)->ClearBreakpointSite();
}
void
BreakpointLocationList::ResolveAllBreakpointSites ()
{
Mutex::Locker locker (m_mutex);
collection::iterator pos, end = m_locations.end();
for (pos = m_locations.begin(); pos != end; ++pos)
(*pos)->ResolveBreakpointSite();
}
size_t
BreakpointLocationList::GetNumResolvedLocations() const
{
Mutex::Locker locker (m_mutex);
size_t resolve_count = 0;
collection::const_iterator pos, end = m_locations.end();
for (pos = m_locations.begin(); pos != end; ++pos)
{
if ((*pos)->IsResolved())
++resolve_count;
}
return resolve_count;
}
break_id_t
BreakpointLocationList::GetNextID()
{
return ++m_next_id;
}
void
BreakpointLocationList::GetDescription (Stream *s, lldb::DescriptionLevel level)
{
Mutex::Locker locker (m_mutex);
collection::iterator pos, end = m_locations.end();
for (pos = m_locations.begin(); pos != end; ++pos)
{
s->Printf(" ");
(*pos)->GetDescription(s, level);
}
}