PDBContext.cpp revision 283625
197403Sobrien//===-- PDBContext.cpp ------------------------------------------*- C++ -*-===//
297403Sobrien//
3169691Skan//                     The LLVM Compiler Infrastructure
497403Sobrien//
597403Sobrien// This file is distributed under the University of Illinois Open Source
697403Sobrien// License. See LICENSE.TXT for details.
797403Sobrien//
897403Sobrien//===----------------------------------------------------------------------===/
997403Sobrien
1097403Sobrien#include "llvm/DebugInfo/PDB/PDBContext.h"
1197403Sobrien#include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
1297403Sobrien#include "llvm/DebugInfo/PDB/IPDBLineNumber.h"
1397403Sobrien#include "llvm/DebugInfo/PDB/IPDBSourceFile.h"
1497403Sobrien#include "llvm/DebugInfo/PDB/PDBSymbol.h"
1597403Sobrien#include "llvm/DebugInfo/PDB/PDBSymbolFunc.h"
1697403Sobrien#include "llvm/DebugInfo/PDB/PDBSymbolData.h"
1797403Sobrien#include "llvm/DebugInfo/PDB/PDBSymbolPublicSymbol.h"
18169691Skan#include "llvm/Object/COFF.h"
1997403Sobrien
2097403Sobrienusing namespace llvm;
2197403Sobrienusing namespace llvm::object;
2297403Sobrien
2397403SobrienPDBContext::PDBContext(const COFFObjectFile &Object,
2497403Sobrien                       std::unique_ptr<IPDBSession> PDBSession,
2597403Sobrien                       bool RelativeAddress)
2697403Sobrien    : DIContext(CK_PDB), Session(std::move(PDBSession)) {
2797403Sobrien  if (!RelativeAddress) {
2897403Sobrien    uint64_t ImageBase = 0;
2997403Sobrien    if (Object.is64()) {
3097403Sobrien      const pe32plus_header *Header = nullptr;
3197403Sobrien      Object.getPE32PlusHeader(Header);
3297403Sobrien      if (Header)
3397403Sobrien        ImageBase = Header->ImageBase;
3497403Sobrien    } else {
3597403Sobrien      const pe32_header *Header = nullptr;
3697403Sobrien      Object.getPE32Header(Header);
3797403Sobrien      if (Header)
3897403Sobrien        ImageBase = static_cast<uint64_t>(Header->ImageBase);
3997403Sobrien    }
4097403Sobrien    Session->setLoadAddress(ImageBase);
4197403Sobrien  }
4297403Sobrien}
4397403Sobrien
4497403Sobrienvoid PDBContext::dump(raw_ostream &OS, DIDumpType DumpType) {}
4597403Sobrien
46169691SkanDILineInfo PDBContext::getLineInfoForAddress(uint64_t Address,
4797403Sobrien                                             DILineInfoSpecifier Specifier) {
4897403Sobrien  DILineInfo Result;
49132720Skan  Result.FunctionName = getFunctionName(Address, Specifier.FNKind);
50132720Skan
5197403Sobrien  uint32_t Length = 1;
5297403Sobrien  std::unique_ptr<PDBSymbol> Symbol =
53132720Skan      Session->findSymbolByAddress(Address, PDB_SymType::None);
5497403Sobrien  if (auto Func = dyn_cast_or_null<PDBSymbolFunc>(Symbol.get())) {
5597403Sobrien    Length = Func->getLength();
5697403Sobrien  } else if (auto Data = dyn_cast_or_null<PDBSymbolData>(Symbol.get())) {
5797403Sobrien    Length = Data->getLength();
58169691Skan  }
5997403Sobrien
60169691Skan  // If we couldn't find a symbol, then just assume 1 byte, so that we get
61169691Skan  // only the line number of the first instruction.
62169691Skan  auto LineNumbers = Session->findLineNumbersByAddress(Address, Length);
63169691Skan  if (!LineNumbers || LineNumbers->getChildCount() == 0)
64169691Skan    return Result;
65169691Skan
66169691Skan  auto LineInfo = LineNumbers->getNext();
6797403Sobrien  assert(LineInfo);
68169691Skan  auto SourceFile = Session->getSourceFileById(LineInfo->getSourceFileId());
69169691Skan
70169691Skan  if (SourceFile &&
71169691Skan      Specifier.FLIKind != DILineInfoSpecifier::FileLineInfoKind::None)
72169691Skan    Result.FileName = SourceFile->getFileName();
73169691Skan  Result.Column = LineInfo->getColumnNumber();
74169691Skan  Result.Line = LineInfo->getLineNumber();
75169691Skan  return Result;
76169691Skan}
77169691Skan
78169691SkanDILineInfoTable
79169691SkanPDBContext::getLineInfoForAddressRange(uint64_t Address, uint64_t Size,
80169691Skan                                       DILineInfoSpecifier Specifier) {
8197403Sobrien  if (Size == 0)
82169691Skan    return DILineInfoTable();
83169691Skan
84169691Skan  DILineInfoTable Table;
85169691Skan  auto LineNumbers = Session->findLineNumbersByAddress(Address, Size);
86169691Skan  if (!LineNumbers || LineNumbers->getChildCount() == 0)
87169691Skan    return Table;
88169691Skan
89169691Skan  while (auto LineInfo = LineNumbers->getNext()) {
9097403Sobrien    DILineInfo LineEntry =
91169691Skan        getLineInfoForAddress(LineInfo->getVirtualAddress(), Specifier);
92169691Skan    Table.push_back(std::make_pair(LineInfo->getVirtualAddress(), LineEntry));
93169691Skan  }
94169691Skan  return Table;
95169691Skan}
96169691Skan
97169691SkanDIInliningInfo
98169691SkanPDBContext::getInliningInfoForAddress(uint64_t Address,
9997403Sobrien                                      DILineInfoSpecifier Specifier) {
100169691Skan  DIInliningInfo InlineInfo;
101169691Skan  DILineInfo Frame = getLineInfoForAddress(Address, Specifier);
102169691Skan  InlineInfo.addFrame(Frame);
103169691Skan  return InlineInfo;
104169691Skan}
105169691Skan
106169691Skanstd::string PDBContext::getFunctionName(uint64_t Address,
107169691Skan                                        DINameKind NameKind) const {
108169691Skan  if (NameKind == DINameKind::None)
109169691Skan    return std::string();
110169691Skan
111169691Skan  if (NameKind == DINameKind::LinkageName) {
112169691Skan    // It is not possible to get the mangled linkage name through a
11397403Sobrien    // PDBSymbolFunc.  For that we have to specifically request a
11497403Sobrien    // PDBSymbolPublicSymbol.
115169691Skan    auto PublicSym =
116169691Skan        Session->findSymbolByAddress(Address, PDB_SymType::PublicSymbol);
117169691Skan    if (auto PS = dyn_cast_or_null<PDBSymbolPublicSymbol>(PublicSym.get()))
118169691Skan      return PS->getName();
119169691Skan  }
120169691Skan
121169691Skan  auto FuncSymbol =
122169691Skan      Session->findSymbolByAddress(Address, PDB_SymType::Function);
123169691Skan
124169691Skan  // This could happen either if there was no public symbol (e.g. not
125169691Skan  // external) or the user requested the short name.  In the former case,
12697403Sobrien  // although they technically requested the linkage name, if the linkage
12797403Sobrien  // name is not available we fallback to at least returning a non-empty
128169691Skan  // string.
129169691Skan  if (auto Func = dyn_cast_or_null<PDBSymbolFunc>(FuncSymbol.get()))
130169691Skan      return Func->getName();
131169691Skan
132169691Skan  return std::string();
133169691Skan}
134169691Skan