]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/Breakpoint/BreakpointResolverAddress.cpp
Upgrade Unbound to 1.6.1. More to follow.
[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);
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
104   // re-resolve it, it is just some
105   // random address and we wouldn't know what to do on reload.  But if it is
106   // section relative, we need to
107   // re-resolve it since the section it's in may have shifted on re-run.
108   bool re_resolve = false;
109   if (m_addr.GetSection() || m_module_filespec)
110     re_resolve = true;
111   else if (m_breakpoint->GetNumLocations() == 0)
112     re_resolve = true;
113
114   if (re_resolve)
115     BreakpointResolver::ResolveBreakpoint(filter);
116 }
117
118 void BreakpointResolverAddress::ResolveBreakpointInModules(
119     SearchFilter &filter, ModuleList &modules) {
120   // See comment in ResolveBreakpoint.
121   bool re_resolve = false;
122   if (m_addr.GetSection())
123     re_resolve = true;
124   else if (m_breakpoint->GetNumLocations() == 0)
125     re_resolve = true;
126
127   if (re_resolve)
128     BreakpointResolver::ResolveBreakpointInModules(filter, modules);
129 }
130
131 Searcher::CallbackReturn
132 BreakpointResolverAddress::SearchCallback(SearchFilter &filter,
133                                           SymbolContext &context, Address *addr,
134                                           bool containing) {
135   assert(m_breakpoint != NULL);
136
137   if (filter.AddressPasses(m_addr)) {
138     if (m_breakpoint->GetNumLocations() == 0) {
139       // If the address is just an offset, and we're given a module, see if we
140       // can find the appropriate module
141       // loaded in the binary, and fix up m_addr to use that.
142       if (!m_addr.IsSectionOffset() && m_module_filespec) {
143         Target &target = m_breakpoint->GetTarget();
144         ModuleSpec module_spec(m_module_filespec);
145         ModuleSP module_sp = target.GetImages().FindFirstModule(module_spec);
146         if (module_sp) {
147           Address tmp_address;
148           if (module_sp->ResolveFileAddress(m_addr.GetOffset(), tmp_address))
149             m_addr = tmp_address;
150         }
151       }
152
153       m_resolved_addr = m_addr.GetLoadAddress(&m_breakpoint->GetTarget());
154       BreakpointLocationSP bp_loc_sp(AddLocation(m_addr));
155       if (bp_loc_sp && !m_breakpoint->IsInternal()) {
156         StreamString s;
157         bp_loc_sp->GetDescription(&s, lldb::eDescriptionLevelVerbose);
158         Log *log(
159             lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
160         if (log)
161           log->Printf("Added location: %s\n", s.GetData());
162       }
163     } else {
164       BreakpointLocationSP loc_sp = m_breakpoint->GetLocationAtIndex(0);
165       lldb::addr_t cur_load_location =
166           m_addr.GetLoadAddress(&m_breakpoint->GetTarget());
167       if (cur_load_location != m_resolved_addr) {
168         m_resolved_addr = cur_load_location;
169         loc_sp->ClearBreakpointSite();
170         loc_sp->ResolveBreakpointSite();
171       }
172     }
173   }
174   return Searcher::eCallbackReturnStop;
175 }
176
177 Searcher::Depth BreakpointResolverAddress::GetDepth() {
178   return Searcher::eDepthTarget;
179 }
180
181 void BreakpointResolverAddress::GetDescription(Stream *s) {
182   s->PutCString("address = ");
183   m_addr.Dump(s, m_breakpoint->GetTarget().GetProcessSP().get(),
184               Address::DumpStyleModuleWithFileAddress,
185               Address::DumpStyleLoadAddress);
186 }
187
188 void BreakpointResolverAddress::Dump(Stream *s) const {}
189
190 lldb::BreakpointResolverSP
191 BreakpointResolverAddress::CopyForBreakpoint(Breakpoint &breakpoint) {
192   lldb::BreakpointResolverSP ret_sp(
193       new BreakpointResolverAddress(&breakpoint, m_addr));
194   return ret_sp;
195 }