LLVM  3.7.0
PDBContext.cpp
Go to the documentation of this file.
1 //===-- PDBContext.cpp ------------------------------------------*- C++ -*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===/
9 
18 #include "llvm/Object/COFF.h"
19 
20 using namespace llvm;
21 using namespace llvm::object;
22 
23 PDBContext::PDBContext(const COFFObjectFile &Object,
24  std::unique_ptr<IPDBSession> PDBSession,
25  bool RelativeAddress)
26  : DIContext(CK_PDB), Session(std::move(PDBSession)) {
27  if (!RelativeAddress) {
28  uint64_t ImageBase = 0;
29  if (Object.is64()) {
30  const pe32plus_header *Header = nullptr;
31  Object.getPE32PlusHeader(Header);
32  if (Header)
33  ImageBase = Header->ImageBase;
34  } else {
35  const pe32_header *Header = nullptr;
36  Object.getPE32Header(Header);
37  if (Header)
38  ImageBase = static_cast<uint64_t>(Header->ImageBase);
39  }
40  Session->setLoadAddress(ImageBase);
41  }
42 }
43 
44 void PDBContext::dump(raw_ostream &OS, DIDumpType DumpType) {}
45 
47  DILineInfoSpecifier Specifier) {
48  DILineInfo Result;
49  Result.FunctionName = getFunctionName(Address, Specifier.FNKind);
50 
51  uint32_t Length = 1;
52  std::unique_ptr<PDBSymbol> Symbol =
53  Session->findSymbolByAddress(Address, PDB_SymType::None);
54  if (auto Func = dyn_cast_or_null<PDBSymbolFunc>(Symbol.get())) {
55  Length = Func->getLength();
56  } else if (auto Data = dyn_cast_or_null<PDBSymbolData>(Symbol.get())) {
57  Length = Data->getLength();
58  }
59 
60  // If we couldn't find a symbol, then just assume 1 byte, so that we get
61  // only the line number of the first instruction.
62  auto LineNumbers = Session->findLineNumbersByAddress(Address, Length);
63  if (!LineNumbers || LineNumbers->getChildCount() == 0)
64  return Result;
65 
66  auto LineInfo = LineNumbers->getNext();
67  assert(LineInfo);
68  auto SourceFile = Session->getSourceFileById(LineInfo->getSourceFileId());
69 
70  if (SourceFile &&
72  Result.FileName = SourceFile->getFileName();
73  Result.Column = LineInfo->getColumnNumber();
74  Result.Line = LineInfo->getLineNumber();
75  return Result;
76 }
77 
80  DILineInfoSpecifier Specifier) {
81  if (Size == 0)
82  return DILineInfoTable();
83 
84  DILineInfoTable Table;
85  auto LineNumbers = Session->findLineNumbersByAddress(Address, Size);
86  if (!LineNumbers || LineNumbers->getChildCount() == 0)
87  return Table;
88 
89  while (auto LineInfo = LineNumbers->getNext()) {
90  DILineInfo LineEntry =
91  getLineInfoForAddress(LineInfo->getVirtualAddress(), Specifier);
92  Table.push_back(std::make_pair(LineInfo->getVirtualAddress(), LineEntry));
93  }
94  return Table;
95 }
96 
99  DILineInfoSpecifier Specifier) {
100  DIInliningInfo InlineInfo;
101  DILineInfo Frame = getLineInfoForAddress(Address, Specifier);
102  InlineInfo.addFrame(Frame);
103  return InlineInfo;
104 }
105 
106 std::string PDBContext::getFunctionName(uint64_t Address,
107  DINameKind NameKind) const {
108  if (NameKind == DINameKind::None)
109  return std::string();
110 
111  if (NameKind == DINameKind::LinkageName) {
112  // It is not possible to get the mangled linkage name through a
113  // PDBSymbolFunc. For that we have to specifically request a
114  // PDBSymbolPublicSymbol.
115  auto PublicSym =
116  Session->findSymbolByAddress(Address, PDB_SymType::PublicSymbol);
117  if (auto PS = dyn_cast_or_null<PDBSymbolPublicSymbol>(PublicSym.get()))
118  return PS->getName();
119  }
120 
121  auto FuncSymbol =
122  Session->findSymbolByAddress(Address, PDB_SymType::Function);
123 
124  // This could happen either if there was no public symbol (e.g. not
125  // external) or the user requested the short name. In the former case,
126  // although they technically requested the linkage name, if the linkage
127  // name is not available we fallback to at least returning a non-empty
128  // string.
129  if (auto Func = dyn_cast_or_null<PDBSymbolFunc>(FuncSymbol.get()))
130  return Func->getName();
131 
132  return std::string();
133 }
void push_back(const T &Elt)
Definition: SmallVector.h:222
The 64-bit PE header that follows the COFF header.
Definition: Object/COFF.h:127
std::string FileName
Definition: DIContext.h:32
void addFrame(const DILineInfo &Frame)
Definition: DIContext.h:63
DINameKind
A DINameKind is passed to name search methods to specify a preference regarding the type of name reso...
Definition: DIContext.h:70
DIInliningInfo getInliningInfoForAddress(uint64_t Address, DILineInfoSpecifier Specifier=DILineInfoSpecifier()) override
Definition: PDBContext.cpp:98
DILineInfo - a format-neutral container for source line information.
Definition: DIContext.h:31
support::ulittle64_t ImageBase
Definition: Object/COFF.h:136
FunctionNameKind FNKind
Definition: DIContext.h:79
FileLineInfoKind FLIKind
Definition: DIContext.h:78
void dump(raw_ostream &OS, DIDumpType DumpType=DIDT_All) override
Definition: PDBContext.cpp:44
DILineInfoTable getLineInfoForAddressRange(uint64_t Address, uint64_t Size, DILineInfoSpecifier Specifier=DILineInfoSpecifier()) override
Definition: PDBContext.cpp:79
uint32_t Column
Definition: DIContext.h:35
DILineInfoSpecifier - controls which fields of DILineInfo container should be filled with data...
Definition: DIContext.h:74
DIInliningInfo - a format-neutral container for inlined code description.
Definition: DIContext.h:52
The 32-bit PE header that follows the COFF header.
Definition: Object/COFF.h:91
DIDumpType
Selects which debug sections get dumped.
Definition: DIContext.h:87
std::error_code getPE32PlusHeader(const pe32plus_header *&Res) const
uint32_t Line
Definition: DIContext.h:34
SmallVector< std::pair< uint64_t, DILineInfo >, 16 > DILineInfoTable
Definition: DIContext.h:49
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:861
std::string FunctionName
Definition: DIContext.h:33
static StringRef getFunctionName(const DISubprogram *SP)
support::ulittle32_t ImageBase
Definition: Object/COFF.h:101
std::error_code getPE32Header(const pe32_header *&Res) const
This class implements an extremely fast bulk output stream that can only output to a stream...
Definition: raw_ostream.h:38
DILineInfo getLineInfoForAddress(uint64_t Address, DILineInfoSpecifier Specifier=DILineInfoSpecifier()) override
Definition: PDBContext.cpp:46