blob: db1e01aa015435c64187ea60de8129e062d3045d [file] [log] [blame]
Zachary Turner6ac232c2017-03-13 23:28:25 +00001//===- StreamUtil.cpp - PDB stream utilities --------------------*- 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 "StreamUtil.h"
11
12#include "llvm/ADT/DenseMap.h"
13#include "llvm/ADT/DenseMapInfo.h"
14#include "llvm/DebugInfo/PDB/Native/DbiStream.h"
15#include "llvm/DebugInfo/PDB/Native/InfoStream.h"
16#include "llvm/DebugInfo/PDB/Native/ModInfo.h"
17#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
18#include "llvm/DebugInfo/PDB/Native/TpiStream.h"
19
20namespace llvm {
21namespace pdb {
22void discoverStreamPurposes(PDBFile &File,
23 SmallVectorImpl<std::string> &Purposes) {
24
25 // It's OK if we fail to load some of these streams, we still attempt to print
26 // what we can.
27 auto Dbi = File.getPDBDbiStream();
28 auto Tpi = File.getPDBTpiStream();
29 auto Ipi = File.getPDBIpiStream();
30 auto Info = File.getPDBInfoStream();
31
32 uint32_t StreamCount = File.getNumStreams();
33 DenseMap<uint16_t, const ModuleInfoEx *> ModStreams;
34 DenseMap<uint16_t, std::string> NamedStreams;
35
36 if (Dbi) {
37 for (auto &ModI : Dbi->modules()) {
38 uint16_t SN = ModI.Info.getModuleStreamIndex();
39 if (SN != kInvalidStreamIndex)
40 ModStreams[SN] = &ModI;
41 }
42 }
43 if (Info) {
44 for (auto &NSE : Info->named_streams()) {
45 if (NSE.second != kInvalidStreamIndex)
46 NamedStreams[NSE.second] = NSE.first();
47 }
48 }
49
50 Purposes.resize(StreamCount);
51 for (uint16_t StreamIdx = 0; StreamIdx < StreamCount; ++StreamIdx) {
52 std::string Value;
53 if (StreamIdx == OldMSFDirectory)
54 Value = "Old MSF Directory";
55 else if (StreamIdx == StreamPDB)
56 Value = "PDB Stream";
57 else if (StreamIdx == StreamDBI)
58 Value = "DBI Stream";
59 else if (StreamIdx == StreamTPI)
60 Value = "TPI Stream";
61 else if (StreamIdx == StreamIPI)
62 Value = "IPI Stream";
63 else if (Dbi && StreamIdx == Dbi->getGlobalSymbolStreamIndex())
64 Value = "Global Symbol Hash";
65 else if (Dbi && StreamIdx == Dbi->getPublicSymbolStreamIndex())
66 Value = "Public Symbol Hash";
67 else if (Dbi && StreamIdx == Dbi->getSymRecordStreamIndex())
68 Value = "Public Symbol Records";
69 else if (Tpi && StreamIdx == Tpi->getTypeHashStreamIndex())
70 Value = "TPI Hash";
71 else if (Tpi && StreamIdx == Tpi->getTypeHashStreamAuxIndex())
72 Value = "TPI Aux Hash";
73 else if (Ipi && StreamIdx == Ipi->getTypeHashStreamIndex())
74 Value = "IPI Hash";
75 else if (Ipi && StreamIdx == Ipi->getTypeHashStreamAuxIndex())
76 Value = "IPI Aux Hash";
77 else if (Dbi &&
78 StreamIdx == Dbi->getDebugStreamIndex(DbgHeaderType::Exception))
79 Value = "Exception Data";
80 else if (Dbi && StreamIdx == Dbi->getDebugStreamIndex(DbgHeaderType::Fixup))
81 Value = "Fixup Data";
82 else if (Dbi && StreamIdx == Dbi->getDebugStreamIndex(DbgHeaderType::FPO))
83 Value = "FPO Data";
84 else if (Dbi &&
85 StreamIdx == Dbi->getDebugStreamIndex(DbgHeaderType::NewFPO))
86 Value = "New FPO Data";
87 else if (Dbi &&
88 StreamIdx == Dbi->getDebugStreamIndex(DbgHeaderType::OmapFromSrc))
89 Value = "Omap From Source Data";
90 else if (Dbi &&
91 StreamIdx == Dbi->getDebugStreamIndex(DbgHeaderType::OmapToSrc))
92 Value = "Omap To Source Data";
93 else if (Dbi && StreamIdx == Dbi->getDebugStreamIndex(DbgHeaderType::Pdata))
94 Value = "Pdata";
95 else if (Dbi &&
96 StreamIdx == Dbi->getDebugStreamIndex(DbgHeaderType::SectionHdr))
97 Value = "Section Header Data";
98 else if (Dbi &&
99 StreamIdx ==
100 Dbi->getDebugStreamIndex(DbgHeaderType::SectionHdrOrig))
101 Value = "Section Header Original Data";
102 else if (Dbi &&
103 StreamIdx == Dbi->getDebugStreamIndex(DbgHeaderType::TokenRidMap))
104 Value = "Token Rid Data";
105 else if (Dbi && StreamIdx == Dbi->getDebugStreamIndex(DbgHeaderType::Xdata))
106 Value = "Xdata";
107 else {
108 auto ModIter = ModStreams.find(StreamIdx);
109 auto NSIter = NamedStreams.find(StreamIdx);
110 if (ModIter != ModStreams.end()) {
111 Value = "Module \"";
112 Value += ModIter->second->Info.getModuleName().str();
113 Value += "\"";
114 } else if (NSIter != NamedStreams.end()) {
115 Value = "Named Stream \"";
116 Value += NSIter->second;
117 Value += "\"";
118 } else {
119 Value = "???";
120 }
121 }
122 Purposes[StreamIdx] = Value;
123 }
124
125 // Consume errors from missing streams.
126 if (!Dbi)
127 consumeError(Dbi.takeError());
128 if (!Tpi)
129 consumeError(Tpi.takeError());
130 if (!Ipi)
131 consumeError(Ipi.takeError());
132 if (!Info)
133 consumeError(Info.takeError());
134}
135}
136}