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/StreamString.h" 21 #include "lldb/Target/Process.h" 22 #include "lldb/Target/Target.h" 23 24 using namespace lldb; 25 using namespace lldb_private; 26 27 //---------------------------------------------------------------------- 28 // BreakpointResolverAddress: 29 //---------------------------------------------------------------------- 30 BreakpointResolverAddress::BreakpointResolverAddress 31 ( 32 Breakpoint *bkpt, 33 const Address &addr, 34 const FileSpec &module_spec 35 ) : 36 BreakpointResolver (bkpt, BreakpointResolver::AddressResolver), 37 m_addr (addr), 38 m_resolved_addr(LLDB_INVALID_ADDRESS), 39 m_module_filespec(module_spec) 40 { 41 } 42 43 BreakpointResolverAddress::BreakpointResolverAddress 44 ( 45 Breakpoint *bkpt, 46 const Address &addr 47 ) : 48 BreakpointResolver (bkpt, BreakpointResolver::AddressResolver), 49 m_addr (addr), 50 m_resolved_addr(LLDB_INVALID_ADDRESS), 51 m_module_filespec() 52 { 53 } 54 55 BreakpointResolverAddress::~BreakpointResolverAddress () 56 { 57 58 } 59 60 void 61 BreakpointResolverAddress::ResolveBreakpoint (SearchFilter &filter) 62 { 63 // If the address is not section relative, then we should not try to re-resolve it, it is just some 64 // random address and we wouldn't know what to do on reload. But if it is section relative, we need to 65 // re-resolve it since the section it's in may have shifted on re-run. 66 bool re_resolve = false; 67 if (m_addr.GetSection() || m_module_filespec) 68 re_resolve = true; 69 else if (m_breakpoint->GetNumLocations() == 0) 70 re_resolve = true; 71 72 if (re_resolve) 73 BreakpointResolver::ResolveBreakpoint(filter); 74 } 75 76 void 77 BreakpointResolverAddress::ResolveBreakpointInModules 78 ( 79 SearchFilter &filter, 80 ModuleList &modules 81 ) 82 { 83 // See comment in ResolveBreakpoint. 84 bool re_resolve = false; 85 if (m_addr.GetSection()) 86 re_resolve = true; 87 else if (m_breakpoint->GetNumLocations() == 0) 88 re_resolve = true; 89 90 if (re_resolve) 91 BreakpointResolver::ResolveBreakpointInModules (filter, modules); 92 } 93 94 Searcher::CallbackReturn 95 BreakpointResolverAddress::SearchCallback 96 ( 97 SearchFilter &filter, 98 SymbolContext &context, 99 Address *addr, 100 bool containing 101 ) 102 { 103 assert (m_breakpoint != NULL); 104 105 if (filter.AddressPasses (m_addr)) 106 { 107 if (m_breakpoint->GetNumLocations() == 0) 108 { 109 // If the address is just an offset, and we're given a module, see if we can find the appropriate module 110 // loaded in the binary, and fix up m_addr to use that. 111 if (!m_addr.IsSectionOffset() && m_module_filespec) 112 { 113 Target &target = m_breakpoint->GetTarget(); 114 ModuleSpec module_spec(m_module_filespec); 115 ModuleSP module_sp = target.GetImages().FindFirstModule(module_spec); 116 if (module_sp) 117 { 118 Address tmp_address; 119 if (module_sp->ResolveFileAddress(m_addr.GetOffset(), tmp_address)) 120 m_addr = tmp_address; 121 } 122 } 123 124 m_resolved_addr = m_addr.GetLoadAddress(&m_breakpoint->GetTarget()); 125 BreakpointLocationSP bp_loc_sp(AddLocation(m_addr)); 126 if (bp_loc_sp && !m_breakpoint->IsInternal()) 127 { 128 StreamString s; 129 bp_loc_sp->GetDescription(&s, lldb::eDescriptionLevelVerbose); 130 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS)); 131 if (log) 132 log->Printf ("Added location: %s\n", s.GetData()); 133 } 134 } 135 else 136 { 137 BreakpointLocationSP loc_sp = m_breakpoint->GetLocationAtIndex(0); 138 lldb::addr_t cur_load_location = m_addr.GetLoadAddress(&m_breakpoint->GetTarget()); 139 if (cur_load_location != m_resolved_addr) 140 { 141 m_resolved_addr = cur_load_location; 142 loc_sp->ClearBreakpointSite(); 143 loc_sp->ResolveBreakpointSite(); 144 } 145 } 146 } 147 return Searcher::eCallbackReturnStop; 148 } 149 150 Searcher::Depth 151 BreakpointResolverAddress::GetDepth() 152 { 153 return Searcher::eDepthTarget; 154 } 155 156 void 157 BreakpointResolverAddress::GetDescription (Stream *s) 158 { 159 s->PutCString ("address = "); 160 m_addr.Dump(s, m_breakpoint->GetTarget().GetProcessSP().get(), Address::DumpStyleModuleWithFileAddress, Address::DumpStyleLoadAddress); 161 } 162 163 void 164 BreakpointResolverAddress::Dump (Stream *s) const 165 { 166 167 } 168 169 lldb::BreakpointResolverSP 170 BreakpointResolverAddress::CopyForBreakpoint (Breakpoint &breakpoint) 171 { 172 lldb::BreakpointResolverSP ret_sp(new BreakpointResolverAddress(&breakpoint, m_addr)); 173 return ret_sp; 174 } 175 176