]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/Breakpoint/BreakpointResolverAddress.cpp
Merge clang 7.0.1 and several follow-up changes
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / 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/Module.h"
19 #include "lldb/Core/Section.h"
20 #include "lldb/Target/Process.h"
21 #include "lldb/Target/Target.h"
22 #include "lldb/Utility/Log.h"
23 #include "lldb/Utility/StreamString.h"
24
25 using namespace lldb;
26 using namespace lldb_private;
27
28 //----------------------------------------------------------------------
29 // BreakpointResolverAddress:
30 //----------------------------------------------------------------------
31 BreakpointResolverAddress::BreakpointResolverAddress(
32     Breakpoint *bkpt, const Address &addr, const FileSpec &module_spec)
33     : BreakpointResolver(bkpt, BreakpointResolver::AddressResolver),
34       m_addr(addr), m_resolved_addr(LLDB_INVALID_ADDRESS),
35       m_module_filespec(module_spec) {}
36
37 BreakpointResolverAddress::BreakpointResolverAddress(Breakpoint *bkpt,
38                                                      const Address &addr)
39     : BreakpointResolver(bkpt, BreakpointResolver::AddressResolver),
40       m_addr(addr), m_resolved_addr(LLDB_INVALID_ADDRESS), m_module_filespec() {
41 }
42
43 BreakpointResolverAddress::~BreakpointResolverAddress() {}
44
45 BreakpointResolver *BreakpointResolverAddress::CreateFromStructuredData(
46     Breakpoint *bkpt, const StructuredData::Dictionary &options_dict,
47     Status &error) {
48   llvm::StringRef module_name;
49   lldb::addr_t addr_offset;
50   FileSpec module_filespec;
51   bool success;
52
53   success = options_dict.GetValueForKeyAsInteger(
54       GetKey(OptionNames::AddressOffset), addr_offset);
55   if (!success) {
56     error.SetErrorString("BRFL::CFSD: Couldn't find address offset entry.");
57     return nullptr;
58   }
59   Address address(addr_offset);
60
61   success = options_dict.HasKey(GetKey(OptionNames::ModuleName));
62   if (success) {
63     success = options_dict.GetValueForKeyAsString(
64         GetKey(OptionNames::ModuleName), module_name);
65     if (!success) {
66       error.SetErrorString("BRA::CFSD: Couldn't read module name entry.");
67       return nullptr;
68     }
69     module_filespec.SetFile(module_name, false, FileSpec::Style::native);
70   }
71   return new BreakpointResolverAddress(bkpt, address, module_filespec);
72 }
73
74 StructuredData::ObjectSP
75 BreakpointResolverAddress::SerializeToStructuredData() {
76   StructuredData::DictionarySP options_dict_sp(
77       new StructuredData::Dictionary());
78   SectionSP section_sp = m_addr.GetSection();
79   if (section_sp) {
80     ModuleSP module_sp = section_sp->GetModule();
81     ConstString module_name;
82     if (module_sp)
83       module_name.SetCString(module_name.GetCString());
84
85     options_dict_sp->AddStringItem(GetKey(OptionNames::ModuleName),
86                                    module_name.GetCString());
87     options_dict_sp->AddIntegerItem(GetKey(OptionNames::AddressOffset),
88                                     m_addr.GetOffset());
89   } else {
90     options_dict_sp->AddIntegerItem(GetKey(OptionNames::AddressOffset),
91                                     m_addr.GetOffset());
92     if (m_module_filespec) {
93       options_dict_sp->AddStringItem(GetKey(OptionNames::ModuleName),
94                                      m_module_filespec.GetPath());
95     }
96   }
97
98   return WrapOptionsDict(options_dict_sp);
99   return StructuredData::ObjectSP();
100 }
101
102 void BreakpointResolverAddress::ResolveBreakpoint(SearchFilter &filter) {
103   // If the address is not section relative, then we should not try to re-
104   // resolve it, it is just some random address and we wouldn't know what to do
105   // on reload.  But if it is section relative, we need to re-resolve it since
106   // the section it's in may have shifted on re-run.
107   bool re_resolve = false;
108   if (m_addr.GetSection() || m_module_filespec)
109     re_resolve = true;
110   else if (m_breakpoint->GetNumLocations() == 0)
111     re_resolve = true;
112
113   if (re_resolve)
114     BreakpointResolver::ResolveBreakpoint(filter);
115 }
116
117 void BreakpointResolverAddress::ResolveBreakpointInModules(
118     SearchFilter &filter, ModuleList &modules) {
119   // See comment in ResolveBreakpoint.
120   bool re_resolve = false;
121   if (m_addr.GetSection())
122     re_resolve = true;
123   else if (m_breakpoint->GetNumLocations() == 0)
124     re_resolve = true;
125
126   if (re_resolve)
127     BreakpointResolver::ResolveBreakpointInModules(filter, modules);
128 }
129
130 Searcher::CallbackReturn
131 BreakpointResolverAddress::SearchCallback(SearchFilter &filter,
132                                           SymbolContext &context, Address *addr,
133                                           bool containing) {
134   assert(m_breakpoint != NULL);
135
136   if (filter.AddressPasses(m_addr)) {
137     if (m_breakpoint->GetNumLocations() == 0) {
138       // If the address is just an offset, and we're given a module, see if we
139       // can find the appropriate module loaded in the binary, and fix up
140       // m_addr to use that.
141       if (!m_addr.IsSectionOffset() && m_module_filespec) {
142         Target &target = m_breakpoint->GetTarget();
143         ModuleSpec module_spec(m_module_filespec);
144         ModuleSP module_sp = target.GetImages().FindFirstModule(module_spec);
145         if (module_sp) {
146           Address tmp_address;
147           if (module_sp->ResolveFileAddress(m_addr.GetOffset(), tmp_address))
148             m_addr = tmp_address;
149         }
150       }
151
152       m_resolved_addr = m_addr.GetLoadAddress(&m_breakpoint->GetTarget());
153       BreakpointLocationSP bp_loc_sp(AddLocation(m_addr));
154       if (bp_loc_sp && !m_breakpoint->IsInternal()) {
155         StreamString s;
156         bp_loc_sp->GetDescription(&s, lldb::eDescriptionLevelVerbose);
157         Log *log(
158             lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
159         if (log)
160           log->Printf("Added location: %s\n", s.GetData());
161       }
162     } else {
163       BreakpointLocationSP loc_sp = m_breakpoint->GetLocationAtIndex(0);
164       lldb::addr_t cur_load_location =
165           m_addr.GetLoadAddress(&m_breakpoint->GetTarget());
166       if (cur_load_location != m_resolved_addr) {
167         m_resolved_addr = cur_load_location;
168         loc_sp->ClearBreakpointSite();
169         loc_sp->ResolveBreakpointSite();
170       }
171     }
172   }
173   return Searcher::eCallbackReturnStop;
174 }
175
176 Searcher::Depth BreakpointResolverAddress::GetDepth() {
177   return Searcher::eDepthTarget;
178 }
179
180 void BreakpointResolverAddress::GetDescription(Stream *s) {
181   s->PutCString("address = ");
182   m_addr.Dump(s, m_breakpoint->GetTarget().GetProcessSP().get(),
183               Address::DumpStyleModuleWithFileAddress,
184               Address::DumpStyleLoadAddress);
185 }
186
187 void BreakpointResolverAddress::Dump(Stream *s) const {}
188
189 lldb::BreakpointResolverSP
190 BreakpointResolverAddress::CopyForBreakpoint(Breakpoint &breakpoint) {
191   lldb::BreakpointResolverSP ret_sp(
192       new BreakpointResolverAddress(&breakpoint, m_addr));
193   return ret_sp;
194 }