ModuleDebugStream.cpp 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. //===- ModuleDebugStream.cpp - PDB Module Info Stream Access --------------===//
  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/Native/ModuleDebugStream.h"
  9. #include "llvm/ADT/iterator_range.h"
  10. #include "llvm/DebugInfo/CodeView/CodeView.h"
  11. #include "llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h"
  12. #include "llvm/DebugInfo/CodeView/SymbolRecordHelpers.h"
  13. #include "llvm/DebugInfo/MSF/MSFCommon.h"
  14. #include "llvm/DebugInfo/MSF/MappedBlockStream.h"
  15. #include "llvm/DebugInfo/PDB/Native/DbiModuleDescriptor.h"
  16. #include "llvm/DebugInfo/PDB/Native/RawConstants.h"
  17. #include "llvm/DebugInfo/PDB/Native/RawError.h"
  18. #include "llvm/DebugInfo/PDB/Native/RawTypes.h"
  19. #include "llvm/Support/BinaryStreamArray.h"
  20. #include "llvm/Support/BinaryStreamReader.h"
  21. #include "llvm/Support/BinaryStreamRef.h"
  22. #include "llvm/Support/Error.h"
  23. #include <cstdint>
  24. using namespace llvm;
  25. using namespace llvm::codeview;
  26. using namespace llvm::msf;
  27. using namespace llvm::pdb;
  28. ModuleDebugStreamRef::ModuleDebugStreamRef(
  29. const DbiModuleDescriptor &Module,
  30. std::unique_ptr<MappedBlockStream> Stream)
  31. : Mod(Module), Stream(std::move(Stream)) {}
  32. ModuleDebugStreamRef::~ModuleDebugStreamRef() = default;
  33. Error ModuleDebugStreamRef::reload() {
  34. BinaryStreamReader Reader(*Stream);
  35. if (Mod.getModuleStreamIndex() != llvm::pdb::kInvalidStreamIndex) {
  36. if (Error E = reloadSerialize(Reader))
  37. return E;
  38. }
  39. if (Reader.bytesRemaining() > 0)
  40. return make_error<RawError>(raw_error_code::corrupt_file,
  41. "Unexpected bytes in module stream.");
  42. return Error::success();
  43. }
  44. Error ModuleDebugStreamRef::reloadSerialize(BinaryStreamReader &Reader) {
  45. uint32_t SymbolSize = Mod.getSymbolDebugInfoByteSize();
  46. uint32_t C11Size = Mod.getC11LineInfoByteSize();
  47. uint32_t C13Size = Mod.getC13LineInfoByteSize();
  48. if (C11Size > 0 && C13Size > 0)
  49. return make_error<RawError>(raw_error_code::corrupt_file,
  50. "Module has both C11 and C13 line info");
  51. BinaryStreamRef S;
  52. if (auto EC = Reader.readInteger(Signature))
  53. return EC;
  54. Reader.setOffset(0);
  55. if (auto EC = Reader.readSubstream(SymbolsSubstream, SymbolSize))
  56. return EC;
  57. if (auto EC = Reader.readSubstream(C11LinesSubstream, C11Size))
  58. return EC;
  59. if (auto EC = Reader.readSubstream(C13LinesSubstream, C13Size))
  60. return EC;
  61. BinaryStreamReader SymbolReader(SymbolsSubstream.StreamData);
  62. if (auto EC = SymbolReader.readArray(
  63. SymbolArray, SymbolReader.bytesRemaining(), sizeof(uint32_t)))
  64. return EC;
  65. BinaryStreamReader SubsectionsReader(C13LinesSubstream.StreamData);
  66. if (auto EC = SubsectionsReader.readArray(Subsections,
  67. SubsectionsReader.bytesRemaining()))
  68. return EC;
  69. uint32_t GlobalRefsSize;
  70. if (auto EC = Reader.readInteger(GlobalRefsSize))
  71. return EC;
  72. if (auto EC = Reader.readSubstream(GlobalRefsSubstream, GlobalRefsSize))
  73. return EC;
  74. return Error::success();
  75. }
  76. const codeview::CVSymbolArray
  77. ModuleDebugStreamRef::getSymbolArrayForScope(uint32_t ScopeBegin) const {
  78. return limitSymbolArrayToScope(SymbolArray, ScopeBegin);
  79. }
  80. BinarySubstreamRef ModuleDebugStreamRef::getSymbolsSubstream() const {
  81. return SymbolsSubstream;
  82. }
  83. BinarySubstreamRef ModuleDebugStreamRef::getC11LinesSubstream() const {
  84. return C11LinesSubstream;
  85. }
  86. BinarySubstreamRef ModuleDebugStreamRef::getC13LinesSubstream() const {
  87. return C13LinesSubstream;
  88. }
  89. BinarySubstreamRef ModuleDebugStreamRef::getGlobalRefsSubstream() const {
  90. return GlobalRefsSubstream;
  91. }
  92. iterator_range<codeview::CVSymbolArray::Iterator>
  93. ModuleDebugStreamRef::symbols(bool *HadError) const {
  94. return make_range(SymbolArray.begin(HadError), SymbolArray.end());
  95. }
  96. CVSymbol ModuleDebugStreamRef::readSymbolAtOffset(uint32_t Offset) const {
  97. auto Iter = SymbolArray.at(Offset);
  98. assert(Iter != SymbolArray.end());
  99. return *Iter;
  100. }
  101. iterator_range<ModuleDebugStreamRef::DebugSubsectionIterator>
  102. ModuleDebugStreamRef::subsections() const {
  103. return make_range(Subsections.begin(), Subsections.end());
  104. }
  105. bool ModuleDebugStreamRef::hasDebugSubsections() const {
  106. return !C13LinesSubstream.empty();
  107. }
  108. Error ModuleDebugStreamRef::commit() { return Error::success(); }
  109. Expected<codeview::DebugChecksumsSubsectionRef>
  110. ModuleDebugStreamRef::findChecksumsSubsection() const {
  111. codeview::DebugChecksumsSubsectionRef Result;
  112. for (const auto &SS : subsections()) {
  113. if (SS.kind() != DebugSubsectionKind::FileChecksums)
  114. continue;
  115. if (auto EC = Result.initialize(SS.getRecordData()))
  116. return std::move(EC);
  117. return Result;
  118. }
  119. return Result;
  120. }