1 //===-- BreakpointResolverAddress.cpp ---------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "lldb/Breakpoint/BreakpointResolverAddress.h"
14 // Other libraries and framework includes
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"
26 using namespace lldb_private;
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) {}
37 BreakpointResolverAddress::BreakpointResolverAddress(Breakpoint *bkpt,
39 : BreakpointResolver(bkpt, BreakpointResolver::AddressResolver),
40 m_addr(addr), m_resolved_addr(LLDB_INVALID_ADDRESS), m_module_filespec() {
43 BreakpointResolverAddress::~BreakpointResolverAddress() {}
45 BreakpointResolver *BreakpointResolverAddress::CreateFromStructuredData(
46 Breakpoint *bkpt, const StructuredData::Dictionary &options_dict,
48 llvm::StringRef module_name;
49 lldb::addr_t addr_offset;
50 FileSpec module_filespec;
53 success = options_dict.GetValueForKeyAsInteger(
54 GetKey(OptionNames::AddressOffset), addr_offset);
56 error.SetErrorString("BRFL::CFSD: Couldn't find address offset entry.");
59 Address address(addr_offset);
61 success = options_dict.HasKey(GetKey(OptionNames::ModuleName));
63 success = options_dict.GetValueForKeyAsString(
64 GetKey(OptionNames::ModuleName), module_name);
66 error.SetErrorString("BRA::CFSD: Couldn't read module name entry.");
69 module_filespec.SetFile(module_name, false, FileSpec::Style::native);
71 return new BreakpointResolverAddress(bkpt, address, module_filespec);
74 StructuredData::ObjectSP
75 BreakpointResolverAddress::SerializeToStructuredData() {
76 StructuredData::DictionarySP options_dict_sp(
77 new StructuredData::Dictionary());
78 SectionSP section_sp = m_addr.GetSection();
80 ModuleSP module_sp = section_sp->GetModule();
81 ConstString module_name;
83 module_name.SetCString(module_name.GetCString());
85 options_dict_sp->AddStringItem(GetKey(OptionNames::ModuleName),
86 module_name.GetCString());
87 options_dict_sp->AddIntegerItem(GetKey(OptionNames::AddressOffset),
90 options_dict_sp->AddIntegerItem(GetKey(OptionNames::AddressOffset),
92 if (m_module_filespec) {
93 options_dict_sp->AddStringItem(GetKey(OptionNames::ModuleName),
94 m_module_filespec.GetPath());
98 return WrapOptionsDict(options_dict_sp);
99 return StructuredData::ObjectSP();
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)
110 else if (m_breakpoint->GetNumLocations() == 0)
114 BreakpointResolver::ResolveBreakpoint(filter);
117 void BreakpointResolverAddress::ResolveBreakpointInModules(
118 SearchFilter &filter, ModuleList &modules) {
119 // See comment in ResolveBreakpoint.
120 bool re_resolve = false;
121 if (m_addr.GetSection())
123 else if (m_breakpoint->GetNumLocations() == 0)
127 BreakpointResolver::ResolveBreakpointInModules(filter, modules);
130 Searcher::CallbackReturn
131 BreakpointResolverAddress::SearchCallback(SearchFilter &filter,
132 SymbolContext &context, Address *addr,
134 assert(m_breakpoint != NULL);
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);
147 if (module_sp->ResolveFileAddress(m_addr.GetOffset(), tmp_address))
148 m_addr = tmp_address;
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()) {
156 bp_loc_sp->GetDescription(&s, lldb::eDescriptionLevelVerbose);
158 lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
160 log->Printf("Added location: %s\n", s.GetData());
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();
173 return Searcher::eCallbackReturnStop;
176 Searcher::Depth BreakpointResolverAddress::GetDepth() {
177 return Searcher::eDepthTarget;
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);
187 void BreakpointResolverAddress::Dump(Stream *s) const {}
189 lldb::BreakpointResolverSP
190 BreakpointResolverAddress::CopyForBreakpoint(Breakpoint &breakpoint) {
191 lldb::BreakpointResolverSP ret_sp(
192 new BreakpointResolverAddress(&breakpoint, m_addr));