DbiModuleDescriptorBuilder.h 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. #pragma once
  2. #ifdef __GNUC__
  3. #pragma GCC diagnostic push
  4. #pragma GCC diagnostic ignored "-Wunused-parameter"
  5. #endif
  6. //===- DbiModuleDescriptorBuilder.h - PDB module information ----*- C++ -*-===//
  7. //
  8. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  9. // See https://llvm.org/LICENSE.txt for license information.
  10. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  11. //
  12. //===----------------------------------------------------------------------===//
  13. #ifndef LLVM_DEBUGINFO_PDB_NATIVE_DBIMODULEDESCRIPTORBUILDER_H
  14. #define LLVM_DEBUGINFO_PDB_NATIVE_DBIMODULEDESCRIPTORBUILDER_H
  15. #include "llvm/ADT/ArrayRef.h"
  16. #include "llvm/ADT/StringRef.h"
  17. #include "llvm/DebugInfo/CodeView/CVRecord.h"
  18. #include "llvm/DebugInfo/CodeView/DebugSubsectionRecord.h"
  19. #include "llvm/DebugInfo/PDB/Native/RawTypes.h"
  20. #include "llvm/Support/BinaryStreamRef.h"
  21. #include "llvm/Support/Error.h"
  22. #include <cstdint>
  23. #include <string>
  24. #include <vector>
  25. namespace llvm {
  26. class BinaryStreamWriter;
  27. namespace codeview {
  28. class DebugSubsection;
  29. }
  30. namespace msf {
  31. class MSFBuilder;
  32. struct MSFLayout;
  33. }
  34. namespace pdb {
  35. // Represents merged or unmerged symbols. Merged symbols can be written to the
  36. // output file as is, but unmerged symbols must be rewritten first. In either
  37. // case, the size must be known up front.
  38. struct SymbolListWrapper {
  39. explicit SymbolListWrapper(ArrayRef<uint8_t> Syms)
  40. : SymPtr(const_cast<uint8_t *>(Syms.data())), SymSize(Syms.size()),
  41. NeedsToBeMerged(false) {}
  42. explicit SymbolListWrapper(void *SymSrc, uint32_t Length)
  43. : SymPtr(SymSrc), SymSize(Length), NeedsToBeMerged(true) {}
  44. ArrayRef<uint8_t> asArray() const {
  45. return ArrayRef<uint8_t>(static_cast<const uint8_t *>(SymPtr), SymSize);
  46. }
  47. uint32_t size() const { return SymSize; }
  48. void *SymPtr = nullptr;
  49. uint32_t SymSize = 0;
  50. bool NeedsToBeMerged = false;
  51. };
  52. /// Represents a string table reference at some offset in the module symbol
  53. /// stream.
  54. struct StringTableFixup {
  55. uint32_t StrTabOffset = 0;
  56. uint32_t SymOffsetOfReference = 0;
  57. };
  58. class DbiModuleDescriptorBuilder {
  59. friend class DbiStreamBuilder;
  60. public:
  61. DbiModuleDescriptorBuilder(StringRef ModuleName, uint32_t ModIndex,
  62. msf::MSFBuilder &Msf);
  63. ~DbiModuleDescriptorBuilder();
  64. DbiModuleDescriptorBuilder(const DbiModuleDescriptorBuilder &) = delete;
  65. DbiModuleDescriptorBuilder &
  66. operator=(const DbiModuleDescriptorBuilder &) = delete;
  67. void setPdbFilePathNI(uint32_t NI);
  68. void setObjFileName(StringRef Name);
  69. // Callback to merge one source of unmerged symbols.
  70. using MergeSymbolsCallback = Error (*)(void *Ctx, void *Symbols,
  71. BinaryStreamWriter &Writer);
  72. void setMergeSymbolsCallback(void *Ctx, MergeSymbolsCallback Callback) {
  73. MergeSymsCtx = Ctx;
  74. MergeSymsCallback = Callback;
  75. }
  76. void setStringTableFixups(std::vector<StringTableFixup> &&Fixups) {
  77. StringTableFixups = std::move(Fixups);
  78. }
  79. void setFirstSectionContrib(const SectionContrib &SC);
  80. void addSymbol(codeview::CVSymbol Symbol);
  81. void addSymbolsInBulk(ArrayRef<uint8_t> BulkSymbols);
  82. // Add symbols of known size which will be merged (rewritten) when committing
  83. // the PDB to disk.
  84. void addUnmergedSymbols(void *SymSrc, uint32_t SymLength);
  85. void
  86. addDebugSubsection(std::shared_ptr<codeview::DebugSubsection> Subsection);
  87. void
  88. addDebugSubsection(const codeview::DebugSubsectionRecord &SubsectionContents);
  89. uint16_t getStreamIndex() const;
  90. StringRef getModuleName() const { return ModuleName; }
  91. StringRef getObjFileName() const { return ObjFileName; }
  92. unsigned getModuleIndex() const { return Layout.Mod; }
  93. ArrayRef<std::string> source_files() const { return SourceFiles; }
  94. uint32_t calculateSerializedLength() const;
  95. /// Return the offset within the module symbol stream of the next symbol
  96. /// record passed to addSymbol. Add four to account for the signature.
  97. uint32_t getNextSymbolOffset() const { return SymbolByteSize + 4; }
  98. void finalize();
  99. Error finalizeMsfLayout();
  100. /// Commit the DBI descriptor to the DBI stream.
  101. Error commit(BinaryStreamWriter &ModiWriter);
  102. /// Commit the accumulated symbols to the module symbol stream. Safe to call
  103. /// in parallel on different DbiModuleDescriptorBuilder objects. Only modifies
  104. /// the pre-allocated stream in question.
  105. Error commitSymbolStream(const msf::MSFLayout &MsfLayout,
  106. WritableBinaryStreamRef MsfBuffer);
  107. private:
  108. uint32_t calculateC13DebugInfoSize() const;
  109. void addSourceFile(StringRef Path);
  110. msf::MSFBuilder &MSF;
  111. uint32_t SymbolByteSize = 0;
  112. uint32_t PdbFilePathNI = 0;
  113. std::string ModuleName;
  114. std::string ObjFileName;
  115. std::vector<std::string> SourceFiles;
  116. std::vector<SymbolListWrapper> Symbols;
  117. void *MergeSymsCtx = nullptr;
  118. MergeSymbolsCallback MergeSymsCallback = nullptr;
  119. std::vector<StringTableFixup> StringTableFixups;
  120. std::vector<codeview::DebugSubsectionRecordBuilder> C13Builders;
  121. ModuleInfoHeader Layout;
  122. };
  123. } // end namespace pdb
  124. } // end namespace llvm
  125. #endif // LLVM_DEBUGINFO_PDB_NATIVE_DBIMODULEDESCRIPTORBUILDER_H
  126. #ifdef __GNUC__
  127. #pragma GCC diagnostic pop
  128. #endif