1ac7ddfbfSEd Maste //===-- BreakpointResolverAddress.cpp ---------------------------*- C++ -*-===// 2ac7ddfbfSEd Maste // 3ac7ddfbfSEd Maste // The LLVM Compiler Infrastructure 4ac7ddfbfSEd Maste // 5ac7ddfbfSEd Maste // This file is distributed under the University of Illinois Open Source 6ac7ddfbfSEd Maste // License. See LICENSE.TXT for details. 7ac7ddfbfSEd Maste // 8ac7ddfbfSEd Maste //===----------------------------------------------------------------------===// 9ac7ddfbfSEd Maste 10ac7ddfbfSEd Maste #include "lldb/Breakpoint/BreakpointResolverAddress.h" 11ac7ddfbfSEd Maste 12ac7ddfbfSEd Maste // C Includes 13ac7ddfbfSEd Maste // C++ Includes 14ac7ddfbfSEd Maste // Other libraries and framework includes 15ac7ddfbfSEd Maste // Project includes 16ac7ddfbfSEd Maste 17ac7ddfbfSEd Maste #include "lldb/Breakpoint/BreakpointLocation.h" 18ac7ddfbfSEd Maste #include "lldb/Core/Log.h" 199f2f44ceSEd Maste #include "lldb/Core/Module.h" 20435933ddSDimitry Andric #include "lldb/Core/Section.h" 21ac7ddfbfSEd Maste #include "lldb/Core/StreamString.h" 221c3bbb01SEd Maste #include "lldb/Target/Process.h" 23ac7ddfbfSEd Maste #include "lldb/Target/Target.h" 24ac7ddfbfSEd Maste 25ac7ddfbfSEd Maste using namespace lldb; 26ac7ddfbfSEd Maste using namespace lldb_private; 27ac7ddfbfSEd Maste 28ac7ddfbfSEd Maste //---------------------------------------------------------------------- 29ac7ddfbfSEd Maste // BreakpointResolverAddress: 30ac7ddfbfSEd Maste //---------------------------------------------------------------------- 31435933ddSDimitry Andric BreakpointResolverAddress::BreakpointResolverAddress( 32435933ddSDimitry Andric Breakpoint *bkpt, const Address &addr, const FileSpec &module_spec) 33435933ddSDimitry Andric : BreakpointResolver(bkpt, BreakpointResolver::AddressResolver), 34435933ddSDimitry Andric m_addr(addr), m_resolved_addr(LLDB_INVALID_ADDRESS), 35435933ddSDimitry Andric m_module_filespec(module_spec) {} 36435933ddSDimitry Andric 37435933ddSDimitry Andric BreakpointResolverAddress::BreakpointResolverAddress(Breakpoint *bkpt, 38435933ddSDimitry Andric const Address &addr) 39435933ddSDimitry Andric : BreakpointResolver(bkpt, BreakpointResolver::AddressResolver), 40435933ddSDimitry Andric m_addr(addr), m_resolved_addr(LLDB_INVALID_ADDRESS), m_module_filespec() { 419f2f44ceSEd Maste } 429f2f44ceSEd Maste 43435933ddSDimitry Andric BreakpointResolverAddress::~BreakpointResolverAddress() {} 44435933ddSDimitry Andric 45435933ddSDimitry Andric BreakpointResolver *BreakpointResolverAddress::CreateFromStructuredData( 46435933ddSDimitry Andric Breakpoint *bkpt, const StructuredData::Dictionary &options_dict, 47435933ddSDimitry Andric Error &error) { 48435933ddSDimitry Andric std::string module_name; 49435933ddSDimitry Andric lldb::addr_t addr_offset; 50435933ddSDimitry Andric FileSpec module_filespec; 51435933ddSDimitry Andric bool success; 52435933ddSDimitry Andric 53435933ddSDimitry Andric success = options_dict.GetValueForKeyAsInteger( 54435933ddSDimitry Andric GetKey(OptionNames::AddressOffset), addr_offset); 55435933ddSDimitry Andric if (!success) { 56435933ddSDimitry Andric error.SetErrorString("BRFL::CFSD: Couldn't find address offset entry."); 57435933ddSDimitry Andric return nullptr; 58435933ddSDimitry Andric } 59435933ddSDimitry Andric Address address(addr_offset); 60435933ddSDimitry Andric 61435933ddSDimitry Andric success = options_dict.HasKey(GetKey(OptionNames::ModuleName)); 62435933ddSDimitry Andric if (success) { 63435933ddSDimitry Andric success = options_dict.GetValueForKeyAsString( 64435933ddSDimitry Andric GetKey(OptionNames::ModuleName), module_name); 65435933ddSDimitry Andric if (!success) { 66435933ddSDimitry Andric error.SetErrorString("BRA::CFSD: Couldn't read module name entry."); 67435933ddSDimitry Andric return nullptr; 68435933ddSDimitry Andric } 69435933ddSDimitry Andric module_filespec.SetFile(module_name, false); 70435933ddSDimitry Andric } 71435933ddSDimitry Andric return new BreakpointResolverAddress(bkpt, address, module_filespec); 72ac7ddfbfSEd Maste } 73ac7ddfbfSEd Maste 74435933ddSDimitry Andric StructuredData::ObjectSP 75435933ddSDimitry Andric BreakpointResolverAddress::SerializeToStructuredData() { 76435933ddSDimitry Andric StructuredData::DictionarySP options_dict_sp( 77435933ddSDimitry Andric new StructuredData::Dictionary()); 78435933ddSDimitry Andric SectionSP section_sp = m_addr.GetSection(); 79435933ddSDimitry Andric if (section_sp) { 80435933ddSDimitry Andric ModuleSP module_sp = section_sp->GetModule(); 81435933ddSDimitry Andric ConstString module_name; 82435933ddSDimitry Andric if (module_sp) 83435933ddSDimitry Andric module_name.SetCString(module_name.GetCString()); 84ac7ddfbfSEd Maste 85435933ddSDimitry Andric options_dict_sp->AddStringItem(GetKey(OptionNames::ModuleName), 86435933ddSDimitry Andric module_name.GetCString()); 87435933ddSDimitry Andric options_dict_sp->AddIntegerItem(GetKey(OptionNames::AddressOffset), 88435933ddSDimitry Andric m_addr.GetOffset()); 89435933ddSDimitry Andric } else { 90435933ddSDimitry Andric options_dict_sp->AddIntegerItem(GetKey(OptionNames::AddressOffset), 91435933ddSDimitry Andric m_addr.GetOffset()); 92435933ddSDimitry Andric if (m_module_filespec) { 93435933ddSDimitry Andric options_dict_sp->AddStringItem(GetKey(OptionNames::ModuleName), 94435933ddSDimitry Andric m_module_filespec.GetPath()); 95435933ddSDimitry Andric } 96ac7ddfbfSEd Maste } 97ac7ddfbfSEd Maste 98435933ddSDimitry Andric return WrapOptionsDict(options_dict_sp); 99435933ddSDimitry Andric return StructuredData::ObjectSP(); 100435933ddSDimitry Andric } 101435933ddSDimitry Andric 102435933ddSDimitry Andric void BreakpointResolverAddress::ResolveBreakpoint(SearchFilter &filter) { 103435933ddSDimitry Andric // If the address is not section relative, then we should not try to 104435933ddSDimitry Andric // re-resolve it, it is just some 105435933ddSDimitry Andric // random address and we wouldn't know what to do on reload. But if it is 106435933ddSDimitry Andric // section relative, we need to 1079f2f44ceSEd Maste // re-resolve it since the section it's in may have shifted on re-run. 1089f2f44ceSEd Maste bool re_resolve = false; 1099f2f44ceSEd Maste if (m_addr.GetSection() || m_module_filespec) 1109f2f44ceSEd Maste re_resolve = true; 1119f2f44ceSEd Maste else if (m_breakpoint->GetNumLocations() == 0) 1129f2f44ceSEd Maste re_resolve = true; 1139f2f44ceSEd Maste 1149f2f44ceSEd Maste if (re_resolve) 115ac7ddfbfSEd Maste BreakpointResolver::ResolveBreakpoint(filter); 116ac7ddfbfSEd Maste } 117ac7ddfbfSEd Maste 118435933ddSDimitry Andric void BreakpointResolverAddress::ResolveBreakpointInModules( 119435933ddSDimitry Andric SearchFilter &filter, ModuleList &modules) { 1209f2f44ceSEd Maste // See comment in ResolveBreakpoint. 1219f2f44ceSEd Maste bool re_resolve = false; 1229f2f44ceSEd Maste if (m_addr.GetSection()) 1239f2f44ceSEd Maste re_resolve = true; 1249f2f44ceSEd Maste else if (m_breakpoint->GetNumLocations() == 0) 1259f2f44ceSEd Maste re_resolve = true; 1269f2f44ceSEd Maste 1279f2f44ceSEd Maste if (re_resolve) 128ac7ddfbfSEd Maste BreakpointResolver::ResolveBreakpointInModules(filter, modules); 129ac7ddfbfSEd Maste } 130ac7ddfbfSEd Maste 131ac7ddfbfSEd Maste Searcher::CallbackReturn 132435933ddSDimitry Andric BreakpointResolverAddress::SearchCallback(SearchFilter &filter, 133435933ddSDimitry Andric SymbolContext &context, Address *addr, 134435933ddSDimitry Andric bool containing) { 135ac7ddfbfSEd Maste assert(m_breakpoint != NULL); 136ac7ddfbfSEd Maste 137435933ddSDimitry Andric if (filter.AddressPasses(m_addr)) { 138435933ddSDimitry Andric if (m_breakpoint->GetNumLocations() == 0) { 139435933ddSDimitry Andric // If the address is just an offset, and we're given a module, see if we 140435933ddSDimitry Andric // can find the appropriate module 1419f2f44ceSEd Maste // loaded in the binary, and fix up m_addr to use that. 142435933ddSDimitry Andric if (!m_addr.IsSectionOffset() && m_module_filespec) { 1439f2f44ceSEd Maste Target &target = m_breakpoint->GetTarget(); 1449f2f44ceSEd Maste ModuleSpec module_spec(m_module_filespec); 1459f2f44ceSEd Maste ModuleSP module_sp = target.GetImages().FindFirstModule(module_spec); 146435933ddSDimitry Andric if (module_sp) { 1479f2f44ceSEd Maste Address tmp_address; 1489f2f44ceSEd Maste if (module_sp->ResolveFileAddress(m_addr.GetOffset(), tmp_address)) 1499f2f44ceSEd Maste m_addr = tmp_address; 1509f2f44ceSEd Maste } 1519f2f44ceSEd Maste } 1529f2f44ceSEd Maste 1539f2f44ceSEd Maste m_resolved_addr = m_addr.GetLoadAddress(&m_breakpoint->GetTarget()); 1544bb0738eSEd Maste BreakpointLocationSP bp_loc_sp(AddLocation(m_addr)); 155435933ddSDimitry Andric if (bp_loc_sp && !m_breakpoint->IsInternal()) { 156ac7ddfbfSEd Maste StreamString s; 157ac7ddfbfSEd Maste bp_loc_sp->GetDescription(&s, lldb::eDescriptionLevelVerbose); 158435933ddSDimitry Andric Log *log( 159435933ddSDimitry Andric lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS)); 160ac7ddfbfSEd Maste if (log) 161ac7ddfbfSEd Maste log->Printf("Added location: %s\n", s.GetData()); 162ac7ddfbfSEd Maste } 163435933ddSDimitry Andric } else { 1649f2f44ceSEd Maste BreakpointLocationSP loc_sp = m_breakpoint->GetLocationAtIndex(0); 165435933ddSDimitry Andric lldb::addr_t cur_load_location = 166435933ddSDimitry Andric m_addr.GetLoadAddress(&m_breakpoint->GetTarget()); 167435933ddSDimitry Andric if (cur_load_location != m_resolved_addr) { 1689f2f44ceSEd Maste m_resolved_addr = cur_load_location; 1699f2f44ceSEd Maste loc_sp->ClearBreakpointSite(); 1709f2f44ceSEd Maste loc_sp->ResolveBreakpointSite(); 1719f2f44ceSEd Maste } 1729f2f44ceSEd Maste } 1739f2f44ceSEd Maste } 174ac7ddfbfSEd Maste return Searcher::eCallbackReturnStop; 175ac7ddfbfSEd Maste } 176ac7ddfbfSEd Maste 177435933ddSDimitry Andric Searcher::Depth BreakpointResolverAddress::GetDepth() { 178ac7ddfbfSEd Maste return Searcher::eDepthTarget; 179ac7ddfbfSEd Maste } 180ac7ddfbfSEd Maste 181435933ddSDimitry Andric void BreakpointResolverAddress::GetDescription(Stream *s) { 182ac7ddfbfSEd Maste s->PutCString("address = "); 183435933ddSDimitry Andric m_addr.Dump(s, m_breakpoint->GetTarget().GetProcessSP().get(), 184435933ddSDimitry Andric Address::DumpStyleModuleWithFileAddress, 185435933ddSDimitry Andric Address::DumpStyleLoadAddress); 186ac7ddfbfSEd Maste } 187ac7ddfbfSEd Maste 188435933ddSDimitry Andric void BreakpointResolverAddress::Dump(Stream *s) const {} 1897aa51b79SEd Maste 1907aa51b79SEd Maste lldb::BreakpointResolverSP 191435933ddSDimitry Andric BreakpointResolverAddress::CopyForBreakpoint(Breakpoint &breakpoint) { 192435933ddSDimitry Andric lldb::BreakpointResolverSP ret_sp( 193435933ddSDimitry Andric new BreakpointResolverAddress(&breakpoint, m_addr)); 1947aa51b79SEd Maste return ret_sp; 1957aa51b79SEd Maste } 196