1 //===- PDB.cpp ------------------------------------------------------------===//
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
14 #include "SymbolTable.h"
16 #include "llvm/DebugInfo/CodeView/CVDebugRecord.h"
17 #include "llvm/DebugInfo/CodeView/CVTypeDumper.h"
18 #include "llvm/DebugInfo/CodeView/SymbolDumper.h"
19 #include "llvm/DebugInfo/CodeView/TypeDatabase.h"
20 #include "llvm/DebugInfo/CodeView/TypeDumpVisitor.h"
21 #include "llvm/DebugInfo/CodeView/TypeStreamMerger.h"
22 #include "llvm/DebugInfo/CodeView/TypeTableBuilder.h"
23 #include "llvm/DebugInfo/MSF/ByteStream.h"
24 #include "llvm/DebugInfo/MSF/MSFBuilder.h"
25 #include "llvm/DebugInfo/MSF/MSFCommon.h"
26 #include "llvm/DebugInfo/PDB/Raw/DbiStream.h"
27 #include "llvm/DebugInfo/PDB/Raw/DbiStreamBuilder.h"
28 #include "llvm/DebugInfo/PDB/Raw/InfoStream.h"
29 #include "llvm/DebugInfo/PDB/Raw/InfoStreamBuilder.h"
30 #include "llvm/DebugInfo/PDB/Raw/PDBFile.h"
31 #include "llvm/DebugInfo/PDB/Raw/PDBFileBuilder.h"
32 #include "llvm/DebugInfo/PDB/Raw/TpiStream.h"
33 #include "llvm/DebugInfo/PDB/Raw/TpiStreamBuilder.h"
34 #include "llvm/Object/COFF.h"
35 #include "llvm/Support/Endian.h"
36 #include "llvm/Support/FileOutputBuffer.h"
37 #include "llvm/Support/ScopedPrinter.h"
41 using namespace lld::coff;
43 using namespace llvm::codeview;
44 using namespace llvm::support;
45 using namespace llvm::support::endian;
47 using llvm::object::coff_section;
49 static ExitOnError ExitOnErr;
51 // Returns a list of all SectionChunks.
52 static std::vector<coff_section> getInputSections(SymbolTable *Symtab) {
53 std::vector<coff_section> V;
54 for (Chunk *C : Symtab->getChunks())
55 if (auto *SC = dyn_cast<SectionChunk>(C))
56 V.push_back(*SC->Header);
60 static SectionChunk *findByName(std::vector<SectionChunk *> &Sections,
62 for (SectionChunk *C : Sections)
63 if (C->getSectionName() == Name)
68 static ArrayRef<uint8_t> getDebugSection(ObjectFile *File, StringRef SecName) {
69 SectionChunk *Sec = findByName(File->getDebugChunks(), SecName);
73 // First 4 bytes are section magic.
74 ArrayRef<uint8_t> Data = Sec->getContents();
76 fatal(SecName + " too short");
77 if (read32le(Data.data()) != COFF::DEBUG_SECTION_MAGIC)
78 fatal(SecName + " has an invalid magic");
82 // Merge .debug$T sections and returns it.
83 static std::vector<uint8_t> mergeDebugT(SymbolTable *Symtab) {
84 ScopedPrinter W(outs());
86 // Visit all .debug$T sections to add them to Builder.
87 codeview::TypeTableBuilder Builder(BAlloc);
88 for (ObjectFile *File : Symtab->ObjectFiles) {
89 ArrayRef<uint8_t> Data = getDebugSection(File, ".debug$T");
93 msf::ByteStream Stream(Data);
94 codeview::CVTypeArray Types;
95 msf::StreamReader Reader(Stream);
96 if (auto EC = Reader.readArray(Types, Reader.getLength()))
97 fatal(EC, "Reader::readArray failed");
98 if (!codeview::mergeTypeStreams(Builder, Types))
99 fatal("codeview::mergeTypeStreams failed");
102 // Construct section contents.
103 std::vector<uint8_t> V;
104 Builder.ForEachRecord([&](TypeIndex TI, ArrayRef<uint8_t> Rec) {
105 V.insert(V.end(), Rec.begin(), Rec.end());
110 static void dumpDebugT(ScopedPrinter &W, ObjectFile *File) {
111 ListScope LS(W, "DebugT");
112 ArrayRef<uint8_t> Data = getDebugSection(File, ".debug$T");
117 TypeDumpVisitor TDV(TDB, &W, false);
118 CVTypeDumper TypeDumper(TDB);
119 if (auto EC = TypeDumper.dump(Data, TDV))
120 fatal(EC, "CVTypeDumper::dump failed");
123 static void dumpDebugS(ScopedPrinter &W, ObjectFile *File) {
124 ListScope LS(W, "DebugS");
125 ArrayRef<uint8_t> Data = getDebugSection(File, ".debug$S");
129 msf::ByteStream Stream(Data);
130 CVSymbolArray Symbols;
131 msf::StreamReader Reader(Stream);
132 if (auto EC = Reader.readArray(Symbols, Reader.getLength()))
133 fatal(EC, "StreamReader.readArray<CVSymbolArray> failed");
136 CVSymbolDumper SymbolDumper(W, TDB, nullptr, false);
137 if (auto EC = SymbolDumper.dump(Symbols))
138 fatal(EC, "CVSymbolDumper::dump failed");
141 // Dump CodeView debug info. This is for debugging.
142 static void dumpCodeView(SymbolTable *Symtab) {
143 ScopedPrinter W(outs());
145 for (ObjectFile *File : Symtab->ObjectFiles) {
151 static void addTypeInfo(pdb::TpiStreamBuilder &TpiBuilder,
152 ArrayRef<uint8_t> Data) {
153 msf::ByteStream Stream(Data);
154 codeview::CVTypeArray Records;
155 msf::StreamReader Reader(Stream);
156 if (auto EC = Reader.readArray(Records, Reader.getLength()))
157 fatal(EC, "Reader.readArray failed");
158 for (const codeview::CVType &Rec : Records)
159 TpiBuilder.addTypeRecord(Rec);
162 // Creates a PDB file.
163 void coff::createPDB(StringRef Path, SymbolTable *Symtab,
164 ArrayRef<uint8_t> SectionTable,
165 const llvm::codeview::DebugInfo *DI) {
167 dumpCodeView(Symtab);
169 BumpPtrAllocator Alloc;
170 pdb::PDBFileBuilder Builder(Alloc);
171 ExitOnErr(Builder.initialize(4096)); // 4096 is blocksize
173 // Create streams in MSF for predefined streams, namely
174 // PDB, TPI, DBI and IPI.
175 for (int I = 0; I < (int)pdb::kSpecialStreamCount; ++I)
176 ExitOnErr(Builder.getMsfBuilder().addStream(0));
178 // Add an Info stream.
179 auto &InfoBuilder = Builder.getInfoBuilder();
180 InfoBuilder.setAge(DI->PDB70.Age);
182 *reinterpret_cast<const pdb::PDB_UniqueId *>(&DI->PDB70.Signature));
183 // Should be the current time, but set 0 for reproducibilty.
184 InfoBuilder.setSignature(0);
185 InfoBuilder.setVersion(pdb::PdbRaw_ImplVer::PdbImplVC70);
187 // Add an empty DPI stream.
188 auto &DbiBuilder = Builder.getDbiBuilder();
189 DbiBuilder.setVersionHeader(pdb::PdbDbiV110);
191 // Add an empty TPI stream.
192 auto &TpiBuilder = Builder.getTpiBuilder();
193 TpiBuilder.setVersionHeader(pdb::PdbTpiV80);
194 std::vector<uint8_t> TpiData;
195 if (Config->DebugPdb) {
196 TpiData = mergeDebugT(Symtab);
197 addTypeInfo(TpiBuilder, TpiData);
200 // Add an empty IPI stream.
201 auto &IpiBuilder = Builder.getIpiBuilder();
202 IpiBuilder.setVersionHeader(pdb::PdbTpiV80);
204 // Add Section Contributions.
205 std::vector<pdb::SectionContrib> Contribs =
206 pdb::DbiStreamBuilder::createSectionContribs(getInputSections(Symtab));
207 DbiBuilder.setSectionContribs(Contribs);
209 // Add Section Map stream.
210 ArrayRef<object::coff_section> Sections = {
211 (const object::coff_section *)SectionTable.data(),
212 SectionTable.size() / sizeof(object::coff_section)};
213 std::vector<pdb::SecMapEntry> SectionMap =
214 pdb::DbiStreamBuilder::createSectionMap(Sections);
215 DbiBuilder.setSectionMap(SectionMap);
217 ExitOnErr(DbiBuilder.addModuleInfo("", "* Linker *"));
219 // Add COFF section header stream.
221 DbiBuilder.addDbgStream(pdb::DbgHeaderType::SectionHdr, SectionTable));
224 ExitOnErr(Builder.commit(Path));