1 //===-- DWARFIndex.cpp ----------------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "Plugins/SymbolFile/DWARF/DWARFIndex.h" 10 #include "Plugins/Language/ObjC/ObjCLanguage.h" 11 #include "Plugins/SymbolFile/DWARF/DWARFDIE.h" 12 #include "Plugins/SymbolFile/DWARF/SymbolFileDWARF.h" 13 14 #include "lldb/Core/Mangled.h" 15 #include "lldb/Core/Module.h" 16 #include "lldb/Target/Language.h" 17 18 using namespace lldb_private; 19 using namespace lldb; 20 21 DWARFIndex::~DWARFIndex() = default; 22 23 bool DWARFIndex::ProcessFunctionDIE( 24 const Module::LookupInfo &lookup_info, DIERef ref, SymbolFileDWARF &dwarf, 25 const CompilerDeclContext &parent_decl_ctx, 26 llvm::function_ref<bool(DWARFDIE die)> callback) { 27 llvm::StringRef name = lookup_info.GetLookupName().GetStringRef(); 28 FunctionNameType name_type_mask = lookup_info.GetNameTypeMask(); 29 DWARFDIE die = dwarf.GetDIE(ref); 30 if (!die) { 31 ReportInvalidDIERef(ref, name); 32 return true; 33 } 34 35 if (!(name_type_mask & eFunctionNameTypeFull)) { 36 ConstString name_to_match_against; 37 if (const char *mangled_die_name = die.GetMangledName()) { 38 name_to_match_against = ConstString(mangled_die_name); 39 } else { 40 SymbolFileDWARF *symbols = die.GetDWARF(); 41 if (ConstString demangled_die_name = 42 symbols->ConstructFunctionDemangledName(die)) 43 name_to_match_against = demangled_die_name; 44 } 45 46 if (!lookup_info.NameMatchesLookupInfo(name_to_match_against, 47 lookup_info.GetLanguageType())) 48 return true; 49 } 50 51 // Exit early if we're searching exclusively for methods or selectors and 52 // we have a context specified (no methods in namespaces). 53 uint32_t looking_for_nonmethods = 54 name_type_mask & ~(eFunctionNameTypeMethod | eFunctionNameTypeSelector); 55 if (!looking_for_nonmethods && parent_decl_ctx.IsValid()) 56 return true; 57 58 // Otherwise, we need to also check that the context matches. If it does not 59 // match, we do nothing. 60 if (!SymbolFileDWARF::DIEInDeclContext(parent_decl_ctx, die)) 61 return true; 62 63 // In case of a full match, we just insert everything we find. 64 if (name_type_mask & eFunctionNameTypeFull && die.GetMangledName() == name) 65 return callback(die); 66 67 // If looking for ObjC selectors, we need to also check if the name is a 68 // possible selector. 69 if (name_type_mask & eFunctionNameTypeSelector && 70 ObjCLanguage::IsPossibleObjCMethodName(die.GetName())) 71 return callback(die); 72 73 bool looking_for_methods = name_type_mask & lldb::eFunctionNameTypeMethod; 74 bool looking_for_functions = name_type_mask & lldb::eFunctionNameTypeBase; 75 if (looking_for_methods || looking_for_functions) { 76 // If we're looking for either methods or functions, we definitely want this 77 // die. Otherwise, only keep it if the die type matches what we are 78 // searching for. 79 if ((looking_for_methods && looking_for_functions) || 80 looking_for_methods == die.IsMethod()) 81 return callback(die); 82 } 83 84 return true; 85 } 86 87 DWARFIndex::DIERefCallbackImpl::DIERefCallbackImpl( 88 const DWARFIndex &index, llvm::function_ref<bool(DWARFDIE die)> callback, 89 llvm::StringRef name) 90 : m_index(index), 91 m_dwarf(*llvm::cast<SymbolFileDWARF>( 92 index.m_module.GetSymbolFile()->GetBackingSymbolFile())), 93 m_callback(callback), m_name(name) {} 94 95 bool DWARFIndex::DIERefCallbackImpl::operator()(DIERef ref) const { 96 if (DWARFDIE die = m_dwarf.GetDIE(ref)) 97 return m_callback(die); 98 m_index.ReportInvalidDIERef(ref, m_name); 99 return true; 100 } 101 102 void DWARFIndex::ReportInvalidDIERef(DIERef ref, llvm::StringRef name) const { 103 m_module.ReportErrorIfModifyDetected( 104 "the DWARF debug information has been modified (accelerator table had " 105 "bad die {0:x16} for '{1}')\n", 106 ref.die_offset(), name.str().c_str()); 107 } 108