blob: f41bb32d69af8c480af3232097c57d8d28519c58 [file] [log] [blame]
Zachary Turner2f09b502016-04-29 17:28:47 +00001//===- InfoStream.cpp - PDB Info Stream (Stream 1) Access -------*- C++ -*-===//
Zachary Turnerf34e0162016-04-26 16:20:00 +00002//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Zachary Turnerf34e0162016-04-26 16:20:00 +00006//
7//===----------------------------------------------------------------------===//
8
Adrian McCarthy6b6b8c42017-01-25 22:38:55 +00009#include "llvm/DebugInfo/PDB/Native/InfoStream.h"
Zachary Turnerf34e0162016-04-26 16:20:00 +000010#include "llvm/ADT/BitVector.h"
11#include "llvm/ADT/SmallVector.h"
Adrian McCarthy6b6b8c42017-01-25 22:38:55 +000012#include "llvm/DebugInfo/PDB/Native/RawConstants.h"
13#include "llvm/DebugInfo/PDB/Native/RawError.h"
14#include "llvm/DebugInfo/PDB/Native/RawTypes.h"
Zachary Turnerd9dc2822017-03-02 20:52:51 +000015#include "llvm/Support/BinaryStreamReader.h"
Zachary Turnerf34e0162016-04-26 16:20:00 +000016
17using namespace llvm;
Zachary Turner8848a7a2016-07-06 18:05:57 +000018using namespace llvm::codeview;
Zachary Turnerbac69d32016-07-22 19:56:05 +000019using namespace llvm::msf;
Zachary Turner2f09b502016-04-29 17:28:47 +000020using namespace llvm::pdb;
Zachary Turnerf34e0162016-04-26 16:20:00 +000021
Zachary Turner15b2bdf2018-04-04 17:29:09 +000022InfoStream::InfoStream(std::unique_ptr<BinaryStream> Stream)
Zachary Turnerd5cf5cf2018-03-30 17:16:50 +000023 : Stream(std::move(Stream)), Header(nullptr) {}
Zachary Turnerf34e0162016-04-26 16:20:00 +000024
Zachary Turner819e77d2016-05-06 20:51:57 +000025Error InfoStream::reload() {
Zachary Turner120faca2017-02-27 22:11:43 +000026 BinaryStreamReader Reader(*Stream);
Zachary Turner6ba65de2016-04-29 17:22:58 +000027
Zachary Turnerd5cf5cf2018-03-30 17:16:50 +000028 if (auto EC = Reader.readObject(Header))
David Majnemer74b1fb02016-05-27 22:07:50 +000029 return joinErrors(
30 std::move(EC),
31 make_error<RawError>(raw_error_code::corrupt_file,
32 "PDB Stream does not contain a header."));
Zachary Turnerb56d9042016-05-02 18:09:21 +000033
Zachary Turnerd5cf5cf2018-03-30 17:16:50 +000034 switch (Header->Version) {
Zachary Turner8848a7a2016-07-06 18:05:57 +000035 case PdbImplVC70:
36 case PdbImplVC80:
37 case PdbImplVC110:
38 case PdbImplVC140:
39 break;
40 default:
Zachary Turner819e77d2016-05-06 20:51:57 +000041 return make_error<RawError>(raw_error_code::corrupt_file,
42 "Unsupported PDB stream version.");
Zachary Turner8848a7a2016-07-06 18:05:57 +000043 }
Zachary Turnerf34e0162016-04-26 16:20:00 +000044
Zachary Turner02278ce2017-03-16 20:18:41 +000045 uint32_t Offset = Reader.getOffset();
46 if (auto EC = NamedStreams.load(Reader))
47 return EC;
48 uint32_t NewOffset = Reader.getOffset();
49 NamedStreamMapByteSize = NewOffset - Offset;
Zachary Turner05d5e612017-03-16 20:19:11 +000050
Zachary Turner6c3e41b2017-06-23 20:18:38 +000051 Reader.setOffset(Offset);
52 if (auto EC = Reader.readSubstream(SubNamedStreams, NamedStreamMapByteSize))
53 return EC;
54
Zachary Turner05d5e612017-03-16 20:19:11 +000055 bool Stop = false;
56 while (!Stop && !Reader.empty()) {
57 PdbRaw_FeatureSig Sig;
58 if (auto EC = Reader.readEnum(Sig))
59 return EC;
Zachary Turnerc9500612017-03-16 20:45:11 +000060 // Since this value comes from a file, it's possible we have some strange
61 // value which doesn't correspond to any value. We don't want to warn on
62 // -Wcovered-switch-default in this case, so switch on the integral value
63 // instead of the enumeration value.
64 switch (uint32_t(Sig)) {
65 case uint32_t(PdbRaw_FeatureSig::VC110):
Zachary Turner05d5e612017-03-16 20:19:11 +000066 // No other flags for VC110 PDB.
67 Stop = true;
68 LLVM_FALLTHROUGH;
Zachary Turnerc9500612017-03-16 20:45:11 +000069 case uint32_t(PdbRaw_FeatureSig::VC140):
Zachary Turner05d5e612017-03-16 20:19:11 +000070 Features |= PdbFeatureContainsIdStream;
71 break;
Zachary Turnerc9500612017-03-16 20:45:11 +000072 case uint32_t(PdbRaw_FeatureSig::NoTypeMerge):
Zachary Turner05d5e612017-03-16 20:19:11 +000073 Features |= PdbFeatureNoTypeMerging;
74 break;
Zachary Turnerc9500612017-03-16 20:45:11 +000075 case uint32_t(PdbRaw_FeatureSig::MinimalDebugInfo):
Zachary Turner05d5e612017-03-16 20:19:11 +000076 Features |= PdbFeatureMinimalDebugInfo;
Galina Kistanova8c1e2f92017-05-30 19:02:49 +000077 break;
Zachary Turner05d5e612017-03-16 20:19:11 +000078 default:
79 continue;
80 }
81 FeatureSignatures.push_back(Sig);
82 }
Zachary Turner02278ce2017-03-16 20:18:41 +000083 return Error::success();
Zachary Turnerf34e0162016-04-26 16:20:00 +000084}
85
Zachary Turner02278ce2017-03-16 20:18:41 +000086uint32_t InfoStream::getStreamSize() const { return Stream->getLength(); }
87
Zachary Turnerd11328a2018-04-02 18:35:21 +000088Expected<uint32_t> InfoStream::getNamedStreamIndex(llvm::StringRef Name) const {
Zachary Turnerf34e0162016-04-26 16:20:00 +000089 uint32_t Result;
Zachary Turner60667ca2017-01-20 22:41:40 +000090 if (!NamedStreams.get(Name, Result))
Zachary Turnerd11328a2018-04-02 18:35:21 +000091 return make_error<RawError>(raw_error_code::no_stream);
Zachary Turnerf34e0162016-04-26 16:20:00 +000092 return Result;
93}
94
Zachary Turnercafd4762018-02-16 20:46:04 +000095StringMap<uint32_t> InfoStream::named_streams() const {
Zachary Turner85ed80b2016-05-25 03:43:17 +000096 return NamedStreams.entries();
97}
98
Zachary Turner990d0c82017-06-12 21:34:53 +000099bool InfoStream::containsIdStream() const {
100 return !!(Features & PdbFeatureContainsIdStream);
101}
102
Zachary Turner2f09b502016-04-29 17:28:47 +0000103PdbRaw_ImplVer InfoStream::getVersion() const {
Zachary Turnerd5cf5cf2018-03-30 17:16:50 +0000104 return static_cast<PdbRaw_ImplVer>(uint32_t(Header->Version));
Zachary Turnerf34e0162016-04-26 16:20:00 +0000105}
106
Zachary Turnerd5cf5cf2018-03-30 17:16:50 +0000107uint32_t InfoStream::getSignature() const {
108 return uint32_t(Header->Signature);
109}
Zachary Turnerf34e0162016-04-26 16:20:00 +0000110
Zachary Turnerd5cf5cf2018-03-30 17:16:50 +0000111uint32_t InfoStream::getAge() const { return uint32_t(Header->Age); }
Zachary Turnerf34e0162016-04-26 16:20:00 +0000112
Zachary Turnerd5cf5cf2018-03-30 17:16:50 +0000113GUID InfoStream::getGuid() const { return Header->Guid; }
Zachary Turner760ad4d2017-01-20 22:42:09 +0000114
Zachary Turner02278ce2017-03-16 20:18:41 +0000115uint32_t InfoStream::getNamedStreamMapByteSize() const {
116 return NamedStreamMapByteSize;
117}
118
Zachary Turner05d5e612017-03-16 20:19:11 +0000119PdbRaw_Features InfoStream::getFeatures() const { return Features; }
120
121ArrayRef<PdbRaw_FeatureSig> InfoStream::getFeatureSignatures() const {
122 return FeatureSignatures;
123}
124
Zachary Turner760ad4d2017-01-20 22:42:09 +0000125const NamedStreamMap &InfoStream::getNamedStreams() const {
126 return NamedStreams;
127}
Zachary Turner6c3e41b2017-06-23 20:18:38 +0000128
129BinarySubstreamRef InfoStream::getNamedStreamsBuffer() const {
130 return SubNamedStreams;
131}