blob: 4d352004dec30464e4433293d3ae103e11b91092 [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"
Zachary Turner8120ebf2017-07-05 21:54:58 +000011#include "FormatUtil.h"
Zachary Turner6ac232c2017-03-13 23:28:25 +000012
13#include "llvm/ADT/DenseMap.h"
14#include "llvm/ADT/DenseMapInfo.h"
Zachary Turner67c56012017-04-27 16:11:19 +000015#include "llvm/DebugInfo/PDB/Native/DbiModuleDescriptor.h"
Zachary Turner1eb9a022017-05-04 23:53:29 +000016#include "llvm/DebugInfo/PDB/Native/DbiModuleList.h"
Zachary Turner6ac232c2017-03-13 23:28:25 +000017#include "llvm/DebugInfo/PDB/Native/DbiStream.h"
18#include "llvm/DebugInfo/PDB/Native/InfoStream.h"
Zachary Turner6ac232c2017-03-13 23:28:25 +000019#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
20#include "llvm/DebugInfo/PDB/Native/TpiStream.h"
21
Zachary Turner8120ebf2017-07-05 21:54:58 +000022using namespace llvm;
23using namespace llvm::pdb;
24
Zachary Turnera9d944f2017-07-10 19:16:49 +000025void llvm::pdb::discoverStreamPurposes(
26 PDBFile &File,
27 SmallVectorImpl<std::pair<StreamPurpose, std::string>> &Purposes) {
Zachary Turner6ac232c2017-03-13 23:28:25 +000028 // It's OK if we fail to load some of these streams, we still attempt to print
29 // what we can.
30 auto Dbi = File.getPDBDbiStream();
31 auto Tpi = File.getPDBTpiStream();
32 auto Ipi = File.getPDBIpiStream();
33 auto Info = File.getPDBInfoStream();
34
35 uint32_t StreamCount = File.getNumStreams();
Zachary Turner1eb9a022017-05-04 23:53:29 +000036 DenseMap<uint16_t, DbiModuleDescriptor> ModStreams;
Zachary Turner6ac232c2017-03-13 23:28:25 +000037 DenseMap<uint16_t, std::string> NamedStreams;
38
39 if (Dbi) {
Zachary Turner1eb9a022017-05-04 23:53:29 +000040 const DbiModuleList &Modules = Dbi->modules();
41 for (uint32_t I = 0; I < Modules.getModuleCount(); ++I) {
42 DbiModuleDescriptor Descriptor = Modules.getModuleDescriptor(I);
43 uint16_t SN = Descriptor.getModuleStreamIndex();
Zachary Turner6ac232c2017-03-13 23:28:25 +000044 if (SN != kInvalidStreamIndex)
Zachary Turner1eb9a022017-05-04 23:53:29 +000045 ModStreams[SN] = Descriptor;
Zachary Turner6ac232c2017-03-13 23:28:25 +000046 }
47 }
48 if (Info) {
49 for (auto &NSE : Info->named_streams()) {
50 if (NSE.second != kInvalidStreamIndex)
51 NamedStreams[NSE.second] = NSE.first();
52 }
53 }
54
55 Purposes.resize(StreamCount);
56 for (uint16_t StreamIdx = 0; StreamIdx < StreamCount; ++StreamIdx) {
Zachary Turnera9d944f2017-07-10 19:16:49 +000057 std::pair<StreamPurpose, std::string> Value;
Zachary Turner6ac232c2017-03-13 23:28:25 +000058 if (StreamIdx == OldMSFDirectory)
Zachary Turnera9d944f2017-07-10 19:16:49 +000059 Value = std::make_pair(StreamPurpose::Other, "Old MSF Directory");
Zachary Turner6ac232c2017-03-13 23:28:25 +000060 else if (StreamIdx == StreamPDB)
Zachary Turnera9d944f2017-07-10 19:16:49 +000061 Value = std::make_pair(StreamPurpose::Other, "PDB Stream");
Zachary Turner6ac232c2017-03-13 23:28:25 +000062 else if (StreamIdx == StreamDBI)
Zachary Turnera9d944f2017-07-10 19:16:49 +000063 Value = std::make_pair(StreamPurpose::Other, "DBI Stream");
Zachary Turner6ac232c2017-03-13 23:28:25 +000064 else if (StreamIdx == StreamTPI)
Zachary Turnera9d944f2017-07-10 19:16:49 +000065 Value = std::make_pair(StreamPurpose::Other, "TPI Stream");
Zachary Turner6ac232c2017-03-13 23:28:25 +000066 else if (StreamIdx == StreamIPI)
Zachary Turnera9d944f2017-07-10 19:16:49 +000067 Value = std::make_pair(StreamPurpose::Other, "IPI Stream");
Zachary Turner6ac232c2017-03-13 23:28:25 +000068 else if (Dbi && StreamIdx == Dbi->getGlobalSymbolStreamIndex())
Zachary Turnera9d944f2017-07-10 19:16:49 +000069 Value = std::make_pair(StreamPurpose::Other, "Global Symbol Hash");
Zachary Turner6ac232c2017-03-13 23:28:25 +000070 else if (Dbi && StreamIdx == Dbi->getPublicSymbolStreamIndex())
Zachary Turnera9d944f2017-07-10 19:16:49 +000071 Value = std::make_pair(StreamPurpose::Other, "Public Symbol Hash");
Zachary Turner6ac232c2017-03-13 23:28:25 +000072 else if (Dbi && StreamIdx == Dbi->getSymRecordStreamIndex())
Zachary Turnera9d944f2017-07-10 19:16:49 +000073 Value = std::make_pair(StreamPurpose::Other, "Public Symbol Records");
Zachary Turner6ac232c2017-03-13 23:28:25 +000074 else if (Tpi && StreamIdx == Tpi->getTypeHashStreamIndex())
Zachary Turnera9d944f2017-07-10 19:16:49 +000075 Value = std::make_pair(StreamPurpose::Other, "TPI Hash");
Zachary Turner6ac232c2017-03-13 23:28:25 +000076 else if (Tpi && StreamIdx == Tpi->getTypeHashStreamAuxIndex())
Zachary Turnera9d944f2017-07-10 19:16:49 +000077 Value = std::make_pair(StreamPurpose::Other, "TPI Aux Hash");
Zachary Turner6ac232c2017-03-13 23:28:25 +000078 else if (Ipi && StreamIdx == Ipi->getTypeHashStreamIndex())
Zachary Turnera9d944f2017-07-10 19:16:49 +000079 Value = std::make_pair(StreamPurpose::Other, "IPI Hash");
Zachary Turner6ac232c2017-03-13 23:28:25 +000080 else if (Ipi && StreamIdx == Ipi->getTypeHashStreamAuxIndex())
Zachary Turnera9d944f2017-07-10 19:16:49 +000081 Value = std::make_pair(StreamPurpose::Other, "IPI Aux Hash");
Zachary Turner6ac232c2017-03-13 23:28:25 +000082 else if (Dbi &&
83 StreamIdx == Dbi->getDebugStreamIndex(DbgHeaderType::Exception))
Zachary Turnera9d944f2017-07-10 19:16:49 +000084 Value = std::make_pair(StreamPurpose::Other, "Exception Data");
Zachary Turner6ac232c2017-03-13 23:28:25 +000085 else if (Dbi && StreamIdx == Dbi->getDebugStreamIndex(DbgHeaderType::Fixup))
Zachary Turnera9d944f2017-07-10 19:16:49 +000086 Value = std::make_pair(StreamPurpose::Other, "Fixup Data");
Zachary Turner6ac232c2017-03-13 23:28:25 +000087 else if (Dbi && StreamIdx == Dbi->getDebugStreamIndex(DbgHeaderType::FPO))
Zachary Turnera9d944f2017-07-10 19:16:49 +000088 Value = std::make_pair(StreamPurpose::Other, "FPO Data");
Zachary Turner6ac232c2017-03-13 23:28:25 +000089 else if (Dbi &&
90 StreamIdx == Dbi->getDebugStreamIndex(DbgHeaderType::NewFPO))
Zachary Turnera9d944f2017-07-10 19:16:49 +000091 Value = std::make_pair(StreamPurpose::Other, "New FPO Data");
Zachary Turner6ac232c2017-03-13 23:28:25 +000092 else if (Dbi &&
93 StreamIdx == Dbi->getDebugStreamIndex(DbgHeaderType::OmapFromSrc))
Zachary Turnera9d944f2017-07-10 19:16:49 +000094 Value = std::make_pair(StreamPurpose::Other, "Omap From Source Data");
Zachary Turner6ac232c2017-03-13 23:28:25 +000095 else if (Dbi &&
96 StreamIdx == Dbi->getDebugStreamIndex(DbgHeaderType::OmapToSrc))
Zachary Turnera9d944f2017-07-10 19:16:49 +000097 Value = std::make_pair(StreamPurpose::Other, "Omap To Source Data");
Zachary Turner6ac232c2017-03-13 23:28:25 +000098 else if (Dbi && StreamIdx == Dbi->getDebugStreamIndex(DbgHeaderType::Pdata))
Zachary Turnera9d944f2017-07-10 19:16:49 +000099 Value = std::make_pair(StreamPurpose::Other, "Pdata");
Zachary Turner6ac232c2017-03-13 23:28:25 +0000100 else if (Dbi &&
101 StreamIdx == Dbi->getDebugStreamIndex(DbgHeaderType::SectionHdr))
Zachary Turnera9d944f2017-07-10 19:16:49 +0000102 Value = std::make_pair(StreamPurpose::Other, "Section Header Data");
Zachary Turner6ac232c2017-03-13 23:28:25 +0000103 else if (Dbi &&
104 StreamIdx ==
105 Dbi->getDebugStreamIndex(DbgHeaderType::SectionHdrOrig))
Zachary Turnera9d944f2017-07-10 19:16:49 +0000106 Value =
107 std::make_pair(StreamPurpose::Other, "Section Header Original Data");
Zachary Turner6ac232c2017-03-13 23:28:25 +0000108 else if (Dbi &&
109 StreamIdx == Dbi->getDebugStreamIndex(DbgHeaderType::TokenRidMap))
Zachary Turnera9d944f2017-07-10 19:16:49 +0000110 Value = std::make_pair(StreamPurpose::Other, "Token Rid Data");
Zachary Turner6ac232c2017-03-13 23:28:25 +0000111 else if (Dbi && StreamIdx == Dbi->getDebugStreamIndex(DbgHeaderType::Xdata))
Zachary Turnera9d944f2017-07-10 19:16:49 +0000112 Value = std::make_pair(StreamPurpose::Other, "Xdata");
Zachary Turner6ac232c2017-03-13 23:28:25 +0000113 else {
114 auto ModIter = ModStreams.find(StreamIdx);
115 auto NSIter = NamedStreams.find(StreamIdx);
116 if (ModIter != ModStreams.end()) {
Zachary Turnera9d944f2017-07-10 19:16:49 +0000117 Value = std::make_pair(StreamPurpose::ModuleStream,
118 ModIter->second.getModuleName());
Zachary Turner6ac232c2017-03-13 23:28:25 +0000119 } else if (NSIter != NamedStreams.end()) {
Zachary Turnera9d944f2017-07-10 19:16:49 +0000120 Value = std::make_pair(StreamPurpose::NamedStream, NSIter->second);
Zachary Turner6ac232c2017-03-13 23:28:25 +0000121 } else {
Zachary Turnera9d944f2017-07-10 19:16:49 +0000122 Value = std::make_pair(StreamPurpose::Other, "???");
Zachary Turner6ac232c2017-03-13 23:28:25 +0000123 }
124 }
125 Purposes[StreamIdx] = Value;
126 }
127
128 // Consume errors from missing streams.
129 if (!Dbi)
130 consumeError(Dbi.takeError());
131 if (!Tpi)
132 consumeError(Tpi.takeError());
133 if (!Ipi)
134 consumeError(Ipi.takeError());
135 if (!Info)
136 consumeError(Info.takeError());
137}
Zachary Turnera9d944f2017-07-10 19:16:49 +0000138
139void llvm::pdb::discoverStreamPurposes(PDBFile &File,
140 SmallVectorImpl<std::string> &Purposes) {
141 SmallVector<std::pair<StreamPurpose, std::string>, 24> SP;
142 discoverStreamPurposes(File, SP);
143 Purposes.reserve(SP.size());
144 for (const auto &P : SP) {
145 if (P.first == StreamPurpose::NamedStream)
146 Purposes.push_back(formatv("Named Stream \"{0}\"", P.second));
147 else if (P.first == StreamPurpose::ModuleStream)
148 Purposes.push_back(formatv("Module \"{0}\"", P.second));
149 else
150 Purposes.push_back(P.second);
151 }
152}