Home | History | Annotate | Line # | Download | only in Native
      1 //===- InfoStream.cpp - PDB Info Stream (Stream 1) Access -------*- C++ -*-===//
      2 //
      3 // 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
      6 //
      7 //===----------------------------------------------------------------------===//
      8 
      9 #include "llvm/DebugInfo/PDB/Native/InfoStream.h"
     10 #include "llvm/ADT/BitVector.h"
     11 #include "llvm/ADT/SmallVector.h"
     12 #include "llvm/DebugInfo/PDB/Native/RawConstants.h"
     13 #include "llvm/DebugInfo/PDB/Native/RawError.h"
     14 #include "llvm/DebugInfo/PDB/Native/RawTypes.h"
     15 #include "llvm/Support/BinaryStreamReader.h"
     16 
     17 using namespace llvm;
     18 using namespace llvm::codeview;
     19 using namespace llvm::msf;
     20 using namespace llvm::pdb;
     21 
     22 InfoStream::InfoStream(std::unique_ptr<BinaryStream> Stream)
     23     : Stream(std::move(Stream)), Header(nullptr) {}
     24 
     25 Error InfoStream::reload() {
     26   BinaryStreamReader Reader(*Stream);
     27 
     28   if (auto EC = Reader.readObject(Header))
     29     return joinErrors(
     30         std::move(EC),
     31         make_error<RawError>(raw_error_code::corrupt_file,
     32                              "PDB Stream does not contain a header."));
     33 
     34   switch (Header->Version) {
     35   case PdbImplVC70:
     36   case PdbImplVC80:
     37   case PdbImplVC110:
     38   case PdbImplVC140:
     39     break;
     40   default:
     41     return make_error<RawError>(raw_error_code::corrupt_file,
     42                                 "Unsupported PDB stream version.");
     43   }
     44 
     45   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;
     50 
     51   Reader.setOffset(Offset);
     52   if (auto EC = Reader.readSubstream(SubNamedStreams, NamedStreamMapByteSize))
     53     return EC;
     54 
     55   bool Stop = false;
     56   while (!Stop && !Reader.empty()) {
     57     PdbRaw_FeatureSig Sig;
     58     if (auto EC = Reader.readEnum(Sig))
     59       return EC;
     60     // 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):
     66       // No other flags for VC110 PDB.
     67       Stop = true;
     68       LLVM_FALLTHROUGH;
     69     case uint32_t(PdbRaw_FeatureSig::VC140):
     70       Features |= PdbFeatureContainsIdStream;
     71       break;
     72     case uint32_t(PdbRaw_FeatureSig::NoTypeMerge):
     73       Features |= PdbFeatureNoTypeMerging;
     74       break;
     75     case uint32_t(PdbRaw_FeatureSig::MinimalDebugInfo):
     76       Features |= PdbFeatureMinimalDebugInfo;
     77       break;
     78     default:
     79       continue;
     80     }
     81     FeatureSignatures.push_back(Sig);
     82   }
     83   return Error::success();
     84 }
     85 
     86 uint32_t InfoStream::getStreamSize() const { return Stream->getLength(); }
     87 
     88 Expected<uint32_t> InfoStream::getNamedStreamIndex(llvm::StringRef Name) const {
     89   uint32_t Result;
     90   if (!NamedStreams.get(Name, Result))
     91     return make_error<RawError>(raw_error_code::no_stream);
     92   return Result;
     93 }
     94 
     95 StringMap<uint32_t> InfoStream::named_streams() const {
     96   return NamedStreams.entries();
     97 }
     98 
     99 bool InfoStream::containsIdStream() const {
    100   return !!(Features & PdbFeatureContainsIdStream);
    101 }
    102 
    103 PdbRaw_ImplVer InfoStream::getVersion() const {
    104   return static_cast<PdbRaw_ImplVer>(uint32_t(Header->Version));
    105 }
    106 
    107 uint32_t InfoStream::getSignature() const {
    108   return uint32_t(Header->Signature);
    109 }
    110 
    111 uint32_t InfoStream::getAge() const { return uint32_t(Header->Age); }
    112 
    113 GUID InfoStream::getGuid() const { return Header->Guid; }
    114 
    115 uint32_t InfoStream::getNamedStreamMapByteSize() const {
    116   return NamedStreamMapByteSize;
    117 }
    118 
    119 PdbRaw_Features InfoStream::getFeatures() const { return Features; }
    120 
    121 ArrayRef<PdbRaw_FeatureSig> InfoStream::getFeatureSignatures() const {
    122   return FeatureSignatures;
    123 }
    124 
    125 const NamedStreamMap &InfoStream::getNamedStreams() const {
    126   return NamedStreams;
    127 }
    128 
    129 BinarySubstreamRef InfoStream::getNamedStreamsBuffer() const {
    130   return SubNamedStreams;
    131 }
    132