AddressResolverName.cpp revision 24943d2ee8bfaa7cf5893e4709143924157a5c1e
1//===-- AddressResolverName.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/Core/AddressResolverName.h" 11 12// Project includes 13#include "lldb/Core/Log.h" 14#include "lldb/Core/StreamString.h" 15#include "lldb/lldb-private-log.h" 16 17using namespace lldb; 18using namespace lldb_private; 19 20AddressResolverName::AddressResolverName 21( 22 const char *func_name, 23 AddressResolver::MatchType type 24) : 25 AddressResolver (), 26 m_func_name (func_name), 27 m_class_name (NULL), 28 m_regex (), 29 m_match_type (type) 30{ 31 if (m_match_type == AddressResolver::Regexp) 32 { 33 if (!m_regex.Compile (m_func_name.AsCString())) 34 { 35 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS); 36 37 if (log) 38 log->Warning ("function name regexp: \"%s\" did not compile.", m_func_name.AsCString()); 39 } 40 } 41} 42 43AddressResolverName::AddressResolverName 44( 45 RegularExpression &func_regex 46) : 47 AddressResolver (), 48 m_func_name (NULL), 49 m_class_name (NULL), 50 m_regex (func_regex), 51 m_match_type (AddressResolver::Regexp) 52{ 53 54} 55 56AddressResolverName::AddressResolverName 57( 58 const char *class_name, 59 const char *method, 60 AddressResolver::MatchType type 61) : 62 AddressResolver (), 63 m_func_name (method), 64 m_class_name (class_name), 65 m_regex (), 66 m_match_type (type) 67{ 68 69} 70 71AddressResolverName::~AddressResolverName () 72{ 73} 74 75// FIXME: Right now we look at the module level, and call the module's "FindFunctions". 76// Greg says he will add function tables, maybe at the CompileUnit level to accelerate function 77// lookup. At that point, we should switch the depth to CompileUnit, and look in these tables. 78 79Searcher::CallbackReturn 80AddressResolverName::SearchCallback 81( 82 SearchFilter &filter, 83 SymbolContext &context, 84 Address *addr, 85 bool containing 86) 87{ 88 SymbolContextList func_list; 89 SymbolContextList sym_list; 90 91 bool skip_prologue = true; 92 uint32_t i; 93 SymbolContext sc; 94 Address func_addr; 95 96 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS); 97 98 if (m_class_name) 99 { 100 if (log) 101 log->Warning ("Class/method function specification not supported yet.\n"); 102 return Searcher::eCallbackReturnStop; 103 } 104 105 switch (m_match_type) 106 { 107 case AddressResolver::Exact: 108 if (context.module_sp) 109 { 110 context.module_sp->FindSymbolsWithNameAndType (m_func_name, eSymbolTypeCode, sym_list); 111 context.module_sp->FindFunctions (m_func_name, false, func_list); 112 } 113 break; 114 case AddressResolver::Regexp: 115 if (context.module_sp) 116 { 117 context.module_sp->FindSymbolsMatchingRegExAndType (m_regex, eSymbolTypeCode, sym_list); 118 context.module_sp->FindFunctions (m_regex, true, func_list); 119 } 120 break; 121 case AddressResolver::Glob: 122 if (log) 123 log->Warning ("glob is not supported yet."); 124 break; 125 } 126 127 // Remove any duplicates between the funcion list and the symbol list 128 if (func_list.GetSize()) 129 { 130 for (i = 0; i < func_list.GetSize(); i++) 131 { 132 if (func_list.GetContextAtIndex(i, sc) == false) 133 continue; 134 135 if (sc.function == NULL) 136 continue; 137 uint32_t j = 0; 138 while (j < sym_list.GetSize()) 139 { 140 SymbolContext symbol_sc; 141 if (sym_list.GetContextAtIndex(j, symbol_sc)) 142 { 143 if (symbol_sc.symbol && symbol_sc.symbol->GetAddressRangePtr()) 144 { 145 if (sc.function->GetAddressRange().GetBaseAddress() == symbol_sc.symbol->GetAddressRangePtr()->GetBaseAddress()) 146 { 147 sym_list.RemoveContextAtIndex(j); 148 continue; // Don't increment j 149 } 150 } 151 } 152 153 j++; 154 } 155 } 156 157 for (i = 0; i < func_list.GetSize(); i++) 158 { 159 if (func_list.GetContextAtIndex(i, sc)) 160 { 161 if (sc.function) 162 { 163 func_addr = sc.function->GetAddressRange().GetBaseAddress(); 164 addr_t byte_size = sc.function->GetAddressRange().GetByteSize(); 165 if (skip_prologue) 166 { 167 const uint32_t prologue_byte_size = sc.function->GetPrologueByteSize(); 168 if (prologue_byte_size) 169 { 170 func_addr.SetOffset (func_addr.GetOffset() + prologue_byte_size); 171 byte_size -= prologue_byte_size; 172 } 173 } 174 175 if (filter.AddressPasses (func_addr)) 176 { 177 AddressRange new_range (func_addr, byte_size); 178 m_address_ranges.push_back (new_range); 179 } 180 } 181 } 182 } 183 } 184 185 for (i = 0; i < sym_list.GetSize(); i++) 186 { 187 if (sym_list.GetContextAtIndex(i, sc)) 188 { 189 if (sc.symbol && sc.symbol->GetAddressRangePtr()) 190 { 191 func_addr = sc.symbol->GetAddressRangePtr()->GetBaseAddress(); 192 addr_t byte_size = sc.symbol->GetAddressRangePtr()->GetByteSize(); 193 194 if (skip_prologue) 195 { 196 const uint32_t prologue_byte_size = sc.symbol->GetPrologueByteSize(); 197 if (prologue_byte_size) 198 { 199 func_addr.SetOffset (func_addr.GetOffset() + prologue_byte_size); 200 byte_size -= prologue_byte_size; 201 } 202 } 203 204 if (filter.AddressPasses (func_addr)) 205 { 206 AddressRange new_range (func_addr, byte_size); 207 m_address_ranges.push_back (new_range); 208 } 209 } 210 } 211 } 212 return Searcher::eCallbackReturnContinue; 213} 214 215Searcher::Depth 216AddressResolverName::GetDepth() 217{ 218 return Searcher::eDepthModule; 219} 220 221void 222AddressResolverName::GetDescription (Stream *s) 223{ 224 s->PutCString("Address by function name: "); 225 226 if (m_match_type == AddressResolver::Regexp) 227 s->Printf("'%s' (regular expression)", m_regex.GetText()); 228 else 229 s->Printf("'%s'", m_func_name.AsCString()); 230} 231 232