brintos

brintos / llvm-project-archived public Read only

0
0
Text · 6.8 KiB · 64a8005 Raw
183 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8 9#include "Plugins/SymbolFile/DWARF/DWARFIndex.h"10#include "DWARFDebugInfoEntry.h"11#include "DWARFDeclContext.h"12#include "Plugins/Language/ObjC/ObjCLanguage.h"13#include "Plugins/SymbolFile/DWARF/DWARFDIE.h"14#include "Plugins/SymbolFile/DWARF/SymbolFileDWARF.h"15 16#include "lldb/Core/Mangled.h"17#include "lldb/Core/Module.h"18#include "lldb/Target/Language.h"19#include "lldb/lldb-private-enumerations.h"20 21using namespace lldb_private;22using namespace lldb;23using namespace lldb_private::plugin::dwarf;24 25DWARFIndex::~DWARFIndex() = default;26 27IterationAction DWARFIndex::ProcessFunctionDIE(28    const Module::LookupInfo &lookup_info, DWARFDIE die,29    const CompilerDeclContext &parent_decl_ctx,30    llvm::function_ref<IterationAction(DWARFDIE die)> callback) {31  llvm::StringRef name = lookup_info.GetLookupName().GetStringRef();32  FunctionNameType name_type_mask = lookup_info.GetNameTypeMask();33 34  if (!(name_type_mask & eFunctionNameTypeFull)) {35    ConstString name_to_match_against;36    if (const char *mangled_die_name = die.GetMangledName()) {37      name_to_match_against = ConstString(mangled_die_name);38    } else {39      SymbolFileDWARF *symbols = die.GetDWARF();40      if (ConstString demangled_die_name =41              symbols->ConstructFunctionDemangledName(die))42        name_to_match_against = demangled_die_name;43    }44 45    if (!lookup_info.NameMatchesLookupInfo(name_to_match_against,46                                           lookup_info.GetLanguageType()))47      return IterationAction::Continue;48  }49 50  // Exit early if we're searching exclusively for methods or selectors and51  // we have a context specified (no methods in namespaces).52  uint32_t looking_for_nonmethods =53      name_type_mask & ~(eFunctionNameTypeMethod | eFunctionNameTypeSelector);54  if (!looking_for_nonmethods && parent_decl_ctx.IsValid())55    return IterationAction::Continue;56 57  // Otherwise, we need to also check that the context matches. If it does not58  // match, we do nothing.59  if (!SymbolFileDWARF::DIEInDeclContext(parent_decl_ctx, die))60    return IterationAction::Continue;61 62  // In case of a full match, we just insert everything we find.63  if (name_type_mask & eFunctionNameTypeFull && die.GetMangledName() == name)64    return callback(die);65 66  // If looking for ObjC selectors, we need to also check if the name is a67  // possible selector.68  if (name_type_mask & eFunctionNameTypeSelector &&69      ObjCLanguage::IsPossibleObjCMethodName(die.GetName()))70    return callback(die);71 72  bool looking_for_methods = name_type_mask & lldb::eFunctionNameTypeMethod;73  bool looking_for_functions = name_type_mask & lldb::eFunctionNameTypeBase;74  if (looking_for_methods || looking_for_functions) {75    // If we're looking for either methods or functions, we definitely want this76    // die. Otherwise, only keep it if the die type matches what we are77    // searching for.78    if ((looking_for_methods && looking_for_functions) ||79        looking_for_methods == die.IsMethod())80      return callback(die);81  }82 83  return IterationAction::Continue;84}85 86DWARFIndex::DIERefCallbackImpl::DIERefCallbackImpl(87    const DWARFIndex &index,88    llvm::function_ref<IterationAction(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 95IterationAction 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 IterationAction::Continue;100}101 102IterationAction DWARFIndex::DIERefCallbackImpl::operator()(103    const llvm::AppleAcceleratorTable::Entry &entry) const {104  return this->operator()(DIERef(std::nullopt, DIERef::Section::DebugInfo,105                                 *entry.getDIESectionOffset()));106}107 108void DWARFIndex::ReportInvalidDIERef(DIERef ref, llvm::StringRef name) const {109  m_module.ReportErrorIfModifyDetected(110      "the DWARF debug information has been modified (accelerator table had "111      "bad die {0:x16} for '{1}')\n",112      ref.die_offset(), name.str().c_str());113}114 115void DWARFIndex::GetFullyQualifiedType(116    const DWARFDeclContext &context,117    llvm::function_ref<IterationAction(DWARFDIE die)> callback) {118  GetTypes(context, [&](DWARFDIE die) {119    return GetFullyQualifiedTypeImpl(context, die, callback);120  });121}122 123IterationAction DWARFIndex::GetFullyQualifiedTypeImpl(124    const DWARFDeclContext &context, DWARFDIE die,125    llvm::function_ref<IterationAction(DWARFDIE die)> callback) {126  DWARFDeclContext dwarf_decl_ctx = die.GetDWARFDeclContext();127  if (dwarf_decl_ctx == context)128    return callback(die);129  return IterationAction::Continue;130}131 132void DWARFIndex::GetTypesWithQuery(133    TypeQuery &query,134    llvm::function_ref<IterationAction(DWARFDIE die)> callback) {135  GetTypes(query.GetTypeBasename(), [&](DWARFDIE die) {136    return ProcessTypeDIEMatchQuery(query, die, callback);137  });138}139 140IterationAction DWARFIndex::ProcessTypeDIEMatchQuery(141    TypeQuery &query, DWARFDIE die,142    llvm::function_ref<IterationAction(DWARFDIE die)> callback) {143  // Check the language, but only if we have a language filter.144  if (query.HasLanguage() &&145      !query.LanguageMatches(SymbolFileDWARF::GetLanguageFamily(*die.GetCU())))146    return IterationAction::Continue;147 148  // Since mangled names are unique, we only need to check if the names are149  // the same.150  if (query.GetSearchByMangledName()) {151    if (die.GetMangledName(/*substitute_name_allowed=*/false) !=152        query.GetTypeBasename().GetStringRef())153      return IterationAction::Continue;154    return callback(die);155  }156 157  std::vector<lldb_private::CompilerContext> die_context;158  if (query.GetModuleSearch())159    die_context = die.GetDeclContext();160  else161    die_context = die.GetTypeLookupContext();162 163  if (!query.ContextMatches(die_context))164    return IterationAction::Continue;165  return callback(die);166}167 168void DWARFIndex::GetNamespacesWithParents(169    ConstString name, const CompilerDeclContext &parent_decl_ctx,170    llvm::function_ref<IterationAction(DWARFDIE die)> callback) {171  GetNamespaces(name, [&](DWARFDIE die) {172    return ProcessNamespaceDieMatchParents(parent_decl_ctx, die, callback);173  });174}175 176IterationAction DWARFIndex::ProcessNamespaceDieMatchParents(177    const CompilerDeclContext &parent_decl_ctx, DWARFDIE die,178    llvm::function_ref<IterationAction(DWARFDIE die)> callback) {179  if (!SymbolFileDWARF::DIEInDeclContext(parent_decl_ctx, die))180    return IterationAction::Continue;181  return callback(die);182}183