Mercurial > hg > CbC > CbC_llvm
comparison tools/llvm-pdbutil/YAMLOutputStyle.cpp @ 121:803732b1fca8
LLVM 5.0
author | kono |
---|---|
date | Fri, 27 Oct 2017 17:07:41 +0900 |
parents | |
children | 3a76565eade5 |
comparison
equal
deleted
inserted
replaced
120:1172e4bd9c6f | 121:803732b1fca8 |
---|---|
1 //===- 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 | |
12 #include "PdbYaml.h" | |
13 #include "llvm-pdbutil.h" | |
14 | |
15 #include "llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h" | |
16 #include "llvm/DebugInfo/CodeView/DebugInlineeLinesSubsection.h" | |
17 #include "llvm/DebugInfo/CodeView/DebugLinesSubsection.h" | |
18 #include "llvm/DebugInfo/CodeView/DebugSubsection.h" | |
19 #include "llvm/DebugInfo/CodeView/DebugUnknownSubsection.h" | |
20 #include "llvm/DebugInfo/CodeView/Line.h" | |
21 #include "llvm/DebugInfo/CodeView/StringsAndChecksums.h" | |
22 #include "llvm/DebugInfo/MSF/MappedBlockStream.h" | |
23 #include "llvm/DebugInfo/PDB/Native/DbiStream.h" | |
24 #include "llvm/DebugInfo/PDB/Native/InfoStream.h" | |
25 #include "llvm/DebugInfo/PDB/Native/ModuleDebugStream.h" | |
26 #include "llvm/DebugInfo/PDB/Native/PDBFile.h" | |
27 #include "llvm/DebugInfo/PDB/Native/RawConstants.h" | |
28 #include "llvm/DebugInfo/PDB/Native/RawError.h" | |
29 #include "llvm/DebugInfo/PDB/Native/TpiStream.h" | |
30 | |
31 using namespace llvm; | |
32 using namespace llvm::codeview; | |
33 using namespace llvm::pdb; | |
34 | |
35 static bool checkModuleSubsection(opts::ModuleSubsection MS) { | |
36 return any_of(opts::pdb2yaml::DumpModuleSubsections, | |
37 [=](opts::ModuleSubsection M) { | |
38 return M == MS || M == opts::ModuleSubsection::All; | |
39 }); | |
40 } | |
41 | |
42 YAMLOutputStyle::YAMLOutputStyle(PDBFile &File) | |
43 : File(File), Out(outs()), Obj(File.getAllocator()) { | |
44 Out.setWriteDefaultValues(!opts::pdb2yaml::Minimal); | |
45 } | |
46 | |
47 Error YAMLOutputStyle::dump() { | |
48 if (opts::pdb2yaml::StreamDirectory) | |
49 opts::pdb2yaml::StreamMetadata = true; | |
50 | |
51 if (auto EC = dumpFileHeaders()) | |
52 return EC; | |
53 | |
54 if (auto EC = dumpStreamMetadata()) | |
55 return EC; | |
56 | |
57 if (auto EC = dumpStreamDirectory()) | |
58 return EC; | |
59 | |
60 if (auto EC = dumpStringTable()) | |
61 return EC; | |
62 | |
63 if (auto EC = dumpPDBStream()) | |
64 return EC; | |
65 | |
66 if (auto EC = dumpDbiStream()) | |
67 return EC; | |
68 | |
69 if (auto EC = dumpTpiStream()) | |
70 return EC; | |
71 | |
72 if (auto EC = dumpIpiStream()) | |
73 return EC; | |
74 | |
75 flush(); | |
76 return Error::success(); | |
77 } | |
78 | |
79 | |
80 Error YAMLOutputStyle::dumpFileHeaders() { | |
81 if (opts::pdb2yaml::NoFileHeaders) | |
82 return Error::success(); | |
83 | |
84 yaml::MSFHeaders Headers; | |
85 Obj.Headers.emplace(); | |
86 Obj.Headers->SuperBlock.NumBlocks = File.getBlockCount(); | |
87 Obj.Headers->SuperBlock.BlockMapAddr = File.getBlockMapIndex(); | |
88 Obj.Headers->SuperBlock.BlockSize = File.getBlockSize(); | |
89 auto Blocks = File.getDirectoryBlockArray(); | |
90 Obj.Headers->DirectoryBlocks.assign(Blocks.begin(), Blocks.end()); | |
91 Obj.Headers->NumDirectoryBlocks = File.getNumDirectoryBlocks(); | |
92 Obj.Headers->SuperBlock.NumDirectoryBytes = File.getNumDirectoryBytes(); | |
93 Obj.Headers->NumStreams = | |
94 opts::pdb2yaml::StreamMetadata ? File.getNumStreams() : 0; | |
95 Obj.Headers->SuperBlock.FreeBlockMapBlock = File.getFreeBlockMapBlock(); | |
96 Obj.Headers->SuperBlock.Unknown1 = File.getUnknown1(); | |
97 Obj.Headers->FileSize = File.getFileSize(); | |
98 | |
99 return Error::success(); | |
100 } | |
101 | |
102 Error YAMLOutputStyle::dumpStringTable() { | |
103 bool RequiresStringTable = opts::pdb2yaml::DumpModuleFiles || | |
104 !opts::pdb2yaml::DumpModuleSubsections.empty(); | |
105 bool RequestedStringTable = opts::pdb2yaml::StringTable; | |
106 if (!RequiresStringTable && !RequestedStringTable) | |
107 return Error::success(); | |
108 | |
109 auto ExpectedST = File.getStringTable(); | |
110 if (!ExpectedST) | |
111 return ExpectedST.takeError(); | |
112 | |
113 Obj.StringTable.emplace(); | |
114 const auto &ST = ExpectedST.get(); | |
115 for (auto ID : ST.name_ids()) { | |
116 auto S = ST.getStringForID(ID); | |
117 if (!S) | |
118 return S.takeError(); | |
119 if (S->empty()) | |
120 continue; | |
121 Obj.StringTable->push_back(*S); | |
122 } | |
123 return Error::success(); | |
124 } | |
125 | |
126 Error YAMLOutputStyle::dumpStreamMetadata() { | |
127 if (!opts::pdb2yaml::StreamMetadata) | |
128 return Error::success(); | |
129 | |
130 Obj.StreamSizes.emplace(); | |
131 Obj.StreamSizes->assign(File.getStreamSizes().begin(), | |
132 File.getStreamSizes().end()); | |
133 return Error::success(); | |
134 } | |
135 | |
136 Error YAMLOutputStyle::dumpStreamDirectory() { | |
137 if (!opts::pdb2yaml::StreamDirectory) | |
138 return Error::success(); | |
139 | |
140 auto StreamMap = File.getStreamMap(); | |
141 Obj.StreamMap.emplace(); | |
142 for (auto &Stream : StreamMap) { | |
143 pdb::yaml::StreamBlockList BlockList; | |
144 BlockList.Blocks.assign(Stream.begin(), Stream.end()); | |
145 Obj.StreamMap->push_back(BlockList); | |
146 } | |
147 | |
148 return Error::success(); | |
149 } | |
150 | |
151 Error YAMLOutputStyle::dumpPDBStream() { | |
152 if (!opts::pdb2yaml::PdbStream) | |
153 return Error::success(); | |
154 | |
155 auto IS = File.getPDBInfoStream(); | |
156 if (!IS) | |
157 return IS.takeError(); | |
158 | |
159 auto &InfoS = IS.get(); | |
160 Obj.PdbStream.emplace(); | |
161 Obj.PdbStream->Age = InfoS.getAge(); | |
162 Obj.PdbStream->Guid = InfoS.getGuid(); | |
163 Obj.PdbStream->Signature = InfoS.getSignature(); | |
164 Obj.PdbStream->Version = InfoS.getVersion(); | |
165 Obj.PdbStream->Features = InfoS.getFeatureSignatures(); | |
166 | |
167 return Error::success(); | |
168 } | |
169 | |
170 static opts::ModuleSubsection convertSubsectionKind(DebugSubsectionKind K) { | |
171 switch (K) { | |
172 case DebugSubsectionKind::CrossScopeExports: | |
173 return opts::ModuleSubsection::CrossScopeExports; | |
174 case DebugSubsectionKind::CrossScopeImports: | |
175 return opts::ModuleSubsection::CrossScopeImports; | |
176 case DebugSubsectionKind::FileChecksums: | |
177 return opts::ModuleSubsection::FileChecksums; | |
178 case DebugSubsectionKind::InlineeLines: | |
179 return opts::ModuleSubsection::InlineeLines; | |
180 case DebugSubsectionKind::Lines: | |
181 return opts::ModuleSubsection::Lines; | |
182 case DebugSubsectionKind::Symbols: | |
183 return opts::ModuleSubsection::Symbols; | |
184 case DebugSubsectionKind::StringTable: | |
185 return opts::ModuleSubsection::StringTable; | |
186 case DebugSubsectionKind::FrameData: | |
187 return opts::ModuleSubsection::FrameData; | |
188 default: | |
189 return opts::ModuleSubsection::Unknown; | |
190 } | |
191 llvm_unreachable("Unreachable!"); | |
192 } | |
193 | |
194 Error YAMLOutputStyle::dumpDbiStream() { | |
195 if (!opts::pdb2yaml::DbiStream) | |
196 return Error::success(); | |
197 | |
198 auto DbiS = File.getPDBDbiStream(); | |
199 if (!DbiS) | |
200 return DbiS.takeError(); | |
201 | |
202 auto &DS = DbiS.get(); | |
203 Obj.DbiStream.emplace(); | |
204 Obj.DbiStream->Age = DS.getAge(); | |
205 Obj.DbiStream->BuildNumber = DS.getBuildNumber(); | |
206 Obj.DbiStream->Flags = DS.getFlags(); | |
207 Obj.DbiStream->MachineType = DS.getMachineType(); | |
208 Obj.DbiStream->PdbDllRbld = DS.getPdbDllRbld(); | |
209 Obj.DbiStream->PdbDllVersion = DS.getPdbDllVersion(); | |
210 Obj.DbiStream->VerHeader = DS.getDbiVersion(); | |
211 if (opts::pdb2yaml::DumpModules) { | |
212 const auto &Modules = DS.modules(); | |
213 for (uint32_t I = 0; I < Modules.getModuleCount(); ++I) { | |
214 DbiModuleDescriptor MI = Modules.getModuleDescriptor(I); | |
215 | |
216 Obj.DbiStream->ModInfos.emplace_back(); | |
217 yaml::PdbDbiModuleInfo &DMI = Obj.DbiStream->ModInfos.back(); | |
218 | |
219 DMI.Mod = MI.getModuleName(); | |
220 DMI.Obj = MI.getObjFileName(); | |
221 if (opts::pdb2yaml::DumpModuleFiles) { | |
222 auto Files = Modules.source_files(I); | |
223 DMI.SourceFiles.assign(Files.begin(), Files.end()); | |
224 } | |
225 | |
226 uint16_t ModiStream = MI.getModuleStreamIndex(); | |
227 if (ModiStream == kInvalidStreamIndex) | |
228 continue; | |
229 | |
230 auto ModStreamData = msf::MappedBlockStream::createIndexedStream( | |
231 File.getMsfLayout(), File.getMsfBuffer(), ModiStream, | |
232 File.getAllocator()); | |
233 | |
234 pdb::ModuleDebugStreamRef ModS(MI, std::move(ModStreamData)); | |
235 if (auto EC = ModS.reload()) | |
236 return EC; | |
237 | |
238 auto ExpectedST = File.getStringTable(); | |
239 if (!ExpectedST) | |
240 return ExpectedST.takeError(); | |
241 if (!opts::pdb2yaml::DumpModuleSubsections.empty() && | |
242 ModS.hasDebugSubsections()) { | |
243 auto ExpectedChecksums = ModS.findChecksumsSubsection(); | |
244 if (!ExpectedChecksums) | |
245 return ExpectedChecksums.takeError(); | |
246 | |
247 StringsAndChecksumsRef SC(ExpectedST->getStringTable(), | |
248 *ExpectedChecksums); | |
249 | |
250 for (const auto &SS : ModS.subsections()) { | |
251 opts::ModuleSubsection OptionKind = convertSubsectionKind(SS.kind()); | |
252 if (!checkModuleSubsection(OptionKind)) | |
253 continue; | |
254 | |
255 auto Converted = | |
256 CodeViewYAML::YAMLDebugSubsection::fromCodeViewSubection(SC, SS); | |
257 if (!Converted) | |
258 return Converted.takeError(); | |
259 DMI.Subsections.push_back(*Converted); | |
260 } | |
261 } | |
262 | |
263 if (opts::pdb2yaml::DumpModuleSyms) { | |
264 DMI.Modi.emplace(); | |
265 | |
266 DMI.Modi->Signature = ModS.signature(); | |
267 bool HadError = false; | |
268 for (auto &Sym : ModS.symbols(&HadError)) { | |
269 auto ES = CodeViewYAML::SymbolRecord::fromCodeViewSymbol(Sym); | |
270 if (!ES) | |
271 return ES.takeError(); | |
272 | |
273 DMI.Modi->Symbols.push_back(*ES); | |
274 } | |
275 } | |
276 } | |
277 } | |
278 return Error::success(); | |
279 } | |
280 | |
281 Error YAMLOutputStyle::dumpTpiStream() { | |
282 if (!opts::pdb2yaml::TpiStream) | |
283 return Error::success(); | |
284 | |
285 auto TpiS = File.getPDBTpiStream(); | |
286 if (!TpiS) | |
287 return TpiS.takeError(); | |
288 | |
289 auto &TS = TpiS.get(); | |
290 Obj.TpiStream.emplace(); | |
291 Obj.TpiStream->Version = TS.getTpiVersion(); | |
292 for (auto &Record : TS.types(nullptr)) { | |
293 auto ExpectedRecord = CodeViewYAML::LeafRecord::fromCodeViewRecord(Record); | |
294 if (!ExpectedRecord) | |
295 return ExpectedRecord.takeError(); | |
296 Obj.TpiStream->Records.push_back(*ExpectedRecord); | |
297 } | |
298 | |
299 return Error::success(); | |
300 } | |
301 | |
302 Error YAMLOutputStyle::dumpIpiStream() { | |
303 if (!opts::pdb2yaml::IpiStream) | |
304 return Error::success(); | |
305 | |
306 auto InfoS = File.getPDBInfoStream(); | |
307 if (!InfoS) | |
308 return InfoS.takeError(); | |
309 if (!InfoS->containsIdStream()) | |
310 return Error::success(); | |
311 | |
312 auto IpiS = File.getPDBIpiStream(); | |
313 if (!IpiS) | |
314 return IpiS.takeError(); | |
315 | |
316 auto &IS = IpiS.get(); | |
317 Obj.IpiStream.emplace(); | |
318 Obj.IpiStream->Version = IS.getTpiVersion(); | |
319 for (auto &Record : IS.types(nullptr)) { | |
320 auto ExpectedRecord = CodeViewYAML::LeafRecord::fromCodeViewRecord(Record); | |
321 if (!ExpectedRecord) | |
322 return ExpectedRecord.takeError(); | |
323 | |
324 Obj.IpiStream->Records.push_back(*ExpectedRecord); | |
325 } | |
326 | |
327 return Error::success(); | |
328 } | |
329 | |
330 void YAMLOutputStyle::flush() { | |
331 Out << Obj; | |
332 outs().flush(); | |
333 } |