llvm-project/lldb/source/Breakpoint/BreakpointResolverAddress.cpp

176 lines
5.2 KiB
C++

//===-- BreakpointResolverAddress.cpp ---------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "lldb/Breakpoint/BreakpointResolverAddress.h"
// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes
#include "lldb/Breakpoint/BreakpointLocation.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/StreamString.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
using namespace lldb;
using namespace lldb_private;
//----------------------------------------------------------------------
// BreakpointResolverAddress:
//----------------------------------------------------------------------
BreakpointResolverAddress::BreakpointResolverAddress
(
Breakpoint *bkpt,
const Address &addr,
const FileSpec &module_spec
) :
BreakpointResolver (bkpt, BreakpointResolver::AddressResolver),
m_addr (addr),
m_resolved_addr(LLDB_INVALID_ADDRESS),
m_module_filespec(module_spec)
{
}
BreakpointResolverAddress::BreakpointResolverAddress
(
Breakpoint *bkpt,
const Address &addr
) :
BreakpointResolver (bkpt, BreakpointResolver::AddressResolver),
m_addr (addr),
m_resolved_addr(LLDB_INVALID_ADDRESS),
m_module_filespec()
{
}
BreakpointResolverAddress::~BreakpointResolverAddress ()
{
}
void
BreakpointResolverAddress::ResolveBreakpoint (SearchFilter &filter)
{
// If the address is not section relative, then we should not try to re-resolve it, it is just some
// random address and we wouldn't know what to do on reload. But if it is section relative, we need to
// re-resolve it since the section it's in may have shifted on re-run.
bool re_resolve = false;
if (m_addr.GetSection() || m_module_filespec)
re_resolve = true;
else if (m_breakpoint->GetNumLocations() == 0)
re_resolve = true;
if (re_resolve)
BreakpointResolver::ResolveBreakpoint(filter);
}
void
BreakpointResolverAddress::ResolveBreakpointInModules
(
SearchFilter &filter,
ModuleList &modules
)
{
// See comment in ResolveBreakpoint.
bool re_resolve = false;
if (m_addr.GetSection())
re_resolve = true;
else if (m_breakpoint->GetNumLocations() == 0)
re_resolve = true;
if (re_resolve)
BreakpointResolver::ResolveBreakpointInModules (filter, modules);
}
Searcher::CallbackReturn
BreakpointResolverAddress::SearchCallback
(
SearchFilter &filter,
SymbolContext &context,
Address *addr,
bool containing
)
{
assert (m_breakpoint != NULL);
if (filter.AddressPasses (m_addr))
{
if (m_breakpoint->GetNumLocations() == 0)
{
// If the address is just an offset, and we're given a module, see if we can find the appropriate module
// loaded in the binary, and fix up m_addr to use that.
if (!m_addr.IsSectionOffset() && m_module_filespec)
{
Target &target = m_breakpoint->GetTarget();
ModuleSpec module_spec(m_module_filespec);
ModuleSP module_sp = target.GetImages().FindFirstModule(module_spec);
if (module_sp)
{
Address tmp_address;
if (module_sp->ResolveFileAddress(m_addr.GetOffset(), tmp_address))
m_addr = tmp_address;
}
}
m_resolved_addr = m_addr.GetLoadAddress(&m_breakpoint->GetTarget());
BreakpointLocationSP bp_loc_sp(AddLocation(m_addr));
if (bp_loc_sp && !m_breakpoint->IsInternal())
{
StreamString s;
bp_loc_sp->GetDescription(&s, lldb::eDescriptionLevelVerbose);
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS));
if (log)
log->Printf ("Added location: %s\n", s.GetData());
}
}
else
{
BreakpointLocationSP loc_sp = m_breakpoint->GetLocationAtIndex(0);
lldb::addr_t cur_load_location = m_addr.GetLoadAddress(&m_breakpoint->GetTarget());
if (cur_load_location != m_resolved_addr)
{
m_resolved_addr = cur_load_location;
loc_sp->ClearBreakpointSite();
loc_sp->ResolveBreakpointSite();
}
}
}
return Searcher::eCallbackReturnStop;
}
Searcher::Depth
BreakpointResolverAddress::GetDepth()
{
return Searcher::eDepthTarget;
}
void
BreakpointResolverAddress::GetDescription (Stream *s)
{
s->PutCString ("address = ");
m_addr.Dump(s, m_breakpoint->GetTarget().GetProcessSP().get(), Address::DumpStyleModuleWithFileAddress, Address::DumpStyleLoadAddress);
}
void
BreakpointResolverAddress::Dump (Stream *s) const
{
}
lldb::BreakpointResolverSP
BreakpointResolverAddress::CopyForBreakpoint (Breakpoint &breakpoint)
{
lldb::BreakpointResolverSP ret_sp(new BreakpointResolverAddress(&breakpoint, m_addr));
return ret_sp;
}