1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-24 03:33:20 +01:00

[llvm-pdbdump] Rework command line options.

When dumping huge PDB files, too many of the options were grouped
together so you would get neverending spew of output.  This patch
introduces more granular display options so you can only dump the
fields you actually care about.

llvm-svn: 270607
This commit is contained in:
Zachary Turner 2016-05-24 20:31:48 +00:00
parent 837c08b0ff
commit 4f6bada416
5 changed files with 148 additions and 76 deletions

View File

@ -34,6 +34,7 @@ public:
PdbRaw_DbiVer getDbiVersion() const;
uint32_t getAge() const;
uint16_t getPublicSymbolStreamIndex() const;
uint16_t getGlobalSymbolStreamIndex() const;
bool isIncrementallyLinked() const;
bool hasCTypes() const;

View File

@ -188,6 +188,10 @@ uint16_t DbiStream::getPublicSymbolStreamIndex() const {
return Header->PublicSymbolStreamIndex;
}
uint16_t DbiStream::getGlobalSymbolStreamIndex() const {
return Header->GlobalSymbolStreamIndex;
}
bool DbiStream::isIncrementallyLinked() const {
return (Header->Flags & FlagIncrementalMask) != 0;
}

View File

@ -15,8 +15,12 @@ using namespace llvm;
using namespace llvm::pdb;
MappedBlockStream::MappedBlockStream(uint32_t StreamIdx, const PDBFile &File) : Pdb(File) {
if (StreamIdx >= Pdb.getNumStreams()) {
StreamLength = 0;
} else {
StreamLength = Pdb.getStreamByteSize(StreamIdx);
BlockList = Pdb.getStreamBlockList(StreamIdx);
}
}
Error MappedBlockStream::readBytes(uint32_t Offset,
@ -54,5 +58,23 @@ Error MappedBlockStream::readBytes(uint32_t Offset,
Error MappedBlockStream::getArrayRef(uint32_t Offset, ArrayRef<uint8_t> &Buffer,
uint32_t Length) const {
uint32_t BlockNum = Offset / Pdb.getBlockSize();
uint32_t OffsetInBlock = Offset % Pdb.getBlockSize();
uint32_t BytesAvailableInBlock = Pdb.getBlockSize() - OffsetInBlock;
// If this is the last block in the stream, not all of the data is valid.
if (BlockNum == BlockList.size() - 1) {
uint32_t AllocatedBytesInBlock = StreamLength % Pdb.getBlockSize();
if (AllocatedBytesInBlock < BytesAvailableInBlock)
BytesAvailableInBlock = AllocatedBytesInBlock;
}
if (BytesAvailableInBlock < Length)
return make_error<RawError>(raw_error_code::feature_unsupported);
uint32_t StreamBlockAddr = BlockList[BlockNum];
StringRef Data = Pdb.getBlockData(StreamBlockAddr, Pdb.getBlockSize());
Data = Data.substr(OffsetInBlock, Length);
Buffer = ArrayRef<uint8_t>(Data.bytes_begin(), Data.bytes_end());
return Error::success();
}

View File

@ -1,7 +1,9 @@
; RUN: llvm-pdbdump --dump-headers -dump-tpi-records -dump-tpi-record-bytes -dump-module-syms \
; RUN: -dump-sym-record-bytes --dump-publics %p/Inputs/empty.pdb | FileCheck -check-prefix=EMPTY %s
; RUN: llvm-pdbdump --dump-headers %p/Inputs/big-read.pdb | FileCheck -check-prefix=BIG %s
; RUN: llvm-pdbdump --dump-headers %p/Inputs/bad-block-size.pdb | FileCheck -check-prefix=BAD-BLOCK-SIZE %s
; RUN: llvm-pdbdump -raw-headers -raw-tpi-records -raw-tpi-record-bytes -raw-module-syms \
; RUN: -raw-sym-record-bytes -raw-publics -raw-module-files -raw-stream-name=/names \
; RUN: %p/Inputs/empty.pdb | FileCheck -check-prefix=EMPTY %s
; RUN: llvm-pdbdump -raw-headers -raw-stream-name=/names -raw-modules -raw-module-files \
; RUN: %p/Inputs/big-read.pdb | FileCheck -check-prefix=BIG %s
; RUN: llvm-pdbdump -raw-headers %p/Inputs/bad-block-size.pdb | FileCheck -check-prefix=BAD-BLOCK-SIZE %s
; EMPTY: FileHeaders {
; EMPTY-NEXT: BlockSize: 4096
@ -105,6 +107,8 @@
; EMPTY-NEXT: Is Stripped: No
; EMPTY-NEXT: Machine Type: x86
; EMPTY-NEXT: Symbol Record Stream Index: 8
; EMPTY-NEXT: Public Symbol Stream Index: 7
; EMPTY-NEXT: Global Symbol Stream Index: 6
; EMPTY-NEXT: Toolchain Version: 12.0
; EMPTY-NEXT: mspdb120.dll version: 12.0.31101
; EMPTY-NEXT: Modules [
@ -525,6 +529,8 @@
; BIG-NEXT: Is Stripped: No
; BIG-NEXT: Machine Type: x86
; BIG-NEXT: Symbol Record Stream Index: 9
; BIG-NEXT: Public Symbol Stream Index: 8
; BIG-NEXT: Global Symbol Stream Index: 7
; BIG-NEXT: Toolchain Version: 14.0
; BIG-NEXT: mspdb140.dll version: 14.0.23918
; BIG-NEXT: Modules [

View File

@ -104,31 +104,38 @@ cl::opt<uint64_t> LoadAddress(
cl::desc("Assume the module is loaded at the specified address"),
cl::cat(OtherOptions));
cl::opt<bool> DumpHeaders("dump-headers", cl::desc("dump PDB headers"),
cl::opt<bool> DumpHeaders("raw-headers", cl::desc("dump PDB headers"),
cl::cat(NativeOtions));
cl::opt<bool> DumpStreamSizes("dump-stream-sizes",
cl::opt<bool> DumpStreamSizes("raw-stream-sizes",
cl::desc("dump PDB stream sizes"),
cl::cat(NativeOtions));
cl::opt<bool> DumpStreamBlocks("dump-stream-blocks",
cl::opt<bool> DumpStreamBlocks("raw-stream-blocks",
cl::desc("dump PDB stream blocks"),
cl::cat(NativeOtions));
cl::opt<bool> DumpTpiRecords("dump-tpi-records",
cl::opt<bool> DumpTpiRecords("raw-tpi-records",
cl::desc("dump CodeView type records"),
cl::cat(NativeOtions));
cl::opt<bool>
DumpTpiRecordBytes("dump-tpi-record-bytes",
DumpTpiRecordBytes("raw-tpi-record-bytes",
cl::desc("dump CodeView type record raw bytes"),
cl::cat(NativeOtions));
cl::opt<std::string> DumpStreamData("dump-stream", cl::desc("dump stream data"),
cl::opt<std::string> DumpStreamDataIdx("raw-stream",
cl::desc("dump stream data"),
cl::cat(NativeOtions));
cl::opt<bool> DumpModuleSyms("dump-module-syms",
cl::desc("dump module symbols"),
cl::opt<std::string> DumpStreamDataName("raw-stream-name",
cl::desc("dump stream data"),
cl::cat(NativeOtions));
cl::opt<bool> DumpPublics("dump-publics",
cl::desc("dump Publics stream data"),
cl::opt<bool> DumpModules("raw-modules", cl::desc("dump compiland information"),
cl::cat(NativeOtions));
cl::opt<bool> DumpModuleFiles("raw-module-files",
cl::desc("dump file information"),
cl::cat(NativeOtions));
cl::opt<bool> DumpModuleSyms("raw-module-syms", cl::desc("dump module symbols"),
cl::cat(NativeOtions));
cl::opt<bool> DumpPublics("raw-publics", cl::desc("dump Publics stream data"),
cl::cat(NativeOtions));
cl::opt<bool>
DumpSymRecordBytes("dump-sym-record-bytes",
DumpSymRecordBytes("raw-sym-record-bytes",
cl::desc("dump CodeView symbol record raw bytes"),
cl::cat(NativeOtions));
@ -227,28 +234,22 @@ static Error dumpStreamBlocks(ScopedPrinter &P, PDBFile &File) {
static Error dumpStreamData(ScopedPrinter &P, PDBFile &File) {
uint32_t StreamCount = File.getNumStreams();
StringRef DumpStreamStr = opts::DumpStreamData;
StringRef DumpStreamStr = opts::DumpStreamDataIdx;
uint32_t DumpStreamNum;
if (DumpStreamStr.getAsInteger(/*Radix=*/0U, DumpStreamNum) ||
DumpStreamNum >= StreamCount)
return Error::success();
uint32_t StreamBytesRead = 0;
uint32_t StreamSize = File.getStreamByteSize(DumpStreamNum);
auto StreamBlocks = File.getStreamBlockList(DumpStreamNum);
for (uint32_t StreamBlockAddr : StreamBlocks) {
uint32_t BytesLeftToReadInStream = StreamSize - StreamBytesRead;
if (BytesLeftToReadInStream == 0)
break;
MappedBlockStream S(DumpStreamNum, File);
StreamReader R(S);
while (R.bytesRemaining() > 0) {
ArrayRef<uint8_t> Data;
uint32_t BytesToReadInBlock = std::min(
BytesLeftToReadInStream, static_cast<uint32_t>(File.getBlockSize()));
auto StreamBlockData =
File.getBlockData(StreamBlockAddr, BytesToReadInBlock);
outs() << StreamBlockData;
StreamBytesRead += StreamBlockData.size();
R.bytesRemaining(), static_cast<uint32_t>(File.getBlockSize()));
if (auto EC = R.getArrayRef(Data, BytesToReadInBlock))
return EC;
outs() << StringRef(reinterpret_cast<const char *>(Data.begin()),
Data.size());
}
return Error::success();
}
@ -268,18 +269,20 @@ static Error dumpInfoStream(ScopedPrinter &P, PDBFile &File) {
return Error::success();
}
static Error dumpNamedStream(ScopedPrinter &P, PDBFile &File,
StringRef Stream) {
static Error dumpNamedStream(ScopedPrinter &P, PDBFile &File) {
if (opts::DumpStreamDataName.empty())
return Error::success();
auto InfoS = File.getPDBInfoStream();
if (auto EC = InfoS.takeError())
return EC;
InfoStream &IS = InfoS.get();
uint32_t NameStreamIndex = IS.getNamedStreamIndex(Stream);
uint32_t NameStreamIndex = IS.getNamedStreamIndex(opts::DumpStreamDataName);
if (NameStreamIndex != 0) {
std::string Name("Stream '");
Name += Stream;
Name += opts::DumpStreamDataName;
Name += "'";
DictScope D(P, Name);
P.printNumber("Index", NameStreamIndex);
@ -319,6 +322,8 @@ static Error dumpDbiStream(ScopedPrinter &P, PDBFile &File,
P.printBoolean("Is Stripped", DS.isStripped());
P.printObject("Machine Type", DS.getMachineType());
P.printNumber("Symbol Record Stream Index", DS.getSymRecordStreamIndex());
P.printNumber("Public Symbol Stream Index", DS.getPublicSymbolStreamIndex());
P.printNumber("Global Symbol Stream Index", DS.getGlobalSymbolStreamIndex());
uint16_t Major = DS.getBuildMajorVersion();
uint16_t Minor = DS.getBuildMinorVersion();
@ -330,6 +335,7 @@ static Error dumpDbiStream(ScopedPrinter &P, PDBFile &File,
DllStream.flush();
P.printVersion(DllName, Major, Minor, DS.getPdbDllVersion());
if (opts::DumpModules || opts::DumpModuleSyms || opts::DumpModuleFiles) {
ListScope L(P, "Modules");
for (auto &Modi : DS.modules()) {
DictScope DD(P);
@ -345,14 +351,18 @@ static Error dumpDbiStream(ScopedPrinter &P, PDBFile &File,
P.printNumber("Symbol Byte Size", Modi.Info.getSymbolDebugInfoByteSize());
P.printNumber("Type Server Index", Modi.Info.getTypeServerIndex());
P.printBoolean("Has EC Info", Modi.Info.hasECInfo());
{
if (opts::DumpModuleFiles) {
std::string FileListName =
to_string(Modi.SourceFiles.size()) + " Contributing Source Files";
ListScope LL(P, FileListName);
for (auto File : Modi.SourceFiles)
P.printString(File);
}
if (opts::DumpModuleSyms || opts::DumpSymRecordBytes) {
bool HasModuleDI =
(Modi.Info.getModuleStreamIndex() < File.getNumStreams());
bool ShouldDumpSymbols =
(opts::DumpModuleSyms || opts::DumpSymRecordBytes);
if (HasModuleDI && ShouldDumpSymbols) {
ListScope SS(P, "Symbols");
ModStream ModS(File, Modi.Info);
if (auto EC = ModS.reload())
@ -369,6 +379,7 @@ static Error dumpDbiStream(ScopedPrinter &P, PDBFile &File,
}
}
}
}
return Error::success();
}
@ -474,7 +485,7 @@ static Error dumpStructure(RawSession &RS) {
if (auto EC = dumpInfoStream(P, File))
return EC;
if (auto EC = dumpNamedStream(P, File, "/names"))
if (auto EC = dumpNamedStream(P, File))
return EC;
codeview::CVTypeDumper TD(P, false);
@ -486,12 +497,40 @@ static Error dumpStructure(RawSession &RS) {
if (auto EC = dumpPublicsStream(P, File, TD))
return EC;
return Error::success();
return Error::success();
}
bool isRawDumpEnabled() {
if (opts::DumpHeaders)
return true;
if (opts::DumpModules)
return true;
if (opts::DumpModuleFiles)
return true;
if (opts::DumpModuleSyms)
return true;
if (!opts::DumpStreamDataIdx.empty())
return true;
if (!opts::DumpStreamDataName.empty())
return true;
if (opts::DumpPublics)
return true;
if (opts::DumpStreamBlocks)
return true;
if (opts::DumpStreamSizes)
return true;
if (opts::DumpSymRecordBytes)
return true;
if (opts::DumpTpiRecordBytes)
return true;
if (opts::DumpTpiRecords)
return true;
return false;
}
static void dumpInput(StringRef Path) {
std::unique_ptr<IPDBSession> Session;
if (opts::DumpHeaders || !opts::DumpStreamData.empty()) {
if (isRawDumpEnabled()) {
auto E = loadDataForPDB(PDB_ReaderType::Raw, Path, Session);
if (!E) {
RawSession *RS = static_cast<RawSession *>(Session.get());