1168404Spjd//===-- AddressResolverName.cpp ---------------------------------*- C++ -*-===// 2168404Spjd// 3168404Spjd// The LLVM Compiler Infrastructure 4168404Spjd// 5168404Spjd// This file is distributed under the University of Illinois Open Source 6168404Spjd// License. See LICENSE.TXT for details. 7168404Spjd// 8168404Spjd//===----------------------------------------------------------------------===// 9168404Spjd 10168404Spjd#include "lldb/Core/AddressResolverName.h" 11168404Spjd 12168404Spjd// Project includes 13168404Spjd#include "lldb/Core/Log.h" 14168404Spjd#include "lldb/Core/Module.h" 15168404Spjd#include "lldb/Core/StreamString.h" 16168404Spjd#include "lldb/Symbol/ClangNamespaceDecl.h" 17168404Spjd#include "lldb/Symbol/Function.h" 18168404Spjd#include "lldb/Symbol/SymbolContext.h" 19168404Spjd#include "lldb/Symbol/Symbol.h" 20168404Spjd#include "lldb/lldb-private-log.h" 21168404Spjd 22168404Spjdusing namespace lldb; 23168404Spjdusing namespace lldb_private; 24168404Spjd 25168404SpjdAddressResolverName::AddressResolverName 26168404Spjd( 27168404Spjd const char *func_name, 28168404Spjd AddressResolver::MatchType type 29168404Spjd) : 30168404Spjd AddressResolver (), 31168404Spjd m_func_name (func_name), 32168404Spjd m_class_name (NULL), 33168404Spjd m_regex (), 34168404Spjd m_match_type (type) 35168404Spjd{ 36168404Spjd if (m_match_type == AddressResolver::Regexp) 37168404Spjd { 38168404Spjd if (!m_regex.Compile (m_func_name.AsCString())) 39168404Spjd { 40168404Spjd Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS)); 41168404Spjd 42168404Spjd if (log) 43168404Spjd log->Warning ("function name regexp: \"%s\" did not compile.", m_func_name.AsCString()); 44168404Spjd } 45168404Spjd } 46168404Spjd} 47168404Spjd 48168404SpjdAddressResolverName::AddressResolverName 49168404Spjd( 50168404Spjd RegularExpression &func_regex 51168404Spjd) : 52168404Spjd AddressResolver (), 53168404Spjd m_func_name (NULL), 54168404Spjd m_class_name (NULL), 55168404Spjd m_regex (func_regex), 56168404Spjd m_match_type (AddressResolver::Regexp) 57168404Spjd{ 58168404Spjd 59168404Spjd} 60168404Spjd 61168404SpjdAddressResolverName::AddressResolverName 62168404Spjd( 63168404Spjd const char *class_name, 64168404Spjd const char *method, 65168404Spjd AddressResolver::MatchType type 66168404Spjd) : 67168404Spjd AddressResolver (), 68168404Spjd m_func_name (method), 69168404Spjd m_class_name (class_name), 70168404Spjd m_regex (), 71168404Spjd m_match_type (type) 72168404Spjd{ 73168404Spjd 74168404Spjd} 75168404Spjd 76168404SpjdAddressResolverName::~AddressResolverName () 77168404Spjd{ 78168404Spjd} 79168404Spjd 80168404Spjd// FIXME: Right now we look at the module level, and call the module's "FindFunctions". 81168404Spjd// Greg says he will add function tables, maybe at the CompileUnit level to accelerate function 82168404Spjd// lookup. At that point, we should switch the depth to CompileUnit, and look in these tables. 83168404Spjd 84168404SpjdSearcher::CallbackReturn 85168404SpjdAddressResolverName::SearchCallback 86168404Spjd( 87168404Spjd SearchFilter &filter, 88168404Spjd SymbolContext &context, 89168404Spjd Address *addr, 90168404Spjd bool containing 91168404Spjd) 92168404Spjd{ 93168404Spjd SymbolContextList func_list; 94168404Spjd SymbolContextList sym_list; 95168404Spjd 96168404Spjd bool skip_prologue = true; 97168404Spjd uint32_t i; 98168404Spjd SymbolContext sc; 99168404Spjd Address func_addr; 100168404Spjd 101168404Spjd Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS)); 102168404Spjd 103168404Spjd if (m_class_name) 104168404Spjd { 105168404Spjd if (log) 106168404Spjd log->Warning ("Class/method function specification not supported yet.\n"); 107168404Spjd return Searcher::eCallbackReturnStop; 108168404Spjd } 109168404Spjd 110168404Spjd const bool include_symbols = false; 111168404Spjd const bool include_inlines = true; 112168404Spjd const bool append = false; 113168404Spjd switch (m_match_type) 114168404Spjd { 115168404Spjd case AddressResolver::Exact: 116168404Spjd if (context.module_sp) 117168404Spjd { 118168404Spjd context.module_sp->FindSymbolsWithNameAndType (m_func_name, 119168404Spjd eSymbolTypeCode, 120168404Spjd sym_list); 121168404Spjd context.module_sp->FindFunctions (m_func_name, 122168404Spjd NULL, 123168404Spjd eFunctionNameTypeAuto, 124168404Spjd include_symbols, 125168404Spjd include_inlines, 126168404Spjd append, 127168404Spjd func_list); 128168404Spjd } 129168404Spjd break; 130168404Spjd 131168404Spjd case AddressResolver::Regexp: 132168404Spjd if (context.module_sp) 133168404Spjd { 134168404Spjd context.module_sp->FindSymbolsMatchingRegExAndType (m_regex, 135168404Spjd eSymbolTypeCode, 136168404Spjd sym_list); 137168404Spjd context.module_sp->FindFunctions (m_regex, 138168404Spjd include_symbols, 139168404Spjd include_inlines, 140168404Spjd append, 141168404Spjd func_list); 142168404Spjd } 143168404Spjd break; 144168404Spjd 145168404Spjd case AddressResolver::Glob: 146168404Spjd if (log) 147168404Spjd log->Warning ("glob is not supported yet."); 148168404Spjd break; 149168404Spjd } 150168404Spjd 151168404Spjd // Remove any duplicates between the funcion list and the symbol list 152168404Spjd if (func_list.GetSize()) 153168404Spjd { 154168404Spjd for (i = 0; i < func_list.GetSize(); i++) 155168404Spjd { 156168404Spjd if (func_list.GetContextAtIndex(i, sc) == false) 157168404Spjd continue; 158168404Spjd 159168404Spjd if (sc.function == NULL) 160168404Spjd continue; 161168404Spjd uint32_t j = 0; 162168404Spjd while (j < sym_list.GetSize()) 163168404Spjd { 164168404Spjd SymbolContext symbol_sc; 165168404Spjd if (sym_list.GetContextAtIndex(j, symbol_sc)) 166168404Spjd { 167168404Spjd if (symbol_sc.symbol && symbol_sc.symbol->ValueIsAddress()) 168168404Spjd { 169168404Spjd if (sc.function->GetAddressRange().GetBaseAddress() == symbol_sc.symbol->GetAddress()) 170168404Spjd { 171168404Spjd sym_list.RemoveContextAtIndex(j); 172168404Spjd continue; // Don't increment j 173168404Spjd } 174168404Spjd } 175168404Spjd } 176168404Spjd 177168404Spjd j++; 178168404Spjd } 179168404Spjd } 180168404Spjd 181168404Spjd for (i = 0; i < func_list.GetSize(); i++) 182168404Spjd { 183168404Spjd if (func_list.GetContextAtIndex(i, sc)) 184168404Spjd { 185168404Spjd if (sc.function) 186168404Spjd { 187168404Spjd func_addr = sc.function->GetAddressRange().GetBaseAddress(); 188168404Spjd addr_t byte_size = sc.function->GetAddressRange().GetByteSize(); 189168404Spjd if (skip_prologue) 190168404Spjd { 191168404Spjd const uint32_t prologue_byte_size = sc.function->GetPrologueByteSize(); 192168404Spjd if (prologue_byte_size) 193168404Spjd { 194168404Spjd func_addr.SetOffset (func_addr.GetOffset() + prologue_byte_size); 195168404Spjd byte_size -= prologue_byte_size; 196168404Spjd } 197168404Spjd } 198168404Spjd 199168404Spjd if (filter.AddressPasses (func_addr)) 200168404Spjd { 201168404Spjd AddressRange new_range (func_addr, byte_size); 202168404Spjd m_address_ranges.push_back (new_range); 203168404Spjd } 204168404Spjd } 205168404Spjd } 206168404Spjd } 207168404Spjd } 208168404Spjd 209168404Spjd for (i = 0; i < sym_list.GetSize(); i++) 210168404Spjd { 211168404Spjd if (sym_list.GetContextAtIndex(i, sc)) 212168404Spjd { 213168404Spjd if (sc.symbol && sc.symbol->ValueIsAddress()) 214168404Spjd { 215168404Spjd func_addr = sc.symbol->GetAddress(); 216168404Spjd addr_t byte_size = sc.symbol->GetByteSize(); 217168404Spjd 218168404Spjd if (skip_prologue) 219168404Spjd { 220168404Spjd const uint32_t prologue_byte_size = sc.symbol->GetPrologueByteSize(); 221168404Spjd if (prologue_byte_size) 222168404Spjd { 223168404Spjd func_addr.SetOffset (func_addr.GetOffset() + prologue_byte_size); 224168404Spjd byte_size -= prologue_byte_size; 225168404Spjd } 226168404Spjd } 227168404Spjd 228168404Spjd if (filter.AddressPasses (func_addr)) 229168404Spjd { 230168404Spjd AddressRange new_range (func_addr, byte_size); 231168404Spjd m_address_ranges.push_back (new_range); 232168404Spjd } 233168404Spjd } 234168404Spjd } 235168404Spjd } 236168404Spjd return Searcher::eCallbackReturnContinue; 237168404Spjd} 238168404Spjd 239168404SpjdSearcher::Depth 240168404SpjdAddressResolverName::GetDepth() 241168404Spjd{ 242168404Spjd return Searcher::eDepthModule; 243168404Spjd} 244168404Spjd 245168404Spjdvoid 246168404SpjdAddressResolverName::GetDescription (Stream *s) 247168404Spjd{ 248168404Spjd s->PutCString("Address by function name: "); 249168404Spjd 250168404Spjd if (m_match_type == AddressResolver::Regexp) 251168404Spjd s->Printf("'%s' (regular expression)", m_regex.GetText()); 252168404Spjd else 253168404Spjd s->Printf("'%s'", m_func_name.AsCString()); 254168404Spjd} 255168404Spjd 256168404Spjd