xref: /freebsd-src/contrib/llvm-project/llvm/lib/DebugInfo/PDB/Native/InfoStream.cpp (revision bdd1243df58e60e85101c09001d9812a789b6bc4)
10b57cec5SDimitry Andric //===- InfoStream.cpp - PDB Info Stream (Stream 1) Access -------*- C++ -*-===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric 
90b57cec5SDimitry Andric #include "llvm/DebugInfo/PDB/Native/InfoStream.h"
100b57cec5SDimitry Andric #include "llvm/DebugInfo/PDB/Native/RawConstants.h"
110b57cec5SDimitry Andric #include "llvm/DebugInfo/PDB/Native/RawError.h"
120b57cec5SDimitry Andric #include "llvm/DebugInfo/PDB/Native/RawTypes.h"
130b57cec5SDimitry Andric #include "llvm/Support/BinaryStreamReader.h"
140b57cec5SDimitry Andric 
150b57cec5SDimitry Andric using namespace llvm;
160b57cec5SDimitry Andric using namespace llvm::codeview;
1781ad6265SDimitry Andric // using namespace llvm::msf;
180b57cec5SDimitry Andric using namespace llvm::pdb;
190b57cec5SDimitry Andric 
InfoStream(std::unique_ptr<BinaryStream> Stream)200b57cec5SDimitry Andric InfoStream::InfoStream(std::unique_ptr<BinaryStream> Stream)
210b57cec5SDimitry Andric     : Stream(std::move(Stream)), Header(nullptr) {}
220b57cec5SDimitry Andric 
reload()230b57cec5SDimitry Andric Error InfoStream::reload() {
240b57cec5SDimitry Andric   BinaryStreamReader Reader(*Stream);
250b57cec5SDimitry Andric 
260b57cec5SDimitry Andric   if (auto EC = Reader.readObject(Header))
270b57cec5SDimitry Andric     return joinErrors(
280b57cec5SDimitry Andric         std::move(EC),
290b57cec5SDimitry Andric         make_error<RawError>(raw_error_code::corrupt_file,
300b57cec5SDimitry Andric                              "PDB Stream does not contain a header."));
310b57cec5SDimitry Andric 
320b57cec5SDimitry Andric   switch (Header->Version) {
330b57cec5SDimitry Andric   case PdbImplVC70:
340b57cec5SDimitry Andric   case PdbImplVC80:
350b57cec5SDimitry Andric   case PdbImplVC110:
360b57cec5SDimitry Andric   case PdbImplVC140:
370b57cec5SDimitry Andric     break;
380b57cec5SDimitry Andric   default:
390b57cec5SDimitry Andric     return make_error<RawError>(raw_error_code::corrupt_file,
400b57cec5SDimitry Andric                                 "Unsupported PDB stream version.");
410b57cec5SDimitry Andric   }
420b57cec5SDimitry Andric 
430b57cec5SDimitry Andric   uint32_t Offset = Reader.getOffset();
440b57cec5SDimitry Andric   if (auto EC = NamedStreams.load(Reader))
450b57cec5SDimitry Andric     return EC;
460b57cec5SDimitry Andric   uint32_t NewOffset = Reader.getOffset();
470b57cec5SDimitry Andric   NamedStreamMapByteSize = NewOffset - Offset;
480b57cec5SDimitry Andric 
490b57cec5SDimitry Andric   Reader.setOffset(Offset);
500b57cec5SDimitry Andric   if (auto EC = Reader.readSubstream(SubNamedStreams, NamedStreamMapByteSize))
510b57cec5SDimitry Andric     return EC;
520b57cec5SDimitry Andric 
530b57cec5SDimitry Andric   bool Stop = false;
540b57cec5SDimitry Andric   while (!Stop && !Reader.empty()) {
550b57cec5SDimitry Andric     PdbRaw_FeatureSig Sig;
560b57cec5SDimitry Andric     if (auto EC = Reader.readEnum(Sig))
570b57cec5SDimitry Andric       return EC;
580b57cec5SDimitry Andric     // Since this value comes from a file, it's possible we have some strange
590b57cec5SDimitry Andric     // value which doesn't correspond to any value.  We don't want to warn on
600b57cec5SDimitry Andric     // -Wcovered-switch-default in this case, so switch on the integral value
610b57cec5SDimitry Andric     // instead of the enumeration value.
620b57cec5SDimitry Andric     switch (uint32_t(Sig)) {
630b57cec5SDimitry Andric     case uint32_t(PdbRaw_FeatureSig::VC110):
640b57cec5SDimitry Andric       // No other flags for VC110 PDB.
650b57cec5SDimitry Andric       Stop = true;
66*bdd1243dSDimitry Andric       [[fallthrough]];
670b57cec5SDimitry Andric     case uint32_t(PdbRaw_FeatureSig::VC140):
680b57cec5SDimitry Andric       Features |= PdbFeatureContainsIdStream;
690b57cec5SDimitry Andric       break;
700b57cec5SDimitry Andric     case uint32_t(PdbRaw_FeatureSig::NoTypeMerge):
710b57cec5SDimitry Andric       Features |= PdbFeatureNoTypeMerging;
720b57cec5SDimitry Andric       break;
730b57cec5SDimitry Andric     case uint32_t(PdbRaw_FeatureSig::MinimalDebugInfo):
740b57cec5SDimitry Andric       Features |= PdbFeatureMinimalDebugInfo;
750b57cec5SDimitry Andric       break;
760b57cec5SDimitry Andric     default:
770b57cec5SDimitry Andric       continue;
780b57cec5SDimitry Andric     }
790b57cec5SDimitry Andric     FeatureSignatures.push_back(Sig);
800b57cec5SDimitry Andric   }
810b57cec5SDimitry Andric   return Error::success();
820b57cec5SDimitry Andric }
830b57cec5SDimitry Andric 
getStreamSize() const840b57cec5SDimitry Andric uint32_t InfoStream::getStreamSize() const { return Stream->getLength(); }
850b57cec5SDimitry Andric 
getNamedStreamIndex(llvm::StringRef Name) const860b57cec5SDimitry Andric Expected<uint32_t> InfoStream::getNamedStreamIndex(llvm::StringRef Name) const {
870b57cec5SDimitry Andric   uint32_t Result;
880b57cec5SDimitry Andric   if (!NamedStreams.get(Name, Result))
890b57cec5SDimitry Andric     return make_error<RawError>(raw_error_code::no_stream);
900b57cec5SDimitry Andric   return Result;
910b57cec5SDimitry Andric }
920b57cec5SDimitry Andric 
named_streams() const930b57cec5SDimitry Andric StringMap<uint32_t> InfoStream::named_streams() const {
940b57cec5SDimitry Andric   return NamedStreams.entries();
950b57cec5SDimitry Andric }
960b57cec5SDimitry Andric 
containsIdStream() const970b57cec5SDimitry Andric bool InfoStream::containsIdStream() const {
980b57cec5SDimitry Andric   return !!(Features & PdbFeatureContainsIdStream);
990b57cec5SDimitry Andric }
1000b57cec5SDimitry Andric 
getVersion() const1010b57cec5SDimitry Andric PdbRaw_ImplVer InfoStream::getVersion() const {
1020b57cec5SDimitry Andric   return static_cast<PdbRaw_ImplVer>(uint32_t(Header->Version));
1030b57cec5SDimitry Andric }
1040b57cec5SDimitry Andric 
getSignature() const1050b57cec5SDimitry Andric uint32_t InfoStream::getSignature() const {
1060b57cec5SDimitry Andric   return uint32_t(Header->Signature);
1070b57cec5SDimitry Andric }
1080b57cec5SDimitry Andric 
getAge() const1090b57cec5SDimitry Andric uint32_t InfoStream::getAge() const { return uint32_t(Header->Age); }
1100b57cec5SDimitry Andric 
getGuid() const1110b57cec5SDimitry Andric GUID InfoStream::getGuid() const { return Header->Guid; }
1120b57cec5SDimitry Andric 
getNamedStreamMapByteSize() const1130b57cec5SDimitry Andric uint32_t InfoStream::getNamedStreamMapByteSize() const {
1140b57cec5SDimitry Andric   return NamedStreamMapByteSize;
1150b57cec5SDimitry Andric }
1160b57cec5SDimitry Andric 
getFeatures() const1170b57cec5SDimitry Andric PdbRaw_Features InfoStream::getFeatures() const { return Features; }
1180b57cec5SDimitry Andric 
getFeatureSignatures() const1190b57cec5SDimitry Andric ArrayRef<PdbRaw_FeatureSig> InfoStream::getFeatureSignatures() const {
1200b57cec5SDimitry Andric   return FeatureSignatures;
1210b57cec5SDimitry Andric }
1220b57cec5SDimitry Andric 
getNamedStreams() const1230b57cec5SDimitry Andric const NamedStreamMap &InfoStream::getNamedStreams() const {
1240b57cec5SDimitry Andric   return NamedStreams;
1250b57cec5SDimitry Andric }
1260b57cec5SDimitry Andric 
getNamedStreamsBuffer() const1270b57cec5SDimitry Andric BinarySubstreamRef InfoStream::getNamedStreamsBuffer() const {
1280b57cec5SDimitry Andric   return SubNamedStreams;
1290b57cec5SDimitry Andric }
130