LLVM  8.0.1
DbiModuleDescriptorBuilder.cpp
Go to the documentation of this file.
1 //===- DbiModuleDescriptorBuilder.cpp - PDB Mod Info Creation ---*- C++ -*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
11 
12 #include "llvm/ADT/ArrayRef.h"
13 #include "llvm/BinaryFormat/COFF.h"
23 
24 using namespace llvm;
25 using namespace llvm::codeview;
26 using namespace llvm::msf;
27 using namespace llvm::pdb;
28 
30  uint32_t C13Size) {
31  uint32_t Size = sizeof(uint32_t); // Signature
32  Size += alignTo(SymbolByteSize, 4); // Symbol Data
33  Size += 0; // TODO: Layout.C11Bytes
34  Size += C13Size; // C13 Debug Info Size
35  Size += sizeof(uint32_t); // GlobalRefs substream size (always 0)
36  Size += 0; // GlobalRefs substream bytes
37  return Size;
38 }
39 
40 DbiModuleDescriptorBuilder::DbiModuleDescriptorBuilder(StringRef ModuleName,
41  uint32_t ModIndex,
42  msf::MSFBuilder &Msf)
43  : MSF(Msf), ModuleName(ModuleName) {
44  ::memset(&Layout, 0, sizeof(Layout));
45  Layout.Mod = ModIndex;
46 }
47 
49 
51  return Layout.ModDiStream;
52 }
53 
55  ObjFileName = Name;
56 }
57 
59  PdbFilePathNI = NI;
60 }
61 
63  const SectionContrib &SC) {
64  Layout.SC = SC;
65 }
66 
68  // Defer to the bulk API. It does the same thing.
69  addSymbolsInBulk(Symbol.data());
70 }
71 
73  ArrayRef<uint8_t> BulkSymbols) {
74  // Do nothing for empty runs of symbols.
75  if (BulkSymbols.empty())
76  return;
77 
78  Symbols.push_back(BulkSymbols);
79  // Symbols written to a PDB file are required to be 4 byte aligned. The same
80  // is not true of object files.
81  assert(BulkSymbols.size() % alignOf(CodeViewContainer::Pdb) == 0 &&
82  "Invalid Symbol alignment!");
83  SymbolByteSize += BulkSymbols.size();
84 }
85 
86 void DbiModuleDescriptorBuilder::addSourceFile(StringRef Path) {
87  SourceFiles.push_back(Path);
88 }
89 
90 uint32_t DbiModuleDescriptorBuilder::calculateC13DebugInfoSize() const {
91  uint32_t Result = 0;
92  for (const auto &Builder : C13Builders) {
93  assert(Builder && "Empty C13 Fragment Builder!");
94  Result += Builder->calculateSerializedLength();
95  }
96  return Result;
97 }
98 
100  uint32_t L = sizeof(Layout);
101  uint32_t M = ModuleName.size() + 1;
102  uint32_t O = ObjFileName.size() + 1;
103  return alignTo(L + M + O, sizeof(uint32_t));
104 }
105 
107  Layout.SC.Imod = Layout.Mod;
108  Layout.FileNameOffs = 0; // TODO: Fix this
109  Layout.Flags = 0; // TODO: Fix this
110  Layout.C11Bytes = 0;
111  Layout.C13Bytes = calculateC13DebugInfoSize();
112  (void)Layout.Mod; // Set in constructor
113  (void)Layout.ModDiStream; // Set in finalizeMsfLayout
114  Layout.NumFiles = SourceFiles.size();
115  Layout.PdbFilePathNI = PdbFilePathNI;
116  Layout.SrcFileNameNI = 0;
117 
118  // This value includes both the signature field as well as the record bytes
119  // from the symbol stream.
120  Layout.SymBytes = SymbolByteSize + sizeof(uint32_t);
121 }
122 
124  this->Layout.ModDiStream = kInvalidStreamIndex;
125  uint32_t C13Size = calculateC13DebugInfoSize();
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  assert(Builder && "Empty C13 Fragment Builder!");
166  if (auto EC = Builder->commit(SymbolWriter))
167  return EC;
168  }
169 
170  // TODO: Figure out what GlobalRefs substream actually is and populate it.
171  if (auto EC = SymbolWriter.writeInteger<uint32_t>(0))
172  return EC;
173  if (SymbolWriter.bytesRemaining() > 0)
174  return make_error<RawError>(raw_error_code::stream_too_long);
175  }
176  return Error::success();
177 }
178 
180  std::shared_ptr<DebugSubsection> Subsection) {
181  assert(Subsection);
182  C13Builders.push_back(llvm::make_unique<DebugSubsectionRecordBuilder>(
183  std::move(Subsection), CodeViewContainer::Pdb));
184 }
185 
187  const DebugSubsectionRecord &SubsectionContents) {
188  C13Builders.push_back(llvm::make_unique<DebugSubsectionRecordBuilder>(
189  SubsectionContents, CodeViewContainer::Pdb));
190 }
Error writeObject(const T &Obj)
Writes the object Obj to the underlying stream, as if by using memcpy.
Error writeBytes(ArrayRef< uint8_t > Buffer)
Write the bytes specified in Buffer to the underlying stream.
This class represents lattice values for constants.
Definition: AllocatorList.h:24
support::ulittle16_t NumFiles
Number of files contributing to this module.
Definition: RawTypes.h:239
support::ulittle32_t SrcFileNameNI
Name Index for src file name.
Definition: RawTypes.h:253
Error commit(BinaryStreamWriter &ModiWriter, const msf::MSFLayout &MsfLayout, WritableBinaryStreamRef MsfBuffer)
support::ulittle32_t SymBytes
Size of local symbol debug info in above stream.
Definition: RawTypes.h:230
uint64_t alignTo(uint64_t Value, uint64_t Align, uint64_t Skew=0)
Returns the next integer (mod 2**64) that is greater than or equal to Value and is a multiple of Alig...
Definition: MathExtras.h:685
uint32_t alignOf(CodeViewContainer Container)
Definition: CodeView.h:589
amdgpu Simplify well known AMD library false Value Value const Twine & Name
The access may reference the value stored in memory.
support::ulittle32_t PdbFilePathNI
Name Index for path to compiler PDB.
Definition: RawTypes.h:256
support::ulittle16_t Flags
See ModInfoFlags definition.
Definition: RawTypes.h:224
SectionContrib SC
First section contribution of this module.
Definition: RawTypes.h:221
ArrayRef< uint8_t > data() const
Definition: CVRecord.h:38
void setFirstSectionContrib(const SectionContrib &SC)
support::ulittle32_t C13Bytes
Size of C13 line number info in above stream.
Definition: RawTypes.h:236
const uint16_t kInvalidStreamIndex
Definition: RawConstants.h:20
support::ulittle16_t Imod
Definition: RawTypes.h:53
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:149
support::ulittle32_t FileNameOffs
Array of [0..NumFiles) DBI name buffer offsets.
Definition: RawTypes.h:250
Provides write only access to a subclass of WritableBinaryStream.
Error writeInteger(T Value)
Write the integer Value to the underlying stream in the specified endianness.
uint32_t bytesRemaining() const
Error writeCString(StringRef Str)
Write the string Str to the underlying stream followed by a null terminator.
static ErrorSuccess success()
Create a success value.
Definition: Error.h:327
support::ulittle32_t Mod
Currently opened module.
Definition: RawTypes.h:218
CHAIN = SC CHAIN, Imm128 - System call.
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
support::ulittle16_t ModDiStream
Stream Number of module debug info.
Definition: RawTypes.h:227
static uint32_t calculateDiSymbolStreamSize(uint32_t SymbolByteSize, uint32_t C13Size)
support::ulittle32_t C11Bytes
Size of C11 line number info in above stream.
Definition: RawTypes.h:233
Error padToAlignment(uint32_t Align)
uint32_t Size
Definition: Profile.cpp:47
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Lightweight error class with error context and mandatory checking.
Definition: Error.h:158
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:49
void addSymbolsInBulk(ArrayRef< uint8_t > BulkSymbols)
BumpPtrAllocator & getAllocator()
Definition: MSFBuilder.h:119
bool empty() const
empty - Check if the array is empty.
Definition: ArrayRef.h:144
void addDebugSubsection(std::shared_ptr< codeview::DebugSubsection > Subsection)