diff options
author | orivej <orivej@yandex-team.ru> | 2022-02-10 16:45:01 +0300 |
---|---|---|
committer | Daniil Cherednik <dcherednik@yandex-team.ru> | 2022-02-10 16:45:01 +0300 |
commit | 2d37894b1b037cf24231090eda8589bbb44fb6fc (patch) | |
tree | be835aa92c6248212e705f25388ebafcf84bc7a1 /contrib/libs/llvm12/lib/DebugInfo/PDB/Native/DbiStream.cpp | |
parent | 718c552901d703c502ccbefdfc3c9028d608b947 (diff) | |
download | ydb-2d37894b1b037cf24231090eda8589bbb44fb6fc.tar.gz |
Restoring authorship annotation for <orivej@yandex-team.ru>. Commit 2 of 2.
Diffstat (limited to 'contrib/libs/llvm12/lib/DebugInfo/PDB/Native/DbiStream.cpp')
-rw-r--r-- | contrib/libs/llvm12/lib/DebugInfo/PDB/Native/DbiStream.cpp | 766 |
1 files changed, 383 insertions, 383 deletions
diff --git a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/DbiStream.cpp b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/DbiStream.cpp index 60fedf6a9f..4eb1680417 100644 --- a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/DbiStream.cpp +++ b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/DbiStream.cpp @@ -1,383 +1,383 @@ -//===- DbiStream.cpp - PDB Dbi Stream (Stream 3) Access -------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#include "llvm/DebugInfo/PDB/Native/DbiStream.h" -#include "llvm/ADT/StringRef.h" -#include "llvm/DebugInfo/MSF/MappedBlockStream.h" -#include "llvm/DebugInfo/PDB/Native/DbiModuleDescriptor.h" -#include "llvm/DebugInfo/PDB/Native/ISectionContribVisitor.h" -#include "llvm/DebugInfo/PDB/Native/PDBFile.h" -#include "llvm/DebugInfo/PDB/Native/RawConstants.h" -#include "llvm/DebugInfo/PDB/Native/RawError.h" -#include "llvm/DebugInfo/PDB/Native/RawTypes.h" -#include "llvm/DebugInfo/PDB/PDBTypes.h" -#include "llvm/Object/COFF.h" -#include "llvm/Support/BinaryStreamArray.h" -#include "llvm/Support/BinaryStreamReader.h" -#include "llvm/Support/Error.h" -#include <algorithm> -#include <cstddef> -#include <cstdint> - -using namespace llvm; -using namespace llvm::codeview; -using namespace llvm::msf; -using namespace llvm::pdb; -using namespace llvm::support; - -template <typename ContribType> -static Error loadSectionContribs(FixedStreamArray<ContribType> &Output, - BinaryStreamReader &Reader) { - if (Reader.bytesRemaining() % sizeof(ContribType) != 0) - return make_error<RawError>( - raw_error_code::corrupt_file, - "Invalid number of bytes of section contributions"); - - uint32_t Count = Reader.bytesRemaining() / sizeof(ContribType); - if (auto EC = Reader.readArray(Output, Count)) - return EC; - return Error::success(); -} - -DbiStream::DbiStream(std::unique_ptr<BinaryStream> Stream) - : Stream(std::move(Stream)), Header(nullptr) {} - -DbiStream::~DbiStream() = default; - -Error DbiStream::reload(PDBFile *Pdb) { - BinaryStreamReader Reader(*Stream); - - if (Stream->getLength() < sizeof(DbiStreamHeader)) - return make_error<RawError>(raw_error_code::corrupt_file, - "DBI Stream does not contain a header."); - if (auto EC = Reader.readObject(Header)) - return make_error<RawError>(raw_error_code::corrupt_file, - "DBI Stream does not contain a header."); - - if (Header->VersionSignature != -1) - return make_error<RawError>(raw_error_code::corrupt_file, - "Invalid DBI version signature."); - - // Require at least version 7, which should be present in all PDBs - // produced in the last decade and allows us to avoid having to - // special case all kinds of complicated arcane formats. - if (Header->VersionHeader < PdbDbiV70) - return make_error<RawError>(raw_error_code::feature_unsupported, - "Unsupported DBI version."); - - if (Stream->getLength() != - sizeof(DbiStreamHeader) + Header->ModiSubstreamSize + - Header->SecContrSubstreamSize + Header->SectionMapSize + - Header->FileInfoSize + Header->TypeServerSize + - Header->OptionalDbgHdrSize + Header->ECSubstreamSize) - return make_error<RawError>(raw_error_code::corrupt_file, - "DBI Length does not equal sum of substreams."); - - // Only certain substreams are guaranteed to be aligned. Validate - // them here. - if (Header->ModiSubstreamSize % sizeof(uint32_t) != 0) - return make_error<RawError>(raw_error_code::corrupt_file, - "DBI MODI substream not aligned."); - if (Header->SecContrSubstreamSize % sizeof(uint32_t) != 0) - return make_error<RawError>( - raw_error_code::corrupt_file, - "DBI section contribution substream not aligned."); - if (Header->SectionMapSize % sizeof(uint32_t) != 0) - return make_error<RawError>(raw_error_code::corrupt_file, - "DBI section map substream not aligned."); - if (Header->FileInfoSize % sizeof(uint32_t) != 0) - return make_error<RawError>(raw_error_code::corrupt_file, - "DBI file info substream not aligned."); - if (Header->TypeServerSize % sizeof(uint32_t) != 0) - return make_error<RawError>(raw_error_code::corrupt_file, - "DBI type server substream not aligned."); - - if (auto EC = Reader.readSubstream(ModiSubstream, Header->ModiSubstreamSize)) - return EC; - - if (auto EC = Reader.readSubstream(SecContrSubstream, - Header->SecContrSubstreamSize)) - return EC; - if (auto EC = Reader.readSubstream(SecMapSubstream, Header->SectionMapSize)) - return EC; - if (auto EC = Reader.readSubstream(FileInfoSubstream, Header->FileInfoSize)) - return EC; - if (auto EC = - Reader.readSubstream(TypeServerMapSubstream, Header->TypeServerSize)) - return EC; - if (auto EC = Reader.readSubstream(ECSubstream, Header->ECSubstreamSize)) - return EC; - if (auto EC = Reader.readArray( - DbgStreams, Header->OptionalDbgHdrSize / sizeof(ulittle16_t))) - return EC; - - if (auto EC = Modules.initialize(ModiSubstream.StreamData, - FileInfoSubstream.StreamData)) - return EC; - - if (auto EC = initializeSectionContributionData()) - return EC; - if (auto EC = initializeSectionHeadersData(Pdb)) - return EC; - if (auto EC = initializeSectionMapData()) - return EC; - if (auto EC = initializeOldFpoRecords(Pdb)) - return EC; - if (auto EC = initializeNewFpoRecords(Pdb)) - return EC; - - if (Reader.bytesRemaining() > 0) - return make_error<RawError>(raw_error_code::corrupt_file, - "Found unexpected bytes in DBI Stream."); - - if (!ECSubstream.empty()) { - BinaryStreamReader ECReader(ECSubstream.StreamData); - if (auto EC = ECNames.reload(ECReader)) - return EC; - } - - return Error::success(); -} - -PdbRaw_DbiVer DbiStream::getDbiVersion() const { - uint32_t Value = Header->VersionHeader; - return static_cast<PdbRaw_DbiVer>(Value); -} - -uint32_t DbiStream::getAge() const { return Header->Age; } - -uint16_t DbiStream::getPublicSymbolStreamIndex() const { - return Header->PublicSymbolStreamIndex; -} - -uint16_t DbiStream::getGlobalSymbolStreamIndex() const { - return Header->GlobalSymbolStreamIndex; -} - -uint16_t DbiStream::getFlags() const { return Header->Flags; } - -bool DbiStream::isIncrementallyLinked() const { - return (Header->Flags & DbiFlags::FlagIncrementalMask) != 0; -} - -bool DbiStream::hasCTypes() const { - return (Header->Flags & DbiFlags::FlagHasCTypesMask) != 0; -} - -bool DbiStream::isStripped() const { - return (Header->Flags & DbiFlags::FlagStrippedMask) != 0; -} - -uint16_t DbiStream::getBuildNumber() const { return Header->BuildNumber; } - -uint16_t DbiStream::getBuildMajorVersion() const { - return (Header->BuildNumber & DbiBuildNo::BuildMajorMask) >> - DbiBuildNo::BuildMajorShift; -} - -uint16_t DbiStream::getBuildMinorVersion() const { - return (Header->BuildNumber & DbiBuildNo::BuildMinorMask) >> - DbiBuildNo::BuildMinorShift; -} - -uint16_t DbiStream::getPdbDllRbld() const { return Header->PdbDllRbld; } - -uint32_t DbiStream::getPdbDllVersion() const { return Header->PdbDllVersion; } - -uint32_t DbiStream::getSymRecordStreamIndex() const { - return Header->SymRecordStreamIndex; -} - -PDB_Machine DbiStream::getMachineType() const { - uint16_t Machine = Header->MachineType; - return static_cast<PDB_Machine>(Machine); -} - -FixedStreamArray<object::coff_section> DbiStream::getSectionHeaders() const { - return SectionHeaders; -} - -bool DbiStream::hasOldFpoRecords() const { return OldFpoStream != nullptr; } - -FixedStreamArray<object::FpoData> DbiStream::getOldFpoRecords() const { - return OldFpoRecords; -} - -bool DbiStream::hasNewFpoRecords() const { return NewFpoStream != nullptr; } - -const DebugFrameDataSubsectionRef &DbiStream::getNewFpoRecords() const { - return NewFpoRecords; -} - -const DbiModuleList &DbiStream::modules() const { return Modules; } - -FixedStreamArray<SecMapEntry> DbiStream::getSectionMap() const { - return SectionMap; -} - -void DbiStream::visitSectionContributions( - ISectionContribVisitor &Visitor) const { - if (!SectionContribs.empty()) { - assert(SectionContribVersion == DbiSecContribVer60); - for (auto &SC : SectionContribs) - Visitor.visit(SC); - } else if (!SectionContribs2.empty()) { - assert(SectionContribVersion == DbiSecContribV2); - for (auto &SC : SectionContribs2) - Visitor.visit(SC); - } -} - -Expected<StringRef> DbiStream::getECName(uint32_t NI) const { - return ECNames.getStringForID(NI); -} - -Error DbiStream::initializeSectionContributionData() { - if (SecContrSubstream.empty()) - return Error::success(); - - BinaryStreamReader SCReader(SecContrSubstream.StreamData); - if (auto EC = SCReader.readEnum(SectionContribVersion)) - return EC; - - if (SectionContribVersion == DbiSecContribVer60) - return loadSectionContribs<SectionContrib>(SectionContribs, SCReader); - if (SectionContribVersion == DbiSecContribV2) - return loadSectionContribs<SectionContrib2>(SectionContribs2, SCReader); - - return make_error<RawError>(raw_error_code::feature_unsupported, - "Unsupported DBI Section Contribution version"); -} - -// Initializes this->SectionHeaders. -Error DbiStream::initializeSectionHeadersData(PDBFile *Pdb) { - Expected<std::unique_ptr<msf::MappedBlockStream>> ExpectedStream = - createIndexedStreamForHeaderType(Pdb, DbgHeaderType::SectionHdr); - if (auto EC = ExpectedStream.takeError()) - return EC; - - auto &SHS = *ExpectedStream; - if (!SHS) - return Error::success(); - - size_t StreamLen = SHS->getLength(); - if (StreamLen % sizeof(object::coff_section)) - return make_error<RawError>(raw_error_code::corrupt_file, - "Corrupted section header stream."); - - size_t NumSections = StreamLen / sizeof(object::coff_section); - BinaryStreamReader Reader(*SHS); - if (auto EC = Reader.readArray(SectionHeaders, NumSections)) - return make_error<RawError>(raw_error_code::corrupt_file, - "Could not read a bitmap."); - - SectionHeaderStream = std::move(SHS); - return Error::success(); -} - -// Initializes this->Fpos. -Error DbiStream::initializeOldFpoRecords(PDBFile *Pdb) { - Expected<std::unique_ptr<msf::MappedBlockStream>> ExpectedStream = - createIndexedStreamForHeaderType(Pdb, DbgHeaderType::FPO); - if (auto EC = ExpectedStream.takeError()) - return EC; - - auto &FS = *ExpectedStream; - if (!FS) - return Error::success(); - - size_t StreamLen = FS->getLength(); - if (StreamLen % sizeof(object::FpoData)) - return make_error<RawError>(raw_error_code::corrupt_file, - "Corrupted Old FPO stream."); - - size_t NumRecords = StreamLen / sizeof(object::FpoData); - BinaryStreamReader Reader(*FS); - if (auto EC = Reader.readArray(OldFpoRecords, NumRecords)) - return make_error<RawError>(raw_error_code::corrupt_file, - "Corrupted Old FPO stream."); - OldFpoStream = std::move(FS); - return Error::success(); -} - -Error DbiStream::initializeNewFpoRecords(PDBFile *Pdb) { - Expected<std::unique_ptr<msf::MappedBlockStream>> ExpectedStream = - createIndexedStreamForHeaderType(Pdb, DbgHeaderType::NewFPO); - if (auto EC = ExpectedStream.takeError()) - return EC; - - auto &FS = *ExpectedStream; - if (!FS) - return Error::success(); - - if (auto EC = NewFpoRecords.initialize(*FS)) - return EC; - - NewFpoStream = std::move(FS); - return Error::success(); -} - -Expected<std::unique_ptr<msf::MappedBlockStream>> -DbiStream::createIndexedStreamForHeaderType(PDBFile *Pdb, - DbgHeaderType Type) const { - if (!Pdb) - return nullptr; - - if (DbgStreams.empty()) - return nullptr; - - uint32_t StreamNum = getDebugStreamIndex(Type); - - // This means there is no such stream. - if (StreamNum == kInvalidStreamIndex) - return nullptr; - - return Pdb->safelyCreateIndexedStream(StreamNum); -} - -BinarySubstreamRef DbiStream::getSectionContributionData() const { - return SecContrSubstream; -} - -BinarySubstreamRef DbiStream::getSecMapSubstreamData() const { - return SecMapSubstream; -} - -BinarySubstreamRef DbiStream::getModiSubstreamData() const { - return ModiSubstream; -} - -BinarySubstreamRef DbiStream::getFileInfoSubstreamData() const { - return FileInfoSubstream; -} - -BinarySubstreamRef DbiStream::getTypeServerMapSubstreamData() const { - return TypeServerMapSubstream; -} - -BinarySubstreamRef DbiStream::getECSubstreamData() const { return ECSubstream; } - -Error DbiStream::initializeSectionMapData() { - if (SecMapSubstream.empty()) - return Error::success(); - - BinaryStreamReader SMReader(SecMapSubstream.StreamData); - const SecMapHeader *Header; - if (auto EC = SMReader.readObject(Header)) - return EC; - if (auto EC = SMReader.readArray(SectionMap, Header->SecCount)) - return EC; - return Error::success(); -} - -uint32_t DbiStream::getDebugStreamIndex(DbgHeaderType Type) const { - uint16_t T = static_cast<uint16_t>(Type); - if (T >= DbgStreams.size()) - return kInvalidStreamIndex; - return DbgStreams[T]; -} +//===- DbiStream.cpp - PDB Dbi Stream (Stream 3) Access -------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "llvm/DebugInfo/PDB/Native/DbiStream.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/DebugInfo/MSF/MappedBlockStream.h" +#include "llvm/DebugInfo/PDB/Native/DbiModuleDescriptor.h" +#include "llvm/DebugInfo/PDB/Native/ISectionContribVisitor.h" +#include "llvm/DebugInfo/PDB/Native/PDBFile.h" +#include "llvm/DebugInfo/PDB/Native/RawConstants.h" +#include "llvm/DebugInfo/PDB/Native/RawError.h" +#include "llvm/DebugInfo/PDB/Native/RawTypes.h" +#include "llvm/DebugInfo/PDB/PDBTypes.h" +#include "llvm/Object/COFF.h" +#include "llvm/Support/BinaryStreamArray.h" +#include "llvm/Support/BinaryStreamReader.h" +#include "llvm/Support/Error.h" +#include <algorithm> +#include <cstddef> +#include <cstdint> + +using namespace llvm; +using namespace llvm::codeview; +using namespace llvm::msf; +using namespace llvm::pdb; +using namespace llvm::support; + +template <typename ContribType> +static Error loadSectionContribs(FixedStreamArray<ContribType> &Output, + BinaryStreamReader &Reader) { + if (Reader.bytesRemaining() % sizeof(ContribType) != 0) + return make_error<RawError>( + raw_error_code::corrupt_file, + "Invalid number of bytes of section contributions"); + + uint32_t Count = Reader.bytesRemaining() / sizeof(ContribType); + if (auto EC = Reader.readArray(Output, Count)) + return EC; + return Error::success(); +} + +DbiStream::DbiStream(std::unique_ptr<BinaryStream> Stream) + : Stream(std::move(Stream)), Header(nullptr) {} + +DbiStream::~DbiStream() = default; + +Error DbiStream::reload(PDBFile *Pdb) { + BinaryStreamReader Reader(*Stream); + + if (Stream->getLength() < sizeof(DbiStreamHeader)) + return make_error<RawError>(raw_error_code::corrupt_file, + "DBI Stream does not contain a header."); + if (auto EC = Reader.readObject(Header)) + return make_error<RawError>(raw_error_code::corrupt_file, + "DBI Stream does not contain a header."); + + if (Header->VersionSignature != -1) + return make_error<RawError>(raw_error_code::corrupt_file, + "Invalid DBI version signature."); + + // Require at least version 7, which should be present in all PDBs + // produced in the last decade and allows us to avoid having to + // special case all kinds of complicated arcane formats. + if (Header->VersionHeader < PdbDbiV70) + return make_error<RawError>(raw_error_code::feature_unsupported, + "Unsupported DBI version."); + + if (Stream->getLength() != + sizeof(DbiStreamHeader) + Header->ModiSubstreamSize + + Header->SecContrSubstreamSize + Header->SectionMapSize + + Header->FileInfoSize + Header->TypeServerSize + + Header->OptionalDbgHdrSize + Header->ECSubstreamSize) + return make_error<RawError>(raw_error_code::corrupt_file, + "DBI Length does not equal sum of substreams."); + + // Only certain substreams are guaranteed to be aligned. Validate + // them here. + if (Header->ModiSubstreamSize % sizeof(uint32_t) != 0) + return make_error<RawError>(raw_error_code::corrupt_file, + "DBI MODI substream not aligned."); + if (Header->SecContrSubstreamSize % sizeof(uint32_t) != 0) + return make_error<RawError>( + raw_error_code::corrupt_file, + "DBI section contribution substream not aligned."); + if (Header->SectionMapSize % sizeof(uint32_t) != 0) + return make_error<RawError>(raw_error_code::corrupt_file, + "DBI section map substream not aligned."); + if (Header->FileInfoSize % sizeof(uint32_t) != 0) + return make_error<RawError>(raw_error_code::corrupt_file, + "DBI file info substream not aligned."); + if (Header->TypeServerSize % sizeof(uint32_t) != 0) + return make_error<RawError>(raw_error_code::corrupt_file, + "DBI type server substream not aligned."); + + if (auto EC = Reader.readSubstream(ModiSubstream, Header->ModiSubstreamSize)) + return EC; + + if (auto EC = Reader.readSubstream(SecContrSubstream, + Header->SecContrSubstreamSize)) + return EC; + if (auto EC = Reader.readSubstream(SecMapSubstream, Header->SectionMapSize)) + return EC; + if (auto EC = Reader.readSubstream(FileInfoSubstream, Header->FileInfoSize)) + return EC; + if (auto EC = + Reader.readSubstream(TypeServerMapSubstream, Header->TypeServerSize)) + return EC; + if (auto EC = Reader.readSubstream(ECSubstream, Header->ECSubstreamSize)) + return EC; + if (auto EC = Reader.readArray( + DbgStreams, Header->OptionalDbgHdrSize / sizeof(ulittle16_t))) + return EC; + + if (auto EC = Modules.initialize(ModiSubstream.StreamData, + FileInfoSubstream.StreamData)) + return EC; + + if (auto EC = initializeSectionContributionData()) + return EC; + if (auto EC = initializeSectionHeadersData(Pdb)) + return EC; + if (auto EC = initializeSectionMapData()) + return EC; + if (auto EC = initializeOldFpoRecords(Pdb)) + return EC; + if (auto EC = initializeNewFpoRecords(Pdb)) + return EC; + + if (Reader.bytesRemaining() > 0) + return make_error<RawError>(raw_error_code::corrupt_file, + "Found unexpected bytes in DBI Stream."); + + if (!ECSubstream.empty()) { + BinaryStreamReader ECReader(ECSubstream.StreamData); + if (auto EC = ECNames.reload(ECReader)) + return EC; + } + + return Error::success(); +} + +PdbRaw_DbiVer DbiStream::getDbiVersion() const { + uint32_t Value = Header->VersionHeader; + return static_cast<PdbRaw_DbiVer>(Value); +} + +uint32_t DbiStream::getAge() const { return Header->Age; } + +uint16_t DbiStream::getPublicSymbolStreamIndex() const { + return Header->PublicSymbolStreamIndex; +} + +uint16_t DbiStream::getGlobalSymbolStreamIndex() const { + return Header->GlobalSymbolStreamIndex; +} + +uint16_t DbiStream::getFlags() const { return Header->Flags; } + +bool DbiStream::isIncrementallyLinked() const { + return (Header->Flags & DbiFlags::FlagIncrementalMask) != 0; +} + +bool DbiStream::hasCTypes() const { + return (Header->Flags & DbiFlags::FlagHasCTypesMask) != 0; +} + +bool DbiStream::isStripped() const { + return (Header->Flags & DbiFlags::FlagStrippedMask) != 0; +} + +uint16_t DbiStream::getBuildNumber() const { return Header->BuildNumber; } + +uint16_t DbiStream::getBuildMajorVersion() const { + return (Header->BuildNumber & DbiBuildNo::BuildMajorMask) >> + DbiBuildNo::BuildMajorShift; +} + +uint16_t DbiStream::getBuildMinorVersion() const { + return (Header->BuildNumber & DbiBuildNo::BuildMinorMask) >> + DbiBuildNo::BuildMinorShift; +} + +uint16_t DbiStream::getPdbDllRbld() const { return Header->PdbDllRbld; } + +uint32_t DbiStream::getPdbDllVersion() const { return Header->PdbDllVersion; } + +uint32_t DbiStream::getSymRecordStreamIndex() const { + return Header->SymRecordStreamIndex; +} + +PDB_Machine DbiStream::getMachineType() const { + uint16_t Machine = Header->MachineType; + return static_cast<PDB_Machine>(Machine); +} + +FixedStreamArray<object::coff_section> DbiStream::getSectionHeaders() const { + return SectionHeaders; +} + +bool DbiStream::hasOldFpoRecords() const { return OldFpoStream != nullptr; } + +FixedStreamArray<object::FpoData> DbiStream::getOldFpoRecords() const { + return OldFpoRecords; +} + +bool DbiStream::hasNewFpoRecords() const { return NewFpoStream != nullptr; } + +const DebugFrameDataSubsectionRef &DbiStream::getNewFpoRecords() const { + return NewFpoRecords; +} + +const DbiModuleList &DbiStream::modules() const { return Modules; } + +FixedStreamArray<SecMapEntry> DbiStream::getSectionMap() const { + return SectionMap; +} + +void DbiStream::visitSectionContributions( + ISectionContribVisitor &Visitor) const { + if (!SectionContribs.empty()) { + assert(SectionContribVersion == DbiSecContribVer60); + for (auto &SC : SectionContribs) + Visitor.visit(SC); + } else if (!SectionContribs2.empty()) { + assert(SectionContribVersion == DbiSecContribV2); + for (auto &SC : SectionContribs2) + Visitor.visit(SC); + } +} + +Expected<StringRef> DbiStream::getECName(uint32_t NI) const { + return ECNames.getStringForID(NI); +} + +Error DbiStream::initializeSectionContributionData() { + if (SecContrSubstream.empty()) + return Error::success(); + + BinaryStreamReader SCReader(SecContrSubstream.StreamData); + if (auto EC = SCReader.readEnum(SectionContribVersion)) + return EC; + + if (SectionContribVersion == DbiSecContribVer60) + return loadSectionContribs<SectionContrib>(SectionContribs, SCReader); + if (SectionContribVersion == DbiSecContribV2) + return loadSectionContribs<SectionContrib2>(SectionContribs2, SCReader); + + return make_error<RawError>(raw_error_code::feature_unsupported, + "Unsupported DBI Section Contribution version"); +} + +// Initializes this->SectionHeaders. +Error DbiStream::initializeSectionHeadersData(PDBFile *Pdb) { + Expected<std::unique_ptr<msf::MappedBlockStream>> ExpectedStream = + createIndexedStreamForHeaderType(Pdb, DbgHeaderType::SectionHdr); + if (auto EC = ExpectedStream.takeError()) + return EC; + + auto &SHS = *ExpectedStream; + if (!SHS) + return Error::success(); + + size_t StreamLen = SHS->getLength(); + if (StreamLen % sizeof(object::coff_section)) + return make_error<RawError>(raw_error_code::corrupt_file, + "Corrupted section header stream."); + + size_t NumSections = StreamLen / sizeof(object::coff_section); + BinaryStreamReader Reader(*SHS); + if (auto EC = Reader.readArray(SectionHeaders, NumSections)) + return make_error<RawError>(raw_error_code::corrupt_file, + "Could not read a bitmap."); + + SectionHeaderStream = std::move(SHS); + return Error::success(); +} + +// Initializes this->Fpos. +Error DbiStream::initializeOldFpoRecords(PDBFile *Pdb) { + Expected<std::unique_ptr<msf::MappedBlockStream>> ExpectedStream = + createIndexedStreamForHeaderType(Pdb, DbgHeaderType::FPO); + if (auto EC = ExpectedStream.takeError()) + return EC; + + auto &FS = *ExpectedStream; + if (!FS) + return Error::success(); + + size_t StreamLen = FS->getLength(); + if (StreamLen % sizeof(object::FpoData)) + return make_error<RawError>(raw_error_code::corrupt_file, + "Corrupted Old FPO stream."); + + size_t NumRecords = StreamLen / sizeof(object::FpoData); + BinaryStreamReader Reader(*FS); + if (auto EC = Reader.readArray(OldFpoRecords, NumRecords)) + return make_error<RawError>(raw_error_code::corrupt_file, + "Corrupted Old FPO stream."); + OldFpoStream = std::move(FS); + return Error::success(); +} + +Error DbiStream::initializeNewFpoRecords(PDBFile *Pdb) { + Expected<std::unique_ptr<msf::MappedBlockStream>> ExpectedStream = + createIndexedStreamForHeaderType(Pdb, DbgHeaderType::NewFPO); + if (auto EC = ExpectedStream.takeError()) + return EC; + + auto &FS = *ExpectedStream; + if (!FS) + return Error::success(); + + if (auto EC = NewFpoRecords.initialize(*FS)) + return EC; + + NewFpoStream = std::move(FS); + return Error::success(); +} + +Expected<std::unique_ptr<msf::MappedBlockStream>> +DbiStream::createIndexedStreamForHeaderType(PDBFile *Pdb, + DbgHeaderType Type) const { + if (!Pdb) + return nullptr; + + if (DbgStreams.empty()) + return nullptr; + + uint32_t StreamNum = getDebugStreamIndex(Type); + + // This means there is no such stream. + if (StreamNum == kInvalidStreamIndex) + return nullptr; + + return Pdb->safelyCreateIndexedStream(StreamNum); +} + +BinarySubstreamRef DbiStream::getSectionContributionData() const { + return SecContrSubstream; +} + +BinarySubstreamRef DbiStream::getSecMapSubstreamData() const { + return SecMapSubstream; +} + +BinarySubstreamRef DbiStream::getModiSubstreamData() const { + return ModiSubstream; +} + +BinarySubstreamRef DbiStream::getFileInfoSubstreamData() const { + return FileInfoSubstream; +} + +BinarySubstreamRef DbiStream::getTypeServerMapSubstreamData() const { + return TypeServerMapSubstream; +} + +BinarySubstreamRef DbiStream::getECSubstreamData() const { return ECSubstream; } + +Error DbiStream::initializeSectionMapData() { + if (SecMapSubstream.empty()) + return Error::success(); + + BinaryStreamReader SMReader(SecMapSubstream.StreamData); + const SecMapHeader *Header; + if (auto EC = SMReader.readObject(Header)) + return EC; + if (auto EC = SMReader.readArray(SectionMap, Header->SecCount)) + return EC; + return Error::success(); +} + +uint32_t DbiStream::getDebugStreamIndex(DbgHeaderType Type) const { + uint16_t T = static_cast<uint16_t>(Type); + if (T >= DbgStreams.size()) + return kInvalidStreamIndex; + return DbgStreams[T]; +} |