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
23namespace llvm {
24class BinaryStreamWriter;
25namespace codeview {
26class DebugSubsection;
27}
28
29namespace msf {
30class MSFBuilder;
31struct MSFLayout;
32}
33namespace 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.
38struct 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
45 ArrayRef<uint8_t> asArray() const {
46 return ArrayRef<uint8_t>(static_cast<const uint8_t *>(SymPtr), SymSize);
47 }
48
49 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.
58struct StringTableFixup {
59 uint32_t StrTabOffset = 0;
60 uint32_t SymOffsetOfReference = 0;
61};
62
63class DbiModuleDescriptorBuilder {
64 friend class DbiStreamBuilder;
65
66public:
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
82 void setMergeSymbolsCallback(void *Ctx, MergeSymbolsCallback Callback) {
83 MergeSymsCtx = Ctx;
84 MergeSymsCallback = Callback;
85 }
86
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;
106 StringRef getModuleName() const { return ModuleName; }
107 StringRef getObjFileName() const { return ObjFileName; }
108
109 unsigned getModuleIndex() const { return Layout.Mod; }
110
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.
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
131private:
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

source code of llvm/include/llvm/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.h