PDBContext.cpp 6.1 KB

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