]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - source/Breakpoint/BreakpointResolverAddress.cpp
Vendor import of lldb release_39 branch r276489:
[FreeBSD/FreeBSD.git] / source / Breakpoint / BreakpointResolverAddress.cpp
1 //===-- BreakpointResolverAddress.cpp ---------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include "lldb/Breakpoint/BreakpointResolverAddress.h"
11
12 // C Includes
13 // C++ Includes
14 // Other libraries and framework includes
15 // Project includes
16
17 #include "lldb/Breakpoint/BreakpointLocation.h"
18 #include "lldb/Core/Log.h"
19 #include "lldb/Core/Module.h"
20 #include "lldb/Core/StreamString.h"
21 #include "lldb/Target/Process.h"
22 #include "lldb/Target/Target.h"
23
24 using namespace lldb;
25 using namespace lldb_private;
26
27 //----------------------------------------------------------------------
28 // BreakpointResolverAddress:
29 //----------------------------------------------------------------------
30 BreakpointResolverAddress::BreakpointResolverAddress
31 (
32     Breakpoint *bkpt,
33     const Address &addr,
34     const FileSpec &module_spec
35 ) :
36     BreakpointResolver (bkpt, BreakpointResolver::AddressResolver),
37     m_addr (addr),
38     m_resolved_addr(LLDB_INVALID_ADDRESS),
39     m_module_filespec(module_spec)
40 {
41 }
42
43 BreakpointResolverAddress::BreakpointResolverAddress
44 (
45     Breakpoint *bkpt,
46     const Address &addr
47 ) :
48     BreakpointResolver (bkpt, BreakpointResolver::AddressResolver),
49     m_addr (addr),
50     m_resolved_addr(LLDB_INVALID_ADDRESS),
51     m_module_filespec()
52 {
53 }
54
55 BreakpointResolverAddress::~BreakpointResolverAddress ()
56 {
57
58 }
59
60 void
61 BreakpointResolverAddress::ResolveBreakpoint (SearchFilter &filter)
62 {
63     // If the address is not section relative, then we should not try to re-resolve it, it is just some
64     // random address and we wouldn't know what to do on reload.  But if it is section relative, we need to
65     // re-resolve it since the section it's in may have shifted on re-run.
66     bool re_resolve = false;
67     if (m_addr.GetSection() || m_module_filespec)
68         re_resolve = true;
69     else if (m_breakpoint->GetNumLocations() == 0)
70         re_resolve = true;
71     
72     if (re_resolve)
73         BreakpointResolver::ResolveBreakpoint(filter);
74 }
75
76 void
77 BreakpointResolverAddress::ResolveBreakpointInModules
78 (
79     SearchFilter &filter,
80     ModuleList &modules
81 )
82 {
83     // See comment in ResolveBreakpoint.
84     bool re_resolve = false;
85     if (m_addr.GetSection())
86         re_resolve = true;
87     else if (m_breakpoint->GetNumLocations() == 0)
88         re_resolve = true;
89     
90     if (re_resolve)
91         BreakpointResolver::ResolveBreakpointInModules (filter, modules);
92 }
93
94 Searcher::CallbackReturn
95 BreakpointResolverAddress::SearchCallback
96 (
97     SearchFilter &filter,
98     SymbolContext &context,
99     Address *addr,
100     bool containing
101 )
102 {
103     assert (m_breakpoint != NULL);
104
105     if (filter.AddressPasses (m_addr))
106     {
107         if (m_breakpoint->GetNumLocations() == 0)
108         {
109             // If the address is just an offset, and we're given a module, see if we can find the appropriate module
110             // loaded in the binary, and fix up m_addr to use that.
111             if (!m_addr.IsSectionOffset() && m_module_filespec)
112             {
113                 Target &target = m_breakpoint->GetTarget();
114                 ModuleSpec module_spec(m_module_filespec);
115                 ModuleSP module_sp = target.GetImages().FindFirstModule(module_spec);
116                 if (module_sp)
117                 {
118                     Address tmp_address;
119                     if (module_sp->ResolveFileAddress(m_addr.GetOffset(), tmp_address))
120                         m_addr = tmp_address;
121                 }
122             }
123             
124             m_resolved_addr = m_addr.GetLoadAddress(&m_breakpoint->GetTarget());
125             BreakpointLocationSP bp_loc_sp(AddLocation(m_addr));
126             if (bp_loc_sp && !m_breakpoint->IsInternal())
127             {
128                     StreamString s;
129                     bp_loc_sp->GetDescription(&s, lldb::eDescriptionLevelVerbose);
130                     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS));
131                     if (log)
132                         log->Printf ("Added location: %s\n", s.GetData());
133             }
134         }
135         else
136         {
137             BreakpointLocationSP loc_sp = m_breakpoint->GetLocationAtIndex(0);
138             lldb::addr_t cur_load_location = m_addr.GetLoadAddress(&m_breakpoint->GetTarget());
139             if (cur_load_location != m_resolved_addr)
140             {
141                 m_resolved_addr = cur_load_location;
142                 loc_sp->ClearBreakpointSite();
143                 loc_sp->ResolveBreakpointSite();
144             }
145         }
146     }
147     return Searcher::eCallbackReturnStop;
148 }
149
150 Searcher::Depth
151 BreakpointResolverAddress::GetDepth()
152 {
153     return Searcher::eDepthTarget;
154 }
155
156 void
157 BreakpointResolverAddress::GetDescription (Stream *s)
158 {
159     s->PutCString ("address = ");
160     m_addr.Dump(s, m_breakpoint->GetTarget().GetProcessSP().get(), Address::DumpStyleModuleWithFileAddress, Address::DumpStyleLoadAddress);
161 }
162
163 void
164 BreakpointResolverAddress::Dump (Stream *s) const
165 {
166
167 }
168
169 lldb::BreakpointResolverSP
170 BreakpointResolverAddress::CopyForBreakpoint (Breakpoint &breakpoint)
171 {
172     lldb::BreakpointResolverSP ret_sp(new BreakpointResolverAddress(&breakpoint, m_addr));
173     return ret_sp;
174 }
175