Index: include/llvm/DebugInfo/PDB/Native/DbiStream.h =================================================================== --- include/llvm/DebugInfo/PDB/Native/DbiStream.h +++ include/llvm/DebugInfo/PDB/Native/DbiStream.h @@ -11,6 +11,7 @@ #define LLVM_DEBUGINFO_PDB_RAW_PDBDBISTREAM_H #include "llvm/DebugInfo/CodeView/DebugSubsection.h" +#include "llvm/DebugInfo/CodeView/DebugFrameDataSubsection.h" #include "llvm/DebugInfo/MSF/MappedBlockStream.h" #include "llvm/DebugInfo/PDB/Native/DbiModuleDescriptor.h" #include "llvm/DebugInfo/PDB/Native/DbiModuleList.h" @@ -80,7 +81,8 @@ FixedStreamArray getSectionHeaders() const; - FixedStreamArray getFpoRecords(); + FixedStreamArray getOldFpoRecords() const; + const codeview::DebugFrameDataSubsectionRef &getNewFpoRecords() const; FixedStreamArray getSectionMap() const; void visitSectionContributions(ISectionContribVisitor &Visitor) const; @@ -91,7 +93,8 @@ Error initializeSectionContributionData(); Error initializeSectionHeadersData(PDBFile *Pdb); Error initializeSectionMapData(); - Error initializeFpoRecords(PDBFile *Pdb); + Error initializeOldFpoRecords(PDBFile *Pdb); + Error initializeNewFpoRecords(PDBFile *Pdb); std::unique_ptr Stream; @@ -117,8 +120,11 @@ std::unique_ptr SectionHeaderStream; FixedStreamArray SectionHeaders; - std::unique_ptr FpoStream; - FixedStreamArray FpoRecords; + std::unique_ptr OldFpoStream; + FixedStreamArray OldFpoRecords; + + std::unique_ptr NewFpoStream; + codeview::DebugFrameDataSubsectionRef NewFpoRecords; const DbiStreamHeader *Header; }; Index: lib/DebugInfo/PDB/Native/DbiStream.cpp =================================================================== --- lib/DebugInfo/PDB/Native/DbiStream.cpp +++ lib/DebugInfo/PDB/Native/DbiStream.cpp @@ -127,8 +127,10 @@ return EC; if (auto EC = initializeSectionMapData()) return EC; - if (auto EC = initializeFpoRecords(Pdb)) + if (auto EC = initializeOldFpoRecords(Pdb)) return EC; + if (auto EC = initializeNewFpoRecords(Pdb)) + return EC; if (Reader.bytesRemaining() > 0) return make_error(raw_error_code::corrupt_file, @@ -201,8 +203,12 @@ return SectionHeaders; } -FixedStreamArray DbiStream::getFpoRecords() { - return FpoRecords; +FixedStreamArray DbiStream::getOldFpoRecords() const { + return OldFpoRecords; +} + +const DebugFrameDataSubsectionRef& DbiStream::getNewFpoRecords() const { + return NewFpoRecords; } const DbiModuleList &DbiStream::modules() const { return Modules; } @@ -279,14 +285,14 @@ } // Initializes this->Fpos. -Error DbiStream::initializeFpoRecords(PDBFile *Pdb) { +Error DbiStream::initializeOldFpoRecords(PDBFile *Pdb) { if (!Pdb) return Error::success(); if (DbgStreams.size() == 0) return Error::success(); - uint32_t StreamNum = getDebugStreamIndex(DbgHeaderType::NewFPO); + uint32_t StreamNum = getDebugStreamIndex(DbgHeaderType::FPO); // This means there is no FPO data. if (StreamNum == kInvalidStreamIndex) @@ -301,14 +307,40 @@ size_t StreamLen = FS->getLength(); if (StreamLen % sizeof(object::FpoData)) return make_error(raw_error_code::corrupt_file, - "Corrupted New FPO stream."); + "Corrupted Old FPO stream."); size_t NumRecords = StreamLen / sizeof(object::FpoData); BinaryStreamReader Reader(*FS); - if (auto EC = Reader.readArray(FpoRecords, NumRecords)) + if (auto EC = Reader.readArray(OldFpoRecords, NumRecords)) return make_error(raw_error_code::corrupt_file, - "Corrupted New FPO stream."); - FpoStream = std::move(FS); + "Corrupted Old FPO stream."); + OldFpoStream = std::move(FS); + return Error::success(); +} + +Error DbiStream::initializeNewFpoRecords(PDBFile *Pdb) { + if (!Pdb) + return Error::success(); + + if (DbgStreams.size() == 0) + return Error::success(); + + uint32_t StreamNum = getDebugStreamIndex(DbgHeaderType::NewFPO); + + // This means there is no FPO data. + if (StreamNum == kInvalidStreamIndex) + return Error::success(); + + if (StreamNum >= Pdb->getNumStreams()) + return make_error(raw_error_code::no_stream); + + auto FS = MappedBlockStream::createIndexedStream( + Pdb->getMsfLayout(), Pdb->getMsfBuffer(), StreamNum, Pdb->getAllocator()); + + if (auto EC = NewFpoRecords.initialize(*FS)) + return EC; + + NewFpoStream = std::move(FS); return Error::success(); }