diff options
Diffstat (limited to 'llvm/lib/DebugInfo/PDB')
-rw-r--r-- | llvm/lib/DebugInfo/PDB/CMakeLists.txt | 1 | ||||
-rw-r--r-- | llvm/lib/DebugInfo/PDB/Raw/DbiStream.cpp | 81 | ||||
-rw-r--r-- | llvm/lib/DebugInfo/PDB/Raw/EnumTables.cpp | 38 | ||||
-rw-r--r-- | llvm/lib/DebugInfo/PDB/Raw/ModStream.cpp | 4 |
4 files changed, 114 insertions, 10 deletions
diff --git a/llvm/lib/DebugInfo/PDB/CMakeLists.txt b/llvm/lib/DebugInfo/PDB/CMakeLists.txt index 0938c0762c8..46074f769cd 100644 --- a/llvm/lib/DebugInfo/PDB/CMakeLists.txt +++ b/llvm/lib/DebugInfo/PDB/CMakeLists.txt @@ -29,6 +29,7 @@ endif() add_pdb_impl_folder(Raw Raw/DbiStream.cpp + Raw/EnumTables.cpp Raw/InfoStream.cpp Raw/MappedBlockStream.cpp Raw/ModInfo.cpp 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 diff --git a/llvm/lib/DebugInfo/PDB/Raw/EnumTables.cpp b/llvm/lib/DebugInfo/PDB/Raw/EnumTables.cpp new file mode 100644 index 00000000000..fc9270c6994 --- /dev/null +++ b/llvm/lib/DebugInfo/PDB/Raw/EnumTables.cpp @@ -0,0 +1,38 @@ +//===- EnumTables.cpp - Enum to string conversion tables --------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "llvm/DebugInfo/PDB/Raw/EnumTables.h" +#include "llvm/DebugInfo/PDB/Raw/RawConstants.h" + +using namespace llvm; +using namespace llvm::pdb; + +#define PDB_ENUM_CLASS_ENT(enum_class, enum) \ + { #enum, std::underlying_type < enum_class > ::type(enum_class::enum) } + +#define PDB_ENUM_ENT(ns, enum) \ + { #enum, ns::enum } + +static const EnumEntry<uint16_t> OMFSegMapDescFlagNames[] = { + PDB_ENUM_CLASS_ENT(OMFSegDescFlags, Read), + PDB_ENUM_CLASS_ENT(OMFSegDescFlags, Write), + PDB_ENUM_CLASS_ENT(OMFSegDescFlags, Execute), + PDB_ENUM_CLASS_ENT(OMFSegDescFlags, AddressIs32Bit), + PDB_ENUM_CLASS_ENT(OMFSegDescFlags, IsSelector), + PDB_ENUM_CLASS_ENT(OMFSegDescFlags, IsAbsoluteAddress), + PDB_ENUM_CLASS_ENT(OMFSegDescFlags, IsGroup), +}; + +namespace llvm { +namespace pdb { +ArrayRef<EnumEntry<uint16_t>> getOMFSegMapDescFlagNames() { + return makeArrayRef(OMFSegMapDescFlagNames); +} +} +}
\ No newline at end of file diff --git a/llvm/lib/DebugInfo/PDB/Raw/ModStream.cpp b/llvm/lib/DebugInfo/PDB/Raw/ModStream.cpp index 8b7a71508f8..b7204cb5afa 100644 --- a/llvm/lib/DebugInfo/PDB/Raw/ModStream.cpp +++ b/llvm/lib/DebugInfo/PDB/Raw/ModStream.cpp @@ -45,6 +45,10 @@ Error ModStream::reload() { return EC; if (auto EC = Reader.readStreamRef(C13LinesSubstream, C13Size)) return EC; + ArrayRef<uint8_t> LineBytes; + codeview::StreamReader LinesReader(C13LinesSubstream); + if (auto EC = LinesReader.readBytes(LineBytes, C13LinesSubstream.getLength())) + return EC; uint32_t GlobalRefsSize; if (auto EC = Reader.readInteger(GlobalRefsSize)) |