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