LLVM  12.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 }
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
uint32_t alignOf(CodeViewContainer Container)
Definition: CodeView.h:606
Definition: BitVector.h:959
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:50
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
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:156
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.
assume Assume Builder
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:332
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)
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Definition: Alignment.h:158
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())
uint32_t getNextSymbolOffset() const
Return the offset within the module symbol stream of the next symbol record passed to addSymbol...
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:57
void addSymbolsInBulk(ArrayRef< uint8_t > BulkSymbols)
CVRecord is a fat pointer (base + size pair) to a symbol or type record.
Definition: CVRecord.h:30
BumpPtrAllocator & getAllocator()
Definition: MSFBuilder.h:118
bool empty() const
empty - Check if the array is empty.
Definition: ArrayRef.h:151
void addDebugSubsection(std::shared_ptr< codeview::DebugSubsection > Subsection)