LLVM  15.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"
12 #include "llvm/BinaryFormat/COFF.h"
20 
21 using namespace llvm;
22 using namespace llvm::codeview;
23 using namespace llvm::msf;
24 using namespace llvm::pdb;
25 
26 namespace llvm {
27 namespace codeview {
28 class 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 
43 DbiModuleDescriptorBuilder::DbiModuleDescriptorBuilder(StringRef ModuleName,
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 
101 void DbiModuleDescriptorBuilder::addSourceFile(StringRef Path) {
102  SourceFiles.push_back(std::string(Path));
103 }
104 
105 uint32_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 
169  auto NS = WritableMappedBlockStream::createIndexedStream(
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 }
llvm::Check::Size
@ Size
Definition: FileCheck.h:77
llvm::alignTo
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Definition: Alignment.h:148
RawConstants.h
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:17
llvm::BinaryStreamWriter::writeInteger
Error writeInteger(T Value)
Write the integer Value to the underlying stream in the specified endianness.
Definition: BinaryStreamWriter.h:58
M
We currently emits eax Perhaps this is what we really should generate is Is imull three or four cycles eax eax The current instruction priority is based on pattern complexity The former is more complex because it folds a load so the latter will not be emitted Perhaps we should use AddedComplexity to give LEA32r a higher priority We should always try to match LEA first since the LEA matching code does some estimate to determine whether the match is profitable if we care more about code then imull is better It s two bytes shorter than movl leal On a Pentium M
Definition: README.txt:252
llvm::pdb::ModuleInfoHeader::PdbFilePathNI
support::ulittle32_t PdbFilePathNI
Name Index for path to compiler PDB.
Definition: RawTypes.h:255
llvm::pdb::DbiModuleDescriptorBuilder::addSymbolsInBulk
void addSymbolsInBulk(ArrayRef< uint8_t > BulkSymbols)
Definition: DbiModuleDescriptorBuilder.cpp:75
llvm::pdb::SectionContrib
Definition: RawTypes.h:46
llvm::pdb::DbiModuleDescriptorBuilder::addUnmergedSymbols
void addUnmergedSymbols(void *SymSrc, uint32_t SymLength)
Definition: DbiModuleDescriptorBuilder.cpp:89
llvm::pdb::ModuleInfoHeader::ModDiStream
support::ulittle16_t ModDiStream
Stream Number of module debug info.
Definition: RawTypes.h:226
llvm::BinaryStreamWriter
Provides write only access to a subclass of WritableBinaryStream.
Definition: BinaryStreamWriter.h:30
llvm::Error::success
static ErrorSuccess success()
Create a success value.
Definition: Error.h:329
llvm::pdb::kInvalidStreamIndex
const uint16_t kInvalidStreamIndex
Definition: RawConstants.h:19
llvm::pdb::ModuleInfoHeader::C11Bytes
support::ulittle32_t C11Bytes
Size of C11 line number info in above stream.
Definition: RawTypes.h:232
COFF.h
llvm::pdb::DbiModuleDescriptorBuilder::calculateSerializedLength
uint32_t calculateSerializedLength() const
Definition: DbiModuleDescriptorBuilder.cpp:113
llvm::BinaryStreamWriter::setOffset
void setOffset(uint64_t Off)
Definition: BinaryStreamWriter.h:177
llvm::pdb::ModuleInfoHeader::C13Bytes
support::ulittle32_t C13Bytes
Size of C13 line number info in above stream.
Definition: RawTypes.h:235
llvm::pdb::SymbolListWrapper
Definition: DbiModuleDescriptorBuilder.h:38
llvm::pdb::DbiModuleDescriptorBuilder::commit
Error commit(BinaryStreamWriter &ModiWriter)
Commit the DBI descriptor to the DBI stream.
Definition: DbiModuleDescriptorBuilder.cpp:150
llvm::msf::MSFBuilder::addStream
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:155
RawError.h
llvm::msf
Definition: IMSFFile.h:18
llvm::msf::MSFBuilder
Definition: MSFBuilder.h:27
llvm::ArrayRef::empty
bool empty() const
empty - Check if the array is empty.
Definition: ArrayRef.h:159
llvm::pdb::ModuleInfoHeader::SymBytes
support::ulittle32_t SymBytes
Size of local symbol debug info in above stream.
Definition: RawTypes.h:229
llvm::PPCISD::SC
@ SC
CHAIN = SC CHAIN, Imm128 - System call.
Definition: PPCISelLowering.h:418
llvm::ModRefInfo::Ref
@ Ref
The access may reference the value stored in memory.
DebugSubsectionRecord.h
E
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
llvm::msf::MSFLayout
Definition: MSFCommon.h:51
llvm::pdb::DbiModuleDescriptorBuilder::setFirstSectionContrib
void setFirstSectionContrib(const SectionContrib &SC)
Definition: DbiModuleDescriptorBuilder.cpp:65
llvm::pdb::DbiModuleDescriptorBuilder::setObjFileName
void setObjFileName(StringRef Name)
Definition: DbiModuleDescriptorBuilder.cpp:57
llvm::pdb::DbiModuleDescriptorBuilder::finalize
void finalize()
Definition: DbiModuleDescriptorBuilder.cpp:120
MSFBuilder.h
CodeView.h
llvm::pdb
Definition: ConcreteSymbolEnumerator.h:20
llvm::pdb::ModuleInfoHeader::NumFiles
support::ulittle16_t NumFiles
Number of files contributing to this module.
Definition: RawTypes.h:238
llvm::pdb::DbiModuleDescriptorBuilder::addDebugSubsection
void addDebugSubsection(std::shared_ptr< codeview::DebugSubsection > Subsection)
llvm::codeview::alignOf
uint32_t alignOf(CodeViewContainer Container)
Definition: CodeView.h:611
llvm::pdb::DbiModuleDescriptorBuilder::commitSymbolStream
Error commitSymbolStream(const msf::MSFLayout &MsfLayout, WritableBinaryStreamRef MsfBuffer)
Commit the accumulated symbols to the module symbol stream.
Definition: DbiModuleDescriptorBuilder.cpp:164
llvm::RISCVFenceField::O
@ O
Definition: RISCVBaseInfo.h:239
llvm::pdb::ModuleInfoHeader::SC
SectionContrib SC
First section contribution of this module.
Definition: RawTypes.h:220
llvm::BinaryStreamWriter::bytesRemaining
uint64_t bytesRemaining() const
Definition: BinaryStreamWriter.h:180
llvm::pdb::DbiModuleDescriptorBuilder::getNextSymbolOffset
uint32_t getNextSymbolOffset() const
Return the offset within the module symbol stream of the next symbol record passed to addSymbol.
Definition: DbiModuleDescriptorBuilder.h:119
move
compiles ldr LCPI1_0 ldr ldr mov lsr tst moveq r1 ldr LCPI1_1 and r0 bx lr It would be better to do something like to fold the shift into the conditional move
Definition: README.txt:546
ArrayRef.h
llvm::BinaryStreamWriter::getOffset
uint64_t getOffset() const
Definition: BinaryStreamWriter.h:178
MappedBlockStream.h
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::codeview::DebugSubsectionRecord
Definition: DebugSubsectionRecord.h:35
llvm::BinaryStreamWriter::writeCString
Error writeCString(StringRef Str)
Write the string Str to the underlying stream followed by a null terminator.
Definition: BinaryStreamWriter.cpp:46
llvm::pdb::DbiModuleDescriptorBuilder::addSymbol
void addSymbol(codeview::CVSymbol Symbol)
Definition: DbiModuleDescriptorBuilder.cpp:70
ModuleName
Definition: ItaniumDemangle.h:989
llvm::codeview::CompileSym2Flags::EC
@ EC
Builder
assume Assume Builder
Definition: AssumeBundleBuilder.cpp:651
llvm::ArrayRef< uint8_t >
llvm::BinaryStreamWriter::writeObject
Error writeObject(const T &Obj)
Writes the object Obj to the underlying stream, as if by using memcpy.
Definition: BinaryStreamWriter.h:129
llvm::BinaryStreamWriter::writeBytes
Error writeBytes(ArrayRef< uint8_t > Buffer)
Write the bytes specified in Buffer to the underlying stream.
Definition: BinaryStreamWriter.cpp:27
Fixup
PowerPC TLS Dynamic Call Fixup
Definition: PPCTLSDynamicCall.cpp:233
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:58
llvm::codeview::CVRecord
CVRecord is a fat pointer (base + size pair) to a symbol or type record.
Definition: CVRecord.h:29
uint32_t
llvm::pdb::DbiModuleDescriptorBuilder::getStreamIndex
uint16_t getStreamIndex() const
Definition: DbiModuleDescriptorBuilder.cpp:53
llvm::msf::MSFBuilder::getAllocator
BumpPtrAllocator & getAllocator()
Definition: MSFBuilder.h:119
llvm::pdb::StringTableFixup
Represents a string table reference at some offset in the module symbol stream.
Definition: DbiModuleDescriptorBuilder.h:58
llvm::COFF::DEBUG_SECTION_MAGIC
@ DEBUG_SECTION_MAGIC
Definition: COFF.h:725
llvm::GraphProgram::Name
Name
Definition: GraphWriter.h:50
std
Definition: BitVector.h:851
llvm::codeview::DebugSubsection
Definition: DebugSubsection.h:34
uint16_t
llvm::BinaryStreamWriter::padToAlignment
Error padToAlignment(uint32_t Align)
Definition: BinaryStreamWriter.cpp:94
llvm::Error
Lightweight error class with error context and mandatory checking.
Definition: Error.h:155
llvm::codeview
Definition: AppendingTypeTableBuilder.h:22
llvm::ARMBuildAttrs::Symbol
@ Symbol
Definition: ARMBuildAttributes.h:83
calculateDiSymbolStreamSize
static uint32_t calculateDiSymbolStreamSize(uint32_t SymbolByteSize, uint32_t C13Size)
Definition: DbiModuleDescriptorBuilder.cpp:32
llvm::codeview::DebugSubsectionRecordBuilder
Definition: DebugSubsectionRecord.h:51
llvm::pdb::ModuleInfoHeader::SrcFileNameNI
support::ulittle32_t SrcFileNameNI
Name Index for src file name.
Definition: RawTypes.h:252
llvm::pdb::raw_error_code::stream_too_long
@ stream_too_long
llvm::ArrayRef::size
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:164
llvm::pdb::DbiModuleDescriptorBuilder::finalizeMsfLayout
Error finalizeMsfLayout()
Definition: DbiModuleDescriptorBuilder.cpp:137
llvm::pdb::DbiModuleDescriptorBuilder::setPdbFilePathNI
void setPdbFilePathNI(uint32_t NI)
Definition: DbiModuleDescriptorBuilder.cpp:61
llvm::pdb::ModuleInfoHeader::Flags
support::ulittle16_t Flags
See ModInfoFlags definition.
Definition: RawTypes.h:223
llvm::pdb::ModuleInfoHeader::FileNameOffs
support::ulittle32_t FileNameOffs
Array of [0..NumFiles) DBI name buffer offsets.
Definition: RawTypes.h:249
BinaryStreamWriter.h
DbiModuleDescriptorBuilder.h
llvm::WritableBinaryStreamRef
Definition: BinaryStreamRef.h:220
SpecialSubKind::string
@ string
llvm::pdb::DbiModuleDescriptorBuilder::~DbiModuleDescriptorBuilder
~DbiModuleDescriptorBuilder()
llvm::pdb::ModuleInfoHeader::Mod
support::ulittle32_t Mod
Currently opened module.
Definition: RawTypes.h:217