blob: f81381e17276dc75bcb073b76ddd9cec48d1d30c [file] [log] [blame]
Zachary Turner7120a472016-06-06 20:37:05 +00001//===- YAMLOutputStyle.cpp ------------------------------------ *- C++ --*-===//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// 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
Zachary Turner7120a472016-06-06 20:37:05 +00006//
7//===----------------------------------------------------------------------===//
8
9#include "YAMLOutputStyle.h"
10
11#include "PdbYaml.h"
Zachary Turnerbd336e42017-06-09 20:46:17 +000012#include "llvm-pdbutil.h"
Zachary Turner7120a472016-06-06 20:37:05 +000013
Zachary Turner8c099fe2017-05-30 16:36:15 +000014#include "llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h"
Zachary Turner8c099fe2017-05-30 16:36:15 +000015#include "llvm/DebugInfo/CodeView/DebugSubsection.h"
Zachary Turner8c099fe2017-05-30 16:36:15 +000016#include "llvm/DebugInfo/CodeView/DebugUnknownSubsection.h"
Zachary Turnera8cfc292017-06-14 15:59:27 +000017#include "llvm/DebugInfo/CodeView/StringsAndChecksums.h"
Zachary Turner3b147642016-10-08 01:12:01 +000018#include "llvm/DebugInfo/MSF/MappedBlockStream.h"
Adrian McCarthy6b6b8c42017-01-25 22:38:55 +000019#include "llvm/DebugInfo/PDB/Native/DbiStream.h"
Zachary Turnered2597e2018-10-26 00:17:31 +000020#include "llvm/DebugInfo/PDB/Native/GlobalsStream.h"
Adrian McCarthy6b6b8c42017-01-25 22:38:55 +000021#include "llvm/DebugInfo/PDB/Native/InfoStream.h"
Zachary Turner67c56012017-04-27 16:11:19 +000022#include "llvm/DebugInfo/PDB/Native/ModuleDebugStream.h"
Adrian McCarthy6b6b8c42017-01-25 22:38:55 +000023#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
Zachary Turnered2597e2018-10-26 00:17:31 +000024#include "llvm/DebugInfo/PDB/Native/PublicsStream.h"
Adrian McCarthy6b6b8c42017-01-25 22:38:55 +000025#include "llvm/DebugInfo/PDB/Native/RawConstants.h"
Zachary Turnered2597e2018-10-26 00:17:31 +000026#include "llvm/DebugInfo/PDB/Native/SymbolStream.h"
Adrian McCarthy6b6b8c42017-01-25 22:38:55 +000027#include "llvm/DebugInfo/PDB/Native/TpiStream.h"
Zachary Turner7120a472016-06-06 20:37:05 +000028
29using namespace llvm;
Zachary Turnerc37cb0c2017-04-27 16:12:16 +000030using namespace llvm::codeview;
Zachary Turner7120a472016-06-06 20:37:05 +000031using namespace llvm::pdb;
32
Zachary Turner63055452017-06-15 22:24:24 +000033static bool checkModuleSubsection(opts::ModuleSubsection MS) {
34 return any_of(opts::pdb2yaml::DumpModuleSubsections,
35 [=](opts::ModuleSubsection M) {
36 return M == MS || M == opts::ModuleSubsection::All;
37 });
38}
39
Zachary Turnerc6d54da2016-09-09 17:46:17 +000040YAMLOutputStyle::YAMLOutputStyle(PDBFile &File)
Zachary Turnerea4e6072017-03-15 22:18:53 +000041 : File(File), Out(outs()), Obj(File.getAllocator()) {
42 Out.setWriteDefaultValues(!opts::pdb2yaml::Minimal);
43}
Zachary Turner7120a472016-06-06 20:37:05 +000044
Zachary Turnera30bd1a2016-06-30 17:42:48 +000045Error YAMLOutputStyle::dump() {
Zachary Turnerfaa554b2016-07-15 22:16:56 +000046 if (opts::pdb2yaml::StreamDirectory)
Zachary Turner8848a7a2016-07-06 18:05:57 +000047 opts::pdb2yaml::StreamMetadata = true;
Zachary Turner5b6e4e02017-04-29 01:13:21 +000048
Zachary Turnera30bd1a2016-06-30 17:42:48 +000049 if (auto EC = dumpFileHeaders())
50 return EC;
Zachary Turner7120a472016-06-06 20:37:05 +000051
Zachary Turnera30bd1a2016-06-30 17:42:48 +000052 if (auto EC = dumpStreamMetadata())
53 return EC;
54
55 if (auto EC = dumpStreamDirectory())
56 return EC;
57
Zachary Turner760ad4d2017-01-20 22:42:09 +000058 if (auto EC = dumpStringTable())
59 return EC;
60
Zachary Turner8848a7a2016-07-06 18:05:57 +000061 if (auto EC = dumpPDBStream())
62 return EC;
63
Zachary Turnerdbeaea72016-07-11 21:45:26 +000064 if (auto EC = dumpDbiStream())
65 return EC;
66
Zachary Turnerac5763e2016-08-18 16:49:29 +000067 if (auto EC = dumpTpiStream())
68 return EC;
69
Zachary Turnerde9ba152016-09-15 18:22:31 +000070 if (auto EC = dumpIpiStream())
71 return EC;
72
Zachary Turnered2597e2018-10-26 00:17:31 +000073 if (auto EC = dumpPublics())
74 return EC;
75
Zachary Turnera30bd1a2016-06-30 17:42:48 +000076 flush();
77 return Error::success();
78}
79
Zachary Turneree3b9c22017-04-25 20:22:02 +000080
Zachary Turnera30bd1a2016-06-30 17:42:48 +000081Error YAMLOutputStyle::dumpFileHeaders() {
Zachary Turnerf6b93822016-07-11 21:45:09 +000082 if (opts::pdb2yaml::NoFileHeaders)
83 return Error::success();
84
Zachary Turnera3225b02016-07-29 20:56:36 +000085 yaml::MSFHeaders Headers;
Zachary Turnerf6b93822016-07-11 21:45:09 +000086 Obj.Headers.emplace();
87 Obj.Headers->SuperBlock.NumBlocks = File.getBlockCount();
88 Obj.Headers->SuperBlock.BlockMapAddr = File.getBlockMapIndex();
Zachary Turnerf6b93822016-07-11 21:45:09 +000089 Obj.Headers->SuperBlock.BlockSize = File.getBlockSize();
Zachary Turner7120a472016-06-06 20:37:05 +000090 auto Blocks = File.getDirectoryBlockArray();
Zachary Turnerf6b93822016-07-11 21:45:09 +000091 Obj.Headers->DirectoryBlocks.assign(Blocks.begin(), Blocks.end());
92 Obj.Headers->NumDirectoryBlocks = File.getNumDirectoryBlocks();
93 Obj.Headers->SuperBlock.NumDirectoryBytes = File.getNumDirectoryBytes();
94 Obj.Headers->NumStreams =
Zachary Turnerab58ae82016-06-30 17:43:00 +000095 opts::pdb2yaml::StreamMetadata ? File.getNumStreams() : 0;
Zachary Turnerb927e022016-07-15 22:17:19 +000096 Obj.Headers->SuperBlock.FreeBlockMapBlock = File.getFreeBlockMapBlock();
Zachary Turnerf6b93822016-07-11 21:45:09 +000097 Obj.Headers->SuperBlock.Unknown1 = File.getUnknown1();
98 Obj.Headers->FileSize = File.getFileSize();
Zachary Turner7120a472016-06-06 20:37:05 +000099
100 return Error::success();
101}
102
Zachary Turner760ad4d2017-01-20 22:42:09 +0000103Error YAMLOutputStyle::dumpStringTable() {
Zachary Turner63055452017-06-15 22:24:24 +0000104 bool RequiresStringTable = opts::pdb2yaml::DumpModuleFiles ||
105 !opts::pdb2yaml::DumpModuleSubsections.empty();
Zachary Turner92dcdda2017-06-02 19:49:14 +0000106 bool RequestedStringTable = opts::pdb2yaml::StringTable;
107 if (!RequiresStringTable && !RequestedStringTable)
Zachary Turner760ad4d2017-01-20 22:42:09 +0000108 return Error::success();
109
Zachary Turner760ad4d2017-01-20 22:42:09 +0000110 auto ExpectedST = File.getStringTable();
111 if (!ExpectedST)
112 return ExpectedST.takeError();
113
Zachary Turner92dcdda2017-06-02 19:49:14 +0000114 Obj.StringTable.emplace();
Zachary Turner760ad4d2017-01-20 22:42:09 +0000115 const auto &ST = ExpectedST.get();
116 for (auto ID : ST.name_ids()) {
Zachary Turner2d5c2cd2017-05-03 17:11:11 +0000117 auto S = ST.getStringForID(ID);
118 if (!S)
119 return S.takeError();
120 if (S->empty())
121 continue;
122 Obj.StringTable->push_back(*S);
Zachary Turner760ad4d2017-01-20 22:42:09 +0000123 }
124 return Error::success();
125}
126
Zachary Turnera30bd1a2016-06-30 17:42:48 +0000127Error YAMLOutputStyle::dumpStreamMetadata() {
128 if (!opts::pdb2yaml::StreamMetadata)
Zachary Turner7120a472016-06-06 20:37:05 +0000129 return Error::success();
130
Zachary Turnerfaa554b2016-07-15 22:16:56 +0000131 Obj.StreamSizes.emplace();
132 Obj.StreamSizes->assign(File.getStreamSizes().begin(),
133 File.getStreamSizes().end());
Zachary Turner7120a472016-06-06 20:37:05 +0000134 return Error::success();
135}
136
Zachary Turnera30bd1a2016-06-30 17:42:48 +0000137Error YAMLOutputStyle::dumpStreamDirectory() {
138 if (!opts::pdb2yaml::StreamDirectory)
Zachary Turner7120a472016-06-06 20:37:05 +0000139 return Error::success();
140
Zachary Turner1dc9fd32016-06-14 20:48:36 +0000141 auto StreamMap = File.getStreamMap();
142 Obj.StreamMap.emplace();
143 for (auto &Stream : StreamMap) {
144 pdb::yaml::StreamBlockList BlockList;
Zachary Turnerfaa554b2016-07-15 22:16:56 +0000145 BlockList.Blocks.assign(Stream.begin(), Stream.end());
Zachary Turner1dc9fd32016-06-14 20:48:36 +0000146 Obj.StreamMap->push_back(BlockList);
Zachary Turner25e8b052016-06-06 20:37:17 +0000147 }
Zachary Turner25e8b052016-06-06 20:37:17 +0000148
Zachary Turner7120a472016-06-06 20:37:05 +0000149 return Error::success();
150}
151
Zachary Turner8848a7a2016-07-06 18:05:57 +0000152Error YAMLOutputStyle::dumpPDBStream() {
153 if (!opts::pdb2yaml::PdbStream)
154 return Error::success();
155
156 auto IS = File.getPDBInfoStream();
157 if (!IS)
158 return IS.takeError();
159
160 auto &InfoS = IS.get();
161 Obj.PdbStream.emplace();
162 Obj.PdbStream->Age = InfoS.getAge();
163 Obj.PdbStream->Guid = InfoS.getGuid();
164 Obj.PdbStream->Signature = InfoS.getSignature();
165 Obj.PdbStream->Version = InfoS.getVersion();
Zachary Turner05d5e612017-03-16 20:19:11 +0000166 Obj.PdbStream->Features = InfoS.getFeatureSignatures();
Zachary Turner8848a7a2016-07-06 18:05:57 +0000167
168 return Error::success();
169}
170
Zachary Turner3eedd162017-06-08 23:39:33 +0000171static opts::ModuleSubsection convertSubsectionKind(DebugSubsectionKind K) {
172 switch (K) {
173 case DebugSubsectionKind::CrossScopeExports:
174 return opts::ModuleSubsection::CrossScopeExports;
175 case DebugSubsectionKind::CrossScopeImports:
176 return opts::ModuleSubsection::CrossScopeImports;
177 case DebugSubsectionKind::FileChecksums:
178 return opts::ModuleSubsection::FileChecksums;
179 case DebugSubsectionKind::InlineeLines:
180 return opts::ModuleSubsection::InlineeLines;
181 case DebugSubsectionKind::Lines:
182 return opts::ModuleSubsection::Lines;
Zachary Turnerdeb39132017-06-09 00:28:08 +0000183 case DebugSubsectionKind::Symbols:
184 return opts::ModuleSubsection::Symbols;
185 case DebugSubsectionKind::StringTable:
186 return opts::ModuleSubsection::StringTable;
187 case DebugSubsectionKind::FrameData:
188 return opts::ModuleSubsection::FrameData;
Zachary Turner3eedd162017-06-08 23:39:33 +0000189 default:
190 return opts::ModuleSubsection::Unknown;
191 }
192 llvm_unreachable("Unreachable!");
193}
194
Zachary Turnerdbeaea72016-07-11 21:45:26 +0000195Error YAMLOutputStyle::dumpDbiStream() {
196 if (!opts::pdb2yaml::DbiStream)
197 return Error::success();
198
Alexandre Ganea741cc352018-08-06 19:35:00 +0000199 if (!File.hasPDBDbiStream())
200 return Error::success();
201
Zachary Turnerdbeaea72016-07-11 21:45:26 +0000202 auto DbiS = File.getPDBDbiStream();
203 if (!DbiS)
204 return DbiS.takeError();
205
206 auto &DS = DbiS.get();
207 Obj.DbiStream.emplace();
208 Obj.DbiStream->Age = DS.getAge();
209 Obj.DbiStream->BuildNumber = DS.getBuildNumber();
210 Obj.DbiStream->Flags = DS.getFlags();
211 Obj.DbiStream->MachineType = DS.getMachineType();
212 Obj.DbiStream->PdbDllRbld = DS.getPdbDllRbld();
213 Obj.DbiStream->PdbDllVersion = DS.getPdbDllVersion();
214 Obj.DbiStream->VerHeader = DS.getDbiVersion();
Zachary Turner63055452017-06-15 22:24:24 +0000215 if (opts::pdb2yaml::DumpModules) {
Zachary Turner1eb9a022017-05-04 23:53:29 +0000216 const auto &Modules = DS.modules();
217 for (uint32_t I = 0; I < Modules.getModuleCount(); ++I) {
218 DbiModuleDescriptor MI = Modules.getModuleDescriptor(I);
219
Zachary Turner5b6e4e02017-04-29 01:13:21 +0000220 Obj.DbiStream->ModInfos.emplace_back();
221 yaml::PdbDbiModuleInfo &DMI = Obj.DbiStream->ModInfos.back();
222
Zachary Turner1eb9a022017-05-04 23:53:29 +0000223 DMI.Mod = MI.getModuleName();
224 DMI.Obj = MI.getObjFileName();
Zachary Turner63055452017-06-15 22:24:24 +0000225 if (opts::pdb2yaml::DumpModuleFiles) {
Zachary Turner1eb9a022017-05-04 23:53:29 +0000226 auto Files = Modules.source_files(I);
227 DMI.SourceFiles.assign(Files.begin(), Files.end());
228 }
Zachary Turner3b147642016-10-08 01:12:01 +0000229
Zachary Turner1eb9a022017-05-04 23:53:29 +0000230 uint16_t ModiStream = MI.getModuleStreamIndex();
Zachary Turner5b6e4e02017-04-29 01:13:21 +0000231 if (ModiStream == kInvalidStreamIndex)
232 continue;
233
Zachary Turneree3b9c22017-04-25 20:22:02 +0000234 auto ModStreamData = msf::MappedBlockStream::createIndexedStream(
Zachary Turner5b74ff32017-06-03 00:33:35 +0000235 File.getMsfLayout(), File.getMsfBuffer(), ModiStream,
236 File.getAllocator());
Zachary Turneree3b9c22017-04-25 20:22:02 +0000237
Zachary Turner1eb9a022017-05-04 23:53:29 +0000238 pdb::ModuleDebugStreamRef ModS(MI, std::move(ModStreamData));
Zachary Turneree3b9c22017-04-25 20:22:02 +0000239 if (auto EC = ModS.reload())
240 return EC;
241
Zachary Turner92dcdda2017-06-02 19:49:14 +0000242 auto ExpectedST = File.getStringTable();
243 if (!ExpectedST)
244 return ExpectedST.takeError();
Zachary Turner63055452017-06-15 22:24:24 +0000245 if (!opts::pdb2yaml::DumpModuleSubsections.empty() &&
Zachary Turner92dcdda2017-06-02 19:49:14 +0000246 ModS.hasDebugSubsections()) {
247 auto ExpectedChecksums = ModS.findChecksumsSubsection();
248 if (!ExpectedChecksums)
249 return ExpectedChecksums.takeError();
250
Zachary Turnera8cfc292017-06-14 15:59:27 +0000251 StringsAndChecksumsRef SC(ExpectedST->getStringTable(),
252 *ExpectedChecksums);
253
Zachary Turner92dcdda2017-06-02 19:49:14 +0000254 for (const auto &SS : ModS.subsections()) {
Zachary Turner3eedd162017-06-08 23:39:33 +0000255 opts::ModuleSubsection OptionKind = convertSubsectionKind(SS.kind());
Zachary Turner63055452017-06-15 22:24:24 +0000256 if (!checkModuleSubsection(OptionKind))
Zachary Turner3eedd162017-06-08 23:39:33 +0000257 continue;
258
Zachary Turner92dcdda2017-06-02 19:49:14 +0000259 auto Converted =
Zachary Turnera8cfc292017-06-14 15:59:27 +0000260 CodeViewYAML::YAMLDebugSubsection::fromCodeViewSubection(SC, SS);
Zachary Turner92dcdda2017-06-02 19:49:14 +0000261 if (!Converted)
262 return Converted.takeError();
263 DMI.Subsections.push_back(*Converted);
264 }
Zachary Turneree3b9c22017-04-25 20:22:02 +0000265 }
266
Zachary Turner63055452017-06-15 22:24:24 +0000267 if (opts::pdb2yaml::DumpModuleSyms) {
Zachary Turner3b147642016-10-08 01:12:01 +0000268 DMI.Modi.emplace();
Zachary Turner3b147642016-10-08 01:12:01 +0000269
270 DMI.Modi->Signature = ModS.signature();
271 bool HadError = false;
272 for (auto &Sym : ModS.symbols(&HadError)) {
Zachary Turner1e4d3692017-05-30 23:50:44 +0000273 auto ES = CodeViewYAML::SymbolRecord::fromCodeViewSymbol(Sym);
274 if (!ES)
275 return ES.takeError();
276
277 DMI.Modi->Symbols.push_back(*ES);
Zachary Turner3b147642016-10-08 01:12:01 +0000278 }
279 }
Zachary Turnerd218c262016-07-22 15:46:37 +0000280 }
281 }
Zachary Turnerdbeaea72016-07-11 21:45:26 +0000282 return Error::success();
283}
284
Zachary Turnerac5763e2016-08-18 16:49:29 +0000285Error YAMLOutputStyle::dumpTpiStream() {
286 if (!opts::pdb2yaml::TpiStream)
287 return Error::success();
288
289 auto TpiS = File.getPDBTpiStream();
290 if (!TpiS)
291 return TpiS.takeError();
292
293 auto &TS = TpiS.get();
294 Obj.TpiStream.emplace();
295 Obj.TpiStream->Version = TS.getTpiVersion();
296 for (auto &Record : TS.types(nullptr)) {
Zachary Turnerd4273832017-05-30 21:53:05 +0000297 auto ExpectedRecord = CodeViewYAML::LeafRecord::fromCodeViewRecord(Record);
298 if (!ExpectedRecord)
299 return ExpectedRecord.takeError();
300 Obj.TpiStream->Records.push_back(*ExpectedRecord);
Zachary Turnerac5763e2016-08-18 16:49:29 +0000301 }
302
303 return Error::success();
304}
305
Zachary Turnerde9ba152016-09-15 18:22:31 +0000306Error YAMLOutputStyle::dumpIpiStream() {
307 if (!opts::pdb2yaml::IpiStream)
308 return Error::success();
309
Zachary Turner990d0c82017-06-12 21:34:53 +0000310 auto InfoS = File.getPDBInfoStream();
311 if (!InfoS)
312 return InfoS.takeError();
313 if (!InfoS->containsIdStream())
314 return Error::success();
315
Zachary Turnerde9ba152016-09-15 18:22:31 +0000316 auto IpiS = File.getPDBIpiStream();
317 if (!IpiS)
318 return IpiS.takeError();
319
320 auto &IS = IpiS.get();
321 Obj.IpiStream.emplace();
322 Obj.IpiStream->Version = IS.getTpiVersion();
323 for (auto &Record : IS.types(nullptr)) {
Zachary Turnerd4273832017-05-30 21:53:05 +0000324 auto ExpectedRecord = CodeViewYAML::LeafRecord::fromCodeViewRecord(Record);
325 if (!ExpectedRecord)
326 return ExpectedRecord.takeError();
327
328 Obj.IpiStream->Records.push_back(*ExpectedRecord);
Zachary Turnerde9ba152016-09-15 18:22:31 +0000329 }
330
331 return Error::success();
332}
333
Zachary Turnered2597e2018-10-26 00:17:31 +0000334Error YAMLOutputStyle::dumpPublics() {
335 if (!opts::pdb2yaml::PublicsStream)
336 return Error::success();
337
338 Obj.PublicsStream.emplace();
339 auto ExpectedPublics = File.getPDBPublicsStream();
340 if (!ExpectedPublics) {
341 llvm::consumeError(ExpectedPublics.takeError());
342 return Error::success();
343 }
344
345 PublicsStream &Publics = *ExpectedPublics;
346 const GSIHashTable &PublicsTable = Publics.getPublicsTable();
347
348 auto ExpectedSyms = File.getPDBSymbolStream();
349 if (!ExpectedSyms) {
350 llvm::consumeError(ExpectedSyms.takeError());
351 return Error::success();
352 }
353
354 BinaryStreamRef SymStream =
355 ExpectedSyms->getSymbolArray().getUnderlyingStream();
356 for (uint32_t PubSymOff : PublicsTable) {
357 Expected<CVSymbol> Sym = readSymbolFromStream(SymStream, PubSymOff);
358 if (!Sym)
359 return Sym.takeError();
360 auto ES = CodeViewYAML::SymbolRecord::fromCodeViewSymbol(*Sym);
361 if (!ES)
362 return ES.takeError();
363
364 Obj.PublicsStream->PubSyms.push_back(*ES);
365 }
366
367 return Error::success();
368}
369
Zachary Turner7120a472016-06-06 20:37:05 +0000370void YAMLOutputStyle::flush() {
371 Out << Obj;
372 outs().flush();
373}