xref: /freebsd/contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.h (revision 700637cbb5e582861067a11aaca4d053546871d2)
1 //===- DbiModuleDescriptorBuilder.h - PDB module information ----*- 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 
9 #ifndef LLVM_DEBUGINFO_PDB_NATIVE_DBIMODULEDESCRIPTORBUILDER_H
10 #define LLVM_DEBUGINFO_PDB_NATIVE_DBIMODULEDESCRIPTORBUILDER_H
11 
12 #include "llvm/ADT/ArrayRef.h"
13 #include "llvm/ADT/StringRef.h"
14 #include "llvm/DebugInfo/CodeView/CVRecord.h"
15 #include "llvm/DebugInfo/CodeView/DebugSubsectionRecord.h"
16 #include "llvm/DebugInfo/PDB/Native/RawTypes.h"
17 #include "llvm/Support/BinaryStreamRef.h"
18 #include "llvm/Support/Compiler.h"
19 #include "llvm/Support/Error.h"
20 #include <cstdint>
21 #include <string>
22 #include <vector>
23 
24 namespace llvm {
25 class BinaryStreamWriter;
26 namespace codeview {
27 class DebugSubsection;
28 }
29 
30 namespace msf {
31 class MSFBuilder;
32 struct MSFLayout;
33 }
34 namespace pdb {
35 
36 // Represents merged or unmerged symbols. Merged symbols can be written to the
37 // output file as is, but unmerged symbols must be rewritten first. In either
38 // case, the size must be known up front.
39 struct SymbolListWrapper {
SymbolListWrapperSymbolListWrapper40   explicit SymbolListWrapper(ArrayRef<uint8_t> Syms)
41       : SymPtr(const_cast<uint8_t *>(Syms.data())), SymSize(Syms.size()),
42         NeedsToBeMerged(false) {}
SymbolListWrapperSymbolListWrapper43   explicit SymbolListWrapper(void *SymSrc, uint32_t Length)
44       : SymPtr(SymSrc), SymSize(Length), NeedsToBeMerged(true) {}
45 
asArraySymbolListWrapper46   ArrayRef<uint8_t> asArray() const {
47     return ArrayRef<uint8_t>(static_cast<const uint8_t *>(SymPtr), SymSize);
48   }
49 
sizeSymbolListWrapper50   uint32_t size() const { return SymSize; }
51 
52   void *SymPtr = nullptr;
53   uint32_t SymSize = 0;
54   bool NeedsToBeMerged = false;
55 };
56 
57 /// Represents a string table reference at some offset in the module symbol
58 /// stream.
59 struct StringTableFixup {
60   uint32_t StrTabOffset = 0;
61   uint32_t SymOffsetOfReference = 0;
62 };
63 
64 class DbiModuleDescriptorBuilder {
65   friend class DbiStreamBuilder;
66 
67 public:
68   LLVM_ABI DbiModuleDescriptorBuilder(StringRef ModuleName, uint32_t ModIndex,
69                                       msf::MSFBuilder &Msf);
70   LLVM_ABI ~DbiModuleDescriptorBuilder();
71 
72   DbiModuleDescriptorBuilder(const DbiModuleDescriptorBuilder &) = delete;
73   DbiModuleDescriptorBuilder &
74   operator=(const DbiModuleDescriptorBuilder &) = delete;
75 
76   LLVM_ABI void setPdbFilePathNI(uint32_t NI);
77   LLVM_ABI void setObjFileName(StringRef Name);
78 
79   // Callback to merge one source of unmerged symbols.
80   using MergeSymbolsCallback = Error (*)(void *Ctx, void *Symbols,
81                                          BinaryStreamWriter &Writer);
82 
setMergeSymbolsCallback(void * Ctx,MergeSymbolsCallback Callback)83   void setMergeSymbolsCallback(void *Ctx, MergeSymbolsCallback Callback) {
84     MergeSymsCtx = Ctx;
85     MergeSymsCallback = Callback;
86   }
87 
setStringTableFixups(std::vector<StringTableFixup> && Fixups)88   void setStringTableFixups(std::vector<StringTableFixup> &&Fixups) {
89     StringTableFixups = std::move(Fixups);
90   }
91 
92   LLVM_ABI void setFirstSectionContrib(const SectionContrib &SC);
93   LLVM_ABI void addSymbol(codeview::CVSymbol Symbol);
94   LLVM_ABI void addSymbolsInBulk(ArrayRef<uint8_t> BulkSymbols);
95 
96   // Add symbols of known size which will be merged (rewritten) when committing
97   // the PDB to disk.
98   LLVM_ABI void addUnmergedSymbols(void *SymSrc, uint32_t SymLength);
99 
100   LLVM_ABI void
101   addDebugSubsection(std::shared_ptr<codeview::DebugSubsection> Subsection);
102 
103   LLVM_ABI void
104   addDebugSubsection(const codeview::DebugSubsectionRecord &SubsectionContents);
105 
106   LLVM_ABI uint16_t getStreamIndex() const;
getModuleName()107   StringRef getModuleName() const { return ModuleName; }
getObjFileName()108   StringRef getObjFileName() const { return ObjFileName; }
109 
getModuleIndex()110   unsigned getModuleIndex() const { return Layout.Mod; }
111 
source_files()112   ArrayRef<std::string> source_files() const { return SourceFiles; }
113 
114   LLVM_ABI uint32_t calculateSerializedLength() const;
115 
116   /// Return the offset within the module symbol stream of the next symbol
117   /// record passed to addSymbol. Add four to account for the signature.
getNextSymbolOffset()118   uint32_t getNextSymbolOffset() const { return SymbolByteSize + 4; }
119 
120   LLVM_ABI void finalize();
121   LLVM_ABI Error finalizeMsfLayout();
122 
123   /// Commit the DBI descriptor to the DBI stream.
124   LLVM_ABI Error commit(BinaryStreamWriter &ModiWriter);
125 
126   /// Commit the accumulated symbols to the module symbol stream. Safe to call
127   /// in parallel on different DbiModuleDescriptorBuilder objects. Only modifies
128   /// the pre-allocated stream in question.
129   LLVM_ABI Error commitSymbolStream(const msf::MSFLayout &MsfLayout,
130                                     WritableBinaryStreamRef MsfBuffer);
131 
132 private:
133   uint32_t calculateC13DebugInfoSize() const;
134 
135   void addSourceFile(StringRef Path);
136   msf::MSFBuilder &MSF;
137 
138   uint32_t SymbolByteSize = 0;
139   uint32_t PdbFilePathNI = 0;
140   std::string ModuleName;
141   std::string ObjFileName;
142   std::vector<std::string> SourceFiles;
143   std::vector<SymbolListWrapper> Symbols;
144 
145   void *MergeSymsCtx = nullptr;
146   MergeSymbolsCallback MergeSymsCallback = nullptr;
147 
148   std::vector<StringTableFixup> StringTableFixups;
149 
150   std::vector<codeview::DebugSubsectionRecordBuilder> C13Builders;
151 
152   ModuleInfoHeader Layout;
153 };
154 
155 } // end namespace pdb
156 
157 } // end namespace llvm
158 
159 #endif // LLVM_DEBUGINFO_PDB_NATIVE_DBIMODULEDESCRIPTORBUILDER_H
160