blob: 105b3ca2a07fd45d9dd9ff8ecb4165465f4ddae2 [file] [log] [blame]
Zachary Turner7120a472016-06-06 20:37:05 +00001//===- YAMLOutputStyle.cpp ------------------------------------ *- 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 "YAMLOutputStyle.h"
11
Zachary Turner5b6e4e02017-04-29 01:13:21 +000012#include "C13DebugFragmentVisitor.h"
Zachary Turner7120a472016-06-06 20:37:05 +000013#include "PdbYaml.h"
14#include "llvm-pdbdump.h"
15
Zachary Turner8c099fe2017-05-30 16:36:15 +000016#include "llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h"
17#include "llvm/DebugInfo/CodeView/DebugInlineeLinesSubsection.h"
18#include "llvm/DebugInfo/CodeView/DebugLinesSubsection.h"
19#include "llvm/DebugInfo/CodeView/DebugSubsection.h"
Zachary Turner8c099fe2017-05-30 16:36:15 +000020#include "llvm/DebugInfo/CodeView/DebugUnknownSubsection.h"
Zachary Turneree3b9c22017-04-25 20:22:02 +000021#include "llvm/DebugInfo/CodeView/Line.h"
Zachary Turner3b147642016-10-08 01:12:01 +000022#include "llvm/DebugInfo/MSF/MappedBlockStream.h"
Adrian McCarthy6b6b8c42017-01-25 22:38:55 +000023#include "llvm/DebugInfo/PDB/Native/DbiStream.h"
24#include "llvm/DebugInfo/PDB/Native/InfoStream.h"
Zachary Turner67c56012017-04-27 16:11:19 +000025#include "llvm/DebugInfo/PDB/Native/ModuleDebugStream.h"
Adrian McCarthy6b6b8c42017-01-25 22:38:55 +000026#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
27#include "llvm/DebugInfo/PDB/Native/RawConstants.h"
Zachary Turner5b6e4e02017-04-29 01:13:21 +000028#include "llvm/DebugInfo/PDB/Native/RawError.h"
Adrian McCarthy6b6b8c42017-01-25 22:38:55 +000029#include "llvm/DebugInfo/PDB/Native/TpiStream.h"
Zachary Turner7120a472016-06-06 20:37:05 +000030
31using namespace llvm;
Zachary Turnerc37cb0c2017-04-27 16:12:16 +000032using namespace llvm::codeview;
Zachary Turner7120a472016-06-06 20:37:05 +000033using namespace llvm::pdb;
34
Zachary Turnerc6d54da2016-09-09 17:46:17 +000035YAMLOutputStyle::YAMLOutputStyle(PDBFile &File)
Zachary Turnerea4e6072017-03-15 22:18:53 +000036 : File(File), Out(outs()), Obj(File.getAllocator()) {
37 Out.setWriteDefaultValues(!opts::pdb2yaml::Minimal);
38}
Zachary Turner7120a472016-06-06 20:37:05 +000039
Zachary Turnera30bd1a2016-06-30 17:42:48 +000040Error YAMLOutputStyle::dump() {
Zachary Turnerfaa554b2016-07-15 22:16:56 +000041 if (opts::pdb2yaml::StreamDirectory)
Zachary Turner8848a7a2016-07-06 18:05:57 +000042 opts::pdb2yaml::StreamMetadata = true;
Zachary Turner5b6e4e02017-04-29 01:13:21 +000043
Zachary Turnera30bd1a2016-06-30 17:42:48 +000044 if (auto EC = dumpFileHeaders())
45 return EC;
Zachary Turner7120a472016-06-06 20:37:05 +000046
Zachary Turnera30bd1a2016-06-30 17:42:48 +000047 if (auto EC = dumpStreamMetadata())
48 return EC;
49
50 if (auto EC = dumpStreamDirectory())
51 return EC;
52
Zachary Turner760ad4d2017-01-20 22:42:09 +000053 if (auto EC = dumpStringTable())
54 return EC;
55
Zachary Turner8848a7a2016-07-06 18:05:57 +000056 if (auto EC = dumpPDBStream())
57 return EC;
58
Zachary Turnerdbeaea72016-07-11 21:45:26 +000059 if (auto EC = dumpDbiStream())
60 return EC;
61
Zachary Turnerac5763e2016-08-18 16:49:29 +000062 if (auto EC = dumpTpiStream())
63 return EC;
64
Zachary Turnerde9ba152016-09-15 18:22:31 +000065 if (auto EC = dumpIpiStream())
66 return EC;
67
Zachary Turnera30bd1a2016-06-30 17:42:48 +000068 flush();
69 return Error::success();
70}
71
Zachary Turneree3b9c22017-04-25 20:22:02 +000072
Zachary Turnera30bd1a2016-06-30 17:42:48 +000073Error YAMLOutputStyle::dumpFileHeaders() {
Zachary Turnerf6b93822016-07-11 21:45:09 +000074 if (opts::pdb2yaml::NoFileHeaders)
75 return Error::success();
76
Zachary Turnera3225b02016-07-29 20:56:36 +000077 yaml::MSFHeaders Headers;
Zachary Turnerf6b93822016-07-11 21:45:09 +000078 Obj.Headers.emplace();
79 Obj.Headers->SuperBlock.NumBlocks = File.getBlockCount();
80 Obj.Headers->SuperBlock.BlockMapAddr = File.getBlockMapIndex();
Zachary Turnerf6b93822016-07-11 21:45:09 +000081 Obj.Headers->SuperBlock.BlockSize = File.getBlockSize();
Zachary Turner7120a472016-06-06 20:37:05 +000082 auto Blocks = File.getDirectoryBlockArray();
Zachary Turnerf6b93822016-07-11 21:45:09 +000083 Obj.Headers->DirectoryBlocks.assign(Blocks.begin(), Blocks.end());
84 Obj.Headers->NumDirectoryBlocks = File.getNumDirectoryBlocks();
85 Obj.Headers->SuperBlock.NumDirectoryBytes = File.getNumDirectoryBytes();
86 Obj.Headers->NumStreams =
Zachary Turnerab58ae82016-06-30 17:43:00 +000087 opts::pdb2yaml::StreamMetadata ? File.getNumStreams() : 0;
Zachary Turnerb927e022016-07-15 22:17:19 +000088 Obj.Headers->SuperBlock.FreeBlockMapBlock = File.getFreeBlockMapBlock();
Zachary Turnerf6b93822016-07-11 21:45:09 +000089 Obj.Headers->SuperBlock.Unknown1 = File.getUnknown1();
90 Obj.Headers->FileSize = File.getFileSize();
Zachary Turner7120a472016-06-06 20:37:05 +000091
92 return Error::success();
93}
94
Zachary Turner760ad4d2017-01-20 22:42:09 +000095Error YAMLOutputStyle::dumpStringTable() {
Zachary Turner3eedd162017-06-08 23:39:33 +000096 bool RequiresStringTable = opts::shared::DumpModuleFiles ||
97 !opts::shared::DumpModuleSubsections.empty();
Zachary Turner92dcdda2017-06-02 19:49:14 +000098 bool RequestedStringTable = opts::pdb2yaml::StringTable;
99 if (!RequiresStringTable && !RequestedStringTable)
Zachary Turner760ad4d2017-01-20 22:42:09 +0000100 return Error::success();
101
Zachary Turner760ad4d2017-01-20 22:42:09 +0000102 auto ExpectedST = File.getStringTable();
103 if (!ExpectedST)
104 return ExpectedST.takeError();
105
Zachary Turner92dcdda2017-06-02 19:49:14 +0000106 Obj.StringTable.emplace();
Zachary Turner760ad4d2017-01-20 22:42:09 +0000107 const auto &ST = ExpectedST.get();
108 for (auto ID : ST.name_ids()) {
Zachary Turner2d5c2cd2017-05-03 17:11:11 +0000109 auto S = ST.getStringForID(ID);
110 if (!S)
111 return S.takeError();
112 if (S->empty())
113 continue;
114 Obj.StringTable->push_back(*S);
Zachary Turner760ad4d2017-01-20 22:42:09 +0000115 }
116 return Error::success();
117}
118
Zachary Turnera30bd1a2016-06-30 17:42:48 +0000119Error YAMLOutputStyle::dumpStreamMetadata() {
120 if (!opts::pdb2yaml::StreamMetadata)
Zachary Turner7120a472016-06-06 20:37:05 +0000121 return Error::success();
122
Zachary Turnerfaa554b2016-07-15 22:16:56 +0000123 Obj.StreamSizes.emplace();
124 Obj.StreamSizes->assign(File.getStreamSizes().begin(),
125 File.getStreamSizes().end());
Zachary Turner7120a472016-06-06 20:37:05 +0000126 return Error::success();
127}
128
Zachary Turnera30bd1a2016-06-30 17:42:48 +0000129Error YAMLOutputStyle::dumpStreamDirectory() {
130 if (!opts::pdb2yaml::StreamDirectory)
Zachary Turner7120a472016-06-06 20:37:05 +0000131 return Error::success();
132
Zachary Turner1dc9fd32016-06-14 20:48:36 +0000133 auto StreamMap = File.getStreamMap();
134 Obj.StreamMap.emplace();
135 for (auto &Stream : StreamMap) {
136 pdb::yaml::StreamBlockList BlockList;
Zachary Turnerfaa554b2016-07-15 22:16:56 +0000137 BlockList.Blocks.assign(Stream.begin(), Stream.end());
Zachary Turner1dc9fd32016-06-14 20:48:36 +0000138 Obj.StreamMap->push_back(BlockList);
Zachary Turner25e8b052016-06-06 20:37:17 +0000139 }
Zachary Turner25e8b052016-06-06 20:37:17 +0000140
Zachary Turner7120a472016-06-06 20:37:05 +0000141 return Error::success();
142}
143
Zachary Turner8848a7a2016-07-06 18:05:57 +0000144Error YAMLOutputStyle::dumpPDBStream() {
145 if (!opts::pdb2yaml::PdbStream)
146 return Error::success();
147
148 auto IS = File.getPDBInfoStream();
149 if (!IS)
150 return IS.takeError();
151
152 auto &InfoS = IS.get();
153 Obj.PdbStream.emplace();
154 Obj.PdbStream->Age = InfoS.getAge();
155 Obj.PdbStream->Guid = InfoS.getGuid();
156 Obj.PdbStream->Signature = InfoS.getSignature();
157 Obj.PdbStream->Version = InfoS.getVersion();
Zachary Turner05d5e612017-03-16 20:19:11 +0000158 Obj.PdbStream->Features = InfoS.getFeatureSignatures();
Zachary Turner8848a7a2016-07-06 18:05:57 +0000159
160 return Error::success();
161}
162
Zachary Turner3eedd162017-06-08 23:39:33 +0000163static opts::ModuleSubsection convertSubsectionKind(DebugSubsectionKind K) {
164 switch (K) {
165 case DebugSubsectionKind::CrossScopeExports:
166 return opts::ModuleSubsection::CrossScopeExports;
167 case DebugSubsectionKind::CrossScopeImports:
168 return opts::ModuleSubsection::CrossScopeImports;
169 case DebugSubsectionKind::FileChecksums:
170 return opts::ModuleSubsection::FileChecksums;
171 case DebugSubsectionKind::InlineeLines:
172 return opts::ModuleSubsection::InlineeLines;
173 case DebugSubsectionKind::Lines:
174 return opts::ModuleSubsection::Lines;
175 default:
176 return opts::ModuleSubsection::Unknown;
177 }
178 llvm_unreachable("Unreachable!");
179}
180
Zachary Turnerdbeaea72016-07-11 21:45:26 +0000181Error YAMLOutputStyle::dumpDbiStream() {
182 if (!opts::pdb2yaml::DbiStream)
183 return Error::success();
184
185 auto DbiS = File.getPDBDbiStream();
186 if (!DbiS)
187 return DbiS.takeError();
188
189 auto &DS = DbiS.get();
190 Obj.DbiStream.emplace();
191 Obj.DbiStream->Age = DS.getAge();
192 Obj.DbiStream->BuildNumber = DS.getBuildNumber();
193 Obj.DbiStream->Flags = DS.getFlags();
194 Obj.DbiStream->MachineType = DS.getMachineType();
195 Obj.DbiStream->PdbDllRbld = DS.getPdbDllRbld();
196 Obj.DbiStream->PdbDllVersion = DS.getPdbDllVersion();
197 Obj.DbiStream->VerHeader = DS.getDbiVersion();
Zachary Turner3eedd162017-06-08 23:39:33 +0000198 if (opts::shared::DumpModules) {
Zachary Turner1eb9a022017-05-04 23:53:29 +0000199 const auto &Modules = DS.modules();
200 for (uint32_t I = 0; I < Modules.getModuleCount(); ++I) {
201 DbiModuleDescriptor MI = Modules.getModuleDescriptor(I);
202
Zachary Turner5b6e4e02017-04-29 01:13:21 +0000203 Obj.DbiStream->ModInfos.emplace_back();
204 yaml::PdbDbiModuleInfo &DMI = Obj.DbiStream->ModInfos.back();
205
Zachary Turner1eb9a022017-05-04 23:53:29 +0000206 DMI.Mod = MI.getModuleName();
207 DMI.Obj = MI.getObjFileName();
Zachary Turner3eedd162017-06-08 23:39:33 +0000208 if (opts::shared::DumpModuleFiles) {
Zachary Turner1eb9a022017-05-04 23:53:29 +0000209 auto Files = Modules.source_files(I);
210 DMI.SourceFiles.assign(Files.begin(), Files.end());
211 }
Zachary Turner3b147642016-10-08 01:12:01 +0000212
Zachary Turner1eb9a022017-05-04 23:53:29 +0000213 uint16_t ModiStream = MI.getModuleStreamIndex();
Zachary Turner5b6e4e02017-04-29 01:13:21 +0000214 if (ModiStream == kInvalidStreamIndex)
215 continue;
216
Zachary Turneree3b9c22017-04-25 20:22:02 +0000217 auto ModStreamData = msf::MappedBlockStream::createIndexedStream(
Zachary Turner5b74ff32017-06-03 00:33:35 +0000218 File.getMsfLayout(), File.getMsfBuffer(), ModiStream,
219 File.getAllocator());
Zachary Turneree3b9c22017-04-25 20:22:02 +0000220
Zachary Turner1eb9a022017-05-04 23:53:29 +0000221 pdb::ModuleDebugStreamRef ModS(MI, std::move(ModStreamData));
Zachary Turneree3b9c22017-04-25 20:22:02 +0000222 if (auto EC = ModS.reload())
223 return EC;
224
Zachary Turner92dcdda2017-06-02 19:49:14 +0000225 auto ExpectedST = File.getStringTable();
226 if (!ExpectedST)
227 return ExpectedST.takeError();
Zachary Turner3eedd162017-06-08 23:39:33 +0000228 if (!opts::shared::DumpModuleSubsections.empty() &&
Zachary Turner92dcdda2017-06-02 19:49:14 +0000229 ModS.hasDebugSubsections()) {
230 auto ExpectedChecksums = ModS.findChecksumsSubsection();
231 if (!ExpectedChecksums)
232 return ExpectedChecksums.takeError();
233
234 for (const auto &SS : ModS.subsections()) {
Zachary Turner3eedd162017-06-08 23:39:33 +0000235 opts::ModuleSubsection OptionKind = convertSubsectionKind(SS.kind());
236 if (!opts::checkModuleSubsection(OptionKind))
237 continue;
238
Zachary Turner92dcdda2017-06-02 19:49:14 +0000239 auto Converted =
240 CodeViewYAML::YAMLDebugSubsection::fromCodeViewSubection(
241 ExpectedST->getStringTable(), *ExpectedChecksums, SS);
242 if (!Converted)
243 return Converted.takeError();
244 DMI.Subsections.push_back(*Converted);
245 }
Zachary Turneree3b9c22017-04-25 20:22:02 +0000246 }
247
Zachary Turner3eedd162017-06-08 23:39:33 +0000248 if (opts::shared::DumpModuleSyms) {
Zachary Turner3b147642016-10-08 01:12:01 +0000249 DMI.Modi.emplace();
Zachary Turner3b147642016-10-08 01:12:01 +0000250
251 DMI.Modi->Signature = ModS.signature();
252 bool HadError = false;
253 for (auto &Sym : ModS.symbols(&HadError)) {
Zachary Turner1e4d3692017-05-30 23:50:44 +0000254 auto ES = CodeViewYAML::SymbolRecord::fromCodeViewSymbol(Sym);
255 if (!ES)
256 return ES.takeError();
257
258 DMI.Modi->Symbols.push_back(*ES);
Zachary Turner3b147642016-10-08 01:12:01 +0000259 }
260 }
Zachary Turnerd218c262016-07-22 15:46:37 +0000261 }
262 }
Zachary Turnerdbeaea72016-07-11 21:45:26 +0000263 return Error::success();
264}
265
Zachary Turnerac5763e2016-08-18 16:49:29 +0000266Error YAMLOutputStyle::dumpTpiStream() {
267 if (!opts::pdb2yaml::TpiStream)
268 return Error::success();
269
270 auto TpiS = File.getPDBTpiStream();
271 if (!TpiS)
272 return TpiS.takeError();
273
274 auto &TS = TpiS.get();
275 Obj.TpiStream.emplace();
276 Obj.TpiStream->Version = TS.getTpiVersion();
277 for (auto &Record : TS.types(nullptr)) {
Zachary Turnerd4273832017-05-30 21:53:05 +0000278 auto ExpectedRecord = CodeViewYAML::LeafRecord::fromCodeViewRecord(Record);
279 if (!ExpectedRecord)
280 return ExpectedRecord.takeError();
281 Obj.TpiStream->Records.push_back(*ExpectedRecord);
Zachary Turnerac5763e2016-08-18 16:49:29 +0000282 }
283
284 return Error::success();
285}
286
Zachary Turnerde9ba152016-09-15 18:22:31 +0000287Error YAMLOutputStyle::dumpIpiStream() {
288 if (!opts::pdb2yaml::IpiStream)
289 return Error::success();
290
291 auto IpiS = File.getPDBIpiStream();
292 if (!IpiS)
293 return IpiS.takeError();
294
295 auto &IS = IpiS.get();
296 Obj.IpiStream.emplace();
297 Obj.IpiStream->Version = IS.getTpiVersion();
298 for (auto &Record : IS.types(nullptr)) {
Zachary Turnerd4273832017-05-30 21:53:05 +0000299 auto ExpectedRecord = CodeViewYAML::LeafRecord::fromCodeViewRecord(Record);
300 if (!ExpectedRecord)
301 return ExpectedRecord.takeError();
302
303 Obj.IpiStream->Records.push_back(*ExpectedRecord);
Zachary Turnerde9ba152016-09-15 18:22:31 +0000304 }
305
306 return Error::success();
307}
308
Zachary Turner7120a472016-06-06 20:37:05 +0000309void YAMLOutputStyle::flush() {
310 Out << Obj;
311 outs().flush();
312}