blob: d5c52a69be69fd8fcfd8b5846446d3e952ecbb38 [file] [log] [blame]
Rui Ueyamae7378242015-12-04 23:11:05 +00001//===- PDB.cpp ------------------------------------------------------------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
Rui Ueyama1d99ab32016-09-15 22:24:51 +000010#include "PDB.h"
Rui Ueyama09e0b5f2016-11-12 00:00:51 +000011#include "Chunks.h"
Rui Ueyamabe939b32016-11-21 17:22:35 +000012#include "Config.h"
Rui Ueyamae7378242015-12-04 23:11:05 +000013#include "Error.h"
Rui Ueyama09e0b5f2016-11-12 00:00:51 +000014#include "SymbolTable.h"
15#include "Symbols.h"
Saleem Abdulrasooldf8a13b2017-01-04 17:56:54 +000016#include "llvm/DebugInfo/CodeView/CVDebugRecord.h"
Rui Ueyama24625fd2016-11-22 23:51:34 +000017#include "llvm/DebugInfo/CodeView/SymbolDumper.h"
Rui Ueyamabe939b32016-11-21 17:22:35 +000018#include "llvm/DebugInfo/CodeView/TypeDumper.h"
Rui Ueyama24625fd2016-11-22 23:51:34 +000019#include "llvm/DebugInfo/MSF/ByteStream.h"
Rui Ueyamab28c6d42016-09-16 04:32:33 +000020#include "llvm/DebugInfo/MSF/MSFBuilder.h"
Rui Ueyama7f382992016-09-15 18:55:18 +000021#include "llvm/DebugInfo/MSF/MSFCommon.h"
Rui Ueyamab28c6d42016-09-16 04:32:33 +000022#include "llvm/DebugInfo/PDB/Raw/DbiStream.h"
23#include "llvm/DebugInfo/PDB/Raw/DbiStreamBuilder.h"
24#include "llvm/DebugInfo/PDB/Raw/InfoStream.h"
25#include "llvm/DebugInfo/PDB/Raw/InfoStreamBuilder.h"
26#include "llvm/DebugInfo/PDB/Raw/PDBFile.h"
27#include "llvm/DebugInfo/PDB/Raw/PDBFileBuilder.h"
28#include "llvm/DebugInfo/PDB/Raw/TpiStream.h"
29#include "llvm/DebugInfo/PDB/Raw/TpiStreamBuilder.h"
Rui Ueyama20df4ec2016-10-31 21:09:21 +000030#include "llvm/Object/COFF.h"
Rui Ueyama1763c0d2015-12-08 18:39:55 +000031#include "llvm/Support/Endian.h"
Rui Ueyamae7378242015-12-04 23:11:05 +000032#include "llvm/Support/FileOutputBuffer.h"
Rui Ueyamabe939b32016-11-21 17:22:35 +000033#include "llvm/Support/ScopedPrinter.h"
Rui Ueyamae7378242015-12-04 23:11:05 +000034#include <memory>
35
Rui Ueyama1d99ab32016-09-15 22:24:51 +000036using namespace lld;
Rui Ueyama09e0b5f2016-11-12 00:00:51 +000037using namespace lld::coff;
Rui Ueyamae7378242015-12-04 23:11:05 +000038using namespace llvm;
Rui Ueyamabe939b32016-11-21 17:22:35 +000039using namespace llvm::codeview;
Rui Ueyama1763c0d2015-12-08 18:39:55 +000040using namespace llvm::support;
41using namespace llvm::support::endian;
Rui Ueyamae7378242015-12-04 23:11:05 +000042
Rui Ueyama09e0b5f2016-11-12 00:00:51 +000043using llvm::object::coff_section;
44
Rui Ueyamab28c6d42016-09-16 04:32:33 +000045static ExitOnError ExitOnErr;
46
Rui Ueyama09e0b5f2016-11-12 00:00:51 +000047// Returns a list of all SectionChunks.
48static std::vector<coff_section> getInputSections(SymbolTable *Symtab) {
49 std::vector<coff_section> V;
50 for (Chunk *C : Symtab->getChunks())
51 if (auto *SC = dyn_cast<SectionChunk>(C))
52 V.push_back(*SC->Header);
53 return V;
54}
55
Rui Ueyamabe939b32016-11-21 17:22:35 +000056static SectionChunk *findByName(std::vector<SectionChunk *> &Sections,
57 StringRef Name) {
58 for (SectionChunk *C : Sections)
59 if (C->getSectionName() == Name)
60 return C;
61 return nullptr;
62}
63
Rui Ueyama26186c72016-12-09 04:46:54 +000064static ArrayRef<uint8_t> getDebugT(ObjectFile *File) {
Rui Ueyamac5cb7372016-12-01 01:22:48 +000065 SectionChunk *Sec = findByName(File->getDebugChunks(), ".debug$T");
66 if (!Sec)
Rui Ueyama26186c72016-12-09 04:46:54 +000067 return {};
Rui Ueyamac5cb7372016-12-01 01:22:48 +000068
69 // First 4 bytes are section magic.
70 ArrayRef<uint8_t> Data = Sec->getContents();
71 if (Data.size() < 4)
72 fatal(".debug$T too short");
73 if (read32le(Data.data()) != COFF::DEBUG_SECTION_MAGIC)
74 fatal(".debug$T has an invalid magic");
Rui Ueyama26186c72016-12-09 04:46:54 +000075 return Data.slice(4);
76}
Rui Ueyamac5cb7372016-12-01 01:22:48 +000077
Rui Ueyama26186c72016-12-09 04:46:54 +000078static void dumpDebugT(ScopedPrinter &W, ObjectFile *File) {
79 ArrayRef<uint8_t> Data = getDebugT(File);
80 if (Data.empty())
81 return;
82
83 msf::ByteStream Stream(Data);
Rui Ueyamac5cb7372016-12-01 01:22:48 +000084 CVTypeDumper TypeDumper(&W, false);
Rui Ueyama26186c72016-12-09 04:46:54 +000085 if (auto EC = TypeDumper.dump(Data))
Rui Ueyamac5cb7372016-12-01 01:22:48 +000086 fatal(EC, "CVTypeDumper::dump failed");
87}
88
89static void dumpDebugS(ScopedPrinter &W, ObjectFile *File) {
90 SectionChunk *Sec = findByName(File->getDebugChunks(), ".debug$S");
91 if (!Sec)
92 return;
93
94 msf::ByteStream Stream(Sec->getContents());
95 CVSymbolArray Symbols;
96 msf::StreamReader Reader(Stream);
97 if (auto EC = Reader.readArray(Symbols, Reader.getLength()))
98 fatal(EC, "StreamReader.readArray<CVSymbolArray> failed");
99
100 CVTypeDumper TypeDumper(&W, false);
101 CVSymbolDumper SymbolDumper(W, TypeDumper, nullptr, false);
102 if (auto EC = SymbolDumper.dump(Symbols))
103 fatal(EC, "CVSymbolDumper::dump failed");
104}
105
Rui Ueyamabe939b32016-11-21 17:22:35 +0000106// Dump CodeView debug info. This is for debugging.
107static void dumpCodeView(SymbolTable *Symtab) {
108 ScopedPrinter W(outs());
109
110 for (ObjectFile *File : Symtab->ObjectFiles) {
Rui Ueyamac5cb7372016-12-01 01:22:48 +0000111 dumpDebugT(W, File);
112 dumpDebugS(W, File);
Rui Ueyamabe939b32016-11-21 17:22:35 +0000113 }
114}
115
Rui Ueyama26186c72016-12-09 04:46:54 +0000116static void addTypeInfo(SymbolTable *Symtab,
117 pdb::TpiStreamBuilder &TpiBuilder) {
118 for (ObjectFile *File : Symtab->ObjectFiles) {
119 ArrayRef<uint8_t> Data = getDebugT(File);
120 if (Data.empty())
121 continue;
122
123 msf::ByteStream Stream(Data);
124 codeview::CVTypeArray Records;
125 msf::StreamReader Reader(Stream);
126 if (auto EC = Reader.readArray(Records, Reader.getLength()))
127 fatal(EC, "Reader.readArray failed");
128 for (const codeview::CVType &Rec : Records)
129 TpiBuilder.addTypeRecord(Rec);
130 }
131}
132
Rui Ueyama09e0b5f2016-11-12 00:00:51 +0000133// Creates a PDB file.
134void coff::createPDB(StringRef Path, SymbolTable *Symtab,
Saleem Abdulrasooldf8a13b2017-01-04 17:56:54 +0000135 ArrayRef<uint8_t> SectionTable,
136 const llvm::codeview::DebugInfo *DI) {
Rui Ueyamabe939b32016-11-21 17:22:35 +0000137 if (Config->DumpPdb)
138 dumpCodeView(Symtab);
139
Rui Ueyamab28c6d42016-09-16 04:32:33 +0000140 BumpPtrAllocator Alloc;
141 pdb::PDBFileBuilder Builder(Alloc);
Rui Ueyama12979542016-09-30 20:53:45 +0000142 ExitOnErr(Builder.initialize(4096)); // 4096 is blocksize
Rui Ueyama7f382992016-09-15 18:55:18 +0000143
Rui Ueyama8d3fb5d2016-10-05 22:08:58 +0000144 // Create streams in MSF for predefined streams, namely
145 // PDB, TPI, DBI and IPI.
146 for (int I = 0; I < (int)pdb::kSpecialStreamCount; ++I)
147 ExitOnErr(Builder.getMsfBuilder().addStream(0));
Rui Ueyama7f382992016-09-15 18:55:18 +0000148
Rui Ueyamabb542b32016-09-16 22:51:17 +0000149 // Add an Info stream.
150 auto &InfoBuilder = Builder.getInfoBuilder();
Saleem Abdulrasooldf8a13b2017-01-04 17:56:54 +0000151 InfoBuilder.setAge(DI->PDB70.Age);
152 InfoBuilder.setGuid(
153 *reinterpret_cast<const pdb::PDB_UniqueId *>(&DI->PDB70.Signature));
Rui Ueyamabb542b32016-09-16 22:51:17 +0000154 // Should be the current time, but set 0 for reproducibilty.
155 InfoBuilder.setSignature(0);
Rui Ueyamabb542b32016-09-16 22:51:17 +0000156 InfoBuilder.setVersion(pdb::PdbRaw_ImplVer::PdbImplVC70);
Rui Ueyama7f382992016-09-15 18:55:18 +0000157
Rui Ueyama1343fac2016-10-06 22:52:01 +0000158 // Add an empty DPI stream.
159 auto &DbiBuilder = Builder.getDbiBuilder();
160 DbiBuilder.setVersionHeader(pdb::PdbDbiV110);
161
Rui Ueyamab28c6d42016-09-16 04:32:33 +0000162 // Add an empty TPI stream.
163 auto &TpiBuilder = Builder.getTpiBuilder();
164 TpiBuilder.setVersionHeader(pdb::PdbTpiV80);
Rui Ueyama327705d2016-12-10 17:23:23 +0000165 if (Config->DebugPdb)
166 addTypeInfo(Symtab, TpiBuilder);
Rui Ueyama1763c0d2015-12-08 18:39:55 +0000167
Rui Ueyamad381c982016-10-05 21:37:25 +0000168 // Add an empty IPI stream.
169 auto &IpiBuilder = Builder.getIpiBuilder();
170 IpiBuilder.setVersionHeader(pdb::PdbTpiV80);
171
Rui Ueyama09e0b5f2016-11-12 00:00:51 +0000172 // Add Section Contributions.
Rui Ueyama09e0b5f2016-11-12 00:00:51 +0000173 std::vector<pdb::SectionContrib> Contribs =
Vitaly Buka4cf112c2016-11-14 20:21:41 +0000174 pdb::DbiStreamBuilder::createSectionContribs(getInputSections(Symtab));
Rui Ueyama09e0b5f2016-11-12 00:00:51 +0000175 DbiBuilder.setSectionContribs(Contribs);
176
Rui Ueyama20df4ec2016-10-31 21:09:21 +0000177 // Add Section Map stream.
178 ArrayRef<object::coff_section> Sections = {
Rui Ueyama6294a242016-11-04 17:41:29 +0000179 (const object::coff_section *)SectionTable.data(),
Rui Ueyama20df4ec2016-10-31 21:09:21 +0000180 SectionTable.size() / sizeof(object::coff_section)};
181 std::vector<pdb::SecMapEntry> SectionMap =
182 pdb::DbiStreamBuilder::createSectionMap(Sections);
183 DbiBuilder.setSectionMap(SectionMap);
184
Rui Ueyamac91f7162016-11-16 01:10:46 +0000185 ExitOnErr(DbiBuilder.addModuleInfo("", "* Linker *"));
186
Rui Ueyama9f66f822016-10-11 19:45:07 +0000187 // Add COFF section header stream.
188 ExitOnErr(
189 DbiBuilder.addDbgStream(pdb::DbgHeaderType::SectionHdr, SectionTable));
190
Rui Ueyama3e9d6bb2016-09-26 23:53:55 +0000191 // Write to a file.
Rui Ueyama5c82eea2016-09-30 20:39:04 +0000192 ExitOnErr(Builder.commit(Path));
Rui Ueyamae7378242015-12-04 23:11:05 +0000193}