LLVM  14.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"
22 
23 using namespace llvm;
24 using namespace llvm::codeview;
25 using namespace llvm::msf;
26 using namespace llvm::pdb;
27 
29  uint32_t C13Size) {
30  uint32_t Size = sizeof(uint32_t); // Signature
31  Size += alignTo(SymbolByteSize, 4); // Symbol Data
32  Size += 0; // TODO: Layout.C11Bytes
33  Size += C13Size; // C13 Debug Info Size
34  Size += sizeof(uint32_t); // GlobalRefs substream size (always 0)
35  Size += 0; // GlobalRefs substream bytes
36  return Size;
37 }
38 
39 DbiModuleDescriptorBuilder::DbiModuleDescriptorBuilder(StringRef ModuleName,
40  uint32_t ModIndex,
41  msf::MSFBuilder &Msf)
42  : MSF(Msf), ModuleName(std::string(ModuleName)) {
43  ::memset(&Layout, 0, sizeof(Layout));
44  Layout.Mod = ModIndex;
45 }
46 
48 
50  return Layout.ModDiStream;
51 }
52 
54  ObjFileName = std::string(Name);
55 }
56 
58  PdbFilePathNI = NI;
59 }
60 
62  const SectionContrib &SC) {
63  Layout.SC = SC;
64 }
65 
67  // Defer to the bulk API. It does the same thing.
68  addSymbolsInBulk(Symbol.data());
69 }
70 
72  ArrayRef<uint8_t> BulkSymbols) {
73  // Do nothing for empty runs of symbols.
74  if (BulkSymbols.empty())
75  return;
76 
77  Symbols.push_back(SymbolListWrapper(BulkSymbols));
78  // Symbols written to a PDB file are required to be 4 byte aligned. The same
79  // is not true of object files.
80  assert(BulkSymbols.size() % alignOf(CodeViewContainer::Pdb) == 0 &&
81  "Invalid Symbol alignment!");
82  SymbolByteSize += BulkSymbols.size();
83 }
84 
86  uint32_t SymLength) {
87  assert(SymLength > 0);
88  Symbols.push_back(SymbolListWrapper(SymSrc, SymLength));
89 
90  // Symbols written to a PDB file are required to be 4 byte aligned. The same
91  // is not true of object files.
92  assert(SymLength % alignOf(CodeViewContainer::Pdb) == 0 &&
93  "Invalid Symbol alignment!");
94  SymbolByteSize += SymLength;
95 }
96 
97 void DbiModuleDescriptorBuilder::addSourceFile(StringRef Path) {
98  SourceFiles.push_back(std::string(Path));
99 }
100 
101 uint32_t DbiModuleDescriptorBuilder::calculateC13DebugInfoSize() const {
102  uint32_t Result = 0;
103  for (const auto &Builder : C13Builders) {
104  Result += Builder.calculateSerializedLength();
105  }
106  return Result;
107 }
108 
110  uint32_t L = sizeof(Layout);
111  uint32_t M = ModuleName.size() + 1;
112  uint32_t O = ObjFileName.size() + 1;
113  return alignTo(L + M + O, sizeof(uint32_t));
114 }
115 
117  Layout.FileNameOffs = 0; // TODO: Fix this
118  Layout.Flags = 0; // TODO: Fix this
119  Layout.C11Bytes = 0;
120  Layout.C13Bytes = calculateC13DebugInfoSize();
121  (void)Layout.Mod; // Set in constructor
122  (void)Layout.ModDiStream; // Set in finalizeMsfLayout
123  Layout.NumFiles = SourceFiles.size();
124  Layout.PdbFilePathNI = PdbFilePathNI;
125  Layout.SrcFileNameNI = 0;
126 
127  // This value includes both the signature field as well as the record bytes
128  // from the symbol stream.
129  Layout.SymBytes =
131 }
132 
134  this->Layout.ModDiStream = kInvalidStreamIndex;
135  uint32_t C13Size = calculateC13DebugInfoSize();
136  if (!C13Size && !SymbolByteSize)
137  return Error::success();
138  auto ExpectedSN =
139  MSF.addStream(calculateDiSymbolStreamSize(SymbolByteSize, C13Size));
140  if (!ExpectedSN)
141  return ExpectedSN.takeError();
142  Layout.ModDiStream = *ExpectedSN;
143  return Error::success();
144 }
145 
147  // We write the Modi record to the `ModiWriter`, but we additionally write its
148  // symbol stream to a brand new stream.
149  if (auto EC = ModiWriter.writeObject(Layout))
150  return EC;
151  if (auto EC = ModiWriter.writeCString(ModuleName))
152  return EC;
153  if (auto EC = ModiWriter.writeCString(ObjFileName))
154  return EC;
155  if (auto EC = ModiWriter.padToAlignment(sizeof(uint32_t)))
156  return EC;
157  return Error::success();
158 }
159 
161  const msf::MSFLayout &MsfLayout, WritableBinaryStreamRef MsfBuffer) {
162  if (Layout.ModDiStream == kInvalidStreamIndex)
163  return Error::success();
164 
165  auto NS = WritableMappedBlockStream::createIndexedStream(
166  MsfLayout, MsfBuffer, Layout.ModDiStream, MSF.getAllocator());
168  BinaryStreamWriter SymbolWriter(Ref);
169  // Write the symbols.
170  if (auto EC = SymbolWriter.writeInteger<uint32_t>(COFF::DEBUG_SECTION_MAGIC))
171  return EC;
172  for (const SymbolListWrapper &Sym : Symbols) {
173  if (Sym.NeedsToBeMerged) {
174  assert(MergeSymsCallback);
175  if (auto EC = MergeSymsCallback(MergeSymsCtx, Sym.SymPtr, SymbolWriter))
176  return EC;
177  } else {
178  if (auto EC = SymbolWriter.writeBytes(Sym.asArray()))
179  return EC;
180  }
181  }
182 
183  // Apply the string table fixups.
184  auto SavedOffset = SymbolWriter.getOffset();
185  for (const StringTableFixup &Fixup : StringTableFixups) {
186  SymbolWriter.setOffset(Fixup.SymOffsetOfReference);
187  if (auto E = SymbolWriter.writeInteger<uint32_t>(Fixup.StrTabOffset))
188  return E;
189  }
190  SymbolWriter.setOffset(SavedOffset);
191 
192  assert(SymbolWriter.getOffset() % alignOf(CodeViewContainer::Pdb) == 0 &&
193  "Invalid debug section alignment!");
194  // TODO: Write C11 Line data
195  for (const auto &Builder : C13Builders) {
196  if (auto EC = Builder.commit(SymbolWriter, CodeViewContainer::Pdb))
197  return EC;
198  }
199 
200  // TODO: Figure out what GlobalRefs substream actually is and populate it.
201  if (auto EC = SymbolWriter.writeInteger<uint32_t>(0))
202  return EC;
203  if (SymbolWriter.bytesRemaining() > 0)
204  return make_error<RawError>(raw_error_code::stream_too_long);
205 
206  return Error::success();
207 }
208 
210  std::shared_ptr<DebugSubsection> Subsection) {
211  assert(Subsection);
212  C13Builders.push_back(DebugSubsectionRecordBuilder(std::move(Subsection)));
213 }
214 
216  const DebugSubsectionRecord &SubsectionContents) {
217  C13Builders.push_back(DebugSubsectionRecordBuilder(SubsectionContents));
218 }
llvm::Check::Size
@ Size
Definition: FileCheck.h:73
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
---------------------— PointerInfo ------------------------------------—
Definition: AllocatorList.h:23
llvm::BinaryStreamWriter::writeInteger
Error writeInteger(T Value)
Write the integer Value to the underlying stream in the specified endianness.
Definition: BinaryStreamWriter.h:64
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:71
llvm::pdb::SectionContrib
Definition: RawTypes.h:46
llvm::pdb::DbiModuleDescriptorBuilder::addUnmergedSymbols
void addUnmergedSymbols(void *SymSrc, uint32_t SymLength)
Definition: DbiModuleDescriptorBuilder.cpp:85
llvm::pdb::ModuleInfoHeader::ModDiStream
support::ulittle16_t ModDiStream
Stream Number of module debug info.
Definition: RawTypes.h:226
DbiModuleDescriptor.h
llvm::BinaryStreamWriter
Provides write only access to a subclass of WritableBinaryStream.
Definition: BinaryStreamWriter.h:31
llvm::Error::success
static ErrorSuccess success()
Create a success value.
Definition: Error.h:331
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:109
llvm::BinaryStreamWriter::setOffset
void setOffset(uint64_t Off)
Definition: BinaryStreamWriter.h:183
GSIStreamBuilder.h
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:40
llvm::pdb::DbiModuleDescriptorBuilder::commit
Error commit(BinaryStreamWriter &ModiWriter)
Commit the DBI descriptor to the DBI stream.
Definition: DbiModuleDescriptorBuilder.cpp:146
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:26
llvm::ArrayRef::empty
bool empty() const
empty - Check if the array is empty.
Definition: ArrayRef.h:160
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:410
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:61
llvm::pdb::DbiModuleDescriptorBuilder::setObjFileName
void setObjFileName(StringRef Name)
Definition: DbiModuleDescriptorBuilder.cpp:53
llvm::pdb::DbiModuleDescriptorBuilder::finalize
void finalize()
Definition: DbiModuleDescriptorBuilder.cpp:116
MSFBuilder.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:609
llvm::pdb::DbiModuleDescriptorBuilder::commitSymbolStream
Error commitSymbolStream(const msf::MSFLayout &MsfLayout, WritableBinaryStreamRef MsfBuffer)
Commit the accumulated symbols to the module symbol stream.
Definition: DbiModuleDescriptorBuilder.cpp:160
llvm::RISCVFenceField::O
@ O
Definition: RISCVBaseInfo.h:192
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:186
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:121
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:184
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:47
llvm::pdb::DbiModuleDescriptorBuilder::addSymbol
void addSymbol(codeview::CVSymbol Symbol)
Definition: DbiModuleDescriptorBuilder.cpp:66
llvm::codeview::CompileSym2Flags::EC
@ EC
Builder
assume Assume Builder
Definition: AssumeBundleBuilder.cpp:650
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:135
llvm::BinaryStreamWriter::writeBytes
Error writeBytes(ArrayRef< uint8_t > Buffer)
Write the bytes specified in Buffer to the underlying stream.
Definition: BinaryStreamWriter.cpp:28
Fixup
PowerPC TLS Dynamic Call Fixup
Definition: PPCTLSDynamicCall.cpp:235
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:30
uint32_t
MSFCommon.h
llvm::pdb::DbiModuleDescriptorBuilder::getStreamIndex
uint16_t getStreamIndex() const
Definition: DbiModuleDescriptorBuilder.cpp:49
llvm::msf::MSFBuilder::getAllocator
BumpPtrAllocator & getAllocator()
Definition: MSFBuilder.h:118
llvm::pdb::StringTableFixup
Represents a string table reference at some offset in the module symbol stream.
Definition: DbiModuleDescriptorBuilder.h:60
llvm::COFF::DEBUG_SECTION_MAGIC
@ DEBUG_SECTION_MAGIC
Definition: COFF.h:726
llvm::GraphProgram::Name
Name
Definition: GraphWriter.h:52
std
Definition: BitVector.h:838
uint16_t
llvm::BinaryStreamWriter::padToAlignment
Error padToAlignment(uint32_t Align)
Definition: BinaryStreamWriter.cpp:95
llvm::Error
Lightweight error class with error context and mandatory checking.
Definition: Error.h:157
llvm::codeview
Definition: AppendingTypeTableBuilder.h:22
llvm::ARMBuildAttrs::Symbol
@ Symbol
Definition: ARMBuildAttributes.h:79
calculateDiSymbolStreamSize
static uint32_t calculateDiSymbolStreamSize(uint32_t SymbolByteSize, uint32_t C13Size)
Definition: DbiModuleDescriptorBuilder.cpp:28
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:165
llvm::pdb::DbiModuleDescriptorBuilder::finalizeMsfLayout
Error finalizeMsfLayout()
Definition: DbiModuleDescriptorBuilder.cpp:133
llvm::pdb::DbiModuleDescriptorBuilder::setPdbFilePathNI
void setPdbFilePathNI(uint32_t NI)
Definition: DbiModuleDescriptorBuilder.cpp:57
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:221
SpecialSubKind::string
@ string
llvm::pdb::DbiModuleDescriptorBuilder::~DbiModuleDescriptorBuilder
~DbiModuleDescriptorBuilder()
Definition: DbiModuleDescriptorBuilder.cpp:47
llvm::pdb::ModuleInfoHeader::Mod
support::ulittle32_t Mod
Currently opened module.
Definition: RawTypes.h:217