Index: llvm/trunk/lib/DebugInfo/PDB/Native/PDBFile.cpp =================================================================== --- llvm/trunk/lib/DebugInfo/PDB/Native/PDBFile.cpp +++ llvm/trunk/lib/DebugInfo/PDB/Native/PDBFile.cpp @@ -401,7 +401,9 @@ return 4; } -bool PDBFile::hasPDBDbiStream() const { return StreamDBI < getNumStreams(); } +bool PDBFile::hasPDBDbiStream() const { + return StreamDBI < getNumStreams() && getStreamByteSize(StreamDBI) > 0; +} bool PDBFile::hasPDBGlobalsStream() { auto DbiS = getPDBDbiStream(); Index: llvm/trunk/test/tools/llvm-pdbdump/Inputs/TypeServerTest.cpp =================================================================== --- llvm/trunk/test/tools/llvm-pdbdump/Inputs/TypeServerTest.cpp +++ llvm/trunk/test/tools/llvm-pdbdump/Inputs/TypeServerTest.cpp @@ -0,0 +1,6 @@ +// Compile with "cl /c /Zi TypeServerTest.cpp /FdTypeServerTest.pdb" + +int main(void) +{ + return 0; +} Index: llvm/trunk/test/tools/llvm-pdbdump/type-server-no-dbi.test =================================================================== --- llvm/trunk/test/tools/llvm-pdbdump/type-server-no-dbi.test +++ llvm/trunk/test/tools/llvm-pdbdump/type-server-no-dbi.test @@ -0,0 +1,46 @@ + +RUN: llvm-pdbutil dump -all %p/Inputs/TypeServerTest.pdb | FileCheck %s --check-prefix=NO-DBI +RUN: llvm-pdbutil pdb2yaml -all %p/Inputs/TypeServerTest.pdb > %t +RUN: FileCheck --input-file=%t %s --check-prefix=NO-DBI-YAML + +NO-DBI-NOT: Native PDB Error: The specified stream could not be loaded. + +NO-DBI: Module Stats +NO-DBI-NEXT: ============================================================ +NO-DBI-NEXT: DBI stream not present + +NO-DBI: S_UDT Record Stats +NO-DBI-NEXT: ============================================================ +NO-DBI-NEXT: Globals stream not present + +NO-DBI: Modules +NO-DBI-NEXT: ============================================================ +NO-DBI-NEXT: DBI stream not present + +NO-DBI: Files +NO-DBI-NEXT: ============================================================ +NO-DBI-NEXT: DBI stream not present + +NO-DBI: Lines +NO-DBI-NEXT: ============================================================ +NO-DBI-NEXT: DBI stream not present + +NO-DBI: Inlinee Lines +NO-DBI-NEXT: ============================================================ +NO-DBI-NEXT: DBI stream not present + +NO-DBI: Cross Module Imports +NO-DBI-NEXT: ============================================================ +NO-DBI-NEXT: DBI stream not present + +NO-DBI: Cross Module Exports +NO-DBI-NEXT: ============================================================ +NO-DBI-NEXT: DBI stream not present + + +NO-DBI-YAML-NOT: Native PDB Error: The specified stream could not be loaded. + +NO-DBI-YAML: TpiStream: +NO-DBI-YAML-NEXT: Version: VC80 +NO-DBI-YAML-NEXT: Records: +NO-DBI-YAML-NEXT: - Kind: LF_ARGLIST Index: llvm/trunk/tools/llvm-pdbutil/DumpOutputStyle.h =================================================================== --- llvm/trunk/tools/llvm-pdbutil/DumpOutputStyle.h +++ llvm/trunk/tools/llvm-pdbutil/DumpOutputStyle.h @@ -70,6 +70,9 @@ PDBFile &getPdb(); object::COFFObjectFile &getObj(); + void printStreamNotValidForObj(); + void printStreamNotPresent(StringRef StreamName); + Error dumpFileSummary(); Error dumpStreamSummary(); Error dumpSymbolStats(); Index: llvm/trunk/tools/llvm-pdbutil/DumpOutputStyle.cpp =================================================================== --- llvm/trunk/tools/llvm-pdbutil/DumpOutputStyle.cpp +++ llvm/trunk/tools/llvm-pdbutil/DumpOutputStyle.cpp @@ -65,6 +65,16 @@ PDBFile &DumpOutputStyle::getPdb() { return File.pdb(); } object::COFFObjectFile &DumpOutputStyle::getObj() { return File.obj(); } +void DumpOutputStyle::printStreamNotValidForObj() { + AutoIndent Indent(P, 4); + P.formatLine("Dumping this stream is not valid for object files"); +} + +void DumpOutputStyle::printStreamNotPresent(StringRef StreamName) { + AutoIndent Indent(P, 4); + P.formatLine("{0} stream not present", StreamName); +} + Error DumpOutputStyle::dump() { if (opts::dump::DumpSummary) { if (auto EC = dumpFileSummary()) @@ -199,14 +209,14 @@ Error DumpOutputStyle::dumpFileSummary() { printHeader(P, "Summary"); - ExitOnError Err("Invalid PDB Format: "); - - AutoIndent Indent(P); if (File.isObj()) { - P.formatLine("Dumping File summary is not valid for object files"); + printStreamNotValidForObj(); return Error::success(); } + AutoIndent Indent(P); + ExitOnError Err("Invalid PDB Format: "); + P.formatLine("Block Size: {0}", getPdb().getBlockSize()); P.formatLine("Number of blocks: {0}", getPdb().getBlockCount()); P.formatLine("Number of streams: {0}", getPdb().getNumStreams()); @@ -326,12 +336,13 @@ Error DumpOutputStyle::dumpStreamSummary() { printHeader(P, "Streams"); - AutoIndent Indent(P); if (File.isObj()) { - P.formatLine("Dumping streams is not valid for object files"); + printStreamNotValidForObj(); return Error::success(); } + AutoIndent Indent(P); + if (StreamPurposes.empty()) discoverStreamPurposes(getPdb(), StreamPurposes); @@ -527,18 +538,18 @@ Error DumpOutputStyle::dumpModules() { printHeader(P, "Modules"); - AutoIndent Indent(P); if (File.isObj()) { - P.formatLine("Dumping modules is not supported for object files"); + printStreamNotValidForObj(); return Error::success(); } if (!getPdb().hasPDBDbiStream()) { - P.formatLine("DBI Stream not present"); + printStreamNotPresent("DBI"); return Error::success(); } + AutoIndent Indent(P); ExitOnError Err("Unexpected error processing modules: "); auto &Stream = Err(getPdb().getPDBDbiStream()); @@ -570,7 +581,12 @@ printHeader(P, "Files"); if (File.isObj()) { - P.formatLine("Dumping files is not valid for object files"); + printStreamNotValidForObj(); + return Error::success(); + } + + if (!getPdb().hasPDBDbiStream()) { + printStreamNotPresent("DBI"); return Error::success(); } @@ -591,6 +607,11 @@ Error DumpOutputStyle::dumpSymbolStats() { printHeader(P, "Module Stats"); + if (File.isPdb() && !getPdb().hasPDBDbiStream()) { + printStreamNotPresent("DBI"); + return Error::success(); + } + ExitOnError Err("Unexpected error processing modules: "); StatCollection SymStats; @@ -625,9 +646,9 @@ } }); - P.printLine(" Summary |"); - AutoIndent Indent(P, 4); if (SymStats.Totals.Count > 0) { + P.printLine(" Summary |"); + AutoIndent Indent(P, 4); printModuleDetailStats(P, "Symbols", SymStats); printModuleDetailStats(P, "Chunks", ChunkStats); } @@ -680,6 +701,11 @@ Error DumpOutputStyle::dumpUdtStats() { printHeader(P, "S_UDT Record Stats"); + if (File.isPdb() && !getPdb().hasPDBGlobalsStream()) { + printStreamNotPresent("Globals"); + return Error::success(); + } + StatCollection UdtStats; StatCollection UdtTargetStats; AutoIndent Indent(P, 4); @@ -726,11 +752,6 @@ P.NewLine(); if (File.isPdb()) { - if (!getPdb().hasPDBGlobalsStream()) { - P.printLine("- Error: globals stream not present"); - return Error::success(); - } - auto &SymbolRecords = cantFail(getPdb().getPDBSymbolStream()); auto ExpGlobals = getPdb().getPDBGlobalsStream(); if (!ExpGlobals) @@ -839,6 +860,11 @@ Error DumpOutputStyle::dumpLines() { printHeader(P, "Lines"); + if (File.isPdb() && !getPdb().hasPDBDbiStream()) { + printStreamNotPresent("DBI"); + return Error::success(); + } + uint32_t LastModi = UINT32_MAX; uint32_t LastNameIndex = UINT32_MAX; iterateModuleSubsections( @@ -875,6 +901,11 @@ Error DumpOutputStyle::dumpInlineeLines() { printHeader(P, "Inlinee Lines"); + if (File.isPdb() && !getPdb().hasPDBDbiStream()) { + printStreamNotPresent("DBI"); + return Error::success(); + } + iterateModuleSubsections( File, PrintScope{P, 2}, [this](uint32_t Modi, const SymbolGroup &Strings, @@ -893,6 +924,12 @@ Error DumpOutputStyle::dumpXmi() { printHeader(P, "Cross Module Imports"); + + if (File.isPdb() && !getPdb().hasPDBDbiStream()) { + printStreamNotPresent("DBI"); + return Error::success(); + } + iterateModuleSubsections( File, PrintScope{P, 2}, [this](uint32_t Modi, const SymbolGroup &Strings, @@ -929,6 +966,11 @@ Error DumpOutputStyle::dumpXme() { printHeader(P, "Cross Module Exports"); + if (File.isPdb() && !getPdb().hasPDBDbiStream()) { + printStreamNotPresent("DBI"); + return Error::success(); + } + iterateModuleSubsections( File, PrintScope{P, 2}, [this](uint32_t Modi, const SymbolGroup &Strings, @@ -1037,12 +1079,13 @@ Error DumpOutputStyle::dumpNamedStreams() { printHeader(P, "Named Streams"); - AutoIndent Indent(P, 2); if (File.isObj()) { - P.formatLine("Dumping Named Streams is only supported for PDB files."); + printStreamNotValidForObj(); return Error::success(); } + + AutoIndent Indent(P); ExitOnError Err("Invalid PDB File: "); auto &IS = Err(File.pdb().getPDBInfoStream()); @@ -1204,7 +1247,6 @@ printHeader(P, "Types (IPI Stream)"); } - AutoIndent Indent(P); assert(!File.isObj()); bool Present = false; @@ -1229,10 +1271,11 @@ } if (!Present) { - P.formatLine("Stream not present"); + printStreamNotPresent(StreamIdx == StreamTPI ? "TPI" : "IPI"); return Error::success(); } + AutoIndent Indent(P); ExitOnError Err("Unexpected error processing types: "); auto &Stream = Err((StreamIdx == StreamTPI) ? getPdb().getPDBTpiStream() @@ -1321,12 +1364,12 @@ Error DumpOutputStyle::dumpModuleSymsForPdb() { printHeader(P, "Symbols"); - AutoIndent Indent(P); - if (!getPdb().hasPDBDbiStream()) { - P.formatLine("DBI Stream not present"); + if (File.isPdb() && !getPdb().hasPDBDbiStream()) { + printStreamNotPresent("DBI"); return Error::success(); } + AutoIndent Indent(P); ExitOnError Err("Unexpected error processing symbols: "); auto &Ids = File.ids(); @@ -1364,18 +1407,19 @@ Error DumpOutputStyle::dumpGSIRecords() { printHeader(P, "GSI Records"); - AutoIndent Indent(P); if (File.isObj()) { - P.formatLine("Dumping Globals is not supported for object files"); + printStreamNotValidForObj(); return Error::success(); } if (!getPdb().hasPDBSymbolStream()) { - P.formatLine("GSI Common Symbol Stream not present"); + printStreamNotPresent("GSI Common Symbol"); return Error::success(); } + AutoIndent Indent(P); + auto &Records = cantFail(getPdb().getPDBSymbolStream()); auto &Types = File.types(); auto &Ids = File.ids(); @@ -1397,17 +1441,18 @@ Error DumpOutputStyle::dumpGlobals() { printHeader(P, "Global Symbols"); - AutoIndent Indent(P); if (File.isObj()) { - P.formatLine("Dumping Globals is not supported for object files"); + printStreamNotValidForObj(); return Error::success(); } if (!getPdb().hasPDBGlobalsStream()) { - P.formatLine("Globals stream not present"); + printStreamNotPresent("Globals"); return Error::success(); } + + AutoIndent Indent(P); ExitOnError Err("Error dumping globals stream: "); auto &Globals = Err(getPdb().getPDBGlobalsStream()); @@ -1418,17 +1463,18 @@ Error DumpOutputStyle::dumpPublics() { printHeader(P, "Public Symbols"); - AutoIndent Indent(P); if (File.isObj()) { - P.formatLine("Dumping Globals is not supported for object files"); + printStreamNotValidForObj(); return Error::success(); } if (!getPdb().hasPDBPublicsStream()) { - P.formatLine("Publics stream not present"); + printStreamNotPresent("Publics"); return Error::success(); } + + AutoIndent Indent(P); ExitOnError Err("Error dumping publics stream: "); auto &Publics = Err(getPdb().getPDBPublicsStream()); @@ -1560,12 +1606,17 @@ void DumpOutputStyle::dumpSectionHeaders(StringRef Label, DbgHeaderType Type) { printHeader(P, Label); - AutoIndent Indent(P); if (File.isObj()) { - P.formatLine("Dumping Section Headers is not supported for object files"); + printStreamNotValidForObj(); + return; + } + + if (!getPdb().hasPDBDbiStream()) { + printStreamNotPresent("DBI"); return; } + AutoIndent Indent(P); ExitOnError Err("Error dumping section headers: "); std::unique_ptr Stream; ArrayRef Headers; @@ -1606,20 +1657,19 @@ Error DumpOutputStyle::dumpSectionContribs() { printHeader(P, "Section Contributions"); - AutoIndent Indent(P); if (File.isObj()) { - P.formatLine( - "Dumping section contributions is not supported for object files"); + printStreamNotValidForObj(); return Error::success(); } - ExitOnError Err("Error dumping section contributions: "); if (!getPdb().hasPDBDbiStream()) { - P.formatLine( - "Section contribs require a DBI Stream, which could not be loaded"); + printStreamNotPresent("DBI"); return Error::success(); } + AutoIndent Indent(P); + ExitOnError Err("Error dumping section contributions: "); + auto &Dbi = Err(getPdb().getPDBDbiStream()); class Visitor : public ISectionContribVisitor { @@ -1651,21 +1701,20 @@ Error DumpOutputStyle::dumpSectionMap() { printHeader(P, "Section Map"); - AutoIndent Indent(P); if (File.isObj()) { - P.formatLine("Dumping section map is not supported for object files"); + printStreamNotValidForObj(); return Error::success(); } - ExitOnError Err("Error dumping section map: "); - if (!getPdb().hasPDBDbiStream()) { - P.formatLine("Dumping the section map requires a DBI Stream, which could " - "not be loaded"); + printStreamNotPresent("DBI"); return Error::success(); } + AutoIndent Indent(P); + ExitOnError Err("Error dumping section map: "); + auto &Dbi = Err(getPdb().getPDBDbiStream()); uint32_t I = 0; Index: llvm/trunk/tools/llvm-pdbutil/InputFile.cpp =================================================================== --- llvm/trunk/tools/llvm-pdbutil/InputFile.cpp +++ llvm/trunk/tools/llvm-pdbutil/InputFile.cpp @@ -41,6 +41,10 @@ auto &Dbi = Err(File.getPDBDbiStream()); const auto &Modules = Dbi.modules(); + if (Index >= Modules.getModuleCount()) + return make_error(raw_error_code::index_out_of_bounds, + "Invalid module index"); + auto Modi = Modules.getModuleDescriptor(Index); ModuleName = Modi.getModuleName(); Index: llvm/trunk/tools/llvm-pdbutil/YAMLOutputStyle.cpp =================================================================== --- llvm/trunk/tools/llvm-pdbutil/YAMLOutputStyle.cpp +++ llvm/trunk/tools/llvm-pdbutil/YAMLOutputStyle.cpp @@ -191,6 +191,9 @@ if (!opts::pdb2yaml::DbiStream) return Error::success(); + if (!File.hasPDBDbiStream()) + return Error::success(); + auto DbiS = File.getPDBDbiStream(); if (!DbiS) return DbiS.takeError();