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