diff options
Diffstat (limited to 'llvm/lib/DebugInfo/PDB/Raw/DbiStream.cpp')
| -rw-r--r-- | llvm/lib/DebugInfo/PDB/Raw/DbiStream.cpp | 81 |
1 files changed, 71 insertions, 10 deletions
diff --git a/llvm/lib/DebugInfo/PDB/Raw/DbiStream.cpp b/llvm/lib/DebugInfo/PDB/Raw/DbiStream.cpp index 1827ab078df..96a68b6caa6 100644 --- a/llvm/lib/DebugInfo/PDB/Raw/DbiStream.cpp +++ b/llvm/lib/DebugInfo/PDB/Raw/DbiStream.cpp @@ -10,14 +10,17 @@ #include "llvm/DebugInfo/CodeView/StreamArray.h" #include "llvm/DebugInfo/CodeView/StreamReader.h" +#include "llvm/DebugInfo/PDB/Raw/ISectionContribVisitor.h" #include "llvm/DebugInfo/PDB/Raw/InfoStream.h" #include "llvm/DebugInfo/PDB/Raw/ModInfo.h" #include "llvm/DebugInfo/PDB/Raw/NameHashTable.h" #include "llvm/DebugInfo/PDB/Raw/PDBFile.h" #include "llvm/DebugInfo/PDB/Raw/RawConstants.h" #include "llvm/DebugInfo/PDB/Raw/RawError.h" +#include "llvm/DebugInfo/PDB/Raw/RawTypes.h" using namespace llvm; +using namespace llvm::codeview; using namespace llvm::pdb; using namespace llvm::support; @@ -73,6 +76,20 @@ struct DbiStream::HeaderInfo { ulittle32_t Reserved; // Pad to 64 bytes }; +template <typename ContribType> +Error loadSectionContribs(FixedStreamArray<ContribType> &Output, + StreamReader &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(PDBFile &File) : Pdb(File), Stream(StreamDBI, File), Header(nullptr) { static_assert(sizeof(HeaderInfo) == 64, "Invalid HeaderInfo size!"); @@ -81,7 +98,7 @@ DbiStream::DbiStream(PDBFile &File) DbiStream::~DbiStream() {} Error DbiStream::reload() { - codeview::StreamReader Reader(Stream); + StreamReader Reader(Stream); if (Stream.getLength() < sizeof(HeaderInfo)) return make_error<RawError>(raw_error_code::corrupt_file, @@ -98,7 +115,7 @@ Error DbiStream::reload() { // 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::corrupt_file, + return make_error<RawError>(raw_error_code::feature_unsupported, "Unsupported DBI version."); auto InfoStream = Pdb.getPDBInfoStream(); @@ -138,7 +155,7 @@ Error DbiStream::reload() { // Since each ModInfo in the stream is a variable length, we have to iterate // them to know how many there actually are. - codeview::VarStreamArray<ModInfo> ModInfoArray; + VarStreamArray<ModInfo> ModInfoArray; if (auto EC = Reader.readArray(ModInfoArray, Header->ModiSubstreamSize)) return EC; for (auto &Info : ModInfoArray) { @@ -161,6 +178,12 @@ Error DbiStream::reload() { sizeof(ulittle16_t))) return EC; + if (auto EC = initializeSectionContributionData()) + return EC; + + if (auto EC = initializeSectionMapData()) + return EC; + if (auto EC = initializeFileInfo()) return EC; @@ -168,7 +191,7 @@ Error DbiStream::reload() { return make_error<RawError>(raw_error_code::corrupt_file, "Found unexpected bytes in DBI Stream."); - codeview::StreamReader ECReader(ECSubstream); + StreamReader ECReader(ECSubstream); if (auto EC = ECNames.load(ECReader)) return EC; @@ -222,6 +245,44 @@ PDB_Machine DbiStream::getMachineType() const { } ArrayRef<ModuleInfoEx> DbiStream::modules() const { return ModuleInfos; } +codeview::FixedStreamArray<SecMapEntry> DbiStream::getSectionMap() const { + return SectionMap; +} + +void llvm::pdb::DbiStream::visitSectionContributions( + ISectionContribVisitor &Visitor) const { + if (SectionContribVersion == DbiSecContribVer60) { + for (auto &SC : SectionContribs) + Visitor.visit(SC); + } else if (SectionContribVersion == DbiSecContribV2) { + for (auto &SC : SectionContribs2) + Visitor.visit(SC); + } +} + +Error DbiStream::initializeSectionContributionData() { + StreamReader SCReader(SecContrSubstream); + 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"); +} + +Error DbiStream::initializeSectionMapData() { + StreamReader SMReader(SecMapSubstream); + const SecMapHeader *Header; + if (auto EC = SMReader.readObject(Header)) + return EC; + if (auto EC = SMReader.readArray(SectionMap, Header->SecCount)) + return EC; + return Error::success(); +} Error DbiStream::initializeFileInfo() { struct FileInfoSubstreamHeader { @@ -246,7 +307,7 @@ Error DbiStream::initializeFileInfo() { // it is computed by summing `ModFileCounts`. // const FileInfoSubstreamHeader *FH; - codeview::StreamReader FISR(FileInfoSubstream); + StreamReader FISR(FileInfoSubstream); if (auto EC = FISR.readObject(FH)) return EC; @@ -256,9 +317,9 @@ Error DbiStream::initializeFileInfo() { return make_error<RawError>(raw_error_code::corrupt_file, "FileInfo substream count doesn't match DBI."); - codeview::FixedStreamArray<ulittle16_t> ModIndexArray; - codeview::FixedStreamArray<ulittle16_t> ModFileCountArray; - codeview::FixedStreamArray<little32_t> FileNameOffsets; + FixedStreamArray<ulittle16_t> ModIndexArray; + FixedStreamArray<ulittle16_t> ModFileCountArray; + FixedStreamArray<little32_t> FileNameOffsets; // First is an array of `NumModules` module indices. This is not used for the // same reason that `NumSourceFiles` is not used. It's an array of uint16's, @@ -286,10 +347,10 @@ Error DbiStream::initializeFileInfo() { if (auto EC = FISR.readArray(FileNameOffsets, NumSourceFiles)) return EC; - codeview::StreamRef NamesBufferRef; + StreamRef NamesBufferRef; if (auto EC = FISR.readStreamRef(NamesBufferRef)) return EC; - codeview::StreamReader Names(NamesBufferRef); + StreamReader Names(NamesBufferRef); // We go through each ModuleInfo, determine the number N of source files for // that module, and then get the next N offsets from the Offsets array, using |

