PDBContext.cpp revision 353358
1//===-- PDBContext.cpp ------------------------------------------*- 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-exception
6//
7//===----------------------------------------------------------------------===/
8
9#include "llvm/DebugInfo/PDB/PDBContext.h"
10#include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
11#include "llvm/DebugInfo/PDB/IPDBLineNumber.h"
12#include "llvm/DebugInfo/PDB/IPDBSourceFile.h"
13#include "llvm/DebugInfo/PDB/PDBSymbol.h"
14#include "llvm/DebugInfo/PDB/PDBSymbolData.h"
15#include "llvm/DebugInfo/PDB/PDBSymbolFunc.h"
16#include "llvm/DebugInfo/PDB/PDBSymbolPublicSymbol.h"
17#include "llvm/Object/COFF.h"
18
19using namespace llvm;
20using namespace llvm::object;
21using namespace llvm::pdb;
22
23PDBContext::PDBContext(const COFFObjectFile &Object,
24                       std::unique_ptr<IPDBSession> PDBSession)
25    : DIContext(CK_PDB), Session(std::move(PDBSession)) {
26  ErrorOr<uint64_t> ImageBase = Object.getImageBase();
27  if (ImageBase)
28    Session->setLoadAddress(ImageBase.get());
29}
30
31void PDBContext::dump(raw_ostream &OS, DIDumpOptions DumpOpts){}
32
33DILineInfo PDBContext::getLineInfoForAddress(object::SectionedAddress Address,
34                                             DILineInfoSpecifier Specifier) {
35  DILineInfo Result;
36  Result.FunctionName = getFunctionName(Address.Address, Specifier.FNKind);
37
38  uint32_t Length = 1;
39  std::unique_ptr<PDBSymbol> Symbol =
40      Session->findSymbolByAddress(Address.Address, PDB_SymType::None);
41  if (auto Func = dyn_cast_or_null<PDBSymbolFunc>(Symbol.get())) {
42    Length = Func->getLength();
43  } else if (auto Data = dyn_cast_or_null<PDBSymbolData>(Symbol.get())) {
44    Length = Data->getLength();
45  }
46
47  // If we couldn't find a symbol, then just assume 1 byte, so that we get
48  // only the line number of the first instruction.
49  auto LineNumbers = Session->findLineNumbersByAddress(Address.Address, Length);
50  if (!LineNumbers || LineNumbers->getChildCount() == 0)
51    return Result;
52
53  auto LineInfo = LineNumbers->getNext();
54  assert(LineInfo);
55  auto SourceFile = Session->getSourceFileById(LineInfo->getSourceFileId());
56
57  if (SourceFile &&
58      Specifier.FLIKind != DILineInfoSpecifier::FileLineInfoKind::None)
59    Result.FileName = SourceFile->getFileName();
60  Result.Column = LineInfo->getColumnNumber();
61  Result.Line = LineInfo->getLineNumber();
62  return Result;
63}
64
65DILineInfoTable
66PDBContext::getLineInfoForAddressRange(object::SectionedAddress Address,
67                                       uint64_t Size,
68                                       DILineInfoSpecifier Specifier) {
69  if (Size == 0)
70    return DILineInfoTable();
71
72  DILineInfoTable Table;
73  auto LineNumbers = Session->findLineNumbersByAddress(Address.Address, Size);
74  if (!LineNumbers || LineNumbers->getChildCount() == 0)
75    return Table;
76
77  while (auto LineInfo = LineNumbers->getNext()) {
78    DILineInfo LineEntry = getLineInfoForAddress(
79        {LineInfo->getVirtualAddress(), Address.SectionIndex}, Specifier);
80    Table.push_back(std::make_pair(LineInfo->getVirtualAddress(), LineEntry));
81  }
82  return Table;
83}
84
85DIInliningInfo
86PDBContext::getInliningInfoForAddress(object::SectionedAddress Address,
87                                      DILineInfoSpecifier Specifier) {
88  DIInliningInfo InlineInfo;
89  DILineInfo Frame = getLineInfoForAddress(Address, Specifier);
90  InlineInfo.addFrame(Frame);
91  return InlineInfo;
92}
93
94std::vector<DILocal>
95PDBContext::getLocalsForAddress(object::SectionedAddress Address) {
96  return std::vector<DILocal>();
97}
98
99std::string PDBContext::getFunctionName(uint64_t Address,
100                                        DINameKind NameKind) const {
101  if (NameKind == DINameKind::None)
102    return std::string();
103
104  std::unique_ptr<PDBSymbol> FuncSymbol =
105      Session->findSymbolByAddress(Address, PDB_SymType::Function);
106  auto *Func = dyn_cast_or_null<PDBSymbolFunc>(FuncSymbol.get());
107
108  if (NameKind == DINameKind::LinkageName) {
109    // It is not possible to get the mangled linkage name through a
110    // PDBSymbolFunc.  For that we have to specifically request a
111    // PDBSymbolPublicSymbol.
112    auto PublicSym =
113        Session->findSymbolByAddress(Address, PDB_SymType::PublicSymbol);
114    if (auto *PS = dyn_cast_or_null<PDBSymbolPublicSymbol>(PublicSym.get())) {
115      // If we also have a function symbol, prefer the use of public symbol name
116      // only if it refers to the same address. The public symbol uses the
117      // linkage name while the function does not.
118      if (!Func || Func->getVirtualAddress() == PS->getVirtualAddress())
119        return PS->getName();
120    }
121  }
122
123  return Func ? Func->getName() : std::string();
124}
125