180814287SRaphael Isemann //===-- BreakpointResolverAddress.cpp -------------------------------------===//
230fdc8d8SChris Lattner //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
630fdc8d8SChris Lattner //
730fdc8d8SChris Lattner //===----------------------------------------------------------------------===//
830fdc8d8SChris Lattner
930fdc8d8SChris Lattner #include "lldb/Breakpoint/BreakpointResolverAddress.h"
1030fdc8d8SChris Lattner #include "lldb/Breakpoint/BreakpointLocation.h"
11055a08a4SJim Ingham #include "lldb/Core/Module.h"
12e14dc268SJim Ingham #include "lldb/Core/Section.h"
13fc858813SZachary Turner #include "lldb/Target/Process.h"
1430fdc8d8SChris Lattner #include "lldb/Target/Target.h"
15c34698a8SPavel Labath #include "lldb/Utility/LLDBLog.h"
16bf9a7730SZachary Turner #include "lldb/Utility/StreamString.h"
1730fdc8d8SChris Lattner
1830fdc8d8SChris Lattner using namespace lldb;
1930fdc8d8SChris Lattner using namespace lldb_private;
2030fdc8d8SChris Lattner
2130fdc8d8SChris Lattner // BreakpointResolverAddress:
BreakpointResolverAddress(const BreakpointSP & bkpt,const Address & addr,const FileSpec & module_spec)22b9c1b51eSKate Stone BreakpointResolverAddress::BreakpointResolverAddress(
236c17cc53STatyana Krasnukha const BreakpointSP &bkpt, const Address &addr, const FileSpec &module_spec)
24b9c1b51eSKate Stone : BreakpointResolver(bkpt, BreakpointResolver::AddressResolver),
25b9c1b51eSKate Stone m_addr(addr), m_resolved_addr(LLDB_INVALID_ADDRESS),
26b9c1b51eSKate Stone m_module_filespec(module_spec) {}
27b9c1b51eSKate Stone
BreakpointResolverAddress(const BreakpointSP & bkpt,const Address & addr)286c17cc53STatyana Krasnukha BreakpointResolverAddress::BreakpointResolverAddress(const BreakpointSP &bkpt,
29b9c1b51eSKate Stone const Address &addr)
30b9c1b51eSKate Stone : BreakpointResolver(bkpt, BreakpointResolver::AddressResolver),
31ee4b6cf5SKazu Hirata m_addr(addr), m_resolved_addr(LLDB_INVALID_ADDRESS) {}
32055a08a4SJim Ingham
CreateFromStructuredData(const BreakpointSP & bkpt,const StructuredData::Dictionary & options_dict,Status & error)33e14dc268SJim Ingham BreakpointResolver *BreakpointResolverAddress::CreateFromStructuredData(
346c17cc53STatyana Krasnukha const BreakpointSP &bkpt, const StructuredData::Dictionary &options_dict,
3597206d57SZachary Turner Status &error) {
362833321fSZachary Turner llvm::StringRef module_name;
37e14dc268SJim Ingham lldb::addr_t addr_offset;
38e14dc268SJim Ingham FileSpec module_filespec;
39e14dc268SJim Ingham bool success;
40e14dc268SJim Ingham
41e14dc268SJim Ingham success = options_dict.GetValueForKeyAsInteger(
42e14dc268SJim Ingham GetKey(OptionNames::AddressOffset), addr_offset);
43e14dc268SJim Ingham if (!success) {
44e14dc268SJim Ingham error.SetErrorString("BRFL::CFSD: Couldn't find address offset entry.");
45e14dc268SJim Ingham return nullptr;
46e14dc268SJim Ingham }
47e14dc268SJim Ingham Address address(addr_offset);
48e14dc268SJim Ingham
49e14dc268SJim Ingham success = options_dict.HasKey(GetKey(OptionNames::ModuleName));
50e14dc268SJim Ingham if (success) {
51e14dc268SJim Ingham success = options_dict.GetValueForKeyAsString(
52e14dc268SJim Ingham GetKey(OptionNames::ModuleName), module_name);
53e14dc268SJim Ingham if (!success) {
54e14dc268SJim Ingham error.SetErrorString("BRA::CFSD: Couldn't read module name entry.");
55e14dc268SJim Ingham return nullptr;
56e14dc268SJim Ingham }
578f3be7a3SJonas Devlieghere module_filespec.SetFile(module_name, FileSpec::Style::native);
58e14dc268SJim Ingham }
59e14dc268SJim Ingham return new BreakpointResolverAddress(bkpt, address, module_filespec);
60e14dc268SJim Ingham }
61e14dc268SJim Ingham
62e14dc268SJim Ingham StructuredData::ObjectSP
SerializeToStructuredData()63e14dc268SJim Ingham BreakpointResolverAddress::SerializeToStructuredData() {
64e14dc268SJim Ingham StructuredData::DictionarySP options_dict_sp(
65e14dc268SJim Ingham new StructuredData::Dictionary());
66e14dc268SJim Ingham SectionSP section_sp = m_addr.GetSection();
67e14dc268SJim Ingham if (section_sp) {
68e14dc268SJim Ingham ModuleSP module_sp = section_sp->GetModule();
69e14dc268SJim Ingham ConstString module_name;
70e14dc268SJim Ingham if (module_sp)
71e14dc268SJim Ingham module_name.SetCString(module_name.GetCString());
72e14dc268SJim Ingham
73e14dc268SJim Ingham options_dict_sp->AddStringItem(GetKey(OptionNames::ModuleName),
74e14dc268SJim Ingham module_name.GetCString());
75e14dc268SJim Ingham options_dict_sp->AddIntegerItem(GetKey(OptionNames::AddressOffset),
76e14dc268SJim Ingham m_addr.GetOffset());
77e14dc268SJim Ingham } else {
78e14dc268SJim Ingham options_dict_sp->AddIntegerItem(GetKey(OptionNames::AddressOffset),
79e14dc268SJim Ingham m_addr.GetOffset());
80e14dc268SJim Ingham if (m_module_filespec) {
81e14dc268SJim Ingham options_dict_sp->AddStringItem(GetKey(OptionNames::ModuleName),
82e14dc268SJim Ingham m_module_filespec.GetPath());
83e14dc268SJim Ingham }
84e14dc268SJim Ingham }
85e14dc268SJim Ingham
86e14dc268SJim Ingham return WrapOptionsDict(options_dict_sp);
87e14dc268SJim Ingham }
88e14dc268SJim Ingham
ResolveBreakpoint(SearchFilter & filter)89b9c1b51eSKate Stone void BreakpointResolverAddress::ResolveBreakpoint(SearchFilter &filter) {
9005097246SAdrian Prantl // If the address is not section relative, then we should not try to re-
9105097246SAdrian Prantl // resolve it, it is just some random address and we wouldn't know what to do
9205097246SAdrian Prantl // on reload. But if it is section relative, we need to re-resolve it since
9305097246SAdrian Prantl // the section it's in may have shifted on re-run.
94055a08a4SJim Ingham bool re_resolve = false;
95055a08a4SJim Ingham if (m_addr.GetSection() || m_module_filespec)
96055a08a4SJim Ingham re_resolve = true;
976c17cc53STatyana Krasnukha else if (GetBreakpoint()->GetNumLocations() == 0)
98055a08a4SJim Ingham re_resolve = true;
99055a08a4SJim Ingham
100055a08a4SJim Ingham if (re_resolve)
10130fdc8d8SChris Lattner BreakpointResolver::ResolveBreakpoint(filter);
10230fdc8d8SChris Lattner }
10330fdc8d8SChris Lattner
ResolveBreakpointInModules(SearchFilter & filter,ModuleList & modules)104b9c1b51eSKate Stone void BreakpointResolverAddress::ResolveBreakpointInModules(
105b9c1b51eSKate Stone SearchFilter &filter, ModuleList &modules) {
106055a08a4SJim Ingham // See comment in ResolveBreakpoint.
107055a08a4SJim Ingham bool re_resolve = false;
108055a08a4SJim Ingham if (m_addr.GetSection())
109055a08a4SJim Ingham re_resolve = true;
1106c17cc53STatyana Krasnukha else if (GetBreakpoint()->GetNumLocations() == 0)
111055a08a4SJim Ingham re_resolve = true;
112055a08a4SJim Ingham
113055a08a4SJim Ingham if (re_resolve)
11430fdc8d8SChris Lattner BreakpointResolver::ResolveBreakpointInModules(filter, modules);
11530fdc8d8SChris Lattner }
11630fdc8d8SChris Lattner
SearchCallback(SearchFilter & filter,SymbolContext & context,Address * addr)11795e264fcSRaphael Isemann Searcher::CallbackReturn BreakpointResolverAddress::SearchCallback(
11895e264fcSRaphael Isemann SearchFilter &filter, SymbolContext &context, Address *addr) {
1196c17cc53STatyana Krasnukha BreakpointSP breakpoint_sp = GetBreakpoint();
1206c17cc53STatyana Krasnukha Breakpoint &breakpoint = *breakpoint_sp;
12130fdc8d8SChris Lattner
122b9c1b51eSKate Stone if (filter.AddressPasses(m_addr)) {
1236c17cc53STatyana Krasnukha if (breakpoint.GetNumLocations() == 0) {
124*b876c236SMuhammad Omair Javaid // If the address is just an offset, and we're given a module, see if we
125*b876c236SMuhammad Omair Javaid // can find the appropriate module loaded in the binary, and fix up
126a3c3482cSWill Hawkins // m_addr to use that.
127*b876c236SMuhammad Omair Javaid if (!m_addr.IsSectionOffset() && m_module_filespec) {
128*b876c236SMuhammad Omair Javaid Target &target = breakpoint.GetTarget();
129055a08a4SJim Ingham ModuleSpec module_spec(m_module_filespec);
130*b876c236SMuhammad Omair Javaid ModuleSP module_sp = target.GetImages().FindFirstModule(module_spec);
131*b876c236SMuhammad Omair Javaid if (module_sp) {
132055a08a4SJim Ingham Address tmp_address;
133*b876c236SMuhammad Omair Javaid if (module_sp->ResolveFileAddress(m_addr.GetOffset(), tmp_address))
134055a08a4SJim Ingham m_addr = tmp_address;
135055a08a4SJim Ingham }
136055a08a4SJim Ingham }
137055a08a4SJim Ingham
1386c17cc53STatyana Krasnukha m_resolved_addr = m_addr.GetLoadAddress(&breakpoint.GetTarget());
1392411167fSJim Ingham BreakpointLocationSP bp_loc_sp(AddLocation(m_addr));
1406c17cc53STatyana Krasnukha if (bp_loc_sp && !breakpoint.IsInternal()) {
14130fdc8d8SChris Lattner StreamString s;
14230fdc8d8SChris Lattner bp_loc_sp->GetDescription(&s, lldb::eDescriptionLevelVerbose);
143a007a6d8SPavel Labath Log *log = GetLog(LLDBLog::Breakpoints);
14463e5fb76SJonas Devlieghere LLDB_LOGF(log, "Added location: %s\n", s.GetData());
14530fdc8d8SChris Lattner }
146b9c1b51eSKate Stone } else {
1476c17cc53STatyana Krasnukha BreakpointLocationSP loc_sp = breakpoint.GetLocationAtIndex(0);
148b9c1b51eSKate Stone lldb::addr_t cur_load_location =
1496c17cc53STatyana Krasnukha m_addr.GetLoadAddress(&breakpoint.GetTarget());
150b9c1b51eSKate Stone if (cur_load_location != m_resolved_addr) {
151055a08a4SJim Ingham m_resolved_addr = cur_load_location;
152055a08a4SJim Ingham loc_sp->ClearBreakpointSite();
153055a08a4SJim Ingham loc_sp->ResolveBreakpointSite();
154055a08a4SJim Ingham }
155055a08a4SJim Ingham }
156055a08a4SJim Ingham }
15730fdc8d8SChris Lattner return Searcher::eCallbackReturnStop;
15830fdc8d8SChris Lattner }
15930fdc8d8SChris Lattner
GetDepth()1604911d36aSJim Ingham lldb::SearchDepth BreakpointResolverAddress::GetDepth() {
1614911d36aSJim Ingham return lldb::eSearchDepthTarget;
16230fdc8d8SChris Lattner }
16330fdc8d8SChris Lattner
GetDescription(Stream * s)164b9c1b51eSKate Stone void BreakpointResolverAddress::GetDescription(Stream *s) {
1650c5cd90dSGreg Clayton s->PutCString("address = ");
1666c17cc53STatyana Krasnukha m_addr.Dump(s, GetBreakpoint()->GetTarget().GetProcessSP().get(),
167b9c1b51eSKate Stone Address::DumpStyleModuleWithFileAddress,
168b9c1b51eSKate Stone Address::DumpStyleLoadAddress);
16930fdc8d8SChris Lattner }
17030fdc8d8SChris Lattner
Dump(Stream * s) const171b9c1b51eSKate Stone void BreakpointResolverAddress::Dump(Stream *s) const {}
17233df7cd3SJim Ingham
17333df7cd3SJim Ingham lldb::BreakpointResolverSP
CopyForBreakpoint(BreakpointSP & breakpoint)1746c17cc53STatyana Krasnukha BreakpointResolverAddress::CopyForBreakpoint(BreakpointSP &breakpoint) {
175b9c1b51eSKate Stone lldb::BreakpointResolverSP ret_sp(
1766c17cc53STatyana Krasnukha new BreakpointResolverAddress(breakpoint, m_addr));
17733df7cd3SJim Ingham return ret_sp;
17833df7cd3SJim Ingham }
179