Path: blob/main/contrib/llvm-project/lldb/source/Breakpoint/BreakpointResolverAddress.cpp
39587 views
//===-- BreakpointResolverAddress.cpp -------------------------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#include "lldb/Breakpoint/BreakpointResolverAddress.h"9#include "lldb/Breakpoint/BreakpointLocation.h"10#include "lldb/Core/Module.h"11#include "lldb/Core/Section.h"12#include "lldb/Target/Process.h"13#include "lldb/Target/Target.h"14#include "lldb/Utility/LLDBLog.h"15#include "lldb/Utility/StreamString.h"1617using namespace lldb;18using namespace lldb_private;1920// BreakpointResolverAddress:21BreakpointResolverAddress::BreakpointResolverAddress(22const BreakpointSP &bkpt, const Address &addr, const FileSpec &module_spec)23: BreakpointResolver(bkpt, BreakpointResolver::AddressResolver),24m_addr(addr), m_resolved_addr(LLDB_INVALID_ADDRESS),25m_module_filespec(module_spec) {}2627BreakpointResolverAddress::BreakpointResolverAddress(const BreakpointSP &bkpt,28const Address &addr)29: BreakpointResolver(bkpt, BreakpointResolver::AddressResolver),30m_addr(addr), m_resolved_addr(LLDB_INVALID_ADDRESS) {}3132BreakpointResolverSP BreakpointResolverAddress::CreateFromStructuredData(33const StructuredData::Dictionary &options_dict, Status &error) {34llvm::StringRef module_name;35lldb::offset_t addr_offset;36FileSpec module_filespec;37bool success;3839success = options_dict.GetValueForKeyAsInteger(40GetKey(OptionNames::AddressOffset), addr_offset);41if (!success) {42error.SetErrorString("BRFL::CFSD: Couldn't find address offset entry.");43return nullptr;44}45Address address(addr_offset);4647success = options_dict.HasKey(GetKey(OptionNames::ModuleName));48if (success) {49success = options_dict.GetValueForKeyAsString(50GetKey(OptionNames::ModuleName), module_name);51if (!success) {52error.SetErrorString("BRA::CFSD: Couldn't read module name entry.");53return nullptr;54}55module_filespec.SetFile(module_name, FileSpec::Style::native);56}57return std::make_shared<BreakpointResolverAddress>(nullptr, address,58module_filespec);59}6061StructuredData::ObjectSP62BreakpointResolverAddress::SerializeToStructuredData() {63StructuredData::DictionarySP options_dict_sp(64new StructuredData::Dictionary());65SectionSP section_sp = m_addr.GetSection();66if (section_sp) {67if (ModuleSP module_sp = section_sp->GetModule()) {68const FileSpec &module_fspec = module_sp->GetFileSpec();69options_dict_sp->AddStringItem(GetKey(OptionNames::ModuleName),70module_fspec.GetPath().c_str());71}72options_dict_sp->AddIntegerItem(GetKey(OptionNames::AddressOffset),73m_addr.GetOffset());74} else {75options_dict_sp->AddIntegerItem(GetKey(OptionNames::AddressOffset),76m_addr.GetOffset());77if (m_module_filespec) {78options_dict_sp->AddStringItem(GetKey(OptionNames::ModuleName),79m_module_filespec.GetPath());80}81}8283return WrapOptionsDict(options_dict_sp);84}8586void BreakpointResolverAddress::ResolveBreakpoint(SearchFilter &filter) {87// If the address is not section relative, then we should not try to re-88// resolve it, it is just some random address and we wouldn't know what to do89// on reload. But if it is section relative, we need to re-resolve it since90// the section it's in may have shifted on re-run.91bool re_resolve = false;92if (m_addr.GetSection() || m_module_filespec)93re_resolve = true;94else if (GetBreakpoint()->GetNumLocations() == 0)95re_resolve = true;9697if (re_resolve)98BreakpointResolver::ResolveBreakpoint(filter);99}100101void BreakpointResolverAddress::ResolveBreakpointInModules(102SearchFilter &filter, ModuleList &modules) {103// See comment in ResolveBreakpoint.104bool re_resolve = false;105if (m_addr.GetSection())106re_resolve = true;107else if (GetBreakpoint()->GetNumLocations() == 0)108re_resolve = true;109110if (re_resolve)111BreakpointResolver::ResolveBreakpointInModules(filter, modules);112}113114Searcher::CallbackReturn BreakpointResolverAddress::SearchCallback(115SearchFilter &filter, SymbolContext &context, Address *addr) {116BreakpointSP breakpoint_sp = GetBreakpoint();117Breakpoint &breakpoint = *breakpoint_sp;118119if (filter.AddressPasses(m_addr)) {120if (breakpoint.GetNumLocations() == 0) {121// If the address is just an offset, and we're given a module, see if we122// can find the appropriate module loaded in the binary, and fix up123// m_addr to use that.124if (!m_addr.IsSectionOffset() && m_module_filespec) {125Target &target = breakpoint.GetTarget();126ModuleSpec module_spec(m_module_filespec);127ModuleSP module_sp = target.GetImages().FindFirstModule(module_spec);128if (module_sp) {129Address tmp_address;130if (module_sp->ResolveFileAddress(m_addr.GetOffset(), tmp_address))131m_addr = tmp_address;132}133}134135m_resolved_addr = m_addr.GetLoadAddress(&breakpoint.GetTarget());136BreakpointLocationSP bp_loc_sp(AddLocation(m_addr));137if (bp_loc_sp && !breakpoint.IsInternal()) {138StreamString s;139bp_loc_sp->GetDescription(&s, lldb::eDescriptionLevelVerbose);140Log *log = GetLog(LLDBLog::Breakpoints);141LLDB_LOGF(log, "Added location: %s\n", s.GetData());142}143} else {144BreakpointLocationSP loc_sp = breakpoint.GetLocationAtIndex(0);145lldb::addr_t cur_load_location =146m_addr.GetLoadAddress(&breakpoint.GetTarget());147if (cur_load_location != m_resolved_addr) {148m_resolved_addr = cur_load_location;149loc_sp->ClearBreakpointSite();150loc_sp->ResolveBreakpointSite();151}152}153}154return Searcher::eCallbackReturnStop;155}156157lldb::SearchDepth BreakpointResolverAddress::GetDepth() {158return lldb::eSearchDepthTarget;159}160161void BreakpointResolverAddress::GetDescription(Stream *s) {162s->PutCString("address = ");163m_addr.Dump(s, GetBreakpoint()->GetTarget().GetProcessSP().get(),164Address::DumpStyleModuleWithFileAddress,165Address::DumpStyleLoadAddress);166}167168void BreakpointResolverAddress::Dump(Stream *s) const {}169170lldb::BreakpointResolverSP171BreakpointResolverAddress::CopyForBreakpoint(BreakpointSP &breakpoint) {172lldb::BreakpointResolverSP ret_sp(173new BreakpointResolverAddress(breakpoint, m_addr));174return ret_sp;175}176177178