summaryrefslogtreecommitdiffstats
path: root/llvm/lib/DebugInfo/PDB/Raw/DbiStream.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/DebugInfo/PDB/Raw/DbiStream.cpp')
-rw-r--r--llvm/lib/DebugInfo/PDB/Raw/DbiStream.cpp81
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
OpenPOWER on IntegriCloud