LLVM  13.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(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 
85 void DbiModuleDescriptorBuilder::addSourceFile(StringRef Path) {
86  SourceFiles.push_back(std::string(Path));
87 }
88 
89 uint32_t DbiModuleDescriptorBuilder::calculateC13DebugInfoSize() const {
90  uint32_t Result = 0;
91  for (const auto &Builder : C13Builders) {
92  Result += Builder.calculateSerializedLength();
93  }
94  return Result;
95 }
96 
98  uint32_t L = sizeof(Layout);
99  uint32_t M = ModuleName.size() + 1;
100  uint32_t O = ObjFileName.size() + 1;
101  return alignTo(L + M + O, sizeof(uint32_t));
102 }
103 
105  Layout.FileNameOffs = 0; // TODO: Fix this
106  Layout.Flags = 0; // TODO: Fix this
107  Layout.C11Bytes = 0;
108  Layout.C13Bytes = calculateC13DebugInfoSize();
109  (void)Layout.Mod; // Set in constructor
110  (void)Layout.ModDiStream; // Set in finalizeMsfLayout
111  Layout.NumFiles = SourceFiles.size();
112  Layout.PdbFilePathNI = PdbFilePathNI;
113  Layout.SrcFileNameNI = 0;
114 
115  // This value includes both the signature field as well as the record bytes
116  // from the symbol stream.
117  Layout.SymBytes =
119 }
120 
122  this->Layout.ModDiStream = kInvalidStreamIndex;
123  uint32_t C13Size = calculateC13DebugInfoSize();
124  if (!C13Size && !SymbolByteSize)
125  return Error::success();
126  auto ExpectedSN =
127  MSF.addStream(calculateDiSymbolStreamSize(SymbolByteSize, C13Size));
128  if (!ExpectedSN)
129  return ExpectedSN.takeError();
130  Layout.ModDiStream = *ExpectedSN;
131  return Error::success();
132 }
133 
135  const msf::MSFLayout &MsfLayout,
136  WritableBinaryStreamRef MsfBuffer) {
137  // We write the Modi record to the `ModiWriter`, but we additionally write its
138  // symbol stream to a brand new stream.
139  if (auto EC = ModiWriter.writeObject(Layout))
140  return EC;
141  if (auto EC = ModiWriter.writeCString(ModuleName))
142  return EC;
143  if (auto EC = ModiWriter.writeCString(ObjFileName))
144  return EC;
145  if (auto EC = ModiWriter.padToAlignment(sizeof(uint32_t)))
146  return EC;
147 
148  if (Layout.ModDiStream != kInvalidStreamIndex) {
149  auto NS = WritableMappedBlockStream::createIndexedStream(
150  MsfLayout, MsfBuffer, Layout.ModDiStream, MSF.getAllocator());
152  BinaryStreamWriter SymbolWriter(Ref);
153  // Write the symbols.
154  if (auto EC =
156  return EC;
157  for (ArrayRef<uint8_t> Syms : Symbols) {
158  if (auto EC = SymbolWriter.writeBytes(Syms))
159  return EC;
160  }
161  assert(SymbolWriter.getOffset() % alignOf(CodeViewContainer::Pdb) == 0 &&
162  "Invalid debug section alignment!");
163  // TODO: Write C11 Line data
164  for (const auto &Builder : C13Builders) {
165  if (auto EC = Builder.commit(SymbolWriter, CodeViewContainer::Pdb))
166  return EC;
167  }
168 
169  // TODO: Figure out what GlobalRefs substream actually is and populate it.
170  if (auto EC = SymbolWriter.writeInteger<uint32_t>(0))
171  return EC;
172  if (SymbolWriter.bytesRemaining() > 0)
173  return make_error<RawError>(raw_error_code::stream_too_long);
174  }
175  return Error::success();
176 }
177 
179  std::shared_ptr<DebugSubsection> Subsection) {
180  assert(Subsection);
181  C13Builders.push_back(DebugSubsectionRecordBuilder(std::move(Subsection)));
182 }
183 
185  const DebugSubsectionRecord &SubsectionContents) {
186  C13Builders.push_back(DebugSubsectionRecordBuilder(SubsectionContents));
187 }
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:158
RawConstants.h
llvm
This class represents lattice values for constants.
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::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:332
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:97
GSIStreamBuilder.h
llvm::pdb::ModuleInfoHeader::C13Bytes
support::ulittle32_t C13Bytes
Size of C13 line number info in above stream.
Definition: RawTypes.h:235
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:154
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:151
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:401
llvm::ModRefInfo::Ref
@ Ref
The access may reference the value stored in memory.
DebugSubsectionRecord.h
llvm::msf::MSFLayout
Definition: MSFCommon.h:51
llvm::BinaryStreamWriter::bytesRemaining
uint32_t bytesRemaining() const
Definition: BinaryStreamWriter.h:186
llvm::BinaryStreamWriter::getOffset
uint32_t getOffset() const
Definition: BinaryStreamWriter.h:184
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:104
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:606
llvm::RISCVFenceField::O
@ O
Definition: RISCVBaseInfo.h:128
llvm::pdb::ModuleInfoHeader::SC
SectionContrib SC
First section contribution of this module.
Definition: RawTypes.h:220
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:75
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
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:643
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
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:57
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::COFF::DEBUG_SECTION_MAGIC
@ DEBUG_SECTION_MAGIC
Definition: COFF.h:725
llvm::GraphProgram::Name
Name
Definition: GraphWriter.h:52
std
Definition: BitVector.h:941
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::pdb::DbiModuleDescriptorBuilder::commit
Error commit(BinaryStreamWriter &ModiWriter, const msf::MSFLayout &MsfLayout, WritableBinaryStreamRef MsfBuffer)
Definition: DbiModuleDescriptorBuilder.cpp:134
llvm::codeview
Definition: AppendingTypeTableBuilder.h:23
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:156
llvm::pdb::DbiModuleDescriptorBuilder::finalizeMsfLayout
Error finalizeMsfLayout()
Definition: DbiModuleDescriptorBuilder.cpp:121
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:222
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