pdbdump: Print out more strcutures.

I don't yet fully understand the meaning of these data strcutures,
but at least it seems that their sizes and types are correct.
With this change, we can read publics streams till end.

Differential Revision: http://reviews.llvm.org/D20343

llvm-svn: 269861
This commit is contained in:
Rui Ueyama 2016-05-17 23:07:48 +00:00
parent c675cfa8a9
commit 8dc18c5f45
4 changed files with 51 additions and 3 deletions

View File

@ -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;

View File

@ -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();
}

View File

@ -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 {

View File

@ -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();
}