PDBContext.cpp 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  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. #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/PDBSymbolFunc.h"
  15. #include "llvm/DebugInfo/PDB/PDBSymbolData.h"
  16. #include "llvm/DebugInfo/PDB/PDBSymbolPublicSymbol.h"
  17. #include "llvm/Object/COFF.h"
  18. using namespace llvm;
  19. using namespace llvm::object;
  20. PDBContext::PDBContext(const COFFObjectFile &Object,
  21. std::unique_ptr<IPDBSession> PDBSession,
  22. bool RelativeAddress)
  23. : DIContext(CK_PDB), Session(std::move(PDBSession)) {
  24. if (!RelativeAddress) {
  25. uint64_t ImageBase = 0;
  26. if (Object.is64()) {
  27. const pe32plus_header *Header = nullptr;
  28. Object.getPE32PlusHeader(Header);
  29. if (Header)
  30. ImageBase = Header->ImageBase;
  31. } else {
  32. const pe32_header *Header = nullptr;
  33. Object.getPE32Header(Header);
  34. if (Header)
  35. ImageBase = static_cast<uint64_t>(Header->ImageBase);
  36. }
  37. Session->setLoadAddress(ImageBase);
  38. }
  39. }
  40. void PDBContext::dump(raw_ostream &OS, DIDumpType DumpType) {}
  41. DILineInfo PDBContext::getLineInfoForAddress(uint64_t Address,
  42. DILineInfoSpecifier Specifier) {
  43. DILineInfo Result;
  44. Result.FunctionName = getFunctionName(Address, Specifier.FNKind);
  45. uint32_t Length = 1;
  46. std::unique_ptr<PDBSymbol> Symbol =
  47. Session->findSymbolByAddress(Address, PDB_SymType::None);
  48. if (auto Func = dyn_cast_or_null<PDBSymbolFunc>(Symbol.get())) {
  49. Length = Func->getLength();
  50. } else if (auto Data = dyn_cast_or_null<PDBSymbolData>(Symbol.get())) {
  51. Length = Data->getLength();
  52. }
  53. // If we couldn't find a symbol, then just assume 1 byte, so that we get
  54. // only the line number of the first instruction.
  55. auto LineNumbers = Session->findLineNumbersByAddress(Address, Length);
  56. if (!LineNumbers || LineNumbers->getChildCount() == 0)
  57. return Result;
  58. auto LineInfo = LineNumbers->getNext();
  59. assert(LineInfo);
  60. auto SourceFile = Session->getSourceFileById(LineInfo->getSourceFileId());
  61. if (SourceFile &&
  62. Specifier.FLIKind != DILineInfoSpecifier::FileLineInfoKind::None)
  63. Result.FileName = SourceFile->getFileName();
  64. Result.Column = LineInfo->getColumnNumber();
  65. Result.Line = LineInfo->getLineNumber();
  66. return Result;
  67. }
  68. DILineInfoTable
  69. PDBContext::getLineInfoForAddressRange(uint64_t Address, uint64_t Size,
  70. DILineInfoSpecifier Specifier) {
  71. if (Size == 0)
  72. return DILineInfoTable();
  73. DILineInfoTable Table;
  74. auto LineNumbers = Session->findLineNumbersByAddress(Address, Size);
  75. if (!LineNumbers || LineNumbers->getChildCount() == 0)
  76. return Table;
  77. while (auto LineInfo = LineNumbers->getNext()) {
  78. DILineInfo LineEntry =
  79. getLineInfoForAddress(LineInfo->getVirtualAddress(), Specifier);
  80. Table.push_back(std::make_pair(LineInfo->getVirtualAddress(), LineEntry));
  81. }
  82. return Table;
  83. }
  84. DIInliningInfo
  85. PDBContext::getInliningInfoForAddress(uint64_t Address,
  86. DILineInfoSpecifier Specifier) {
  87. DIInliningInfo InlineInfo;
  88. DILineInfo Frame = getLineInfoForAddress(Address, Specifier);
  89. InlineInfo.addFrame(Frame);
  90. return InlineInfo;
  91. }
  92. std::string PDBContext::getFunctionName(uint64_t Address,
  93. DINameKind NameKind) const {
  94. if (NameKind == DINameKind::None)
  95. return std::string();
  96. if (NameKind == DINameKind::LinkageName) {
  97. // It is not possible to get the mangled linkage name through a
  98. // PDBSymbolFunc. For that we have to specifically request a
  99. // PDBSymbolPublicSymbol.
  100. auto PublicSym =
  101. Session->findSymbolByAddress(Address, PDB_SymType::PublicSymbol);
  102. if (auto PS = dyn_cast_or_null<PDBSymbolPublicSymbol>(PublicSym.get()))
  103. return PS->getName();
  104. }
  105. auto FuncSymbol =
  106. Session->findSymbolByAddress(Address, PDB_SymType::Function);
  107. // This could happen either if there was no public symbol (e.g. not
  108. // external) or the user requested the short name. In the former case,
  109. // although they technically requested the linkage name, if the linkage
  110. // name is not available we fallback to at least returning a non-empty
  111. // string.
  112. if (auto Func = dyn_cast_or_null<PDBSymbolFunc>(FuncSymbol.get()))
  113. return Func->getName();
  114. return std::string();
  115. }