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