1 //===-- BreakpointResolverAddress.cpp ---------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "lldb/Breakpoint/BreakpointResolverAddress.h" 11 12 // C Includes 13 // C++ Includes 14 // Other libraries and framework includes 15 // Project includes 16 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" 24 25 using namespace lldb; 26 using namespace lldb_private; 27 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) {} 36 37 BreakpointResolverAddress::BreakpointResolverAddress(Breakpoint *bkpt, 38 const Address &addr) 39 : BreakpointResolver(bkpt, BreakpointResolver::AddressResolver), 40 m_addr(addr), m_resolved_addr(LLDB_INVALID_ADDRESS), m_module_filespec() { 41 } 42 43 BreakpointResolverAddress::~BreakpointResolverAddress() {} 44 45 BreakpointResolver *BreakpointResolverAddress::CreateFromStructuredData( 46 Breakpoint *bkpt, const StructuredData::Dictionary &options_dict, 47 Error &error) { 48 std::string module_name; 49 lldb::addr_t addr_offset; 50 FileSpec module_filespec; 51 bool success; 52 53 success = options_dict.GetValueForKeyAsInteger( 54 GetKey(OptionNames::AddressOffset), addr_offset); 55 if (!success) { 56 error.SetErrorString("BRFL::CFSD: Couldn't find address offset entry."); 57 return nullptr; 58 } 59 Address address(addr_offset); 60 61 success = options_dict.HasKey(GetKey(OptionNames::ModuleName)); 62 if (success) { 63 success = options_dict.GetValueForKeyAsString( 64 GetKey(OptionNames::ModuleName), module_name); 65 if (!success) { 66 error.SetErrorString("BRA::CFSD: Couldn't read module name entry."); 67 return nullptr; 68 } 69 module_filespec.SetFile(module_name.c_str(), false); 70 } 71 return new BreakpointResolverAddress(bkpt, address, module_filespec); 72 } 73 74 StructuredData::ObjectSP 75 BreakpointResolverAddress::SerializeToStructuredData() { 76 StructuredData::DictionarySP options_dict_sp( 77 new StructuredData::Dictionary()); 78 SectionSP section_sp = m_addr.GetSection(); 79 if (section_sp) { 80 ModuleSP module_sp = section_sp->GetModule(); 81 ConstString module_name; 82 if (module_sp) 83 module_name.SetCString(module_name.GetCString()); 84 85 options_dict_sp->AddStringItem(GetKey(OptionNames::ModuleName), 86 module_name.GetCString()); 87 options_dict_sp->AddIntegerItem(GetKey(OptionNames::AddressOffset), 88 m_addr.GetOffset()); 89 } else { 90 options_dict_sp->AddIntegerItem(GetKey(OptionNames::AddressOffset), 91 m_addr.GetOffset()); 92 if (m_module_filespec) { 93 options_dict_sp->AddStringItem(GetKey(OptionNames::ModuleName), 94 m_module_filespec.GetPath()); 95 } 96 } 97 98 return WrapOptionsDict(options_dict_sp); 99 return StructuredData::ObjectSP(); 100 } 101 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) 110 re_resolve = true; 111 else if (m_breakpoint->GetNumLocations() == 0) 112 re_resolve = true; 113 114 if (re_resolve) 115 BreakpointResolver::ResolveBreakpoint(filter); 116 } 117 118 void BreakpointResolverAddress::ResolveBreakpointInModules( 119 SearchFilter &filter, ModuleList &modules) { 120 // See comment in ResolveBreakpoint. 121 bool re_resolve = false; 122 if (m_addr.GetSection()) 123 re_resolve = true; 124 else if (m_breakpoint->GetNumLocations() == 0) 125 re_resolve = true; 126 127 if (re_resolve) 128 BreakpointResolver::ResolveBreakpointInModules(filter, modules); 129 } 130 131 Searcher::CallbackReturn 132 BreakpointResolverAddress::SearchCallback(SearchFilter &filter, 133 SymbolContext &context, Address *addr, 134 bool containing) { 135 assert(m_breakpoint != NULL); 136 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); 146 if (module_sp) { 147 Address tmp_address; 148 if (module_sp->ResolveFileAddress(m_addr.GetOffset(), tmp_address)) 149 m_addr = tmp_address; 150 } 151 } 152 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()) { 156 StreamString s; 157 bp_loc_sp->GetDescription(&s, lldb::eDescriptionLevelVerbose); 158 Log *log( 159 lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS)); 160 if (log) 161 log->Printf("Added location: %s\n", s.GetData()); 162 } 163 } else { 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(); 171 } 172 } 173 } 174 return Searcher::eCallbackReturnStop; 175 } 176 177 Searcher::Depth BreakpointResolverAddress::GetDepth() { 178 return Searcher::eDepthTarget; 179 } 180 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); 186 } 187 188 void BreakpointResolverAddress::Dump(Stream *s) const {} 189 190 lldb::BreakpointResolverSP 191 BreakpointResolverAddress::CopyForBreakpoint(Breakpoint &breakpoint) { 192 lldb::BreakpointResolverSP ret_sp( 193 new BreakpointResolverAddress(&breakpoint, m_addr)); 194 return ret_sp; 195 } 196