forked from OSchip/llvm-project
[llvm-pdbutil] Support PDBs without a DBI stream
Differential Revision: https://reviews.llvm.org/D50258 llvm-svn: 339045
This commit is contained in:
parent
7c4f4914e3
commit
741cc3531a
|
@ -401,7 +401,9 @@ uint32_t PDBFile::getPointerSize() {
|
|||
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();
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
// Compile with "cl /c /Zi TypeServerTest.cpp /FdTypeServerTest.pdb"
|
||||
|
||||
int main(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
Binary file not shown.
|
@ -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
|
|
@ -65,6 +65,16 @@ DumpOutputStyle::DumpOutputStyle(InputFile &File)
|
|||
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 @@ static void printHeader(LinePrinter &P, const Twine &S) {
|
|||
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 @@ static bool shouldDumpSymbolGroup(uint32_t Idx, const SymbolGroup &Group) {
|
|||
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 @@ static void dumpSectionContrib(LinePrinter &P, const SectionContrib2 &SC,
|
|||
|
||||
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 @@ Error DumpOutputStyle::dumpModuleFiles() {
|
|||
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::dumpModuleFiles() {
|
|||
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 @@ Error DumpOutputStyle::dumpSymbolStats() {
|
|||
}
|
||||
});
|
||||
|
||||
P.printLine(" Summary |");
|
||||
AutoIndent Indent(P, 4);
|
||||
if (SymStats.Totals.Count > 0) {
|
||||
P.printLine(" Summary |");
|
||||
AutoIndent Indent(P, 4);
|
||||
printModuleDetailStats<SymbolKind>(P, "Symbols", SymStats);
|
||||
printModuleDetailStats<DebugSubsectionKind>(P, "Chunks", ChunkStats);
|
||||
}
|
||||
|
@ -680,6 +701,11 @@ static uint32_t getLongestTypeLeafName(const StatCollection &Stats) {
|
|||
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 @@ Error DumpOutputStyle::dumpUdtStats() {
|
|||
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 @@ static void typesetLinesAndColumns(LinePrinter &P, uint32_t Start,
|
|||
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<DebugLinesSubsectionRef>(
|
||||
|
@ -875,6 +901,11 @@ Error DumpOutputStyle::dumpLines() {
|
|||
Error DumpOutputStyle::dumpInlineeLines() {
|
||||
printHeader(P, "Inlinee Lines");
|
||||
|
||||
if (File.isPdb() && !getPdb().hasPDBDbiStream()) {
|
||||
printStreamNotPresent("DBI");
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
iterateModuleSubsections<DebugInlineeLinesSubsectionRef>(
|
||||
File, PrintScope{P, 2},
|
||||
[this](uint32_t Modi, const SymbolGroup &Strings,
|
||||
|
@ -893,6 +924,12 @@ Error DumpOutputStyle::dumpInlineeLines() {
|
|||
|
||||
Error DumpOutputStyle::dumpXmi() {
|
||||
printHeader(P, "Cross Module Imports");
|
||||
|
||||
if (File.isPdb() && !getPdb().hasPDBDbiStream()) {
|
||||
printStreamNotPresent("DBI");
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
iterateModuleSubsections<DebugCrossModuleImportsSubsectionRef>(
|
||||
File, PrintScope{P, 2},
|
||||
[this](uint32_t Modi, const SymbolGroup &Strings,
|
||||
|
@ -929,6 +966,11 @@ Error DumpOutputStyle::dumpXmi() {
|
|||
Error DumpOutputStyle::dumpXme() {
|
||||
printHeader(P, "Cross Module Exports");
|
||||
|
||||
if (File.isPdb() && !getPdb().hasPDBDbiStream()) {
|
||||
printStreamNotPresent("DBI");
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
iterateModuleSubsections<DebugCrossModuleExportsSubsectionRef>(
|
||||
File, PrintScope{P, 2},
|
||||
[this](uint32_t Modi, const SymbolGroup &Strings,
|
||||
|
@ -1037,12 +1079,13 @@ Error DumpOutputStyle::dumpStringTableFromObj() {
|
|||
|
||||
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 @@ Error DumpOutputStyle::dumpTpiStream(uint32_t StreamIdx) {
|
|||
printHeader(P, "Types (IPI Stream)");
|
||||
}
|
||||
|
||||
AutoIndent Indent(P);
|
||||
assert(!File.isObj());
|
||||
|
||||
bool Present = false;
|
||||
|
@ -1229,10 +1271,11 @@ Error DumpOutputStyle::dumpTpiStream(uint32_t StreamIdx) {
|
|||
}
|
||||
|
||||
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::dumpModuleSymsForObj() {
|
|||
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::dumpModuleSymsForPdb() {
|
|||
|
||||
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::dumpGSIRecords() {
|
|||
|
||||
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::dumpGlobals() {
|
|||
|
||||
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 @@ Error DumpOutputStyle::dumpSectionHeaders() {
|
|||
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<MappedBlockStream> Stream;
|
||||
ArrayRef<object::coff_section> Headers;
|
||||
|
@ -1606,20 +1657,19 @@ void DumpOutputStyle::dumpSectionHeaders(StringRef Label, DbgHeaderType Type) {
|
|||
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::dumpSectionContribs() {
|
|||
|
||||
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;
|
||||
|
|
|
@ -70,6 +70,9 @@ private:
|
|||
PDBFile &getPdb();
|
||||
object::COFFObjectFile &getObj();
|
||||
|
||||
void printStreamNotValidForObj();
|
||||
void printStreamNotPresent(StringRef StreamName);
|
||||
|
||||
Error dumpFileSummary();
|
||||
Error dumpStreamSummary();
|
||||
Error dumpSymbolStats();
|
||||
|
|
|
@ -41,6 +41,10 @@ getModuleDebugStream(PDBFile &File, StringRef &ModuleName, uint32_t Index) {
|
|||
|
||||
auto &Dbi = Err(File.getPDBDbiStream());
|
||||
const auto &Modules = Dbi.modules();
|
||||
if (Index >= Modules.getModuleCount())
|
||||
return make_error<RawError>(raw_error_code::index_out_of_bounds,
|
||||
"Invalid module index");
|
||||
|
||||
auto Modi = Modules.getModuleDescriptor(Index);
|
||||
|
||||
ModuleName = Modi.getModuleName();
|
||||
|
|
|
@ -191,6 +191,9 @@ Error YAMLOutputStyle::dumpDbiStream() {
|
|||
if (!opts::pdb2yaml::DbiStream)
|
||||
return Error::success();
|
||||
|
||||
if (!File.hasPDBDbiStream())
|
||||
return Error::success();
|
||||
|
||||
auto DbiS = File.getPDBDbiStream();
|
||||
if (!DbiS)
|
||||
return DbiS.takeError();
|
||||
|
|
Loading…
Reference in New Issue