LLVM  9.0.0svn
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(ModuleName) {
43  ::memset(&Layout, 0, sizeof(Layout));
44  Layout.Mod = ModIndex;
45 }
46 
48 
50  return Layout.ModDiStream;
51 }
52 
54  ObjFileName = 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(Path);
87 }
88 
89 uint32_t DbiModuleDescriptorBuilder::calculateC13DebugInfoSize() const {
90  uint32_t Result = 0;
91  for (const auto &Builder : C13Builders) {
92  assert(Builder && "Empty C13 Fragment Builder!");
93  Result += Builder->calculateSerializedLength();
94  }
95  return Result;
96 }
97 
99  uint32_t L = sizeof(Layout);
100  uint32_t M = ModuleName.size() + 1;
101  uint32_t O = ObjFileName.size() + 1;
102  return alignTo(L + M + O, sizeof(uint32_t));
103 }
104 
106  Layout.SC.Imod = Layout.Mod;
107  Layout.FileNameOffs = 0; // TODO: Fix this
108  Layout.Flags = 0; // TODO: Fix this
109  Layout.C11Bytes = 0;
110  Layout.C13Bytes = calculateC13DebugInfoSize();
111  (void)Layout.Mod; // Set in constructor
112  (void)Layout.ModDiStream; // Set in finalizeMsfLayout
113  Layout.NumFiles = SourceFiles.size();
114  Layout.PdbFilePathNI = PdbFilePathNI;
115  Layout.SrcFileNameNI = 0;
116 
117  // This value includes both the signature field as well as the record bytes
118  // from the symbol stream.
119  Layout.SymBytes = SymbolByteSize + sizeof(uint32_t);
120 }
121 
123  this->Layout.ModDiStream = kInvalidStreamIndex;
124  uint32_t C13Size = calculateC13DebugInfoSize();
125  auto ExpectedSN =
126  MSF.addStream(calculateDiSymbolStreamSize(SymbolByteSize, C13Size));
127  if (!ExpectedSN)
128  return ExpectedSN.takeError();
129  Layout.ModDiStream = *ExpectedSN;
130  return Error::success();
131 }
132 
134  const msf::MSFLayout &MsfLayout,
135  WritableBinaryStreamRef MsfBuffer) {
136  // We write the Modi record to the `ModiWriter`, but we additionally write its
137  // symbol stream to a brand new stream.
138  if (auto EC = ModiWriter.writeObject(Layout))
139  return EC;
140  if (auto EC = ModiWriter.writeCString(ModuleName))
141  return EC;
142  if (auto EC = ModiWriter.writeCString(ObjFileName))
143  return EC;
144  if (auto EC = ModiWriter.padToAlignment(sizeof(uint32_t)))
145  return EC;
146 
147  if (Layout.ModDiStream != kInvalidStreamIndex) {
148  auto NS = WritableMappedBlockStream::createIndexedStream(
149  MsfLayout, MsfBuffer, Layout.ModDiStream, MSF.getAllocator());
151  BinaryStreamWriter SymbolWriter(Ref);
152  // Write the symbols.
153  if (auto EC =
155  return EC;
156  for (ArrayRef<uint8_t> Syms : Symbols) {
157  if (auto EC = SymbolWriter.writeBytes(Syms))
158  return EC;
159  }
160  assert(SymbolWriter.getOffset() % alignOf(CodeViewContainer::Pdb) == 0 &&
161  "Invalid debug section alignment!");
162  // TODO: Write C11 Line data
163  for (const auto &Builder : C13Builders) {
164  assert(Builder && "Empty C13 Fragment Builder!");
165  if (auto EC = Builder->commit(SymbolWriter))
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(llvm::make_unique<DebugSubsectionRecordBuilder>(
182  std::move(Subsection), CodeViewContainer::Pdb));
183 }
184 
186  const DebugSubsectionRecord &SubsectionContents) {
187  C13Builders.push_back(llvm::make_unique<DebugSubsectionRecordBuilder>(
188  SubsectionContents, CodeViewContainer::Pdb));
189 }
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:23
support::ulittle16_t NumFiles
Number of files contributing to this module.
Definition: RawTypes.h:238
support::ulittle32_t SrcFileNameNI
Name Index for src file name.
Definition: RawTypes.h:252
amdgpu Simplify well known AMD library false FunctionCallee Value const Twine & Name
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:229
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:684
uint32_t alignOf(CodeViewContainer Container)
Definition: CodeView.h:588
The access may reference the value stored in memory.
support::ulittle32_t PdbFilePathNI
Name Index for path to compiler PDB.
Definition: RawTypes.h:255
support::ulittle16_t Flags
See ModInfoFlags definition.
Definition: RawTypes.h:223
SectionContrib SC
First section contribution of this module.
Definition: RawTypes.h:220
ArrayRef< uint8_t > data() const
Definition: CVRecord.h:37
void setFirstSectionContrib(const SectionContrib &SC)
support::ulittle32_t C13Bytes
Size of C13 line number info in above stream.
Definition: RawTypes.h:235
const uint16_t kInvalidStreamIndex
Definition: RawConstants.h:19
support::ulittle16_t Imod
Definition: RawTypes.h:52
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:148
support::ulittle32_t FileNameOffs
Array of [0..NumFiles) DBI name buffer offsets.
Definition: RawTypes.h:249
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:326
support::ulittle32_t Mod
Currently opened module.
Definition: RawTypes.h:217
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:154
support::ulittle16_t ModDiStream
Stream Number of module debug info.
Definition: RawTypes.h:226
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:232
Error padToAlignment(uint32_t Align)
uint32_t Size
Definition: Profile.cpp:46
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Lightweight error class with error context and mandatory checking.
Definition: Error.h:157
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:48
void addSymbolsInBulk(ArrayRef< uint8_t > BulkSymbols)
BumpPtrAllocator & getAllocator()
Definition: MSFBuilder.h:118
bool empty() const
empty - Check if the array is empty.
Definition: ArrayRef.h:143
void addDebugSubsection(std::shared_ptr< codeview::DebugSubsection > Subsection)