Path: blob/main/contrib/llvm-project/llvm/lib/DebugInfo/PDB/Native/NativeFunctionSymbol.cpp
35293 views
//===- NativeFunctionSymbol.cpp - info about function symbols----*- C++ -*-===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#include "llvm/DebugInfo/PDB/Native/NativeFunctionSymbol.h"910#include "llvm/DebugInfo/CodeView/CVRecord.h"11#include "llvm/DebugInfo/CodeView/CodeView.h"12#include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"13#include "llvm/DebugInfo/CodeView/SymbolRecord.h"14#include "llvm/DebugInfo/PDB/Native/ModuleDebugStream.h"15#include "llvm/DebugInfo/PDB/Native/NativeEnumSymbols.h"16#include "llvm/DebugInfo/PDB/Native/NativeSession.h"17#include "llvm/DebugInfo/PDB/Native/SymbolCache.h"18#include "llvm/DebugInfo/PDB/PDBExtras.h"1920using namespace llvm;21using namespace llvm::codeview;22using namespace llvm::pdb;2324NativeFunctionSymbol::NativeFunctionSymbol(NativeSession &Session,25SymIndexId Id,26const codeview::ProcSym &Sym,27uint32_t Offset)28: NativeRawSymbol(Session, PDB_SymType::Function, Id), Sym(Sym),29RecordOffset(Offset) {}3031NativeFunctionSymbol::~NativeFunctionSymbol() = default;3233void NativeFunctionSymbol::dump(raw_ostream &OS, int Indent,34PdbSymbolIdField ShowIdFields,35PdbSymbolIdField RecurseIdFields) const {36NativeRawSymbol::dump(OS, Indent, ShowIdFields, RecurseIdFields);37dumpSymbolField(OS, "name", getName(), Indent);38dumpSymbolField(OS, "length", getLength(), Indent);39dumpSymbolField(OS, "offset", getAddressOffset(), Indent);40dumpSymbolField(OS, "section", getAddressSection(), Indent);41}4243uint32_t NativeFunctionSymbol::getAddressOffset() const {44return Sym.CodeOffset;45}4647uint32_t NativeFunctionSymbol::getAddressSection() const { return Sym.Segment; }48std::string NativeFunctionSymbol::getName() const {49return std::string(Sym.Name);50}5152uint64_t NativeFunctionSymbol::getLength() const { return Sym.CodeSize; }5354uint32_t NativeFunctionSymbol::getRelativeVirtualAddress() const {55return Session.getRVAFromSectOffset(Sym.Segment, Sym.CodeOffset);56}5758uint64_t NativeFunctionSymbol::getVirtualAddress() const {59return Session.getVAFromSectOffset(Sym.Segment, Sym.CodeOffset);60}6162static bool inlineSiteContainsAddress(InlineSiteSym &IS,63uint32_t OffsetInFunc) {64// Returns true if inline site contains the offset.65bool Found = false;66uint32_t CodeOffset = 0;67for (auto &Annot : IS.annotations()) {68switch (Annot.OpCode) {69case BinaryAnnotationsOpCode::CodeOffset:70case BinaryAnnotationsOpCode::ChangeCodeOffset:71case BinaryAnnotationsOpCode::ChangeCodeOffsetAndLineOffset:72CodeOffset += Annot.U1;73if (OffsetInFunc >= CodeOffset)74Found = true;75break;76case BinaryAnnotationsOpCode::ChangeCodeLength:77CodeOffset += Annot.U1;78if (Found && OffsetInFunc < CodeOffset)79return true;80Found = false;81break;82case BinaryAnnotationsOpCode::ChangeCodeLengthAndCodeOffset:83CodeOffset += Annot.U2;84if (OffsetInFunc >= CodeOffset && OffsetInFunc < CodeOffset + Annot.U1)85return true;86Found = false;87break;88default:89break;90}91}92return false;93}9495std::unique_ptr<IPDBEnumSymbols>96NativeFunctionSymbol::findInlineFramesByVA(uint64_t VA) const {97uint16_t Modi;98if (!Session.moduleIndexForVA(VA, Modi))99return nullptr;100101Expected<ModuleDebugStreamRef> ModS = Session.getModuleDebugStream(Modi);102if (!ModS) {103consumeError(ModS.takeError());104return nullptr;105}106CVSymbolArray Syms = ModS->getSymbolArray();107108// Search for inline sites. There should be one matching top level inline109// site. Then search in its nested inline sites.110std::vector<SymIndexId> Frames;111uint32_t CodeOffset = VA - getVirtualAddress();112auto Start = Syms.at(RecordOffset);113auto End = Syms.at(Sym.End);114while (Start != End) {115bool Found = false;116// Find matching inline site within Start and End.117for (; Start != End; ++Start) {118if (Start->kind() != S_INLINESITE)119continue;120121InlineSiteSym IS =122cantFail(SymbolDeserializer::deserializeAs<InlineSiteSym>(*Start));123if (inlineSiteContainsAddress(IS, CodeOffset)) {124// Insert frames in reverse order.125SymIndexId Id = Session.getSymbolCache().getOrCreateInlineSymbol(126IS, getVirtualAddress(), Modi, Start.offset());127Frames.insert(Frames.begin(), Id);128129// Update offsets to search within this inline site.130++Start;131End = Syms.at(IS.End);132Found = true;133break;134}135136Start = Syms.at(IS.End);137if (Start == End)138break;139}140141if (!Found)142break;143}144145return std::make_unique<NativeEnumSymbols>(Session, std::move(Frames));146}147148149