From 653baa2aaab66224c6f610dc133e8857cf53535a Mon Sep 17 00:00:00 2001 From: Bob Haarman Date: Fri, 21 Oct 2016 19:43:19 +0000 Subject: [PATCH] [pdb] added support for dumping globals stream Summary: This adds support for dumping the globals stream from PDB files using llvm-pdbdump, similar to the support we have for the publics stream. Reviewers: ruiu, zturner Subscribers: beanz, mgorny, modocache Differential Revision: https://reviews.llvm.org/D25801 llvm-svn: 284861 --- .../include/llvm/DebugInfo/PDB/Raw/GlobalsStream.h | 45 +++++++++++ llvm/include/llvm/DebugInfo/PDB/Raw/PDBFile.h | 3 + .../include/llvm/DebugInfo/PDB/Raw/PublicsStream.h | 2 +- llvm/lib/DebugInfo/PDB/CMakeLists.txt | 2 + llvm/lib/DebugInfo/PDB/Raw/GSI.cpp | 93 ++++++++++++++++++++++ llvm/lib/DebugInfo/PDB/Raw/GSI.h | 70 ++++++++++++++++ llvm/lib/DebugInfo/PDB/Raw/GlobalsStream.cpp | 46 +++++++++++ llvm/lib/DebugInfo/PDB/Raw/PDBFile.cpp | 17 ++++ llvm/lib/DebugInfo/PDB/Raw/PublicsStream.cpp | 54 ++----------- llvm/test/DebugInfo/PDB/pdbdump-headers.test | 14 +++- llvm/tools/llvm-pdbdump/LLVMOutputStyle.cpp | 24 ++++++ llvm/tools/llvm-pdbdump/LLVMOutputStyle.h | 1 + llvm/tools/llvm-pdbdump/llvm-pdbdump.cpp | 3 + llvm/tools/llvm-pdbdump/llvm-pdbdump.h | 1 + 14 files changed, 326 insertions(+), 49 deletions(-) create mode 100644 llvm/include/llvm/DebugInfo/PDB/Raw/GlobalsStream.h create mode 100644 llvm/lib/DebugInfo/PDB/Raw/GSI.cpp create mode 100644 llvm/lib/DebugInfo/PDB/Raw/GSI.h create mode 100644 llvm/lib/DebugInfo/PDB/Raw/GlobalsStream.cpp diff --git a/llvm/include/llvm/DebugInfo/PDB/Raw/GlobalsStream.h b/llvm/include/llvm/DebugInfo/PDB/Raw/GlobalsStream.h new file mode 100644 index 0000000..175f093c --- /dev/null +++ b/llvm/include/llvm/DebugInfo/PDB/Raw/GlobalsStream.h @@ -0,0 +1,45 @@ +//===- GlobalsStream.h - PDB Index of Symbols by Name ------ ----*- 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_GLOBALS_STREAM_H +#define LLVM_DEBUGINFO_PDB_RAW_GLOBALS_STREAM_H + +#include "llvm/DebugInfo/MSF/MappedBlockStream.h" +#include "llvm/DebugInfo/MSF/StreamArray.h" +#include "llvm/DebugInfo/PDB/PDBTypes.h" +#include "llvm/DebugInfo/PDB/Raw/RawConstants.h" +#include "llvm/DebugInfo/PDB/Raw/RawTypes.h" +#include "llvm/Support/Error.h" + +namespace llvm { +namespace pdb { +class DbiStream; +class PDBFile; + +class GlobalsStream { +public: + explicit GlobalsStream(std::unique_ptr Stream); + ~GlobalsStream(); + Error commit(); + msf::FixedStreamArray getHashBuckets() const { + return HashBuckets; + } + uint32_t getNumBuckets() const { return NumBuckets; } + Error reload(); + +private: + msf::FixedStreamArray HashBuckets; + msf::FixedStreamArray HashRecords; + uint32_t NumBuckets; + std::unique_ptr Stream; +}; +} +} + +#endif diff --git a/llvm/include/llvm/DebugInfo/PDB/Raw/PDBFile.h b/llvm/include/llvm/DebugInfo/PDB/Raw/PDBFile.h index 522bcb3..ede5eaf 100644 --- a/llvm/include/llvm/DebugInfo/PDB/Raw/PDBFile.h +++ b/llvm/include/llvm/DebugInfo/PDB/Raw/PDBFile.h @@ -31,6 +31,7 @@ class WritableStream; namespace pdb { class DbiStream; +class GlobalsStream; class InfoStream; class NameHashTable; class PDBFileBuilder; @@ -86,6 +87,7 @@ public: Expected getPDBInfoStream(); Expected getPDBDbiStream(); + Expected getPDBGlobalsStream(); Expected getPDBTpiStream(); Expected getPDBIpiStream(); Expected getPDBPublicsStream(); @@ -102,6 +104,7 @@ private: std::vector FpmPages; msf::MSFLayout ContainerLayout; + std::unique_ptr Globals; std::unique_ptr Info; std::unique_ptr Dbi; std::unique_ptr Tpi; diff --git a/llvm/include/llvm/DebugInfo/PDB/Raw/PublicsStream.h b/llvm/include/llvm/DebugInfo/PDB/Raw/PublicsStream.h index ba8ed11..577f298 100644 --- a/llvm/include/llvm/DebugInfo/PDB/Raw/PublicsStream.h +++ b/llvm/include/llvm/DebugInfo/PDB/Raw/PublicsStream.h @@ -22,10 +22,10 @@ namespace llvm { namespace pdb { class DbiStream; +struct GSIHashHeader; class PDBFile; class PublicsStream { - struct GSIHashHeader; struct HeaderInfo; public: diff --git a/llvm/lib/DebugInfo/PDB/CMakeLists.txt b/llvm/lib/DebugInfo/PDB/CMakeLists.txt index f28cbe7..04144f2 100644 --- a/llvm/lib/DebugInfo/PDB/CMakeLists.txt +++ b/llvm/lib/DebugInfo/PDB/CMakeLists.txt @@ -31,6 +31,8 @@ add_pdb_impl_folder(Raw Raw/DbiStream.cpp Raw/DbiStreamBuilder.cpp Raw/EnumTables.cpp + Raw/GlobalsStream.cpp + Raw/GSI.cpp Raw/Hash.cpp Raw/InfoStream.cpp Raw/InfoStreamBuilder.cpp diff --git a/llvm/lib/DebugInfo/PDB/Raw/GSI.cpp b/llvm/lib/DebugInfo/PDB/Raw/GSI.cpp new file mode 100644 index 0000000..6ecbb5c --- /dev/null +++ b/llvm/lib/DebugInfo/PDB/Raw/GSI.cpp @@ -0,0 +1,93 @@ +//===- GSI.cpp - Common Functions for GlobalsStream and PublicsStream ----===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "GSI.h" + +#include "llvm/DebugInfo/MSF/StreamArray.h" +#include "llvm/DebugInfo/MSF/StreamReader.h" +#include "llvm/DebugInfo/PDB/Raw/RawError.h" +#include "llvm/DebugInfo/PDB/Raw/RawTypes.h" + +#include "llvm/Support/Error.h" + +namespace llvm { +namespace pdb { + +static Error checkHashHdrVersion(const GSIHashHeader *HashHdr) { + if (HashHdr->VerHdr != GSIHashHeader::HdrVersion) + return make_error( + raw_error_code::feature_unsupported, + "Encountered unsupported globals stream version."); + + return Error::success(); +} + +Error readGSIHashBuckets( + msf::FixedStreamArray &HashBuckets, + const GSIHashHeader *HashHdr, msf::StreamReader &Reader) { + if (auto EC = checkHashHdrVersion(HashHdr)) + return EC; + + // Before the actual hash buckets, there is a bitmap of length determined by + // IPHR_HASH. + ArrayRef Bitmap; + size_t BitmapSizeInBits = alignTo(IPHR_HASH + 1, 32); + uint32_t NumBitmapEntries = BitmapSizeInBits / 8; + if (auto EC = Reader.readBytes(Bitmap, NumBitmapEntries)) + return joinErrors(std::move(EC), + make_error(raw_error_code::corrupt_file, + "Could not read a bitmap.")); + uint32_t NumBuckets = 0; + for (uint8_t B : Bitmap) + NumBuckets += countPopulation(B); + + // Hash buckets follow. + if (auto EC = Reader.readArray(HashBuckets, NumBuckets)) + return joinErrors(std::move(EC), + make_error(raw_error_code::corrupt_file, + "Hash buckets corrupted.")); + + return Error::success(); +} + +Error readGSIHashHeader(const GSIHashHeader *&HashHdr, + msf::StreamReader &Reader) { + if (Reader.readObject(HashHdr)) + return make_error(raw_error_code::corrupt_file, + "Stream does not contain a GSIHashHeader."); + + if (HashHdr->VerSignature != GSIHashHeader::HdrSignature) + return make_error( + raw_error_code::feature_unsupported, + "GSIHashHeader signature (0xffffffff) not found."); + + return Error::success(); +} + +Error readGSIHashRecords(msf::FixedStreamArray &HashRecords, + const GSIHashHeader *HashHdr, + msf::StreamReader &Reader) { + if (auto EC = checkHashHdrVersion(HashHdr)) + return EC; + + // HashHdr->HrSize specifies the number of bytes of PSHashRecords we have. + // Verify that we can read them all. + if (HashHdr->HrSize % sizeof(PSHashRecord)) + return make_error(raw_error_code::corrupt_file, + "Invalid HR array size."); + uint32_t NumHashRecords = HashHdr->HrSize / sizeof(PSHashRecord); + if (auto EC = Reader.readArray(HashRecords, NumHashRecords)) + return joinErrors(std::move(EC), + make_error(raw_error_code::corrupt_file, + "Error reading hash records.")); + + return Error::success(); +} +} +} diff --git a/llvm/lib/DebugInfo/PDB/Raw/GSI.h b/llvm/lib/DebugInfo/PDB/Raw/GSI.h new file mode 100644 index 0000000..82cebd9 --- /dev/null +++ b/llvm/lib/DebugInfo/PDB/Raw/GSI.h @@ -0,0 +1,70 @@ +//===- GSI.h - Common Declarations for GlobalsStream and PublicsStream ----===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// The data structures defined in this file are based on the reference +// implementation which is available at +// https://github.com/Microsoft/microsoft-pdb/blob/master/PDB/dbi/gsi.h +// +// When you are reading the reference source code, you'd find the +// information below useful. +// +// - ppdb1->m_fMinimalDbgInfo seems to be always true. +// - SMALLBUCKETS macro is defined. +// +// The reference doesn't compile, so I learned just by reading code. +// It's not guaranteed to be correct. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_DEBUGINFO_PDB_RAW_GSI_H +#define LLVM_LIB_DEBUGINFO_PDB_RAW_GSI_H + +#include "llvm/DebugInfo/MSF/StreamArray.h" +#include "llvm/DebugInfo/PDB/Raw/RawTypes.h" + +#include "llvm/Support/Endian.h" +#include "llvm/Support/Error.h" + +namespace llvm { + +namespace msf { +class StreamReader; +} + +namespace pdb { + +/// From https://github.com/Microsoft/microsoft-pdb/blob/master/PDB/dbi/gsi.cpp +static const unsigned IPHR_HASH = 4096; + +/// Header of the hash tables found in the globals and publics sections. +/// Based on GSIHashHeader in +/// https://github.com/Microsoft/microsoft-pdb/blob/master/PDB/dbi/gsi.h +struct GSIHashHeader { + enum : unsigned { + HdrSignature = ~0U, + HdrVersion = 0xeffe0000 + 19990810, + }; + support::ulittle32_t VerSignature; + support::ulittle32_t VerHdr; + support::ulittle32_t HrSize; + support::ulittle32_t NumBuckets; +}; + +Error readGSIHashBuckets( + msf::FixedStreamArray &HashBuckets, + const GSIHashHeader *HashHdr, msf::StreamReader &Reader); +Error readGSIHashHeader(const GSIHashHeader *&HashHdr, + msf::StreamReader &Reader); +Error readGSIHashRecords(msf::FixedStreamArray &HashRecords, + const GSIHashHeader *HashHdr, + msf::StreamReader &Reader); +} +} + +#endif diff --git a/llvm/lib/DebugInfo/PDB/Raw/GlobalsStream.cpp b/llvm/lib/DebugInfo/PDB/Raw/GlobalsStream.cpp new file mode 100644 index 0000000..c518452 --- /dev/null +++ b/llvm/lib/DebugInfo/PDB/Raw/GlobalsStream.cpp @@ -0,0 +1,46 @@ +//===- GlobalsStream.cpp - PDB Index of Symbols by Name ---- ----*- 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/GlobalsStream.h" + +#include "GSI.h" +#include "llvm/DebugInfo/PDB/Raw/PDBFile.h" +#include "llvm/DebugInfo/PDB/Raw/RawError.h" +#include "llvm/DebugInfo/PDB/Raw/RawTypes.h" + +#include "llvm/Support/Endian.h" +#include "llvm/Support/Error.h" + +using namespace llvm; +using namespace llvm::msf; +using namespace llvm::pdb; + +GlobalsStream::GlobalsStream(std::unique_ptr Stream) + : Stream(std::move(Stream)) {} + +GlobalsStream::~GlobalsStream() {} + +Error GlobalsStream::reload() { + StreamReader Reader(*Stream); + + const GSIHashHeader *HashHdr; + if (auto EC = readGSIHashHeader(HashHdr, Reader)) + return EC; + + if (auto EC = readGSIHashRecords(HashRecords, HashHdr, Reader)) + return EC; + + if (auto EC = readGSIHashBuckets(HashBuckets, HashHdr, Reader)) + return EC; + NumBuckets = HashBuckets.size(); + + return Error::success(); +} + +Error GlobalsStream::commit() { return Error::success(); } diff --git a/llvm/lib/DebugInfo/PDB/Raw/PDBFile.cpp b/llvm/lib/DebugInfo/PDB/Raw/PDBFile.cpp index 75840b0..f7bb8ab 100644 --- a/llvm/lib/DebugInfo/PDB/Raw/PDBFile.cpp +++ b/llvm/lib/DebugInfo/PDB/Raw/PDBFile.cpp @@ -15,6 +15,7 @@ #include "llvm/DebugInfo/MSF/StreamReader.h" #include "llvm/DebugInfo/MSF/StreamWriter.h" #include "llvm/DebugInfo/PDB/Raw/DbiStream.h" +#include "llvm/DebugInfo/PDB/Raw/GlobalsStream.h" #include "llvm/DebugInfo/PDB/Raw/InfoStream.h" #include "llvm/DebugInfo/PDB/Raw/NameHashTable.h" #include "llvm/DebugInfo/PDB/Raw/PublicsStream.h" @@ -217,6 +218,22 @@ llvm::ArrayRef PDBFile::getDirectoryBlockArray() const { return ContainerLayout.DirectoryBlocks; } +Expected PDBFile::getPDBGlobalsStream() { + if (!Globals) { + auto DbiS = getPDBDbiStream(); + if (!DbiS) + return DbiS.takeError(); + + auto GlobalS = MappedBlockStream::createIndexedStream( + ContainerLayout, *Buffer, DbiS->getGlobalSymbolStreamIndex()); + auto TempGlobals = llvm::make_unique(std::move(GlobalS)); + if (auto EC = TempGlobals->reload()) + return std::move(EC); + Globals = std::move(TempGlobals); + } + return *Globals; +} + Expected PDBFile::getPDBInfoStream() { if (!Info) { auto InfoS = MappedBlockStream::createIndexedStream(ContainerLayout, diff --git a/llvm/lib/DebugInfo/PDB/Raw/PublicsStream.cpp b/llvm/lib/DebugInfo/PDB/Raw/PublicsStream.cpp index 5d4431d..43ac4e5 100644 --- a/llvm/lib/DebugInfo/PDB/Raw/PublicsStream.cpp +++ b/llvm/lib/DebugInfo/PDB/Raw/PublicsStream.cpp @@ -24,6 +24,7 @@ #include "llvm/DebugInfo/PDB/Raw/PublicsStream.h" +#include "GSI.h" #include "llvm/DebugInfo/CodeView/CodeView.h" #include "llvm/DebugInfo/CodeView/TypeRecord.h" #include "llvm/DebugInfo/MSF/MappedBlockStream.h" @@ -44,8 +45,6 @@ using namespace llvm::support; using namespace llvm::pdb; -static const unsigned IPHR_HASH = 4096; - // This is PSGSIHDR struct defined in // https://github.com/Microsoft/microsoft-pdb/blob/master/PDB/dbi/gsi.h struct PublicsStream::HeaderInfo { @@ -59,18 +58,6 @@ struct PublicsStream::HeaderInfo { ulittle32_t NumSections; }; -// This is GSIHashHdr. -struct PublicsStream::GSIHashHeader { - enum : unsigned { - HdrSignature = ~0U, - HdrVersion = 0xeffe0000 + 19990810, - }; - ulittle32_t VerSignature; - ulittle32_t VerHdr; - ulittle32_t HrSize; - ulittle32_t NumBuckets; -}; - PublicsStream::PublicsStream(PDBFile &File, std::unique_ptr Stream) : Pdb(File), Stream(std::move(Stream)) {} @@ -98,40 +85,15 @@ Error PublicsStream::reload() { return make_error(raw_error_code::corrupt_file, "Publics Stream does not contain a header."); - if (Reader.readObject(HashHdr)) - return make_error(raw_error_code::corrupt_file, - "Publics Stream does not contain a header."); - - // An array of HashRecord follows. Read them. - if (HashHdr->HrSize % sizeof(PSHashRecord)) - return make_error(raw_error_code::corrupt_file, - "Invalid HR array size."); - uint32_t NumHashRecords = HashHdr->HrSize / sizeof(PSHashRecord); - if (auto EC = Reader.readArray(HashRecords, NumHashRecords)) - return joinErrors(std::move(EC), - 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); - uint32_t NumBitmapEntries = BitmapSizeInBits / 8; - if (auto EC = Reader.readBytes(Bitmap, NumBitmapEntries)) - return joinErrors(std::move(EC), - make_error(raw_error_code::corrupt_file, - "Could not read a bitmap.")); - for (uint8_t B : Bitmap) - NumBuckets += countPopulation(B); + if (auto EC = readGSIHashHeader(HashHdr, Reader)) + return EC; - // 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. + if (auto EC = readGSIHashRecords(HashRecords, HashHdr, Reader)) + return EC; - // Hash buckets follow. - if (auto EC = Reader.readArray(HashBuckets, NumBuckets)) - return joinErrors(std::move(EC), - make_error(raw_error_code::corrupt_file, - "Hash buckets corrupted.")); + if (auto EC = readGSIHashBuckets(HashBuckets, HashHdr, Reader)) + return EC; + NumBuckets = HashBuckets.size(); // Something called "address map" follows. uint32_t NumAddressMapEntries = Header->AddrMap / sizeof(uint32_t); diff --git a/llvm/test/DebugInfo/PDB/pdbdump-headers.test b/llvm/test/DebugInfo/PDB/pdbdump-headers.test index b6f260f..c98e17f 100644 --- a/llvm/test/DebugInfo/PDB/pdbdump-headers.test +++ b/llvm/test/DebugInfo/PDB/pdbdump-headers.test @@ -1,5 +1,5 @@ ; RUN: llvm-pdbdump raw -headers -tpi-records -tpi-record-bytes -module-syms \ -; RUN: -sym-record-bytes -publics -module-files \ +; RUN: -sym-record-bytes -globals -publics -module-files \ ; RUN: -stream-summary -stream-blocks -ipi-records -ipi-record-bytes \ ; RUN: -section-contribs -section-map -section-headers -line-info \ ; RUN: -tpi-hash -fpo -page-stats %p/Inputs/empty.pdb | FileCheck -check-prefix=EMPTY %s @@ -794,7 +794,12 @@ ; EMPTY-NEXT: SecByteLength: 4294967295 ; EMPTY-NEXT: } ; EMPTY-NEXT: ] -; EMPTY: Publics Stream { +; EMPTY-NEXT: Globals Stream { +; EMPTY-NEXT: Stream number: 6 +; EMPTY-NEXT: Number of buckets: 2 +; EMPTY-NEXT: Hash Buckets: [0, 12] +; EMPTY-NEXT: } +; EMPTY-NEXT: Publics Stream { ; EMPTY-NEXT: Stream number: 7 ; EMPTY-NEXT: SymHash: 556 ; EMPTY-NEXT: AddrMap: 8 @@ -1552,6 +1557,11 @@ ; ALL: SecByteLength: 4294967295 ; ALL: } ; ALL: ] +; ALL: Globals Stream { +; ALL: Stream number: 6 +; ALL: Number of buckets: 2 +; ALL: Hash Buckets: [0, 12] +; ALL: } ; ALL: Publics Stream { ; ALL: Stream number: 7 ; ALL: SymHash: 556 diff --git a/llvm/tools/llvm-pdbdump/LLVMOutputStyle.cpp b/llvm/tools/llvm-pdbdump/LLVMOutputStyle.cpp index db39dae..c69f384 100644 --- a/llvm/tools/llvm-pdbdump/LLVMOutputStyle.cpp +++ b/llvm/tools/llvm-pdbdump/LLVMOutputStyle.cpp @@ -18,6 +18,7 @@ #include "llvm/DebugInfo/PDB/PDBExtras.h" #include "llvm/DebugInfo/PDB/Raw/DbiStream.h" #include "llvm/DebugInfo/PDB/Raw/EnumTables.h" +#include "llvm/DebugInfo/PDB/Raw/GlobalsStream.h" #include "llvm/DebugInfo/PDB/Raw/ISectionContribVisitor.h" #include "llvm/DebugInfo/PDB/Raw/InfoStream.h" #include "llvm/DebugInfo/PDB/Raw/ModInfo.h" @@ -122,6 +123,9 @@ Error LLVMOutputStyle::dump() { if (auto EC = dumpSectionMap()) return EC; + if (auto EC = dumpGlobalsStream()) + return EC; + if (auto EC = dumpPublicsStream()) return EC; @@ -343,6 +347,26 @@ void LLVMOutputStyle::dumpBitVector(StringRef Name, const BitVector &V) { P.printList(Name, Vec); } +Error LLVMOutputStyle::dumpGlobalsStream() { + if (!opts::raw::DumpGlobals) + return Error::success(); + + DictScope D(P, "Globals Stream"); + auto Globals = File.getPDBGlobalsStream(); + if (!Globals) + return Globals.takeError(); + + auto Dbi = File.getPDBDbiStream(); + if (!Dbi) + return Dbi.takeError(); + + P.printNumber("Stream number", Dbi->getGlobalSymbolStreamIndex()); + P.printNumber("Number of buckets", Globals->getNumBuckets()); + P.printList("Hash Buckets", Globals->getHashBuckets()); + + return Error::success(); +} + Error LLVMOutputStyle::dumpStreamBlocks() { if (!opts::raw::DumpStreamBlocks) return Error::success(); diff --git a/llvm/tools/llvm-pdbdump/LLVMOutputStyle.h b/llvm/tools/llvm-pdbdump/LLVMOutputStyle.h index f5740ec..72a3fd4 100644 --- a/llvm/tools/llvm-pdbdump/LLVMOutputStyle.h +++ b/llvm/tools/llvm-pdbdump/LLVMOutputStyle.h @@ -31,6 +31,7 @@ private: Error dumpStreamSummary(); Error dumpFreePageMap(); Error dumpBlockRanges(); + Error dumpGlobalsStream(); Error dumpStreamBytes(); Error dumpStreamBlocks(); Error dumpInfoStream(); diff --git a/llvm/tools/llvm-pdbdump/llvm-pdbdump.cpp b/llvm/tools/llvm-pdbdump/llvm-pdbdump.cpp index a6dd560..b356a28 100644 --- a/llvm/tools/llvm-pdbdump/llvm-pdbdump.cpp +++ b/llvm/tools/llvm-pdbdump/llvm-pdbdump.cpp @@ -215,6 +215,8 @@ cl::opt DumpLineInfo("line-info", cl::cat(FileOptions), cl::sub(RawSubcommand)); // SYMBOL OPTIONS +cl::opt DumpGlobals("globals", cl::desc("dump globals stream data"), + cl::cat(SymbolOptions), cl::sub(RawSubcommand)); cl::opt DumpModuleSyms("module-syms", cl::desc("dump module symbols"), cl::cat(SymbolOptions), cl::sub(RawSubcommand)); cl::opt DumpPublics("publics", cl::desc("dump Publics stream data"), @@ -559,6 +561,7 @@ int main(int argc_, const char *argv_[]) { opts::raw::DumpModules = true; opts::raw::DumpModuleFiles = true; opts::raw::DumpModuleSyms = true; + opts::raw::DumpGlobals = true; opts::raw::DumpPublics = true; opts::raw::DumpSectionHeaders = true; opts::raw::DumpStreamSummary = true; diff --git a/llvm/tools/llvm-pdbdump/llvm-pdbdump.h b/llvm/tools/llvm-pdbdump/llvm-pdbdump.h index 72423d7..42d847a 100644 --- a/llvm/tools/llvm-pdbdump/llvm-pdbdump.h +++ b/llvm/tools/llvm-pdbdump/llvm-pdbdump.h @@ -43,6 +43,7 @@ struct BlockRange { extern llvm::Optional DumpBlockRange; extern llvm::cl::list DumpStreamData; +extern llvm::cl::opt DumpGlobals; extern llvm::cl::opt DumpHeaders; extern llvm::cl::opt DumpStreamBlocks; extern llvm::cl::opt DumpStreamSummary; -- 2.7.4