1 //===-- BreakpointResolverAddress.cpp -------------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include "lldb/Breakpoint/BreakpointResolverAddress.h"
10 #include "lldb/Breakpoint/BreakpointLocation.h"
11 #include "lldb/Core/Module.h"
12 #include "lldb/Core/Section.h"
13 #include "lldb/Target/Process.h"
14 #include "lldb/Target/Target.h"
15 #include "lldb/Utility/LLDBLog.h"
16 #include "lldb/Utility/StreamString.h"
19 using namespace lldb_private
;
21 // BreakpointResolverAddress:
22 BreakpointResolverAddress::BreakpointResolverAddress(
23 const BreakpointSP
&bkpt
, const Address
&addr
, const FileSpec
&module_spec
)
24 : BreakpointResolver(bkpt
, BreakpointResolver::AddressResolver
),
25 m_addr(addr
), m_resolved_addr(LLDB_INVALID_ADDRESS
),
26 m_module_filespec(module_spec
) {}
28 BreakpointResolverAddress::BreakpointResolverAddress(const BreakpointSP
&bkpt
,
30 : BreakpointResolver(bkpt
, BreakpointResolver::AddressResolver
),
31 m_addr(addr
), m_resolved_addr(LLDB_INVALID_ADDRESS
) {}
33 BreakpointResolver
*BreakpointResolverAddress::CreateFromStructuredData(
34 const BreakpointSP
&bkpt
, const StructuredData::Dictionary
&options_dict
,
36 llvm::StringRef module_name
;
37 lldb::offset_t addr_offset
;
38 FileSpec module_filespec
;
41 success
= options_dict
.GetValueForKeyAsInteger(
42 GetKey(OptionNames::AddressOffset
), addr_offset
);
44 error
.SetErrorString("BRFL::CFSD: Couldn't find address offset entry.");
47 Address
address(addr_offset
);
49 success
= options_dict
.HasKey(GetKey(OptionNames::ModuleName
));
51 success
= options_dict
.GetValueForKeyAsString(
52 GetKey(OptionNames::ModuleName
), module_name
);
54 error
.SetErrorString("BRA::CFSD: Couldn't read module name entry.");
57 module_filespec
.SetFile(module_name
, FileSpec::Style::native
);
59 return new BreakpointResolverAddress(bkpt
, address
, module_filespec
);
62 StructuredData::ObjectSP
63 BreakpointResolverAddress::SerializeToStructuredData() {
64 StructuredData::DictionarySP
options_dict_sp(
65 new StructuredData::Dictionary());
66 SectionSP section_sp
= m_addr
.GetSection();
68 ModuleSP module_sp
= section_sp
->GetModule();
69 ConstString module_name
;
71 module_name
.SetCString(module_name
.GetCString());
73 options_dict_sp
->AddStringItem(GetKey(OptionNames::ModuleName
),
74 module_name
.GetCString());
75 options_dict_sp
->AddIntegerItem(GetKey(OptionNames::AddressOffset
),
78 options_dict_sp
->AddIntegerItem(GetKey(OptionNames::AddressOffset
),
80 if (m_module_filespec
) {
81 options_dict_sp
->AddStringItem(GetKey(OptionNames::ModuleName
),
82 m_module_filespec
.GetPath());
86 return WrapOptionsDict(options_dict_sp
);
89 void BreakpointResolverAddress::ResolveBreakpoint(SearchFilter
&filter
) {
90 // If the address is not section relative, then we should not try to re-
91 // resolve it, it is just some random address and we wouldn't know what to do
92 // on reload. But if it is section relative, we need to re-resolve it since
93 // the section it's in may have shifted on re-run.
94 bool re_resolve
= false;
95 if (m_addr
.GetSection() || m_module_filespec
)
97 else if (GetBreakpoint()->GetNumLocations() == 0)
101 BreakpointResolver::ResolveBreakpoint(filter
);
104 void BreakpointResolverAddress::ResolveBreakpointInModules(
105 SearchFilter
&filter
, ModuleList
&modules
) {
106 // See comment in ResolveBreakpoint.
107 bool re_resolve
= false;
108 if (m_addr
.GetSection())
110 else if (GetBreakpoint()->GetNumLocations() == 0)
114 BreakpointResolver::ResolveBreakpointInModules(filter
, modules
);
117 Searcher::CallbackReturn
BreakpointResolverAddress::SearchCallback(
118 SearchFilter
&filter
, SymbolContext
&context
, Address
*addr
) {
119 BreakpointSP breakpoint_sp
= GetBreakpoint();
120 Breakpoint
&breakpoint
= *breakpoint_sp
;
122 if (filter
.AddressPasses(m_addr
)) {
123 if (breakpoint
.GetNumLocations() == 0) {
124 // If the address is just an offset, and we're given a module, see if we
125 // can find the appropriate module loaded in the binary, and fix up
126 // m_addr to use that.
127 if (!m_addr
.IsSectionOffset() && m_module_filespec
) {
128 Target
&target
= breakpoint
.GetTarget();
129 ModuleSpec
module_spec(m_module_filespec
);
130 ModuleSP module_sp
= target
.GetImages().FindFirstModule(module_spec
);
133 if (module_sp
->ResolveFileAddress(m_addr
.GetOffset(), tmp_address
))
134 m_addr
= tmp_address
;
138 m_resolved_addr
= m_addr
.GetLoadAddress(&breakpoint
.GetTarget());
139 BreakpointLocationSP
bp_loc_sp(AddLocation(m_addr
));
140 if (bp_loc_sp
&& !breakpoint
.IsInternal()) {
142 bp_loc_sp
->GetDescription(&s
, lldb::eDescriptionLevelVerbose
);
143 Log
*log
= GetLog(LLDBLog::Breakpoints
);
144 LLDB_LOGF(log
, "Added location: %s\n", s
.GetData());
147 BreakpointLocationSP loc_sp
= breakpoint
.GetLocationAtIndex(0);
148 lldb::addr_t cur_load_location
=
149 m_addr
.GetLoadAddress(&breakpoint
.GetTarget());
150 if (cur_load_location
!= m_resolved_addr
) {
151 m_resolved_addr
= cur_load_location
;
152 loc_sp
->ClearBreakpointSite();
153 loc_sp
->ResolveBreakpointSite();
157 return Searcher::eCallbackReturnStop
;
160 lldb::SearchDepth
BreakpointResolverAddress::GetDepth() {
161 return lldb::eSearchDepthTarget
;
164 void BreakpointResolverAddress::GetDescription(Stream
*s
) {
165 s
->PutCString("address = ");
166 m_addr
.Dump(s
, GetBreakpoint()->GetTarget().GetProcessSP().get(),
167 Address::DumpStyleModuleWithFileAddress
,
168 Address::DumpStyleLoadAddress
);
171 void BreakpointResolverAddress::Dump(Stream
*s
) const {}
173 lldb::BreakpointResolverSP
174 BreakpointResolverAddress::CopyForBreakpoint(BreakpointSP
&breakpoint
) {
175 lldb::BreakpointResolverSP
ret_sp(
176 new BreakpointResolverAddress(breakpoint
, m_addr
));