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/Log.h"
19 #include "lldb/Core/Module.h"
20 #include "lldb/Core/Section.h"
21 #include "lldb/Core/StreamString.h"
22 #include "lldb/Target/Process.h"
23 #include "lldb/Target/Target.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 std::string 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);
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
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)
111 else if (m_breakpoint->GetNumLocations() == 0)
115 BreakpointResolver::ResolveBreakpoint(filter);
118 void BreakpointResolverAddress::ResolveBreakpointInModules(
119 SearchFilter &filter, ModuleList &modules) {
120 // See comment in ResolveBreakpoint.
121 bool re_resolve = false;
122 if (m_addr.GetSection())
124 else if (m_breakpoint->GetNumLocations() == 0)
128 BreakpointResolver::ResolveBreakpointInModules(filter, modules);
131 Searcher::CallbackReturn
132 BreakpointResolverAddress::SearchCallback(SearchFilter &filter,
133 SymbolContext &context, Address *addr,
135 assert(m_breakpoint != NULL);
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);
148 if (module_sp->ResolveFileAddress(m_addr.GetOffset(), tmp_address))
149 m_addr = tmp_address;
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()) {
157 bp_loc_sp->GetDescription(&s, lldb::eDescriptionLevelVerbose);
159 lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
161 log->Printf("Added location: %s\n", s.GetData());
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();
174 return Searcher::eCallbackReturnStop;
177 Searcher::Depth BreakpointResolverAddress::GetDepth() {
178 return Searcher::eDepthTarget;
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);
188 void BreakpointResolverAddress::Dump(Stream *s) const {}
190 lldb::BreakpointResolverSP
191 BreakpointResolverAddress::CopyForBreakpoint(Breakpoint &breakpoint) {
192 lldb::BreakpointResolverSP ret_sp(
193 new BreakpointResolverAddress(&breakpoint, m_addr));