#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"
FixedStreamArray<object::coff_section> getSectionHeaders() const;
- FixedStreamArray<object::FpoData> getFpoRecords();
+ bool hasOldFpoRecords() const;
+ FixedStreamArray<object::FpoData> getOldFpoRecords() const;
+ bool hasNewFpoRecords() const;
+ const codeview::DebugFrameDataSubsectionRef &getNewFpoRecords() const;
FixedStreamArray<SecMapEntry> getSectionMap() const;
void visitSectionContributions(ISectionContribVisitor &Visitor) const;
Error initializeSectionContributionData();
Error initializeSectionHeadersData(PDBFile *Pdb);
Error initializeSectionMapData();
- Error initializeFpoRecords(PDBFile *Pdb);
+ Error initializeOldFpoRecords(PDBFile *Pdb);
+ Error initializeNewFpoRecords(PDBFile *Pdb);
+
+ Expected<std::unique_ptr<msf::MappedBlockStream>>
+ createIndexedStreamForHeaderType(PDBFile *Pdb, DbgHeaderType Type) const;
std::unique_ptr<BinaryStream> Stream;
std::unique_ptr<msf::MappedBlockStream> SectionHeaderStream;
FixedStreamArray<object::coff_section> SectionHeaders;
- std::unique_ptr<msf::MappedBlockStream> FpoStream;
- FixedStreamArray<object::FpoData> FpoRecords;
+ std::unique_ptr<msf::MappedBlockStream> OldFpoStream;
+ FixedStreamArray<object::FpoData> OldFpoRecords;
+
+ std::unique_ptr<msf::MappedBlockStream> NewFpoStream;
+ codeview::DebugFrameDataSubsectionRef NewFpoRecords;
const DbiStreamHeader *Header;
};
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<RawError>(raw_error_code::corrupt_file,
return SectionHeaders;
}
-FixedStreamArray<object::FpoData> DbiStream::getFpoRecords() {
- return FpoRecords;
+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; }
// Initializes this->SectionHeaders.
Error DbiStream::initializeSectionHeadersData(PDBFile *Pdb) {
- if (!Pdb)
- return Error::success();
-
- if (DbgStreams.size() == 0)
- return Error::success();
+ Expected<std::unique_ptr<msf::MappedBlockStream>> ExpectedStream =
+ createIndexedStreamForHeaderType(Pdb, DbgHeaderType::SectionHdr);
+ if (auto EC = ExpectedStream.takeError())
+ return EC;
- uint32_t StreamNum = getDebugStreamIndex(DbgHeaderType::SectionHdr);
- if (StreamNum == kInvalidStreamIndex)
+ auto &SHS = *ExpectedStream;
+ if (!SHS)
return Error::success();
- if (StreamNum >= Pdb->getNumStreams())
- return make_error<RawError>(raw_error_code::no_stream);
-
- auto SHS = MappedBlockStream::createIndexedStream(
- Pdb->getMsfLayout(), Pdb->getMsfBuffer(), StreamNum, Pdb->getAllocator());
-
size_t StreamLen = SHS->getLength();
if (StreamLen % sizeof(object::coff_section))
return make_error<RawError>(raw_error_code::corrupt_file,
}
// Initializes this->Fpos.
-Error DbiStream::initializeFpoRecords(PDBFile *Pdb) {
- if (!Pdb)
- return Error::success();
-
- if (DbgStreams.size() == 0)
- return Error::success();
-
- uint32_t StreamNum = getDebugStreamIndex(DbgHeaderType::NewFPO);
+Error DbiStream::initializeOldFpoRecords(PDBFile *Pdb) {
+ Expected<std::unique_ptr<msf::MappedBlockStream>> ExpectedStream =
+ createIndexedStreamForHeaderType(Pdb, DbgHeaderType::FPO);
+ if (auto EC = ExpectedStream.takeError())
+ return EC;
- // This means there is no FPO data.
- if (StreamNum == kInvalidStreamIndex)
+ auto &FS = *ExpectedStream;
+ if (!FS)
return Error::success();
- if (StreamNum >= Pdb->getNumStreams())
- return make_error<RawError>(raw_error_code::no_stream);
-
- auto FS = MappedBlockStream::createIndexedStream(
- Pdb->getMsfLayout(), Pdb->getMsfBuffer(), StreamNum, Pdb->getAllocator());
-
size_t StreamLen = FS->getLength();
if (StreamLen % sizeof(object::FpoData))
return make_error<RawError>(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<RawError>(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) {
+ 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;
+
+ if (StreamNum >= Pdb->getNumStreams())
+ return make_error<RawError>(raw_error_code::no_stream);
+
+ return MappedBlockStream::createIndexedStream(
+ Pdb->getMsfLayout(), Pdb->getMsfBuffer(), StreamNum, Pdb->getAllocator());
+}
+
BinarySubstreamRef DbiStream::getSectionContributionData() const {
return SecContrSubstream;
}
ExitOnError Err("Error dumping old fpo data:");
auto &Dbi = Err(File.getPDBDbiStream());
- uint32_t Index = Dbi.getDebugStreamIndex(DbgHeaderType::FPO);
- if (Index == kInvalidStreamIndex) {
+ if (!Dbi.hasOldFpoRecords()) {
printStreamNotPresent("FPO");
return Error::success();
}
- std::unique_ptr<MappedBlockStream> OldFpo = File.createIndexedStream(Index);
- BinaryStreamReader Reader(*OldFpo);
- FixedStreamArray<object::FpoData> Records;
- Err(Reader.readArray(Records,
- Reader.bytesRemaining() / sizeof(object::FpoData)));
+ const FixedStreamArray<object::FpoData>& Records = Dbi.getOldFpoRecords();
P.printLine(" RVA | Code | Locals | Params | Prolog | Saved Regs | Use "
"BP | Has SEH | Frame Type");
ExitOnError Err("Error dumping new fpo data:");
auto &Dbi = Err(File.getPDBDbiStream());
- uint32_t Index = Dbi.getDebugStreamIndex(DbgHeaderType::NewFPO);
- if (Index == kInvalidStreamIndex) {
+ if (!Dbi.hasNewFpoRecords()) {
printStreamNotPresent("New FPO");
return Error::success();
}
- std::unique_ptr<MappedBlockStream> NewFpo = File.createIndexedStream(Index);
-
- DebugFrameDataSubsectionRef FDS;
- if (auto EC = FDS.initialize(*NewFpo))
- return make_error<RawError>(raw_error_code::corrupt_file,
- "Invalid new fpo stream");
+ const DebugFrameDataSubsectionRef& FDS = Dbi.getNewFpoRecords();
P.printLine(" RVA | Code | Locals | Params | Stack | Prolog | Saved Regs "
"| Has SEH | Has C++EH | Start | Program");