1ac7ddfbfSEd Maste //===-- BreakpointResolverAddress.cpp ---------------------------*- C++ -*-===//
2ac7ddfbfSEd Maste //
3ac7ddfbfSEd Maste //                     The LLVM Compiler Infrastructure
4ac7ddfbfSEd Maste //
5ac7ddfbfSEd Maste // This file is distributed under the University of Illinois Open Source
6ac7ddfbfSEd Maste // License. See LICENSE.TXT for details.
7ac7ddfbfSEd Maste //
8ac7ddfbfSEd Maste //===----------------------------------------------------------------------===//
9ac7ddfbfSEd Maste 
10ac7ddfbfSEd Maste #include "lldb/Breakpoint/BreakpointResolverAddress.h"
11ac7ddfbfSEd Maste 
12ac7ddfbfSEd Maste // C Includes
13ac7ddfbfSEd Maste // C++ Includes
14ac7ddfbfSEd Maste // Other libraries and framework includes
15ac7ddfbfSEd Maste // Project includes
16ac7ddfbfSEd Maste 
17ac7ddfbfSEd Maste #include "lldb/Breakpoint/BreakpointLocation.h"
18ac7ddfbfSEd Maste #include "lldb/Core/Log.h"
199f2f44ceSEd Maste #include "lldb/Core/Module.h"
20ac7ddfbfSEd Maste #include "lldb/Core/StreamString.h"
211c3bbb01SEd Maste #include "lldb/Target/Process.h"
22ac7ddfbfSEd Maste #include "lldb/Target/Target.h"
23ac7ddfbfSEd Maste 
24ac7ddfbfSEd Maste using namespace lldb;
25ac7ddfbfSEd Maste using namespace lldb_private;
26ac7ddfbfSEd Maste 
27ac7ddfbfSEd Maste //----------------------------------------------------------------------
28ac7ddfbfSEd Maste // BreakpointResolverAddress:
29ac7ddfbfSEd Maste //----------------------------------------------------------------------
30ac7ddfbfSEd Maste BreakpointResolverAddress::BreakpointResolverAddress
31ac7ddfbfSEd Maste (
32ac7ddfbfSEd Maste     Breakpoint *bkpt,
339f2f44ceSEd Maste     const Address &addr,
349f2f44ceSEd Maste     const FileSpec &module_spec
359f2f44ceSEd Maste ) :
369f2f44ceSEd Maste     BreakpointResolver (bkpt, BreakpointResolver::AddressResolver),
379f2f44ceSEd Maste     m_addr (addr),
389f2f44ceSEd Maste     m_resolved_addr(LLDB_INVALID_ADDRESS),
399f2f44ceSEd Maste     m_module_filespec(module_spec)
409f2f44ceSEd Maste {
419f2f44ceSEd Maste }
429f2f44ceSEd Maste 
439f2f44ceSEd Maste BreakpointResolverAddress::BreakpointResolverAddress
449f2f44ceSEd Maste (
459f2f44ceSEd Maste     Breakpoint *bkpt,
46ac7ddfbfSEd Maste     const Address &addr
47ac7ddfbfSEd Maste ) :
48ac7ddfbfSEd Maste     BreakpointResolver (bkpt, BreakpointResolver::AddressResolver),
499f2f44ceSEd Maste     m_addr (addr),
509f2f44ceSEd Maste     m_resolved_addr(LLDB_INVALID_ADDRESS),
519f2f44ceSEd Maste     m_module_filespec()
52ac7ddfbfSEd Maste {
53ac7ddfbfSEd Maste }
54ac7ddfbfSEd Maste 
55ac7ddfbfSEd Maste BreakpointResolverAddress::~BreakpointResolverAddress ()
56ac7ddfbfSEd Maste {
57ac7ddfbfSEd Maste 
58ac7ddfbfSEd Maste }
59ac7ddfbfSEd Maste 
60ac7ddfbfSEd Maste void
61ac7ddfbfSEd Maste BreakpointResolverAddress::ResolveBreakpoint (SearchFilter &filter)
62ac7ddfbfSEd Maste {
639f2f44ceSEd Maste     // If the address is not section relative, then we should not try to re-resolve it, it is just some
649f2f44ceSEd Maste     // random address and we wouldn't know what to do on reload.  But if it is section relative, we need to
659f2f44ceSEd Maste     // re-resolve it since the section it's in may have shifted on re-run.
669f2f44ceSEd Maste     bool re_resolve = false;
679f2f44ceSEd Maste     if (m_addr.GetSection() || m_module_filespec)
689f2f44ceSEd Maste         re_resolve = true;
699f2f44ceSEd Maste     else if (m_breakpoint->GetNumLocations() == 0)
709f2f44ceSEd Maste         re_resolve = true;
719f2f44ceSEd Maste 
729f2f44ceSEd Maste     if (re_resolve)
73ac7ddfbfSEd Maste         BreakpointResolver::ResolveBreakpoint(filter);
74ac7ddfbfSEd Maste }
75ac7ddfbfSEd Maste 
76ac7ddfbfSEd Maste void
77ac7ddfbfSEd Maste BreakpointResolverAddress::ResolveBreakpointInModules
78ac7ddfbfSEd Maste (
79ac7ddfbfSEd Maste     SearchFilter &filter,
80ac7ddfbfSEd Maste     ModuleList &modules
81ac7ddfbfSEd Maste )
82ac7ddfbfSEd Maste {
839f2f44ceSEd Maste     // See comment in ResolveBreakpoint.
849f2f44ceSEd Maste     bool re_resolve = false;
859f2f44ceSEd Maste     if (m_addr.GetSection())
869f2f44ceSEd Maste         re_resolve = true;
879f2f44ceSEd Maste     else if (m_breakpoint->GetNumLocations() == 0)
889f2f44ceSEd Maste         re_resolve = true;
899f2f44ceSEd Maste 
909f2f44ceSEd Maste     if (re_resolve)
91ac7ddfbfSEd Maste         BreakpointResolver::ResolveBreakpointInModules (filter, modules);
92ac7ddfbfSEd Maste }
93ac7ddfbfSEd Maste 
94ac7ddfbfSEd Maste Searcher::CallbackReturn
95ac7ddfbfSEd Maste BreakpointResolverAddress::SearchCallback
96ac7ddfbfSEd Maste (
97ac7ddfbfSEd Maste     SearchFilter &filter,
98ac7ddfbfSEd Maste     SymbolContext &context,
99ac7ddfbfSEd Maste     Address *addr,
100ac7ddfbfSEd Maste     bool containing
101ac7ddfbfSEd Maste )
102ac7ddfbfSEd Maste {
103ac7ddfbfSEd Maste     assert (m_breakpoint != NULL);
104ac7ddfbfSEd Maste 
105ac7ddfbfSEd Maste     if (filter.AddressPasses (m_addr))
106ac7ddfbfSEd Maste     {
1079f2f44ceSEd Maste         if (m_breakpoint->GetNumLocations() == 0)
1089f2f44ceSEd Maste         {
1099f2f44ceSEd Maste             // If the address is just an offset, and we're given a module, see if we can find the appropriate module
1109f2f44ceSEd Maste             // loaded in the binary, and fix up m_addr to use that.
1119f2f44ceSEd Maste             if (!m_addr.IsSectionOffset() && m_module_filespec)
1129f2f44ceSEd Maste             {
1139f2f44ceSEd Maste                 Target &target = m_breakpoint->GetTarget();
1149f2f44ceSEd Maste                 ModuleSpec module_spec(m_module_filespec);
1159f2f44ceSEd Maste                 ModuleSP module_sp = target.GetImages().FindFirstModule(module_spec);
1169f2f44ceSEd Maste                 if (module_sp)
1179f2f44ceSEd Maste                 {
1189f2f44ceSEd Maste                     Address tmp_address;
1199f2f44ceSEd Maste                     if (module_sp->ResolveFileAddress(m_addr.GetOffset(), tmp_address))
1209f2f44ceSEd Maste                         m_addr = tmp_address;
1219f2f44ceSEd Maste                 }
1229f2f44ceSEd Maste             }
1239f2f44ceSEd Maste 
124ac7ddfbfSEd Maste             BreakpointLocationSP bp_loc_sp(m_breakpoint->AddLocation(m_addr));
1259f2f44ceSEd Maste             m_resolved_addr = m_addr.GetLoadAddress(&m_breakpoint->GetTarget());
126ac7ddfbfSEd Maste             if (bp_loc_sp && !m_breakpoint->IsInternal())
127ac7ddfbfSEd Maste             {
128ac7ddfbfSEd Maste                     StreamString s;
129ac7ddfbfSEd Maste                     bp_loc_sp->GetDescription(&s, lldb::eDescriptionLevelVerbose);
130ac7ddfbfSEd Maste                     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS));
131ac7ddfbfSEd Maste                     if (log)
132ac7ddfbfSEd Maste                         log->Printf ("Added location: %s\n", s.GetData());
133ac7ddfbfSEd Maste             }
134ac7ddfbfSEd Maste         }
1359f2f44ceSEd Maste         else
1369f2f44ceSEd Maste         {
1379f2f44ceSEd Maste             BreakpointLocationSP loc_sp = m_breakpoint->GetLocationAtIndex(0);
1389f2f44ceSEd Maste             lldb::addr_t cur_load_location = m_addr.GetLoadAddress(&m_breakpoint->GetTarget());
1399f2f44ceSEd Maste             if (cur_load_location != m_resolved_addr)
1409f2f44ceSEd Maste             {
1419f2f44ceSEd Maste                 m_resolved_addr = cur_load_location;
1429f2f44ceSEd Maste                 loc_sp->ClearBreakpointSite();
1439f2f44ceSEd Maste                 loc_sp->ResolveBreakpointSite();
1449f2f44ceSEd Maste             }
1459f2f44ceSEd Maste         }
1469f2f44ceSEd Maste     }
147ac7ddfbfSEd Maste     return Searcher::eCallbackReturnStop;
148ac7ddfbfSEd Maste }
149ac7ddfbfSEd Maste 
150ac7ddfbfSEd Maste Searcher::Depth
151ac7ddfbfSEd Maste BreakpointResolverAddress::GetDepth()
152ac7ddfbfSEd Maste {
153ac7ddfbfSEd Maste     return Searcher::eDepthTarget;
154ac7ddfbfSEd Maste }
155ac7ddfbfSEd Maste 
156ac7ddfbfSEd Maste void
157ac7ddfbfSEd Maste BreakpointResolverAddress::GetDescription (Stream *s)
158ac7ddfbfSEd Maste {
159ac7ddfbfSEd Maste     s->PutCString ("address = ");
1609f2f44ceSEd Maste     m_addr.Dump(s, m_breakpoint->GetTarget().GetProcessSP().get(), Address::DumpStyleModuleWithFileAddress, Address::DumpStyleLoadAddress);
161ac7ddfbfSEd Maste }
162ac7ddfbfSEd Maste 
163ac7ddfbfSEd Maste void
164ac7ddfbfSEd Maste BreakpointResolverAddress::Dump (Stream *s) const
165ac7ddfbfSEd Maste {
166ac7ddfbfSEd Maste 
167ac7ddfbfSEd Maste }
1687aa51b79SEd Maste 
1697aa51b79SEd Maste lldb::BreakpointResolverSP
1707aa51b79SEd Maste BreakpointResolverAddress::CopyForBreakpoint (Breakpoint &breakpoint)
1717aa51b79SEd Maste {
1727aa51b79SEd Maste     lldb::BreakpointResolverSP ret_sp(new BreakpointResolverAddress(&breakpoint, m_addr));
1737aa51b79SEd Maste     return ret_sp;
1747aa51b79SEd Maste }
1757aa51b79SEd Maste 
176