summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/include/llvm/DebugInfo/PDB/Raw/PublicsStream.h6
-rw-r--r--llvm/lib/DebugInfo/PDB/Raw/PublicsStream.cpp42
-rw-r--r--llvm/test/DebugInfo/PDB/pdbdump-headers.test3
-rw-r--r--llvm/tools/llvm-pdbdump/llvm-pdbdump.cpp3
4 files changed, 51 insertions, 3 deletions
diff --git a/llvm/include/llvm/DebugInfo/PDB/Raw/PublicsStream.h b/llvm/include/llvm/DebugInfo/PDB/Raw/PublicsStream.h
index 5496a84a333..a3cfdb81170 100644
--- a/llvm/include/llvm/DebugInfo/PDB/Raw/PublicsStream.h
+++ b/llvm/include/llvm/DebugInfo/PDB/Raw/PublicsStream.h
@@ -36,11 +36,17 @@ public:
uint32_t getSymHash() const;
uint32_t getAddrMap() const;
uint32_t getNumBuckets() const { return NumBuckets; }
+ ArrayRef<uint32_t> getHashBuckets() const { return HashBuckets; }
+ ArrayRef<uint32_t> getAddressMap() const { return AddressMap; }
+ ArrayRef<uint32_t> getThunkMap() const { return ThunkMap; }
private:
uint32_t StreamNum;
MappedBlockStream Stream;
uint32_t NumBuckets = 0;
+ std::vector<uint32_t> HashBuckets;
+ std::vector<uint32_t> AddressMap;
+ std::vector<uint32_t> ThunkMap;
std::unique_ptr<HeaderInfo> Header;
std::unique_ptr<GSIHashHeader> HashHdr;
diff --git a/llvm/lib/DebugInfo/PDB/Raw/PublicsStream.cpp b/llvm/lib/DebugInfo/PDB/Raw/PublicsStream.cpp
index dbdb1c52d5f..9a2b142ccfb 100644
--- a/llvm/lib/DebugInfo/PDB/Raw/PublicsStream.cpp
+++ b/llvm/lib/DebugInfo/PDB/Raw/PublicsStream.cpp
@@ -53,7 +53,7 @@ struct PublicsStream::HeaderInfo {
ulittle16_t ISectThunkTable;
char Padding[2];
ulittle32_t OffThunkTable;
- ulittle32_t NumSects;
+ ulittle32_t NumSections;
};
@@ -74,6 +74,15 @@ struct PublicsStream::HRFile {
ulittle32_t CRef;
};
+// This struct is defined as "SO" in langapi/include/pdb.h.
+namespace {
+struct SectionOffset {
+ ulittle32_t Off;
+ ulittle16_t Isect;
+ char Padding[2];
+};
+}
+
PublicsStream::PublicsStream(PDBFile &File, uint32_t StreamNum)
: StreamNum(StreamNum), Stream(StreamNum, File) {}
@@ -123,10 +132,37 @@ Error PublicsStream::reload() {
for (uint8_t B : Bitmap)
NumBuckets += countPopulation(B);
- // Buckets follow.
- if (Reader.bytesRemaining() < NumBuckets * sizeof(uint32_t))
+ // We don't yet understand the following data structures completely,
+ // but we at least know the types and sizes. Here we are trying
+ // to read the stream till end so that we at least can detect
+ // corrupted streams.
+
+ // Hash buckets follow.
+ HashBuckets.resize(NumBuckets);
+ if (auto EC = Reader.readArray<uint32_t>(HashBuckets))
return make_error<RawError>(raw_error_code::corrupt_file,
"Hash buckets corrupted.");
+ // Something called "address map" follows.
+ AddressMap.resize(Header->AddrMap / sizeof(uint32_t));
+ if (auto EC = Reader.readArray<uint32_t>(AddressMap))
+ return make_error<RawError>(raw_error_code::corrupt_file,
+ "Could not read an address map.");
+
+ // Something called "thunk map" follows.
+ ThunkMap.resize(Header->NumThunks);
+ if (auto EC = Reader.readArray<uint32_t>(ThunkMap))
+ return make_error<RawError>(raw_error_code::corrupt_file,
+ "Could not read a thunk map.");
+
+ // Something called "section map" follows.
+ std::vector<SectionOffset> SectionMap(Header->NumSections);
+ if (auto EC = Reader.readArray<SectionOffset>(SectionMap))
+ return make_error<RawError>(raw_error_code::corrupt_file,
+ "Could not read a section map.");
+
+ if (Reader.bytesRemaining() > 0)
+ return make_error<RawError>(raw_error_code::corrupt_file,
+ "Corrupted publics stream.");
return Error::success();
}
diff --git a/llvm/test/DebugInfo/PDB/pdbdump-headers.test b/llvm/test/DebugInfo/PDB/pdbdump-headers.test
index e48a37024a5..facbc200c36 100644
--- a/llvm/test/DebugInfo/PDB/pdbdump-headers.test
+++ b/llvm/test/DebugInfo/PDB/pdbdump-headers.test
@@ -313,6 +313,9 @@
; EMPTY-NEXT: SymHash: 556
; EMPTY-NEXT: AddrMap: 8
; EMPTY-NEXT: Number of buckets: 2
+; EMPTY-NEXT: Hash Buckets: [0, 12]
+; EMPTY-NEXT: Address Map: [36, 0]
+; EMPTY-NEXT: Thunk Map: [4112]
; EMPTY-NEXT: }
; BIG: FileHeaders {
diff --git a/llvm/tools/llvm-pdbdump/llvm-pdbdump.cpp b/llvm/tools/llvm-pdbdump/llvm-pdbdump.cpp
index b393b0a1944..362b03dab32 100644
--- a/llvm/tools/llvm-pdbdump/llvm-pdbdump.cpp
+++ b/llvm/tools/llvm-pdbdump/llvm-pdbdump.cpp
@@ -411,6 +411,9 @@ static Error dumpPublicsStream(ScopedPrinter &P, PDBFile &File) {
P.printNumber("SymHash", Publics.getSymHash());
P.printNumber("AddrMap", Publics.getAddrMap());
P.printNumber("Number of buckets", Publics.getNumBuckets());
+ P.printList("Hash Buckets", Publics.getHashBuckets());
+ P.printList("Address Map", Publics.getAddressMap());
+ P.printList("Thunk Map", Publics.getThunkMap());
return Error::success();
}
OpenPOWER on IntegriCloud