Path: blob/main/contrib/llvm-project/llvm/lib/DebugInfo/PDB/PDBContext.cpp
35266 views
//===-- PDBContext.cpp ------------------------------------------*- 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/PDBContext.h"9#include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"10#include "llvm/DebugInfo/PDB/IPDBLineNumber.h"11#include "llvm/DebugInfo/PDB/IPDBSourceFile.h"12#include "llvm/DebugInfo/PDB/PDBSymbol.h"13#include "llvm/DebugInfo/PDB/PDBSymbolData.h"14#include "llvm/DebugInfo/PDB/PDBSymbolFunc.h"15#include "llvm/DebugInfo/PDB/PDBSymbolPublicSymbol.h"16#include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h"17#include "llvm/DebugInfo/PDB/PDBTypes.h"18#include "llvm/Object/COFF.h"1920using namespace llvm;21using namespace llvm::object;22using namespace llvm::pdb;2324PDBContext::PDBContext(const COFFObjectFile &Object,25std::unique_ptr<IPDBSession> PDBSession)26: DIContext(CK_PDB), Session(std::move(PDBSession)) {27ErrorOr<uint64_t> ImageBase = Object.getImageBase();28if (ImageBase)29Session->setLoadAddress(ImageBase.get());30}3132void PDBContext::dump(raw_ostream &OS, DIDumpOptions DumpOpts){}3334DILineInfo PDBContext::getLineInfoForAddress(object::SectionedAddress Address,35DILineInfoSpecifier Specifier) {36DILineInfo Result;37Result.FunctionName = getFunctionName(Address.Address, Specifier.FNKind);3839uint32_t Length = 1;40std::unique_ptr<PDBSymbol> Symbol =41Session->findSymbolByAddress(Address.Address, PDB_SymType::None);42if (auto Func = dyn_cast_or_null<PDBSymbolFunc>(Symbol.get())) {43Length = Func->getLength();44} else if (auto Data = dyn_cast_or_null<PDBSymbolData>(Symbol.get())) {45Length = Data->getLength();46}4748// If we couldn't find a symbol, then just assume 1 byte, so that we get49// only the line number of the first instruction.50auto LineNumbers = Session->findLineNumbersByAddress(Address.Address, Length);51if (!LineNumbers || LineNumbers->getChildCount() == 0)52return Result;5354auto LineInfo = LineNumbers->getNext();55assert(LineInfo);56auto SourceFile = Session->getSourceFileById(LineInfo->getSourceFileId());5758if (SourceFile &&59Specifier.FLIKind != DILineInfoSpecifier::FileLineInfoKind::None)60Result.FileName = SourceFile->getFileName();61Result.Column = LineInfo->getColumnNumber();62Result.Line = LineInfo->getLineNumber();63return Result;64}6566DILineInfo67PDBContext::getLineInfoForDataAddress(object::SectionedAddress Address) {68// Unimplemented. S_GDATA and S_LDATA in CodeView (used to describe global69// variables) aren't capable of carrying line information.70return DILineInfo();71}7273DILineInfoTable74PDBContext::getLineInfoForAddressRange(object::SectionedAddress Address,75uint64_t Size,76DILineInfoSpecifier Specifier) {77if (Size == 0)78return DILineInfoTable();7980DILineInfoTable Table;81auto LineNumbers = Session->findLineNumbersByAddress(Address.Address, Size);82if (!LineNumbers || LineNumbers->getChildCount() == 0)83return Table;8485while (auto LineInfo = LineNumbers->getNext()) {86DILineInfo LineEntry = getLineInfoForAddress(87{LineInfo->getVirtualAddress(), Address.SectionIndex}, Specifier);88Table.push_back(std::make_pair(LineInfo->getVirtualAddress(), LineEntry));89}90return Table;91}9293DIInliningInfo94PDBContext::getInliningInfoForAddress(object::SectionedAddress Address,95DILineInfoSpecifier Specifier) {96DIInliningInfo InlineInfo;97DILineInfo CurrentLine = getLineInfoForAddress(Address, Specifier);9899// Find the function at this address.100std::unique_ptr<PDBSymbol> ParentFunc =101Session->findSymbolByAddress(Address.Address, PDB_SymType::Function);102if (!ParentFunc) {103InlineInfo.addFrame(CurrentLine);104return InlineInfo;105}106107auto Frames = ParentFunc->findInlineFramesByVA(Address.Address);108if (!Frames || Frames->getChildCount() == 0) {109InlineInfo.addFrame(CurrentLine);110return InlineInfo;111}112113while (auto Frame = Frames->getNext()) {114uint32_t Length = 1;115auto LineNumbers = Frame->findInlineeLinesByVA(Address.Address, Length);116if (!LineNumbers || LineNumbers->getChildCount() == 0)117break;118119std::unique_ptr<IPDBLineNumber> Line = LineNumbers->getNext();120assert(Line);121122DILineInfo LineInfo;123LineInfo.FunctionName = Frame->getName();124auto SourceFile = Session->getSourceFileById(Line->getSourceFileId());125if (SourceFile &&126Specifier.FLIKind != DILineInfoSpecifier::FileLineInfoKind::None)127LineInfo.FileName = SourceFile->getFileName();128LineInfo.Line = Line->getLineNumber();129LineInfo.Column = Line->getColumnNumber();130InlineInfo.addFrame(LineInfo);131}132133InlineInfo.addFrame(CurrentLine);134return InlineInfo;135}136137std::vector<DILocal>138PDBContext::getLocalsForAddress(object::SectionedAddress Address) {139return std::vector<DILocal>();140}141142std::string PDBContext::getFunctionName(uint64_t Address,143DINameKind NameKind) const {144if (NameKind == DINameKind::None)145return std::string();146147std::unique_ptr<PDBSymbol> FuncSymbol =148Session->findSymbolByAddress(Address, PDB_SymType::Function);149auto *Func = dyn_cast_or_null<PDBSymbolFunc>(FuncSymbol.get());150151if (NameKind == DINameKind::LinkageName) {152// It is not possible to get the mangled linkage name through a153// PDBSymbolFunc. For that we have to specifically request a154// PDBSymbolPublicSymbol.155auto PublicSym =156Session->findSymbolByAddress(Address, PDB_SymType::PublicSymbol);157if (auto *PS = dyn_cast_or_null<PDBSymbolPublicSymbol>(PublicSym.get())) {158// If we also have a function symbol, prefer the use of public symbol name159// only if it refers to the same address. The public symbol uses the160// linkage name while the function does not.161if (!Func || Func->getVirtualAddress() == PS->getVirtualAddress())162return PS->getName();163}164}165166return Func ? Func->getName() : std::string();167}168169170