Index: include/llvm/DebugInfo/PDB/Raw/DbiStream.h =================================================================== --- include/llvm/DebugInfo/PDB/Raw/DbiStream.h +++ include/llvm/DebugInfo/PDB/Raw/DbiStream.h @@ -14,6 +14,7 @@ #include "llvm/DebugInfo/PDB/Raw/ByteStream.h" #include "llvm/DebugInfo/PDB/Raw/MappedBlockStream.h" #include "llvm/DebugInfo/PDB/Raw/ModInfo.h" +#include "llvm/DebugInfo/PDB/Raw/NameHashTable.h" #include "llvm/DebugInfo/PDB/Raw/RawConstants.h" #include "llvm/Support/Endian.h" @@ -54,6 +55,7 @@ MappedBlockStream Stream; std::vector ModuleInfos; + NameHashTable ECNames; ByteStream ModInfoSubstream; ByteStream SecContrSubstream; Index: include/llvm/DebugInfo/PDB/Raw/NameHashTable.h =================================================================== --- /dev/null +++ include/llvm/DebugInfo/PDB/Raw/NameHashTable.h @@ -0,0 +1,45 @@ +//===- NameHashTable.h - PDB Name Hash Table --------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_DEBUGINFO_PDB_RAW_NAMEHASHTABLE_H +#define LLVM_DEBUGINFO_PDB_RAW_NAMEHASHTABLE_H + +#include "llvm/ADT/StringMap.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/DebugInfo/PDB/Raw/ByteStream.h" + +#include +#include + +namespace llvm { +namespace pdb { +class StreamReader; +class NameHashTable { +public: + NameHashTable(); + + std::error_code load(StreamReader &Stream); + + bool tryGetValue(StringRef Name, uint32_t &Value) const; + uint32_t getNameCount() const { return NameCount; } + uint32_t getHashVersion() const { return HashVersion; } + uint32_t getSignature() const { return Signature; } + +private: + ByteStream NamesBuffer; + std::vector Buckets; + uint32_t Signature; + uint32_t HashVersion; + uint32_t NameCount; + uint32_t HashCount; +}; +} +} + +#endif \ No newline at end of file Index: include/llvm/DebugInfo/PDB/Raw/StreamReader.h =================================================================== --- include/llvm/DebugInfo/PDB/Raw/StreamReader.h +++ include/llvm/DebugInfo/PDB/Raw/StreamReader.h @@ -34,6 +34,11 @@ return readBytes(Buffer); } + template std::error_code 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: lib/DebugInfo/PDB/CMakeLists.txt =================================================================== --- lib/DebugInfo/PDB/CMakeLists.txt +++ lib/DebugInfo/PDB/CMakeLists.txt @@ -33,6 +33,7 @@ Raw/PDBFile.cpp Raw/DbiStream.cpp Raw/InfoStream.cpp + Raw/NameHashTable.cpp Raw/NameMap.cpp Raw/RawSession.cpp Raw/StreamReader.cpp) Index: lib/DebugInfo/PDB/Raw/DbiStream.cpp =================================================================== --- lib/DebugInfo/PDB/Raw/DbiStream.cpp +++ lib/DebugInfo/PDB/Raw/DbiStream.cpp @@ -10,6 +10,7 @@ #include "llvm/DebugInfo/PDB/Raw/DbiStream.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/StreamReader.h" @@ -148,6 +149,9 @@ if (Reader.bytesRemaining() > 0) return std::make_error_code(std::errc::illegal_byte_sequence); + StreamReader ECReader(ECSubstream); + ECNames.load(ECReader); + return std::error_code(); } Index: lib/DebugInfo/PDB/Raw/NameHashTable.cpp =================================================================== --- /dev/null +++ lib/DebugInfo/PDB/Raw/NameHashTable.cpp @@ -0,0 +1,55 @@ +//===- NameHashTable.cpp - PDB Name Hash Table ------------------*- 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/NameHashTable.h" + +#include "llvm/ADT/ArrayRef.h" +#include "llvm/DebugInfo/PDB/Raw/ByteStream.h" +#include "llvm/DebugInfo/PDB/Raw/StreamReader.h" +#include "llvm/Support/Endian.h" + +using namespace llvm; +using namespace llvm::pdb; + +NameHashTable::NameHashTable() + : Signature(0), HashVersion(0), NameCount(0), HashCount(0) {} + +std::error_code NameHashTable::load(StreamReader &Stream) { + struct Header { + support::ulittle32_t Signature; + support::ulittle32_t HashVersion; + support::ulittle32_t ByteSize; + }; + + Header H; + Stream.readObject(&H); + if (H.Signature != 0xEFFEEFFE) + return std::make_error_code(std::errc::illegal_byte_sequence); + if (H.HashVersion != 1) + return std::make_error_code(std::errc::not_supported); + + Signature = H.Signature; + HashVersion = H.HashVersion; + NamesBuffer.initialize(Stream, H.ByteSize); + + Stream.readInteger(HashCount); + std::vector BucketArray(HashCount); + Stream.readArray(BucketArray); + Buckets.assign(BucketArray.begin(), BucketArray.end()); + + if (Stream.bytesRemaining() < sizeof(support::ulittle32_t)) + return std::make_error_code(std::errc::illegal_byte_sequence); + + Stream.readInteger(NameCount); + return std::error_code(); +} + +bool NameHashTable::tryGetValue(StringRef Name, uint32_t &Value) const { + return false; +} Index: tools/llvm-pdbdump/llvm-pdbdump.cpp =================================================================== --- tools/llvm-pdbdump/llvm-pdbdump.cpp +++ tools/llvm-pdbdump/llvm-pdbdump.cpp @@ -39,6 +39,7 @@ #include "llvm/DebugInfo/PDB/Raw/InfoStream.h" #include "llvm/DebugInfo/PDB/Raw/MappedBlockStream.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/RawSession.h" #include "llvm/DebugInfo/PDB/Raw/StreamReader.h" @@ -147,19 +148,6 @@ cl::cat(FilterCategory)); } - -static void reportError(StringRef Input, StringRef Message) { - if (Input == "-") - Input = ""; - errs() << Input << ": " << Message << "\n"; - errs().flush(); - exit(1); -} - -static void reportError(StringRef Input, std::error_code EC) { - reportError(Input, EC.message()); -} - static void dumpStructure(RawSession &RS) { PDBFile &File = RS.getPDBFile(); @@ -253,19 +241,11 @@ outs() << "NameStream: " << NameStreamIndex << '\n'; - // The name stream appears to start with a signature and version. - uint32_t NameStreamSignature; - Reader.readInteger(NameStreamSignature); + NameHashTable NameTable; + NameTable.load(Reader); outs() << "NameStreamSignature: "; - outs().write_hex(NameStreamSignature) << '\n'; - - uint32_t NameStreamVersion; - Reader.readInteger(NameStreamVersion); - outs() << "NameStreamVersion: " << NameStreamVersion << '\n'; - - // We only support this particular version of the name stream. - if (NameStreamSignature != 0xeffeeffe || NameStreamVersion != 1) - reportError("", std::make_error_code(std::errc::not_supported)); + outs().write_hex(NameTable.getSignature()) << '\n'; + outs() << "NameStreamVersion: " << NameTable.getHashVersion() << '\n'; } DbiStream &DS = File.getPDBDbiStream();