ModuleDebugStream.cpp 4.7 KB

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