Index: include/llvm/DebugInfo/CodeView/StreamReader.h =================================================================== --- include/llvm/DebugInfo/CodeView/StreamReader.h +++ include/llvm/DebugInfo/CodeView/StreamReader.h @@ -29,13 +29,13 @@ StreamReader(const StreamInterface &S); Error readBytes(uint32_t Size, ArrayRef &Buffer); - Error readBytes(MutableArrayRef Buffer); Error readInteger(uint16_t &Dest); Error readInteger(uint32_t &Dest); Error readZeroString(StringRef &Dest); Error readFixedString(StringRef &Dest, uint32_t Length); Error readStreamRef(StreamRef &Ref); Error readStreamRef(StreamRef &Ref, uint32_t Length); + Error readBytes(MutableArrayRef Buffer); template Error readObject(const T *&Dest) { ArrayRef Buffer; @@ -60,12 +60,6 @@ return Error::success(); } - template Error readArray(MutableArrayRef Array) { - MutableArrayRef Casted(reinterpret_cast(Array.data()), - Array.size() * sizeof(T)); - return readBytes(Casted); - } - void setOffset(uint32_t Off) { Offset = Off; } uint32_t getOffset() const { return Offset; } uint32_t getLength() const { return Stream.getLength(); } Index: include/llvm/DebugInfo/PDB/Raw/NameHashTable.h =================================================================== --- include/llvm/DebugInfo/PDB/Raw/NameHashTable.h +++ include/llvm/DebugInfo/PDB/Raw/NameHashTable.h @@ -12,7 +12,9 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/StringRef.h" +#include "llvm/DebugInfo/CodeView/StreamArray.h" #include "llvm/DebugInfo/CodeView/StreamRef.h" +#include "llvm/Support/Endian.h" #include "llvm/Support/Error.h" #include #include @@ -36,11 +38,11 @@ StringRef getStringForID(uint32_t ID) const; uint32_t getIDForString(StringRef Str) const; - ArrayRef name_ids() const; + codeview::FixedStreamArray name_ids() const; private: codeview::StreamRef NamesBuffer; - std::vector IDs; + codeview::FixedStreamArray IDs; uint32_t Signature; uint32_t HashVersion; uint32_t NameCount; Index: include/llvm/DebugInfo/PDB/Raw/PublicsStream.h =================================================================== --- include/llvm/DebugInfo/PDB/Raw/PublicsStream.h +++ include/llvm/DebugInfo/PDB/Raw/PublicsStream.h @@ -10,6 +10,7 @@ #ifndef LLVM_DEBUGINFO_PDB_RAW_PUBLICSSTREAM_H #define LLVM_DEBUGINFO_PDB_RAW_PUBLICSSTREAM_H +#include "llvm/DebugInfo/CodeView/StreamArray.h" #include "llvm/DebugInfo/CodeView/SymbolRecord.h" #include "llvm/DebugInfo/CodeView/TypeStream.h" #include "llvm/DebugInfo/PDB/PDBTypes.h" @@ -25,7 +26,6 @@ class PublicsStream { struct GSIHashHeader; - struct HashRecord; struct HeaderInfo; public: @@ -38,10 +38,18 @@ uint32_t getAddrMap() const; uint32_t getNumBuckets() const { return NumBuckets; } iterator_range getSymbols() const; - ArrayRef getHashBuckets() const { return HashBuckets; } - ArrayRef getAddressMap() const { return AddressMap; } - ArrayRef getThunkMap() const { return ThunkMap; } - ArrayRef getSectionOffsets() const { return SectionOffsets; } + codeview::FixedStreamArray getHashBuckets() const { + return HashBuckets; + } + codeview::FixedStreamArray getAddressMap() const { + return AddressMap; + } + codeview::FixedStreamArray getThunkMap() const { + return ThunkMap; + } + codeview::FixedStreamArray getSectionOffsets() const { + return SectionOffsets; + } private: Error readSymbols(); @@ -51,11 +59,12 @@ uint32_t StreamNum; MappedBlockStream Stream; uint32_t NumBuckets = 0; - std::vector HashRecords; - std::vector HashBuckets; - std::vector AddressMap; - std::vector ThunkMap; - std::vector SectionOffsets; + ArrayRef Bitmap; + codeview::FixedStreamArray HashRecords; + codeview::FixedStreamArray HashBuckets; + codeview::FixedStreamArray AddressMap; + codeview::FixedStreamArray ThunkMap; + codeview::FixedStreamArray SectionOffsets; const HeaderInfo *Header; const GSIHashHeader *HashHdr; Index: include/llvm/DebugInfo/PDB/Raw/RawConstants.h =================================================================== --- include/llvm/DebugInfo/PDB/Raw/RawConstants.h +++ include/llvm/DebugInfo/PDB/Raw/RawConstants.h @@ -10,6 +10,8 @@ #ifndef LLVM_DEBUGINFO_PDB_RAW_PDBRAWCONSTANTS_H #define LLVM_DEBUGINFO_PDB_RAW_PDBRAWCONSTANTS_H +#include "llvm/Support/Endian.h" + #include namespace llvm { @@ -71,6 +73,19 @@ Max }; +// This struct is defined as "SO" in langapi/include/pdb.h. +struct SectionOffset { + support::ulittle32_t Off; + support::ulittle16_t Isect; + char Padding[2]; +}; + +// This is HRFile. +struct PSHashRecord { + support::ulittle32_t Off; // Offset in the symbol record stream + support::ulittle32_t CRef; +}; + } // end namespace pdb } // end namespace llvm Index: include/llvm/Support/ScopedPrinter.h =================================================================== --- include/llvm/Support/ScopedPrinter.h +++ include/llvm/Support/ScopedPrinter.h @@ -211,6 +211,19 @@ OS << "]\n"; } + template + void printList(StringRef Label, const T &List, const U &Printer) { + startLine() << Label << ": ["; + bool Comma = false; + for (const auto &Item : List) { + if (Comma) + OS << ", "; + Printer(OS, Item); + Comma = true; + } + OS << "]\n"; + } + template void printHexList(StringRef Label, const T &List) { startLine() << Label << ": ["; bool Comma = false; Index: lib/DebugInfo/PDB/Raw/NameHashTable.cpp =================================================================== --- lib/DebugInfo/PDB/Raw/NameHashTable.cpp +++ lib/DebugInfo/PDB/Raw/NameHashTable.cpp @@ -105,11 +105,9 @@ if (auto EC = Stream.readObject(HashCount)) return EC; - std::vector BucketArray(*HashCount); - if (auto EC = Stream.readArray(BucketArray)) + if (auto EC = Stream.readArray(IDs, *HashCount)) return make_error(raw_error_code::corrupt_file, "Could not read bucket array"); - IDs.assign(BucketArray.begin(), BucketArray.end()); if (Stream.bytesRemaining() < sizeof(support::ulittle32_t)) return make_error(raw_error_code::corrupt_file, @@ -154,4 +152,7 @@ return IDs[0]; } -ArrayRef NameHashTable::name_ids() const { return IDs; } +codeview::FixedStreamArray +NameHashTable::name_ids() const { + return IDs; +} Index: lib/DebugInfo/PDB/Raw/PublicsStream.cpp =================================================================== --- lib/DebugInfo/PDB/Raw/PublicsStream.cpp +++ lib/DebugInfo/PDB/Raw/PublicsStream.cpp @@ -70,21 +70,6 @@ ulittle32_t NumBuckets; }; -// This is HRFile. -struct PublicsStream::HashRecord { - ulittle32_t Off; // Offset in the symbol record stream - 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) : Pdb(File), StreamNum(StreamNum), Stream(StreamNum, File) {} @@ -116,18 +101,18 @@ "Publics Stream does not contain a header."); // An array of HashRecord follows. Read them. - if (HashHdr->HrSize % sizeof(HashRecord)) + if (HashHdr->HrSize % sizeof(PSHashRecord)) return make_error(raw_error_code::corrupt_file, "Invalid HR array size."); - HashRecords.resize(HashHdr->HrSize / sizeof(HashRecord)); - if (auto EC = Reader.readArray(HashRecords)) + uint32_t NumHashRecords = HashHdr->HrSize / sizeof(PSHashRecord); + if (auto EC = Reader.readArray(HashRecords, NumHashRecords)) return make_error(raw_error_code::corrupt_file, "Could not read an HR array"); // A bitmap of a fixed length follows. size_t BitmapSizeInBits = alignTo(IPHR_HASH + 1, 32); - std::vector Bitmap(BitmapSizeInBits / 8); - if (auto EC = Reader.readArray(Bitmap)) + uint32_t NumBitmapEntries = BitmapSizeInBits / 8; + if (auto EC = Reader.readBytes(NumBitmapEntries, Bitmap)) return make_error(raw_error_code::corrupt_file, "Could not read a bitmap."); for (uint8_t B : Bitmap) @@ -139,40 +124,25 @@ // corrupted streams. // Hash buckets follow. - std::vector TempHashBuckets(NumBuckets); - if (auto EC = Reader.readArray(TempHashBuckets)) + if (auto EC = Reader.readArray(HashBuckets, NumBuckets)) return make_error(raw_error_code::corrupt_file, "Hash buckets corrupted."); - HashBuckets.resize(NumBuckets); - std::copy(TempHashBuckets.begin(), TempHashBuckets.end(), - HashBuckets.begin()); // Something called "address map" follows. - std::vector TempAddressMap(Header->AddrMap / sizeof(uint32_t)); - if (auto EC = Reader.readArray(TempAddressMap)) + uint32_t NumAddressMapEntries = Header->AddrMap / sizeof(uint32_t); + if (auto EC = Reader.readArray(AddressMap, NumAddressMapEntries)) return make_error(raw_error_code::corrupt_file, "Could not read an address map."); - AddressMap.resize(Header->AddrMap / sizeof(uint32_t)); - std::copy(TempAddressMap.begin(), TempAddressMap.end(), AddressMap.begin()); // Something called "thunk map" follows. - std::vector TempThunkMap(Header->NumThunks); - ThunkMap.resize(Header->NumThunks); - if (auto EC = Reader.readArray(TempThunkMap)) + if (auto EC = Reader.readArray(ThunkMap, Header->NumThunks)) return make_error(raw_error_code::corrupt_file, "Could not read a thunk map."); - ThunkMap.resize(Header->NumThunks); - std::copy(TempThunkMap.begin(), TempThunkMap.end(), ThunkMap.begin()); // Something called "section map" follows. - std::vector Offsets(Header->NumSections); - if (auto EC = Reader.readArray(Offsets)) + if (auto EC = Reader.readArray(SectionOffsets, Header->NumSections)) return make_error(raw_error_code::corrupt_file, "Could not read a section map."); - for (auto &SO : Offsets) { - SectionOffsets.push_back(SO.Off); - SectionOffsets.push_back(SO.Isect); - } if (Reader.bytesRemaining() > 0) return make_error(raw_error_code::corrupt_file, Index: tools/llvm-pdbdump/llvm-pdbdump.cpp =================================================================== --- tools/llvm-pdbdump/llvm-pdbdump.cpp +++ tools/llvm-pdbdump/llvm-pdbdump.cpp @@ -569,6 +569,11 @@ return Error::success(); } +static void printSectionOffset(llvm::raw_ostream &OS, + const SectionOffset &Off) { + OS << Off.Off << ", " << Off.Isect; +} + static Error dumpPublicsStream(ScopedPrinter &P, PDBFile &File, codeview::CVTypeDumper &TD) { if (!opts::DumpPublics) @@ -586,7 +591,8 @@ P.printList("Hash Buckets", Publics.getHashBuckets()); P.printList("Address Map", Publics.getAddressMap()); P.printList("Thunk Map", Publics.getThunkMap()); - P.printList("Section Offsets", Publics.getSectionOffsets()); + P.printList("Section Offsets", Publics.getSectionOffsets(), + printSectionOffset); ListScope L(P, "Symbols"); codeview::CVSymbolDumper SD(P, TD, nullptr, false); for (auto S : Publics.getSymbols()) {