brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.0 KiB · b1caa5a Raw
148 lines · cpp
1//===- NativeFunctionSymbol.cpp - info about function symbols----*- C++ -*-===//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 "llvm/DebugInfo/PDB/Native/NativeFunctionSymbol.h"10 11#include "llvm/DebugInfo/CodeView/CVRecord.h"12#include "llvm/DebugInfo/CodeView/CodeView.h"13#include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"14#include "llvm/DebugInfo/CodeView/SymbolRecord.h"15#include "llvm/DebugInfo/PDB/Native/ModuleDebugStream.h"16#include "llvm/DebugInfo/PDB/Native/NativeEnumSymbols.h"17#include "llvm/DebugInfo/PDB/Native/NativeSession.h"18#include "llvm/DebugInfo/PDB/Native/SymbolCache.h"19#include "llvm/DebugInfo/PDB/PDBExtras.h"20 21using namespace llvm;22using namespace llvm::codeview;23using namespace llvm::pdb;24 25NativeFunctionSymbol::NativeFunctionSymbol(NativeSession &Session,26                                           SymIndexId Id,27                                           const codeview::ProcSym &Sym,28                                           uint32_t Offset)29    : NativeRawSymbol(Session, PDB_SymType::Function, Id), Sym(Sym),30      RecordOffset(Offset) {}31 32NativeFunctionSymbol::~NativeFunctionSymbol() = default;33 34void NativeFunctionSymbol::dump(raw_ostream &OS, int Indent,35                                PdbSymbolIdField ShowIdFields,36                                PdbSymbolIdField RecurseIdFields) const {37  NativeRawSymbol::dump(OS, Indent, ShowIdFields, RecurseIdFields);38  dumpSymbolField(OS, "name", getName(), Indent);39  dumpSymbolField(OS, "length", getLength(), Indent);40  dumpSymbolField(OS, "offset", getAddressOffset(), Indent);41  dumpSymbolField(OS, "section", getAddressSection(), Indent);42}43 44uint32_t NativeFunctionSymbol::getAddressOffset() const {45  return Sym.CodeOffset;46}47 48uint32_t NativeFunctionSymbol::getAddressSection() const { return Sym.Segment; }49std::string NativeFunctionSymbol::getName() const {50  return std::string(Sym.Name);51}52 53uint64_t NativeFunctionSymbol::getLength() const { return Sym.CodeSize; }54 55uint32_t NativeFunctionSymbol::getRelativeVirtualAddress() const {56  return Session.getRVAFromSectOffset(Sym.Segment, Sym.CodeOffset);57}58 59uint64_t NativeFunctionSymbol::getVirtualAddress() const {60  return Session.getVAFromSectOffset(Sym.Segment, Sym.CodeOffset);61}62 63static bool inlineSiteContainsAddress(InlineSiteSym &IS,64                                      uint32_t OffsetInFunc) {65  // Returns true if inline site contains the offset.66  bool Found = false;67  uint32_t CodeOffset = 0;68  for (auto &Annot : IS.annotations()) {69    switch (Annot.OpCode) {70    case BinaryAnnotationsOpCode::CodeOffset:71    case BinaryAnnotationsOpCode::ChangeCodeOffset:72    case BinaryAnnotationsOpCode::ChangeCodeOffsetAndLineOffset:73      CodeOffset += Annot.U1;74      if (OffsetInFunc >= CodeOffset)75        Found = true;76      break;77    case BinaryAnnotationsOpCode::ChangeCodeLength:78      CodeOffset += Annot.U1;79      if (Found && OffsetInFunc < CodeOffset)80        return true;81      Found = false;82      break;83    case BinaryAnnotationsOpCode::ChangeCodeLengthAndCodeOffset:84      CodeOffset += Annot.U2;85      if (OffsetInFunc >= CodeOffset && OffsetInFunc < CodeOffset + Annot.U1)86        return true;87      Found = false;88      break;89    default:90      break;91    }92  }93  return false;94}95 96std::unique_ptr<IPDBEnumSymbols>97NativeFunctionSymbol::findInlineFramesByVA(uint64_t VA) const {98  uint16_t Modi;99  if (!Session.moduleIndexForVA(VA, Modi))100    return nullptr;101 102  Expected<ModuleDebugStreamRef> ModS = Session.getModuleDebugStream(Modi);103  if (!ModS) {104    consumeError(ModS.takeError());105    return nullptr;106  }107  CVSymbolArray Syms = ModS->getSymbolArray();108 109  // Search for inline sites. There should be one matching top level inline110  // site. Then search in its nested inline sites.111  std::vector<SymIndexId> Frames;112  uint32_t CodeOffset = VA - getVirtualAddress();113  auto Start = Syms.at(RecordOffset);114  auto End = Syms.at(Sym.End);115  while (Start != End) {116    bool Found = false;117    // Find matching inline site within Start and End.118    for (; Start != End; ++Start) {119      if (Start->kind() != S_INLINESITE)120        continue;121 122      InlineSiteSym IS =123          cantFail(SymbolDeserializer::deserializeAs<InlineSiteSym>(*Start));124      if (inlineSiteContainsAddress(IS, CodeOffset)) {125        // Insert frames in reverse order.126        SymIndexId Id = Session.getSymbolCache().getOrCreateInlineSymbol(127            IS, getVirtualAddress(), Modi, Start.offset());128        Frames.insert(Frames.begin(), Id);129 130        // Update offsets to search within this inline site.131        ++Start;132        End = Syms.at(IS.End);133        Found = true;134        break;135      }136 137      Start = Syms.at(IS.End);138      if (Start == End)139        break;140    }141 142    if (!Found)143      break;144  }145 146  return std::make_unique<NativeEnumSymbols>(Session, std::move(Frames));147}148