Rename some PDB classes.
[lldb.git] / llvm / lib / DebugInfo / PDB / Native / DbiModuleDescriptorBuilder.cpp
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
10 #include "llvm/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.h"
11
12 #include "llvm/ADT/ArrayRef.h"
13 #include "llvm/DebugInfo/MSF/MSFBuilder.h"
14 #include "llvm/DebugInfo/MSF/MSFCommon.h"
15 #include "llvm/DebugInfo/MSF/MappedBlockStream.h"
16 #include "llvm/DebugInfo/PDB/Native/DbiModuleDescriptor.h"
17 #include "llvm/DebugInfo/PDB/Native/RawConstants.h"
18 #include "llvm/DebugInfo/PDB/Native/RawError.h"
19 #include "llvm/Support/BinaryItemStream.h"
20 #include "llvm/Support/BinaryStreamWriter.h"
21 #include "llvm/Support/COFF.h"
22
23 using namespace llvm;
24 using namespace llvm::codeview;
25 using namespace llvm::msf;
26 using namespace llvm::pdb;
27
28 namespace llvm {
29 template <> struct BinaryItemTraits<CVSymbol> {
30   static size_t length(const CVSymbol &Item) { return Item.RecordData.size(); }
31
32   static ArrayRef<uint8_t> bytes(const CVSymbol &Item) {
33     return Item.RecordData;
34   }
35 };
36 }
37
38 static uint32_t calculateDiSymbolStreamSize(uint32_t SymbolByteSize) {
39   uint32_t Size = sizeof(uint32_t); // Signature
40   Size += SymbolByteSize;           // Symbol Data
41   Size += 0;                        // TODO: Layout.LineBytes
42   Size += 0;                        // TODO: Layout.C13Bytes
43   Size += sizeof(uint32_t);         // GlobalRefs substream size (always 0)
44   Size += 0;                        // GlobalRefs substream bytes
45   return Size;
46 }
47
48 DbiModuleDescriptorBuilder::DbiModuleDescriptorBuilder(StringRef ModuleName,
49                                                        uint32_t ModIndex,
50                                                        msf::MSFBuilder &Msf)
51     : MSF(Msf), ModuleName(ModuleName) {
52   Layout.Mod = ModIndex;
53 }
54
55 uint16_t DbiModuleDescriptorBuilder::getStreamIndex() const {
56   return Layout.ModDiStream;
57 }
58
59 void DbiModuleDescriptorBuilder::setObjFileName(StringRef Name) {
60   ObjFileName = Name;
61 }
62
63 void DbiModuleDescriptorBuilder::addSymbol(CVSymbol Symbol) {
64   Symbols.push_back(Symbol);
65   SymbolByteSize += Symbol.data().size();
66 }
67
68 void DbiModuleDescriptorBuilder::addSourceFile(StringRef Path) {
69   SourceFiles.push_back(Path);
70 }
71
72 uint32_t DbiModuleDescriptorBuilder::calculateSerializedLength() const {
73   uint32_t L = sizeof(Layout);
74   uint32_t M = ModuleName.size() + 1;
75   uint32_t O = ObjFileName.size() + 1;
76   return alignTo(L + M + O, sizeof(uint32_t));
77 }
78
79 void DbiModuleDescriptorBuilder::finalize() {
80   Layout.C13Bytes = 0;
81   Layout.FileNameOffs = 0; // TODO: Fix this
82   Layout.Flags = 0;        // TODO: Fix this
83   Layout.LineBytes = 0;
84   (void)Layout.Mod;         // Set in constructor
85   (void)Layout.ModDiStream; // Set in finalizeMsfLayout
86   Layout.NumFiles = SourceFiles.size();
87   Layout.PdbFilePathNI = 0;
88   Layout.SrcFileNameNI = 0;
89
90   // This value includes both the signature field as well as the record bytes
91   // from the symbol stream.
92   Layout.SymBytes = SymbolByteSize + sizeof(uint32_t);
93 }
94
95 Error DbiModuleDescriptorBuilder::finalizeMsfLayout() {
96   this->Layout.ModDiStream = kInvalidStreamIndex;
97   auto ExpectedSN = MSF.addStream(calculateDiSymbolStreamSize(SymbolByteSize));
98   if (!ExpectedSN)
99     return ExpectedSN.takeError();
100   Layout.ModDiStream = *ExpectedSN;
101   return Error::success();
102 }
103
104 Error DbiModuleDescriptorBuilder::commit(BinaryStreamWriter &ModiWriter,
105                                          const msf::MSFLayout &MsfLayout,
106                                          WritableBinaryStreamRef MsfBuffer) {
107   // We write the Modi record to the `ModiWriter`, but we additionally write its
108   // symbol stream to a brand new stream.
109   if (auto EC = ModiWriter.writeObject(Layout))
110     return EC;
111   if (auto EC = ModiWriter.writeCString(ModuleName))
112     return EC;
113   if (auto EC = ModiWriter.writeCString(ObjFileName))
114     return EC;
115   if (auto EC = ModiWriter.padToAlignment(sizeof(uint32_t)))
116     return EC;
117
118   if (Layout.ModDiStream != kInvalidStreamIndex) {
119     auto NS = WritableMappedBlockStream::createIndexedStream(
120         MsfLayout, MsfBuffer, Layout.ModDiStream);
121     WritableBinaryStreamRef Ref(*NS);
122     BinaryStreamWriter SymbolWriter(Ref);
123     // Write the symbols.
124     if (auto EC =
125             SymbolWriter.writeInteger<uint32_t>(COFF::DEBUG_SECTION_MAGIC))
126       return EC;
127     BinaryItemStream<CVSymbol> Records(llvm::support::endianness::little);
128     Records.setItems(Symbols);
129     BinaryStreamRef RecordsRef(Records);
130     if (auto EC = SymbolWriter.writeStreamRef(RecordsRef))
131       return EC;
132     // TODO: Write C11 Line data
133     // TODO: Write C13 Line data
134     // TODO: Figure out what GlobalRefs substream actually is and populate it.
135     if (auto EC = SymbolWriter.writeInteger<uint32_t>(0))
136       return EC;
137     if (SymbolWriter.bytesRemaining() > 0)
138       return make_error<RawError>(raw_error_code::stream_too_long);
139   }
140   return Error::success();
141 }