Index: lib/DebugInfo/PDB/Native/PDBFile.cpp =================================================================== --- lib/DebugInfo/PDB/Native/PDBFile.cpp +++ 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(); @@ -467,6 +469,9 @@ uint32_t StreamIndex) const { if (StreamIndex >= getNumStreams()) return make_error(raw_error_code::no_stream); + assert(StreamIndex < Layout.StreamSizes.size() && "Invalid stream index"); + if (Layout.StreamSizes[StreamIndex] == 0) + return make_error(raw_error_code::no_stream); return MappedBlockStream::createIndexedStream(Layout, MsfData, StreamIndex, Allocator); } Index: test/tools/llvm-pdbdump/Inputs/TypeServerTest.cpp =================================================================== --- test/tools/llvm-pdbdump/Inputs/TypeServerTest.cpp +++ test/tools/llvm-pdbdump/Inputs/TypeServerTest.cpp @@ -0,0 +1,15 @@ +// Compile with "cl /c /Zi TypeServerTest.cpp /FdTypeServerTest.pdb" + +#include +#include + +void SimpleFunction(void) +{ + printf("Hello\n"); +} + +int main(void) +{ + SimpleFunction(); + return 0; +} Index: test/tools/llvm-pdbdump/type-server-no-dbi.test =================================================================== --- test/tools/llvm-pdbdump/type-server-no-dbi.test +++ test/tools/llvm-pdbdump/type-server-no-dbi.test @@ -0,0 +1,46 @@ +RUN: llvm-pdbutil dump -all %p/Inputs/TypeServerTest.pdb | FileCheck %s +RUN: llvm-pdbutil pdb2yaml -all %p/Inputs/TypeServerTest.pdb > %t +RUN: FileCheck --input-file=%t %s --check-prefix=YAML +RUN: llvm-pdbutil yaml2pdb -pdb=%t2.pdb %t + +CHECK-NOT: Native PDB Error: The specified stream could not be loaded. + +CHECK: Module Stats +CHECK-NEXT: ============================================================ +CHECK-NEXT: DBI stream not present + +CHECK: S_UDT Record Stats +CHECK-NEXT: ============================================================ +CHECK-NEXT: Globals stream not present + +CHECK: Modules +CHECK-NEXT: ============================================================ +CHECK-NEXT: DBI stream not present + +CHECK: Files +CHECK-NEXT: ============================================================ +CHECK-NEXT: DBI stream not present + +CHECK: Lines +CHECK-NEXT: ============================================================ +CHECK-NEXT: DBI stream not present + +CHECK: Inlinee Lines +CHECK-NEXT: ============================================================ +CHECK-NEXT: DBI stream not present + +CHECK: Cross Module Imports +CHECK-NEXT: ============================================================ +CHECK-NEXT: DBI stream not present + +CHECK: Cross Module Exports +CHECK-NEXT: ============================================================ +CHECK-NEXT: DBI stream not present + + +YAML-NOT: Native PDB Error: The specified stream could not be loaded. + +YAML: TpiStream: +YAML-NEXT: Version: VC80 +YAML-NEXT: Records: +YAML-NEXT: - Kind: LF_STRUCTURE Index: tools/llvm-pdbutil/DumpOutputStyle.h =================================================================== --- tools/llvm-pdbutil/DumpOutputStyle.h +++ tools/llvm-pdbutil/DumpOutputStyle.h @@ -70,6 +70,10 @@ PDBFile &getPdb(); object::COFFObjectFile &getObj(); + bool isPdb(); + bool isDBIStreamPresent(); + bool isGlobalsStreamPresent(); + Error dumpFileSummary(); Error dumpStreamSummary(); Error dumpSymbolStats(); Index: tools/llvm-pdbutil/DumpOutputStyle.cpp =================================================================== --- tools/llvm-pdbutil/DumpOutputStyle.cpp +++ tools/llvm-pdbutil/DumpOutputStyle.cpp @@ -65,6 +65,30 @@ PDBFile &DumpOutputStyle::getPdb() { return File.pdb(); } object::COFFObjectFile &DumpOutputStyle::getObj() { return File.obj(); } +bool DumpOutputStyle::isPdb() { + if (!File.isObj()) + return true; + AutoIndent Indent(P, 4); + P.formatLine("Dumping this stream is not valid for object files"); + return false; +} + +bool DumpOutputStyle::isDBIStreamPresent() { + if (!File.isPdb() || getPdb().hasPDBDbiStream()) + return true; + AutoIndent Indent(P, 4); + P.formatLine("DBI stream not present"); + return false; +} + +bool DumpOutputStyle::isGlobalsStreamPresent() { + if (!File.isPdb() || getPdb().hasPDBGlobalsStream()) + return true; + AutoIndent Indent(P, 4); + P.formatLine("Globals stream not present"); + return false; +} + Error DumpOutputStyle::dump() { if (opts::dump::DumpSummary) { if (auto EC = dumpFileSummary()) @@ -199,13 +223,11 @@ Error DumpOutputStyle::dumpFileSummary() { printHeader(P, "Summary"); - ExitOnError Err("Invalid PDB Format: "); + if (!isPdb()) + return Error::success(); AutoIndent Indent(P); - if (File.isObj()) { - P.formatLine("Dumping File summary is not valid for object files"); - return Error::success(); - } + ExitOnError Err("Invalid PDB Format: "); P.formatLine("Block Size: {0}", getPdb().getBlockSize()); P.formatLine("Number of blocks: {0}", getPdb().getBlockCount()); @@ -326,11 +348,10 @@ Error DumpOutputStyle::dumpStreamSummary() { printHeader(P, "Streams"); - AutoIndent Indent(P); - if (File.isObj()) { - P.formatLine("Dumping streams is not valid for object files"); + if (!isPdb()) return Error::success(); - } + + AutoIndent Indent(P); if (StreamPurposes.empty()) discoverStreamPurposes(getPdb(), StreamPurposes); @@ -527,18 +548,14 @@ Error DumpOutputStyle::dumpModules() { printHeader(P, "Modules"); - AutoIndent Indent(P); - if (File.isObj()) { - P.formatLine("Dumping modules is not supported for object files"); + if (!isPdb()) return Error::success(); - } - if (!getPdb().hasPDBDbiStream()) { - P.formatLine("DBI Stream not present"); + if (!isDBIStreamPresent()) return Error::success(); - } + AutoIndent Indent(P); ExitOnError Err("Unexpected error processing modules: "); auto &Stream = Err(getPdb().getPDBDbiStream()); @@ -569,10 +586,11 @@ Error DumpOutputStyle::dumpModuleFiles() { printHeader(P, "Files"); - if (File.isObj()) { - P.formatLine("Dumping files is not valid for object files"); + if (!isPdb()) + return Error::success(); + + if (!isDBIStreamPresent()) return Error::success(); - } ExitOnError Err("Unexpected error processing modules: "); @@ -591,6 +609,9 @@ Error DumpOutputStyle::dumpSymbolStats() { printHeader(P, "Module Stats"); + if (!isDBIStreamPresent()) + return Error::success(); + ExitOnError Err("Unexpected error processing modules: "); StatCollection SymStats; @@ -680,6 +701,9 @@ Error DumpOutputStyle::dumpUdtStats() { printHeader(P, "S_UDT Record Stats"); + if (!isGlobalsStreamPresent()) + return Error::success(); + StatCollection UdtStats; StatCollection UdtTargetStats; AutoIndent Indent(P, 4); @@ -726,11 +750,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 +858,9 @@ Error DumpOutputStyle::dumpLines() { printHeader(P, "Lines"); + if (!isDBIStreamPresent()) + return Error::success(); + uint32_t LastModi = UINT32_MAX; uint32_t LastNameIndex = UINT32_MAX; iterateModuleSubsections( @@ -875,6 +897,9 @@ Error DumpOutputStyle::dumpInlineeLines() { printHeader(P, "Inlinee Lines"); + if (!isDBIStreamPresent()) + return Error::success(); + iterateModuleSubsections( File, PrintScope{P, 2}, [this](uint32_t Modi, const SymbolGroup &Strings, @@ -893,6 +918,10 @@ Error DumpOutputStyle::dumpXmi() { printHeader(P, "Cross Module Imports"); + + if (!isDBIStreamPresent()) + return Error::success(); + iterateModuleSubsections( File, PrintScope{P, 2}, [this](uint32_t Modi, const SymbolGroup &Strings, @@ -929,6 +958,9 @@ Error DumpOutputStyle::dumpXme() { printHeader(P, "Cross Module Exports"); + if (!isDBIStreamPresent()) + return Error::success(); + iterateModuleSubsections( File, PrintScope{P, 2}, [this](uint32_t Modi, const SymbolGroup &Strings, @@ -1037,12 +1069,11 @@ 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."); + if (!isPdb()) return Error::success(); - } + + AutoIndent Indent(P); ExitOnError Err("Invalid PDB File: "); auto &IS = Err(File.pdb().getPDBInfoStream()); @@ -1204,7 +1235,6 @@ printHeader(P, "Types (IPI Stream)"); } - AutoIndent Indent(P); assert(!File.isObj()); bool Present = false; @@ -1229,10 +1259,12 @@ } if (!Present) { - P.formatLine("Stream not present"); + AutoIndent Indent(P, 4); + P.formatLine("{0} stream not present", 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 +1353,10 @@ Error DumpOutputStyle::dumpModuleSymsForPdb() { printHeader(P, "Symbols"); - AutoIndent Indent(P); - if (!getPdb().hasPDBDbiStream()) { - P.formatLine("DBI Stream not present"); + if (!isDBIStreamPresent()) return Error::success(); - } + AutoIndent Indent(P); ExitOnError Err("Unexpected error processing symbols: "); auto &Ids = File.ids(); @@ -1364,18 +1394,18 @@ Error DumpOutputStyle::dumpGSIRecords() { printHeader(P, "GSI Records"); - AutoIndent Indent(P); - if (File.isObj()) { - P.formatLine("Dumping Globals is not supported for object files"); + if (!isPdb()) return Error::success(); - } if (!getPdb().hasPDBSymbolStream()) { + AutoIndent Indent(P, 4); P.formatLine("GSI Common Symbol Stream not present"); return Error::success(); } + AutoIndent Indent(P); + auto &Records = cantFail(getPdb().getPDBSymbolStream()); auto &Types = File.types(); auto &Ids = File.ids(); @@ -1397,17 +1427,14 @@ Error DumpOutputStyle::dumpGlobals() { printHeader(P, "Global Symbols"); - AutoIndent Indent(P); - if (File.isObj()) { - P.formatLine("Dumping Globals is not supported for object files"); + if (!isPdb()) return Error::success(); - } - if (!getPdb().hasPDBGlobalsStream()) { - P.formatLine("Globals stream not present"); + if (!isGlobalsStreamPresent()) return Error::success(); - } + + AutoIndent Indent(P); ExitOnError Err("Error dumping globals stream: "); auto &Globals = Err(getPdb().getPDBGlobalsStream()); @@ -1418,17 +1445,17 @@ Error DumpOutputStyle::dumpPublics() { printHeader(P, "Public Symbols"); - AutoIndent Indent(P); - if (File.isObj()) { - P.formatLine("Dumping Globals is not supported for object files"); + if (!isPdb()) return Error::success(); - } if (!getPdb().hasPDBPublicsStream()) { + AutoIndent Indent(P, 4); P.formatLine("Publics stream not present"); return Error::success(); } + + AutoIndent Indent(P); ExitOnError Err("Error dumping publics stream: "); auto &Publics = Err(getPdb().getPDBPublicsStream()); @@ -1560,12 +1587,13 @@ 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"); + if (!isPdb()) + return; + + if (!isDBIStreamPresent()) return; - } + AutoIndent Indent(P); ExitOnError Err("Error dumping section headers: "); std::unique_ptr Stream; ArrayRef Headers; @@ -1606,19 +1634,14 @@ Error DumpOutputStyle::dumpSectionContribs() { printHeader(P, "Section Contributions"); - AutoIndent Indent(P); - if (File.isObj()) { - P.formatLine( - "Dumping section contributions is not supported for object files"); + if (!isPdb()) 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"); + if (!isDBIStreamPresent()) return Error::success(); - } + + AutoIndent Indent(P); + ExitOnError Err("Error dumping section contributions: "); auto &Dbi = Err(getPdb().getPDBDbiStream()); @@ -1651,20 +1674,15 @@ Error DumpOutputStyle::dumpSectionMap() { printHeader(P, "Section Map"); - AutoIndent Indent(P); - if (File.isObj()) { - P.formatLine("Dumping section map is not supported for object files"); + if (!isPdb()) 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"); + if (!isDBIStreamPresent()) return Error::success(); - } + + AutoIndent Indent(P); + ExitOnError Err("Error dumping section map: "); auto &Dbi = Err(getPdb().getPDBDbiStream()); Index: tools/llvm-pdbutil/YAMLOutputStyle.cpp =================================================================== --- tools/llvm-pdbutil/YAMLOutputStyle.cpp +++ 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();