LLVM 19.0.0git
DbiModuleDescriptorBuilder.cpp
Go to the documentation of this file.
1//===- DbiModuleDescriptorBuilder.cpp - PDB Mod Info Creation ---*- 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
10
11#include "llvm/ADT/ArrayRef.h"
20
21using namespace llvm;
22using namespace llvm::codeview;
23using namespace llvm::msf;
24using namespace llvm::pdb;
25
26namespace llvm {
27namespace codeview {
28class DebugSubsection;
29}
30} // namespace llvm
31
33 uint32_t C13Size) {
34 uint32_t Size = sizeof(uint32_t); // Signature
35 Size += alignTo(SymbolByteSize, 4); // Symbol Data
36 Size += 0; // TODO: Layout.C11Bytes
37 Size += C13Size; // C13 Debug Info Size
38 Size += sizeof(uint32_t); // GlobalRefs substream size (always 0)
39 Size += 0; // GlobalRefs substream bytes
40 return Size;
41}
42
44 uint32_t ModIndex,
45 msf::MSFBuilder &Msf)
46 : MSF(Msf), ModuleName(std::string(ModuleName)) {
47 ::memset(&Layout, 0, sizeof(Layout));
48 Layout.Mod = ModIndex;
49}
50
52
54 return Layout.ModDiStream;
55}
56
58 ObjFileName = std::string(Name);
59}
60
62 PdbFilePathNI = NI;
63}
64
66 const SectionContrib &SC) {
67 Layout.SC = SC;
68}
69
71 // Defer to the bulk API. It does the same thing.
72 addSymbolsInBulk(Symbol.data());
73}
74
76 ArrayRef<uint8_t> BulkSymbols) {
77 // Do nothing for empty runs of symbols.
78 if (BulkSymbols.empty())
79 return;
80
81 Symbols.push_back(SymbolListWrapper(BulkSymbols));
82 // Symbols written to a PDB file are required to be 4 byte aligned. The same
83 // is not true of object files.
84 assert(BulkSymbols.size() % alignOf(CodeViewContainer::Pdb) == 0 &&
85 "Invalid Symbol alignment!");
86 SymbolByteSize += BulkSymbols.size();
87}
88
90 uint32_t SymLength) {
91 assert(SymLength > 0);
92 Symbols.push_back(SymbolListWrapper(SymSrc, SymLength));
93
94 // Symbols written to a PDB file are required to be 4 byte aligned. The same
95 // is not true of object files.
96 assert(SymLength % alignOf(CodeViewContainer::Pdb) == 0 &&
97 "Invalid Symbol alignment!");
98 SymbolByteSize += SymLength;
99}
100
101void DbiModuleDescriptorBuilder::addSourceFile(StringRef Path) {
102 SourceFiles.push_back(std::string(Path));
103}
104
105uint32_t DbiModuleDescriptorBuilder::calculateC13DebugInfoSize() const {
106 uint32_t Result = 0;
107 for (const auto &Builder : C13Builders) {
108 Result += Builder.calculateSerializedLength();
109 }
110 return Result;
111}
112
114 uint32_t L = sizeof(Layout);
115 uint32_t M = ModuleName.size() + 1;
116 uint32_t O = ObjFileName.size() + 1;
117 return alignTo(L + M + O, sizeof(uint32_t));
118}
119
121 Layout.FileNameOffs = 0; // TODO: Fix this
122 Layout.Flags = 0; // TODO: Fix this
123 Layout.C11Bytes = 0;
124 Layout.C13Bytes = calculateC13DebugInfoSize();
125 (void)Layout.Mod; // Set in constructor
126 (void)Layout.ModDiStream; // Set in finalizeMsfLayout
127 Layout.NumFiles = SourceFiles.size();
128 Layout.PdbFilePathNI = PdbFilePathNI;
129 Layout.SrcFileNameNI = 0;
130
131 // This value includes both the signature field as well as the record bytes
132 // from the symbol stream.
133 Layout.SymBytes =
135}
136
138 this->Layout.ModDiStream = kInvalidStreamIndex;
139 uint32_t C13Size = calculateC13DebugInfoSize();
140 if (!C13Size && !SymbolByteSize)
141 return Error::success();
142 auto ExpectedSN =
143 MSF.addStream(calculateDiSymbolStreamSize(SymbolByteSize, C13Size));
144 if (!ExpectedSN)
145 return ExpectedSN.takeError();
146 Layout.ModDiStream = *ExpectedSN;
147 return Error::success();
148}
149
151 // We write the Modi record to the `ModiWriter`, but we additionally write its
152 // symbol stream to a brand new stream.
153 if (auto EC = ModiWriter.writeObject(Layout))
154 return EC;
155 if (auto EC = ModiWriter.writeCString(ModuleName))
156 return EC;
157 if (auto EC = ModiWriter.writeCString(ObjFileName))
158 return EC;
159 if (auto EC = ModiWriter.padToAlignment(sizeof(uint32_t)))
160 return EC;
161 return Error::success();
162}
163
165 const msf::MSFLayout &MsfLayout, WritableBinaryStreamRef MsfBuffer) {
166 if (Layout.ModDiStream == kInvalidStreamIndex)
167 return Error::success();
168
170 MsfLayout, MsfBuffer, Layout.ModDiStream, MSF.getAllocator());
172 BinaryStreamWriter SymbolWriter(Ref);
173 // Write the symbols.
174 if (auto EC = SymbolWriter.writeInteger<uint32_t>(COFF::DEBUG_SECTION_MAGIC))
175 return EC;
176 for (const SymbolListWrapper &Sym : Symbols) {
177 if (Sym.NeedsToBeMerged) {
178 assert(MergeSymsCallback);
179 if (auto EC = MergeSymsCallback(MergeSymsCtx, Sym.SymPtr, SymbolWriter))
180 return EC;
181 } else {
182 if (auto EC = SymbolWriter.writeBytes(Sym.asArray()))
183 return EC;
184 }
185 }
186
187 // Apply the string table fixups.
188 auto SavedOffset = SymbolWriter.getOffset();
189 for (const StringTableFixup &Fixup : StringTableFixups) {
190 SymbolWriter.setOffset(Fixup.SymOffsetOfReference);
191 if (auto E = SymbolWriter.writeInteger<uint32_t>(Fixup.StrTabOffset))
192 return E;
193 }
194 SymbolWriter.setOffset(SavedOffset);
195
196 assert(SymbolWriter.getOffset() % alignOf(CodeViewContainer::Pdb) == 0 &&
197 "Invalid debug section alignment!");
198 // TODO: Write C11 Line data
199 for (const auto &Builder : C13Builders) {
200 if (auto EC = Builder.commit(SymbolWriter, CodeViewContainer::Pdb))
201 return EC;
202 }
203
204 // TODO: Figure out what GlobalRefs substream actually is and populate it.
205 if (auto EC = SymbolWriter.writeInteger<uint32_t>(0))
206 return EC;
207 if (SymbolWriter.bytesRemaining() > 0)
208 return make_error<RawError>(raw_error_code::stream_too_long);
209
210 return Error::success();
211}
212
214 std::shared_ptr<DebugSubsection> Subsection) {
215 assert(Subsection);
216 C13Builders.push_back(DebugSubsectionRecordBuilder(std::move(Subsection)));
217}
218
220 const DebugSubsectionRecord &SubsectionContents) {
221 C13Builders.push_back(DebugSubsectionRecordBuilder(SubsectionContents));
222}
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static uint32_t calculateDiSymbolStreamSize(uint32_t SymbolByteSize, uint32_t C13Size)
std::string Name
uint64_t Size
Symbol * Sym
Definition: ELF_riscv.cpp:479
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:165
bool empty() const
empty - Check if the array is empty.
Definition: ArrayRef.h:160
Provides write only access to a subclass of WritableBinaryStream.
Error writeCString(StringRef Str)
Write the string Str to the underlying stream followed by a null terminator.
Error writeInteger(T Value)
Write the integer Value to the underlying stream in the specified endianness.
uint64_t bytesRemaining() const
Error writeBytes(ArrayRef< uint8_t > Buffer)
Write the bytes specified in Buffer to the underlying stream.
void setOffset(uint64_t Off)
Error writeObject(const T &Obj)
Writes the object Obj to the underlying stream, as if by using memcpy.
Error padToAlignment(uint32_t Align)
Lightweight error class with error context and mandatory checking.
Definition: Error.h:160
static ErrorSuccess success()
Create a success value.
Definition: Error.h:334
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
CVRecord is a fat pointer (base + size pair) to a symbol or type record.
Definition: CVRecord.h:29
BumpPtrAllocator & getAllocator()
Definition: MSFBuilder.h:119
Expected< uint32_t > addStream(uint32_t Size, ArrayRef< uint32_t > Blocks)
Add a stream to the MSF file with the given size, occupying the given list of blocks.
Definition: MSFBuilder.cpp:156
static std::unique_ptr< WritableMappedBlockStream > createIndexedStream(const MSFLayout &Layout, WritableBinaryStreamRef MsfData, uint32_t StreamIndex, BumpPtrAllocator &Allocator)
void addUnmergedSymbols(void *SymSrc, uint32_t SymLength)
void addDebugSubsection(std::shared_ptr< codeview::DebugSubsection > Subsection)
void setFirstSectionContrib(const SectionContrib &SC)
Error commitSymbolStream(const msf::MSFLayout &MsfLayout, WritableBinaryStreamRef MsfBuffer)
Commit the accumulated symbols to the module symbol stream.
Error commit(BinaryStreamWriter &ModiWriter)
Commit the DBI descriptor to the DBI stream.
uint32_t getNextSymbolOffset() const
Return the offset within the module symbol stream of the next symbol record passed to addSymbol.
void addSymbolsInBulk(ArrayRef< uint8_t > BulkSymbols)
DbiModuleDescriptorBuilder(StringRef ModuleName, uint32_t ModIndex, msf::MSFBuilder &Msf)
@ DEBUG_SECTION_MAGIC
Definition: COFF.h:788
uint32_t alignOf(CodeViewContainer Container)
Definition: CodeView.h:621
const uint16_t kInvalidStreamIndex
Definition: RawConstants.h:19
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ Ref
The access may reference the value stored in memory.
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Definition: Alignment.h:155
Implement std::hash so that hash_code can be used in STL containers.
Definition: BitVector.h:858
support::ulittle32_t PdbFilePathNI
Name Index for path to compiler PDB.
Definition: RawTypes.h:255
support::ulittle32_t FileNameOffs
Array of [0..NumFiles) DBI name buffer offsets.
Definition: RawTypes.h:249
support::ulittle16_t ModDiStream
Stream Number of module debug info.
Definition: RawTypes.h:226
support::ulittle16_t NumFiles
Number of files contributing to this module.
Definition: RawTypes.h:238
support::ulittle16_t Flags
See ModInfoFlags definition.
Definition: RawTypes.h:223
support::ulittle32_t SrcFileNameNI
Name Index for src file name.
Definition: RawTypes.h:252
SectionContrib SC
First section contribution of this module.
Definition: RawTypes.h:220
support::ulittle32_t C13Bytes
Size of C13 line number info in above stream.
Definition: RawTypes.h:235
support::ulittle32_t SymBytes
Size of local symbol debug info in above stream.
Definition: RawTypes.h:229
support::ulittle32_t C11Bytes
Size of C11 line number info in above stream.
Definition: RawTypes.h:232
support::ulittle32_t Mod
Currently opened module.
Definition: RawTypes.h:217
Represents a string table reference at some offset in the module symbol stream.