]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/llvm-pdbutil/StreamUtil.cpp
Merge ^/head r327886 through r327930.
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / llvm-pdbutil / StreamUtil.cpp
1 //===- 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 #include "FormatUtil.h"
12
13 #include "llvm/ADT/DenseMap.h"
14 #include "llvm/ADT/DenseMapInfo.h"
15 #include "llvm/DebugInfo/PDB/Native/DbiModuleDescriptor.h"
16 #include "llvm/DebugInfo/PDB/Native/DbiModuleList.h"
17 #include "llvm/DebugInfo/PDB/Native/DbiStream.h"
18 #include "llvm/DebugInfo/PDB/Native/InfoStream.h"
19 #include "llvm/DebugInfo/PDB/Native/PDBFile.h"
20 #include "llvm/DebugInfo/PDB/Native/TpiStream.h"
21
22 using namespace llvm;
23 using namespace llvm::pdb;
24
25 std::string StreamInfo::getLongName() const {
26   if (Purpose == StreamPurpose::NamedStream)
27     return formatv("Named Stream \"{0}\"", Name).str();
28   if (Purpose == StreamPurpose::ModuleStream)
29     return formatv("Module \"{0}\"", Name).str();
30   return Name;
31 }
32
33 StreamInfo StreamInfo::createStream(StreamPurpose Purpose, StringRef Name,
34                                     uint32_t StreamIndex) {
35   StreamInfo Result;
36   Result.Name = Name;
37   Result.StreamIndex = StreamIndex;
38   Result.Purpose = Purpose;
39   return Result;
40 }
41
42 StreamInfo StreamInfo::createModuleStream(StringRef Module,
43                                           uint32_t StreamIndex, uint32_t Modi) {
44   StreamInfo Result;
45   Result.Name = Module;
46   Result.StreamIndex = StreamIndex;
47   Result.ModuleIndex = Modi;
48   Result.Purpose = StreamPurpose::ModuleStream;
49   return Result;
50 }
51
52 static inline StreamInfo otherStream(StringRef Label, uint32_t Idx) {
53   return StreamInfo::createStream(StreamPurpose::Other, Label, Idx);
54 }
55
56 static inline StreamInfo namedStream(StringRef Label, uint32_t Idx) {
57   return StreamInfo::createStream(StreamPurpose::NamedStream, Label, Idx);
58 }
59
60 static inline StreamInfo symbolStream(StringRef Label, uint32_t Idx) {
61   return StreamInfo::createStream(StreamPurpose::Symbols, Label, Idx);
62 }
63
64 static inline StreamInfo moduleStream(StringRef Label, uint32_t StreamIdx,
65                                       uint32_t Modi) {
66   return StreamInfo::createModuleStream(Label, StreamIdx, Modi);
67 }
68
69 struct IndexedModuleDescriptor {
70   uint32_t Modi;
71   DbiModuleDescriptor Descriptor;
72 };
73
74 void llvm::pdb::discoverStreamPurposes(PDBFile &File,
75                                        SmallVectorImpl<StreamInfo> &Streams) {
76   // It's OK if we fail to load some of these streams, we still attempt to print
77   // what we can.
78   auto Dbi = File.getPDBDbiStream();
79   auto Tpi = File.getPDBTpiStream();
80   auto Ipi = File.getPDBIpiStream();
81   auto Info = File.getPDBInfoStream();
82
83   uint32_t StreamCount = File.getNumStreams();
84   DenseMap<uint16_t, IndexedModuleDescriptor> ModStreams;
85   DenseMap<uint16_t, std::string> NamedStreams;
86
87   if (Dbi) {
88     const DbiModuleList &Modules = Dbi->modules();
89     for (uint32_t I = 0; I < Modules.getModuleCount(); ++I) {
90       IndexedModuleDescriptor IMD;
91       IMD.Modi = I;
92       IMD.Descriptor = Modules.getModuleDescriptor(I);
93       uint16_t SN = IMD.Descriptor.getModuleStreamIndex();
94       if (SN != kInvalidStreamIndex)
95         ModStreams[SN] = IMD;
96     }
97   }
98   if (Info) {
99     for (auto &NSE : Info->named_streams()) {
100       if (NSE.second != kInvalidStreamIndex)
101         NamedStreams[NSE.second] = NSE.first();
102     }
103   }
104
105   Streams.resize(StreamCount);
106   for (uint16_t StreamIdx = 0; StreamIdx < StreamCount; ++StreamIdx) {
107     if (StreamIdx == OldMSFDirectory)
108       Streams[StreamIdx] = otherStream("Old MSF Directory", StreamIdx);
109     else if (StreamIdx == StreamPDB)
110       Streams[StreamIdx] = otherStream("PDB Stream", StreamIdx);
111     else if (StreamIdx == StreamDBI)
112       Streams[StreamIdx] = otherStream("DBI Stream", StreamIdx);
113     else if (StreamIdx == StreamTPI)
114       Streams[StreamIdx] = otherStream("TPI Stream", StreamIdx);
115     else if (StreamIdx == StreamIPI)
116       Streams[StreamIdx] = otherStream("IPI Stream", StreamIdx);
117     else if (Dbi && StreamIdx == Dbi->getGlobalSymbolStreamIndex())
118       Streams[StreamIdx] = otherStream("Global Symbol Hash", StreamIdx);
119     else if (Dbi && StreamIdx == Dbi->getPublicSymbolStreamIndex())
120       Streams[StreamIdx] = otherStream("Public Symbol Hash", StreamIdx);
121     else if (Dbi && StreamIdx == Dbi->getSymRecordStreamIndex())
122       Streams[StreamIdx] = symbolStream("Symbol Records", StreamIdx);
123     else if (Tpi && StreamIdx == Tpi->getTypeHashStreamIndex())
124       Streams[StreamIdx] = otherStream("TPI Hash", StreamIdx);
125     else if (Tpi && StreamIdx == Tpi->getTypeHashStreamAuxIndex())
126       Streams[StreamIdx] = otherStream("TPI Aux Hash", StreamIdx);
127     else if (Ipi && StreamIdx == Ipi->getTypeHashStreamIndex())
128       Streams[StreamIdx] = otherStream("IPI Hash", StreamIdx);
129     else if (Ipi && StreamIdx == Ipi->getTypeHashStreamAuxIndex())
130       Streams[StreamIdx] = otherStream("IPI Aux Hash", StreamIdx);
131     else if (Dbi &&
132              StreamIdx == Dbi->getDebugStreamIndex(DbgHeaderType::Exception))
133       Streams[StreamIdx] = otherStream("Exception Data", StreamIdx);
134     else if (Dbi && StreamIdx == Dbi->getDebugStreamIndex(DbgHeaderType::Fixup))
135       Streams[StreamIdx] = otherStream("Fixup Data", StreamIdx);
136     else if (Dbi && StreamIdx == Dbi->getDebugStreamIndex(DbgHeaderType::FPO))
137       Streams[StreamIdx] = otherStream("FPO Data", StreamIdx);
138     else if (Dbi &&
139              StreamIdx == Dbi->getDebugStreamIndex(DbgHeaderType::NewFPO))
140       Streams[StreamIdx] = otherStream("New FPO Data", StreamIdx);
141     else if (Dbi &&
142              StreamIdx == Dbi->getDebugStreamIndex(DbgHeaderType::OmapFromSrc))
143       Streams[StreamIdx] = otherStream("Omap From Source Data", StreamIdx);
144     else if (Dbi &&
145              StreamIdx == Dbi->getDebugStreamIndex(DbgHeaderType::OmapToSrc))
146       Streams[StreamIdx] = otherStream("Omap To Source Data", StreamIdx);
147     else if (Dbi && StreamIdx == Dbi->getDebugStreamIndex(DbgHeaderType::Pdata))
148       Streams[StreamIdx] = otherStream("Pdata", StreamIdx);
149     else if (Dbi &&
150              StreamIdx == Dbi->getDebugStreamIndex(DbgHeaderType::SectionHdr))
151       Streams[StreamIdx] = otherStream("Section Header Data", StreamIdx);
152     else if (Dbi &&
153              StreamIdx ==
154                  Dbi->getDebugStreamIndex(DbgHeaderType::SectionHdrOrig))
155       Streams[StreamIdx] =
156           otherStream("Section Header Original Data", StreamIdx);
157     else if (Dbi &&
158              StreamIdx == Dbi->getDebugStreamIndex(DbgHeaderType::TokenRidMap))
159       Streams[StreamIdx] = otherStream("Token Rid Data", StreamIdx);
160     else if (Dbi && StreamIdx == Dbi->getDebugStreamIndex(DbgHeaderType::Xdata))
161       Streams[StreamIdx] = otherStream("Xdata", StreamIdx);
162     else {
163       auto ModIter = ModStreams.find(StreamIdx);
164       auto NSIter = NamedStreams.find(StreamIdx);
165       if (ModIter != ModStreams.end()) {
166         Streams[StreamIdx] =
167             moduleStream(ModIter->second.Descriptor.getModuleName(), StreamIdx,
168                          ModIter->second.Modi);
169       } else if (NSIter != NamedStreams.end()) {
170         Streams[StreamIdx] = namedStream(NSIter->second, StreamIdx);
171       } else {
172         Streams[StreamIdx] = otherStream("???", StreamIdx);
173       }
174     }
175   }
176
177   // Consume errors from missing streams.
178   if (!Dbi)
179     consumeError(Dbi.takeError());
180   if (!Tpi)
181     consumeError(Tpi.takeError());
182   if (!Ipi)
183     consumeError(Ipi.takeError());
184   if (!Info)
185     consumeError(Info.takeError());
186 }