diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2022-07-03 14:10:23 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2022-07-03 14:10:23 +0000 |
| commit | 145449b1e420787bb99721a429341fa6be3adfb6 (patch) | |
| tree | 1d56ae694a6de602e348dd80165cf881a36600ed /llvm/tools/llvm-pdbutil | |
| parent | ecbca9f5fb7d7613d2b94982c4825eb0d33d6842 (diff) | |
Diffstat (limited to 'llvm/tools/llvm-pdbutil')
30 files changed, 317 insertions, 1883 deletions
diff --git a/llvm/tools/llvm-pdbutil/BytesOutputStyle.cpp b/llvm/tools/llvm-pdbutil/BytesOutputStyle.cpp index ffc907e09f11..4c851e14a12d 100644 --- a/llvm/tools/llvm-pdbutil/BytesOutputStyle.cpp +++ b/llvm/tools/llvm-pdbutil/BytesOutputStyle.cpp @@ -8,7 +8,6 @@ #include "BytesOutputStyle.h" -#include "FormatUtil.h" #include "StreamUtil.h" #include "llvm-pdbutil.h" @@ -17,6 +16,7 @@ #include "llvm/DebugInfo/MSF/MSFCommon.h" #include "llvm/DebugInfo/MSF/MappedBlockStream.h" #include "llvm/DebugInfo/PDB/Native/DbiStream.h" +#include "llvm/DebugInfo/PDB/Native/FormatUtil.h" #include "llvm/DebugInfo/PDB/Native/InfoStream.h" #include "llvm/DebugInfo/PDB/Native/ModuleDebugStream.h" #include "llvm/DebugInfo/PDB/Native/PDBFile.h" @@ -83,13 +83,13 @@ static void printHeader(LinePrinter &P, const Twine &S) { } BytesOutputStyle::BytesOutputStyle(PDBFile &File) - : File(File), P(2, false, outs()) {} + : File(File), P(2, false, outs(), opts::Filters) {} Error BytesOutputStyle::dump() { - if (opts::bytes::DumpBlockRange.hasValue()) { + if (opts::bytes::DumpBlockRange) { auto &R = *opts::bytes::DumpBlockRange; - uint32_t Max = R.Max.getValueOr(R.Min); + uint32_t Max = R.Max.value_or(R.Min); if (Max < R.Min) return make_error<StringError>( @@ -104,9 +104,9 @@ Error BytesOutputStyle::dump() { P.NewLine(); } - if (opts::bytes::DumpByteRange.hasValue()) { + if (opts::bytes::DumpByteRange) { auto &R = *opts::bytes::DumpByteRange; - uint32_t Max = R.Max.getValueOr(File.getFileSize()); + uint32_t Max = R.Max.value_or(File.getFileSize()); if (Max < R.Min) return make_error<StringError>("Invalid byte range specified. Max < Min", diff --git a/llvm/tools/llvm-pdbutil/BytesOutputStyle.h b/llvm/tools/llvm-pdbutil/BytesOutputStyle.h index d3aceb47679e..cd28032fe7cd 100644 --- a/llvm/tools/llvm-pdbutil/BytesOutputStyle.h +++ b/llvm/tools/llvm-pdbutil/BytesOutputStyle.h @@ -9,10 +9,10 @@ #ifndef LLVM_TOOLS_LLVMPDBDUMP_BYTESOUTPUTSTYLE_H #define LLVM_TOOLS_LLVMPDBDUMP_BYTESOUTPUTSTYLE_H -#include "LinePrinter.h" #include "OutputStyle.h" #include "StreamUtil.h" +#include "llvm/DebugInfo/PDB/Native/LinePrinter.h" #include "llvm/Support/Error.h" namespace llvm { diff --git a/llvm/tools/llvm-pdbutil/DumpOutputStyle.cpp b/llvm/tools/llvm-pdbutil/DumpOutputStyle.cpp index ef299ea9d482..a173eb1faa62 100644 --- a/llvm/tools/llvm-pdbutil/DumpOutputStyle.cpp +++ b/llvm/tools/llvm-pdbutil/DumpOutputStyle.cpp @@ -8,8 +8,6 @@ #include "DumpOutputStyle.h" -#include "FormatUtil.h" -#include "InputFile.h" #include "MinimalSymbolDumper.h" #include "MinimalTypeDumper.h" #include "StreamUtil.h" @@ -38,10 +36,13 @@ #include "llvm/DebugInfo/MSF/MappedBlockStream.h" #include "llvm/DebugInfo/PDB/Native/DbiModuleDescriptor.h" #include "llvm/DebugInfo/PDB/Native/DbiStream.h" +#include "llvm/DebugInfo/PDB/Native/FormatUtil.h" #include "llvm/DebugInfo/PDB/Native/GlobalsStream.h" #include "llvm/DebugInfo/PDB/Native/ISectionContribVisitor.h" #include "llvm/DebugInfo/PDB/Native/InfoStream.h" +#include "llvm/DebugInfo/PDB/Native/InputFile.h" #include "llvm/DebugInfo/PDB/Native/ModuleDebugStream.h" +#include "llvm/DebugInfo/PDB/Native/NativeSession.h" #include "llvm/DebugInfo/PDB/Native/PDBFile.h" #include "llvm/DebugInfo/PDB/Native/PublicsStream.h" #include "llvm/DebugInfo/PDB/Native/RawError.h" @@ -61,7 +62,7 @@ using namespace llvm::msf; using namespace llvm::pdb; DumpOutputStyle::DumpOutputStyle(InputFile &File) - : File(File), P(2, false, outs()) { + : File(File), P(2, false, outs(), opts::Filters) { if (opts::dump::DumpTypeRefStats) RefTracker.reset(new TypeReferenceTracker(File)); } @@ -99,8 +100,8 @@ Error DumpOutputStyle::dump() { } if (opts::dump::DumpSymbolStats) { - if (auto EC = dumpSymbolStats()) - return EC; + ExitOnError Err("Unexpected error processing module stats: "); + Err(dumpSymbolStats()); P.NewLine(); } @@ -129,33 +130,33 @@ Error DumpOutputStyle::dump() { } if (opts::dump::DumpModules) { - if (auto EC = dumpModules()) - return EC; + ExitOnError Err("Unexpected error processing modules: "); + Err(dumpModules()); } if (opts::dump::DumpModuleFiles) { - if (auto EC = dumpModuleFiles()) - return EC; + ExitOnError Err("Unexpected error processing files: "); + Err(dumpModuleFiles()); } if (opts::dump::DumpLines) { - if (auto EC = dumpLines()) - return EC; + ExitOnError Err("Unexpected error processing lines: "); + Err(dumpLines()); } if (opts::dump::DumpInlineeLines) { - if (auto EC = dumpInlineeLines()) - return EC; + ExitOnError Err("Unexpected error processing inlinee lines: "); + Err(dumpInlineeLines()); } if (opts::dump::DumpXmi) { - if (auto EC = dumpXmi()) - return EC; + ExitOnError Err("Unexpected error processing cross module imports: "); + Err(dumpXmi()); } if (opts::dump::DumpXme) { - if (auto EC = dumpXme()) - return EC; + ExitOnError Err("Unexpected error processing cross module exports: "); + Err(dumpXme()); } if (opts::dump::DumpFpo) { @@ -198,9 +199,8 @@ Error DumpOutputStyle::dump() { } if (opts::dump::DumpSymbols) { - auto EC = File.isPdb() ? dumpModuleSymsForPdb() : dumpModuleSymsForObj(); - if (EC) - return EC; + ExitOnError Err("Unexpected error processing symbols: "); + Err(File.isPdb() ? dumpModuleSymsForPdb() : dumpModuleSymsForObj()); } if (opts::dump::DumpTypeRefStats) { @@ -260,7 +260,7 @@ Error DumpOutputStyle::dumpFileSummary() { P.formatLine("Has Globals: {0}", getPdb().hasPDBGlobalsStream()); P.formatLine("Has Publics: {0}", getPdb().hasPDBPublicsStream()); if (getPdb().hasPDBDbiStream()) { - auto &DBI = Err(getPdb().getPDBDbiStream()); + DbiStream &DBI = Err(getPdb().getPDBDbiStream()); P.formatLine("Is incrementally linked: {0}", DBI.isIncrementallyLinked()); P.formatLine("Has conflicting types: {0}", DBI.hasCTypes()); P.formatLine("Is stripped: {0}", DBI.isStripped()); @@ -343,36 +343,6 @@ static void printModuleDetailStats(LinePrinter &P, StringRef Label, } } -static bool isMyCode(const SymbolGroup &Group) { - if (Group.getFile().isObj()) - return true; - - StringRef Name = Group.name(); - if (Name.startswith("Import:")) - return false; - if (Name.endswith_insensitive(".dll")) - return false; - if (Name.equals_insensitive("* linker *")) - return false; - if (Name.startswith_insensitive("f:\\binaries\\Intermediate\\vctools")) - return false; - if (Name.startswith_insensitive("f:\\dd\\vctools\\crt")) - return false; - return true; -} - -static bool shouldDumpSymbolGroup(uint32_t Idx, const SymbolGroup &Group) { - if (opts::dump::JustMyCode && !isMyCode(Group)) - return false; - - // If the arg was not specified on the command line, always dump all modules. - if (opts::dump::DumpModi.getNumOccurrences() == 0) - return true; - - // Otherwise, only dump if this is the same module specified. - return (opts::dump::DumpModi == Idx); -} - Error DumpOutputStyle::dumpStreamSummary() { printHeader(P, "Streams"); @@ -389,7 +359,7 @@ Error DumpOutputStyle::dumpStreamSummary() { uint32_t StreamCount = getPdb().getNumStreams(); uint32_t MaxStreamSize = getPdb().getMaxStreamSize(); - for (uint16_t StreamIdx = 0; StreamIdx < StreamCount; ++StreamIdx) { + for (uint32_t StreamIdx = 0; StreamIdx < StreamCount; ++StreamIdx) { P.formatLine( "Stream {0} ({1} bytes): [{2}]", fmt_align(StreamIdx, AlignStyle::Right, NumDigits(StreamCount)), @@ -409,93 +379,6 @@ Error DumpOutputStyle::dumpStreamSummary() { return Error::success(); } -static Expected<ModuleDebugStreamRef> getModuleDebugStream(PDBFile &File, - uint32_t Index) { - ExitOnError Err("Unexpected error: "); - - auto &Dbi = Err(File.getPDBDbiStream()); - const auto &Modules = Dbi.modules(); - auto Modi = Modules.getModuleDescriptor(Index); - - uint16_t ModiStream = Modi.getModuleStreamIndex(); - if (ModiStream == kInvalidStreamIndex) - return make_error<RawError>(raw_error_code::no_stream, - "Module stream not present"); - - auto ModStreamData = File.createIndexedStream(ModiStream); - - ModuleDebugStreamRef ModS(Modi, std::move(ModStreamData)); - if (auto EC = ModS.reload()) - return make_error<RawError>(raw_error_code::corrupt_file, - "Invalid module stream"); - - return std::move(ModS); -} - -template <typename CallbackT> -static void -iterateOneModule(InputFile &File, const Optional<PrintScope> &HeaderScope, - const SymbolGroup &SG, uint32_t Modi, CallbackT Callback) { - if (HeaderScope) { - HeaderScope->P.formatLine( - "Mod {0:4} | `{1}`: ", - fmt_align(Modi, AlignStyle::Right, HeaderScope->LabelWidth), SG.name()); - } - - AutoIndent Indent(HeaderScope); - Callback(Modi, SG); -} - -template <typename CallbackT> -static void iterateSymbolGroups(InputFile &Input, - const Optional<PrintScope> &HeaderScope, - CallbackT Callback) { - AutoIndent Indent(HeaderScope); - - ExitOnError Err("Unexpected error processing modules: "); - - if (opts::dump::DumpModi.getNumOccurrences() > 0) { - assert(opts::dump::DumpModi.getNumOccurrences() == 1); - uint32_t Modi = opts::dump::DumpModi; - SymbolGroup SG(&Input, Modi); - iterateOneModule(Input, withLabelWidth(HeaderScope, NumDigits(Modi)), SG, - Modi, Callback); - return; - } - - uint32_t I = 0; - - for (const auto &SG : Input.symbol_groups()) { - if (shouldDumpSymbolGroup(I, SG)) - iterateOneModule(Input, withLabelWidth(HeaderScope, NumDigits(I)), SG, I, - Callback); - - ++I; - } -} - -template <typename SubsectionT> -static void iterateModuleSubsections( - InputFile &File, const Optional<PrintScope> &HeaderScope, - llvm::function_ref<void(uint32_t, const SymbolGroup &, SubsectionT &)> - Callback) { - - iterateSymbolGroups(File, HeaderScope, - [&](uint32_t Modi, const SymbolGroup &SG) { - for (const auto &SS : SG.getDebugSubsections()) { - SubsectionT Subsection; - - if (SS.kind() != Subsection.kind()) - continue; - - BinaryStreamReader Reader(SS.getRecordData()); - if (auto EC = Subsection.initialize(Reader)) - continue; - Callback(Modi, SG, Subsection); - } - }); -} - static Expected<std::pair<std::unique_ptr<MappedBlockStream>, ArrayRef<llvm::object::coff_section>>> loadSectionHeaders(PDBFile &File, DbgHeaderType Type) { @@ -504,7 +387,7 @@ loadSectionHeaders(PDBFile &File, DbgHeaderType Type) { "Section headers require a DBI Stream, which could not be loaded", inconvertibleErrorCode()); - auto &Dbi = cantFail(File.getPDBDbiStream()); + DbiStream &Dbi = cantFail(File.getPDBDbiStream()); uint32_t SI = Dbi.getDebugStreamIndex(Type); if (SI == kInvalidStreamIndex) @@ -529,10 +412,10 @@ loadSectionHeaders(PDBFile &File, DbgHeaderType Type) { return std::make_pair(std::move(Stream), Headers); } -static std::vector<std::string> getSectionNames(PDBFile &File) { +static Expected<std::vector<std::string>> getSectionNames(PDBFile &File) { auto ExpectedHeaders = loadSectionHeaders(File, DbgHeaderType::SectionHdr); if (!ExpectedHeaders) - return {}; + return ExpectedHeaders.takeError(); std::unique_ptr<MappedBlockStream> Stream; ArrayRef<object::coff_section> Headers; @@ -590,31 +473,44 @@ Error DumpOutputStyle::dumpModules() { } AutoIndent Indent(P); - ExitOnError Err("Unexpected error processing modules: "); - auto &Stream = Err(getPdb().getPDBDbiStream()); + Expected<DbiStream &> StreamOrErr = getPdb().getPDBDbiStream(); + if (!StreamOrErr) + return StreamOrErr.takeError(); + DbiStream &Stream = *StreamOrErr; const DbiModuleList &Modules = Stream.modules(); - iterateSymbolGroups( - File, PrintScope{P, 11}, [&](uint32_t Modi, const SymbolGroup &Strings) { + return iterateSymbolGroups( + File, PrintScope{P, 11}, + [&](uint32_t Modi, const SymbolGroup &Strings) -> Error { auto Desc = Modules.getModuleDescriptor(Modi); if (opts::dump::DumpSectionContribs) { - std::vector<std::string> Sections = getSectionNames(getPdb()); + auto SectionsOrErr = getSectionNames(getPdb()); + if (!SectionsOrErr) + return SectionsOrErr.takeError(); + ArrayRef<std::string> Sections = *SectionsOrErr; dumpSectionContrib(P, Desc.getSectionContrib(), Sections, 0); } P.formatLine("Obj: `{0}`: ", Desc.getObjFileName()); P.formatLine("debug stream: {0}, # files: {1}, has ec info: {2}", Desc.getModuleStreamIndex(), Desc.getNumberOfFiles(), Desc.hasECInfo()); - StringRef PdbFilePath = - Err(Stream.getECName(Desc.getPdbFilePathNameIndex())); - StringRef SrcFilePath = - Err(Stream.getECName(Desc.getSourceFileNameIndex())); + + auto PdbPathOrErr = Stream.getECName(Desc.getPdbFilePathNameIndex()); + if (!PdbPathOrErr) + return PdbPathOrErr.takeError(); + StringRef PdbFilePath = *PdbPathOrErr; + + auto SrcPathOrErr = Stream.getECName(Desc.getSourceFileNameIndex()); + if (!SrcPathOrErr) + return SrcPathOrErr.takeError(); + StringRef SrcFilePath = *SrcPathOrErr; + P.formatLine("pdb file ni: {0} `{1}`, src file ni: {2} `{3}`", Desc.getPdbFilePathNameIndex(), PdbFilePath, Desc.getSourceFileNameIndex(), SrcFilePath); + return Error::success(); }); - return Error::success(); } Error DumpOutputStyle::dumpModuleFiles() { @@ -630,18 +526,20 @@ Error DumpOutputStyle::dumpModuleFiles() { return Error::success(); } - ExitOnError Err("Unexpected error processing modules: "); - - iterateSymbolGroups(File, PrintScope{P, 11}, - [this, &Err](uint32_t Modi, const SymbolGroup &Strings) { - auto &Stream = Err(getPdb().getPDBDbiStream()); + return iterateSymbolGroups( + File, PrintScope{P, 11}, + [this](uint32_t Modi, const SymbolGroup &Strings) -> Error { + Expected<DbiStream &> StreamOrErr = getPdb().getPDBDbiStream(); + if (!StreamOrErr) + return StreamOrErr.takeError(); + DbiStream &Stream = *StreamOrErr; - const DbiModuleList &Modules = Stream.modules(); - for (const auto &F : Modules.source_files(Modi)) { - Strings.formatFromFileName(P, F); - } - }); - return Error::success(); + const DbiModuleList &Modules = Stream.modules(); + for (const auto &F : Modules.source_files(Modi)) { + Strings.formatFromFileName(P, F); + } + return Error::success(); + }); } Error DumpOutputStyle::dumpSymbolStats() { @@ -652,39 +550,40 @@ Error DumpOutputStyle::dumpSymbolStats() { return Error::success(); } - ExitOnError Err("Unexpected error processing modules: "); - StatCollection SymStats; StatCollection ChunkStats; + PrintScope Scope(P, 2); - Optional<PrintScope> Scope; - if (File.isPdb()) - Scope.emplace(P, 2); + if (Error Err = iterateSymbolGroups( + File, Scope, [&](uint32_t Modi, const SymbolGroup &SG) -> Error { + StatCollection SS = getSymbolStats(SG, SymStats); + StatCollection CS = getChunkStats(SG, ChunkStats); - iterateSymbolGroups(File, Scope, [&](uint32_t Modi, const SymbolGroup &SG) { - StatCollection SS = getSymbolStats(SG, SymStats); - StatCollection CS = getChunkStats(SG, ChunkStats); + if (!SG.getFile().isPdb()) + return Error::success(); - if (SG.getFile().isPdb()) { - AutoIndent Indent(P); - auto Modules = cantFail(File.pdb().getPDBDbiStream()).modules(); - uint32_t ModCount = Modules.getModuleCount(); - DbiModuleDescriptor Desc = Modules.getModuleDescriptor(Modi); - uint32_t StreamIdx = Desc.getModuleStreamIndex(); + AutoIndent Indent(P); + auto Modules = cantFail(File.pdb().getPDBDbiStream()).modules(); + uint32_t ModCount = Modules.getModuleCount(); + DbiModuleDescriptor Desc = Modules.getModuleDescriptor(Modi); + uint32_t StreamIdx = Desc.getModuleStreamIndex(); - if (StreamIdx == kInvalidStreamIndex) { - P.formatLine("Mod {0} (debug info not present): [{1}]", - fmt_align(Modi, AlignStyle::Right, NumDigits(ModCount)), - Desc.getModuleName()); - return; - } - P.formatLine("Stream {0}, {1} bytes", StreamIdx, - getPdb().getStreamByteSize(StreamIdx)); + if (StreamIdx == kInvalidStreamIndex) { + P.formatLine( + "Mod {0} (debug info not present): [{1}]", + fmt_align(Modi, AlignStyle::Right, NumDigits(ModCount)), + Desc.getModuleName()); + return Error::success(); + } + P.formatLine("Stream {0}, {1} bytes", StreamIdx, + getPdb().getStreamByteSize(StreamIdx)); - printModuleDetailStats<SymbolKind>(P, "Symbols", SS); - printModuleDetailStats<DebugSubsectionKind>(P, "Chunks", CS); - } - }); + printModuleDetailStats<SymbolKind>(P, "Symbols", SS); + printModuleDetailStats<DebugSubsectionKind>(P, "Chunks", CS); + + return Error::success(); + })) + return Err; if (SymStats.Totals.Count > 0) { P.printLine(" Summary |"); @@ -944,11 +843,11 @@ Error DumpOutputStyle::dumpLines() { uint32_t LastModi = UINT32_MAX; uint32_t LastNameIndex = UINT32_MAX; - iterateModuleSubsections<DebugLinesSubsectionRef>( + return iterateModuleSubsections<DebugLinesSubsectionRef>( File, PrintScope{P, 4}, - [this, &LastModi, &LastNameIndex](uint32_t Modi, - const SymbolGroup &Strings, - DebugLinesSubsectionRef &Lines) { + [this, &LastModi, + &LastNameIndex](uint32_t Modi, const SymbolGroup &Strings, + DebugLinesSubsectionRef &Lines) -> Error { uint16_t Segment = Lines.header()->RelocSegment; uint32_t Begin = Lines.header()->RelocOffset; uint32_t End = Begin + Lines.header()->CodeSize; @@ -970,9 +869,8 @@ Error DumpOutputStyle::dumpLines() { P.NewLine(); typesetLinesAndColumns(P, Begin, Block); } + return Error::success(); }); - - return Error::success(); } Error DumpOutputStyle::dumpInlineeLines() { @@ -983,10 +881,10 @@ Error DumpOutputStyle::dumpInlineeLines() { return Error::success(); } - iterateModuleSubsections<DebugInlineeLinesSubsectionRef>( + return iterateModuleSubsections<DebugInlineeLinesSubsectionRef>( File, PrintScope{P, 2}, [this](uint32_t Modi, const SymbolGroup &Strings, - DebugInlineeLinesSubsectionRef &Lines) { + DebugInlineeLinesSubsectionRef &Lines) -> Error { P.formatLine("{0,+8} | {1,+5} | {2}", "Inlinee", "Line", "Source File"); for (const auto &Entry : Lines) { P.formatLine("{0,+8} | {1,+5} | ", Entry.Header->Inlinee, @@ -998,9 +896,8 @@ Error DumpOutputStyle::dumpInlineeLines() { } } P.NewLine(); + return Error::success(); }); - - return Error::success(); } Error DumpOutputStyle::dumpXmi() { @@ -1011,10 +908,10 @@ Error DumpOutputStyle::dumpXmi() { return Error::success(); } - iterateModuleSubsections<DebugCrossModuleImportsSubsectionRef>( + return iterateModuleSubsections<DebugCrossModuleImportsSubsectionRef>( File, PrintScope{P, 2}, [this](uint32_t Modi, const SymbolGroup &Strings, - DebugCrossModuleImportsSubsectionRef &Imports) { + DebugCrossModuleImportsSubsectionRef &Imports) -> Error { P.formatLine("{0,=32} | {1}", "Imported Module", "Type IDs"); for (const auto &Xmi : Imports) { @@ -1039,9 +936,8 @@ Error DumpOutputStyle::dumpXmi() { typesetItemList(TIs, P.getIndentLevel() + 35, 12, " "); P.formatLine("{0,+32} | {1}", Module, Result); } + return Error::success(); }); - - return Error::success(); } Error DumpOutputStyle::dumpXme() { @@ -1052,18 +948,17 @@ Error DumpOutputStyle::dumpXme() { return Error::success(); } - iterateModuleSubsections<DebugCrossModuleExportsSubsectionRef>( + return iterateModuleSubsections<DebugCrossModuleExportsSubsectionRef>( File, PrintScope{P, 2}, [this](uint32_t Modi, const SymbolGroup &Strings, - DebugCrossModuleExportsSubsectionRef &Exports) { + DebugCrossModuleExportsSubsectionRef &Exports) -> Error { P.formatLine("{0,-10} | {1}", "Local ID", "Global ID"); for (const auto &Export : Exports) { P.formatLine("{0,+10:X+} | {1}", TypeIndex(Export.Local), TypeIndex(Export.Global)); } + return Error::success(); }); - - return Error::success(); } std::string formatFrameType(object::frame_type FT) { @@ -1084,7 +979,7 @@ Error DumpOutputStyle::dumpOldFpo(PDBFile &File) { printHeader(P, "Old FPO Data"); ExitOnError Err("Error dumping old fpo data:"); - auto &Dbi = Err(File.getPDBDbiStream()); + DbiStream &Dbi = Err(File.getPDBDbiStream()); if (!Dbi.hasOldFpoRecords()) { printStreamNotPresent("FPO"); @@ -1111,7 +1006,7 @@ Error DumpOutputStyle::dumpNewFpo(PDBFile &File) { printHeader(P, "New FPO Data"); ExitOnError Err("Error dumping new fpo data:"); - auto &Dbi = Err(File.getPDBDbiStream()); + DbiStream &Dbi = Err(File.getPDBDbiStream()); if (!Dbi.hasNewFpoRecords()) { printStreamNotPresent("New FPO"); @@ -1232,10 +1127,10 @@ Error DumpOutputStyle::dumpStringTableFromPdb() { } Error DumpOutputStyle::dumpStringTableFromObj() { - iterateModuleSubsections<DebugStringTableSubsectionRef>( + return iterateModuleSubsections<DebugStringTableSubsectionRef>( File, PrintScope{P, 4}, [&](uint32_t Modi, const SymbolGroup &Strings, - DebugStringTableSubsectionRef &Strings2) { + DebugStringTableSubsectionRef &Strings2) -> Error { BinaryStreamRef StringTableBuffer = Strings2.getBuffer(); BinaryStreamReader Reader(StringTableBuffer); while (Reader.bytesRemaining() > 0) { @@ -1248,8 +1143,8 @@ Error DumpOutputStyle::dumpStringTableFromObj() { P.formatLine("{0} | {1}", fmt_align(Offset, AlignStyle::Right, 4), Str); } + return Error::success(); }); - return Error::success(); } Error DumpOutputStyle::dumpNamedStreams() { @@ -1352,10 +1247,16 @@ static void dumpPartialTypeStream(LinePrinter &Printer, for (const auto &I : TiList) { TypeIndex TI(I); - CVType Type = Types.getType(TI); - if (auto EC = codeview::visitTypeRecord(Type, TI, V)) - Printer.formatLine("An error occurred dumping type record {0}: {1}", TI, - toString(std::move(EC))); + if (TI.isSimple()) { + Printer.formatLine("{0} | {1}", fmt_align(I, AlignStyle::Right, Width), + Types.getTypeName(TI)); + } else if (Optional<CVType> Type = Types.tryGetType(TI)) { + if (auto EC = codeview::visitTypeRecord(*Type, TI, V)) + Printer.formatLine("An error occurred dumping type record {0}: {1}", + TI, toString(std::move(EC))); + } else { + Printer.formatLine("Type {0} doesn't exist in TPI stream", TI); + } } } } @@ -1526,8 +1427,6 @@ Error DumpOutputStyle::dumpModuleSymsForObj() { AutoIndent Indent(P); - ExitOnError Err("Unexpected error processing symbols: "); - auto &Types = File.types(); SymbolVisitorCallbackPipeline Pipeline; @@ -1538,25 +1437,18 @@ Error DumpOutputStyle::dumpModuleSymsForObj() { Pipeline.addCallbackToPipeline(Dumper); CVSymbolVisitor Visitor(Pipeline); - std::unique_ptr<llvm::Error> SymbolError; - - iterateModuleSubsections<DebugSymbolsSubsectionRef>( + return iterateModuleSubsections<DebugSymbolsSubsectionRef>( File, PrintScope{P, 2}, [&](uint32_t Modi, const SymbolGroup &Strings, - DebugSymbolsSubsectionRef &Symbols) { + DebugSymbolsSubsectionRef &Symbols) -> Error { Dumper.setSymbolGroup(&Strings); for (auto Symbol : Symbols) { if (auto EC = Visitor.visitSymbolRecord(Symbol)) { - SymbolError = std::make_unique<Error>(std::move(EC)); - return; + return EC; } } + return Error::success(); }); - - if (SymbolError) - return std::move(*SymbolError); - - return Error::success(); } Error DumpOutputStyle::dumpModuleSymsForPdb() { @@ -1568,18 +1460,18 @@ Error DumpOutputStyle::dumpModuleSymsForPdb() { } AutoIndent Indent(P); - ExitOnError Err("Unexpected error processing symbols: "); auto &Ids = File.ids(); auto &Types = File.types(); - iterateSymbolGroups( - File, PrintScope{P, 2}, [&](uint32_t I, const SymbolGroup &Strings) { + return iterateSymbolGroups( + File, PrintScope{P, 2}, + [&](uint32_t I, const SymbolGroup &Strings) -> Error { auto ExpectedModS = getModuleDebugStream(File.pdb(), I); if (!ExpectedModS) { P.formatLine("Error loading module stream {0}. {1}", I, toString(ExpectedModS.takeError())); - return; + return Error::success(); } ModuleDebugStreamRef &ModS = *ExpectedModS; @@ -1593,14 +1485,25 @@ Error DumpOutputStyle::dumpModuleSymsForPdb() { Pipeline.addCallbackToPipeline(Dumper); CVSymbolVisitor Visitor(Pipeline); auto SS = ModS.getSymbolsSubstream(); - if (auto EC = - Visitor.visitSymbolStream(ModS.getSymbolArray(), SS.Offset)) { + if (opts::Filters.SymbolOffset) { + CVSymbolVisitor::FilterOptions Filter; + Filter.SymbolOffset = opts::Filters.SymbolOffset; + Filter.ParentRecursiveDepth = opts::Filters.ParentRecurseDepth; + Filter.ChildRecursiveDepth = opts::Filters.ChildrenRecurseDepth; + if (auto EC = Visitor.visitSymbolStreamFiltered(ModS.getSymbolArray(), + Filter)) { + P.formatLine("Error while processing symbol records. {0}", + toString(std::move(EC))); + return EC; + } + } else if (auto EC = Visitor.visitSymbolStream(ModS.getSymbolArray(), + SS.Offset)) { P.formatLine("Error while processing symbol records. {0}", toString(std::move(EC))); - return; + return EC; } + return Error::success(); }); - return Error::success(); } Error DumpOutputStyle::dumpTypeRefStats() { @@ -1925,7 +1828,7 @@ Error DumpOutputStyle::dumpSectionContribs() { AutoIndent Indent(P); ExitOnError Err("Error dumping section contributions: "); - auto &Dbi = Err(getPdb().getPDBDbiStream()); + DbiStream &Dbi = Err(getPdb().getPDBDbiStream()); class Visitor : public ISectionContribVisitor { public: @@ -1948,8 +1851,11 @@ Error DumpOutputStyle::dumpSectionContribs() { ArrayRef<std::string> Names; }; - std::vector<std::string> Names = getSectionNames(getPdb()); - Visitor V(P, makeArrayRef(Names)); + auto NamesOrErr = getSectionNames(getPdb()); + if (!NamesOrErr) + return NamesOrErr.takeError(); + ArrayRef<std::string> Names = *NamesOrErr; + Visitor V(P, Names); Dbi.visitSectionContributions(V); return Error::success(); } @@ -1970,7 +1876,7 @@ Error DumpOutputStyle::dumpSectionMap() { AutoIndent Indent(P); ExitOnError Err("Error dumping section map: "); - auto &Dbi = Err(getPdb().getPDBDbiStream()); + DbiStream &Dbi = Err(getPdb().getPDBDbiStream()); uint32_t I = 0; for (auto &M : Dbi.getSectionMap()) { diff --git a/llvm/tools/llvm-pdbutil/DumpOutputStyle.h b/llvm/tools/llvm-pdbutil/DumpOutputStyle.h index 041fb93a18a5..217d25d66d8b 100644 --- a/llvm/tools/llvm-pdbutil/DumpOutputStyle.h +++ b/llvm/tools/llvm-pdbutil/DumpOutputStyle.h @@ -9,13 +9,13 @@ #ifndef LLVM_TOOLS_LLVMPDBDUMP_DUMPOUTPUTSTYLE_H #define LLVM_TOOLS_LLVMPDBDUMP_DUMPOUTPUTSTYLE_H -#include "LinePrinter.h" #include "OutputStyle.h" #include "StreamUtil.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/Optional.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/DebugInfo/PDB/Native/LinePrinter.h" #include "llvm/DebugInfo/PDB/Native/RawConstants.h" #include <string> diff --git a/llvm/tools/llvm-pdbutil/ExplainOutputStyle.cpp b/llvm/tools/llvm-pdbutil/ExplainOutputStyle.cpp index b631bdf8f2b1..13a5f6ea6fe7 100644 --- a/llvm/tools/llvm-pdbutil/ExplainOutputStyle.cpp +++ b/llvm/tools/llvm-pdbutil/ExplainOutputStyle.cpp @@ -8,17 +8,20 @@ #include "ExplainOutputStyle.h" -#include "FormatUtil.h" -#include "InputFile.h" #include "StreamUtil.h" #include "llvm-pdbutil.h" #include "llvm/DebugInfo/CodeView/Formatters.h" +#include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h" #include "llvm/DebugInfo/MSF/MappedBlockStream.h" #include "llvm/DebugInfo/PDB/Native/DbiStream.h" +#include "llvm/DebugInfo/PDB/Native/FormatUtil.h" #include "llvm/DebugInfo/PDB/Native/InfoStream.h" +#include "llvm/DebugInfo/PDB/Native/InputFile.h" +#include "llvm/DebugInfo/PDB/Native/NativeSession.h" #include "llvm/DebugInfo/PDB/Native/PDBFile.h" #include "llvm/DebugInfo/PDB/Native/RawTypes.h" +#include "llvm/Object/COFF.h" #include "llvm/Support/BinaryByteStream.h" #include "llvm/Support/BinaryStreamArray.h" #include "llvm/Support/Error.h" @@ -29,7 +32,7 @@ using namespace llvm::msf; using namespace llvm::pdb; ExplainOutputStyle::ExplainOutputStyle(InputFile &File, uint64_t FileOffset) - : File(File), FileOffset(FileOffset), P(2, false, outs()) {} + : File(File), FileOffset(FileOffset), P(2, false, outs(), opts::Filters) {} Error ExplainOutputStyle::dump() { P.formatLine("Explaining file offset {0} of file '{1}'.", FileOffset, diff --git a/llvm/tools/llvm-pdbutil/ExplainOutputStyle.h b/llvm/tools/llvm-pdbutil/ExplainOutputStyle.h index f405cf615e92..e3d19f25a9ea 100644 --- a/llvm/tools/llvm-pdbutil/ExplainOutputStyle.h +++ b/llvm/tools/llvm-pdbutil/ExplainOutputStyle.h @@ -9,9 +9,10 @@ #ifndef LLVM_TOOLS_LLVMPDBDUMP_EXPLAINOUTPUTSTYLE_H #define LLVM_TOOLS_LLVMPDBDUMP_EXPLAINOUTPUTSTYLE_H -#include "LinePrinter.h" #include "OutputStyle.h" +#include "llvm/DebugInfo/PDB/Native/LinePrinter.h" + #include <string> namespace llvm { diff --git a/llvm/tools/llvm-pdbutil/FormatUtil.cpp b/llvm/tools/llvm-pdbutil/FormatUtil.cpp deleted file mode 100644 index b4837398f1d0..000000000000 --- a/llvm/tools/llvm-pdbutil/FormatUtil.cpp +++ /dev/null @@ -1,258 +0,0 @@ -//===- FormatUtil.cpp ----------------------------------------- *- C++ --*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#include "FormatUtil.h" -#include "llvm/ADT/STLExtras.h" -#include "llvm/ADT/StringExtras.h" -#include "llvm/BinaryFormat/COFF.h" -#include "llvm/DebugInfo/CodeView/CodeView.h" -#include "llvm/Support/FormatAdapters.h" -#include "llvm/Support/FormatVariadic.h" - -using namespace llvm; -using namespace llvm::codeview; -using namespace llvm::pdb; - -std::string llvm::pdb::truncateStringBack(StringRef S, uint32_t MaxLen) { - if (MaxLen == 0 || S.size() <= MaxLen || S.size() <= 3) - return std::string(S); - - assert(MaxLen >= 3); - uint32_t FinalLen = std::min<size_t>(S.size(), MaxLen - 3); - S = S.take_front(FinalLen); - return std::string(S) + std::string("..."); -} - -std::string llvm::pdb::truncateStringMiddle(StringRef S, uint32_t MaxLen) { - if (MaxLen == 0 || S.size() <= MaxLen || S.size() <= 3) - return std::string(S); - - assert(MaxLen >= 3); - uint32_t FinalLen = std::min<size_t>(S.size(), MaxLen - 3); - StringRef Front = S.take_front(FinalLen / 2); - StringRef Back = S.take_back(Front.size()); - return std::string(Front) + std::string("...") + std::string(Back); -} - -std::string llvm::pdb::truncateStringFront(StringRef S, uint32_t MaxLen) { - if (MaxLen == 0 || S.size() <= MaxLen || S.size() <= 3) - return std::string(S); - - assert(MaxLen >= 3); - S = S.take_back(MaxLen - 3); - return std::string("...") + std::string(S); -} - -std::string llvm::pdb::truncateQuotedNameFront(StringRef Label, StringRef Name, - uint32_t MaxLen) { - uint32_t RequiredExtraChars = Label.size() + 1 + 2; - if (MaxLen == 0 || RequiredExtraChars + Name.size() <= MaxLen) - return formatv("{0} \"{1}\"", Label, Name).str(); - - assert(MaxLen >= RequiredExtraChars); - std::string TN = truncateStringFront(Name, MaxLen - RequiredExtraChars); - return formatv("{0} \"{1}\"", Label, TN).str(); -} - -std::string llvm::pdb::truncateQuotedNameBack(StringRef Label, StringRef Name, - uint32_t MaxLen) { - uint32_t RequiredExtraChars = Label.size() + 1 + 2; - if (MaxLen == 0 || RequiredExtraChars + Name.size() <= MaxLen) - return formatv("{0} \"{1}\"", Label, Name).str(); - - assert(MaxLen >= RequiredExtraChars); - std::string TN = truncateStringBack(Name, MaxLen - RequiredExtraChars); - return formatv("{0} \"{1}\"", Label, TN).str(); -} - -std::string llvm::pdb::typesetItemList(ArrayRef<std::string> Opts, - uint32_t IndentLevel, uint32_t GroupSize, - StringRef Sep) { - std::string Result; - while (!Opts.empty()) { - ArrayRef<std::string> ThisGroup; - ThisGroup = Opts.take_front(GroupSize); - Opts = Opts.drop_front(ThisGroup.size()); - Result += join(ThisGroup, Sep); - if (!Opts.empty()) { - Result += Sep; - Result += "\n"; - Result += std::string(formatv("{0}", fmt_repeat(' ', IndentLevel))); - } - } - return Result; -} - -std::string llvm::pdb::typesetStringList(uint32_t IndentLevel, - ArrayRef<StringRef> Strings) { - std::string Result = "["; - for (const auto &S : Strings) { - Result += std::string(formatv("\n{0}{1}", fmt_repeat(' ', IndentLevel), S)); - } - Result += "]"; - return Result; -} - -std::string llvm::pdb::formatChunkKind(DebugSubsectionKind Kind, - bool Friendly) { - if (Friendly) { - switch (Kind) { - RETURN_CASE(DebugSubsectionKind, None, "none"); - RETURN_CASE(DebugSubsectionKind, Symbols, "symbols"); - RETURN_CASE(DebugSubsectionKind, Lines, "lines"); - RETURN_CASE(DebugSubsectionKind, StringTable, "strings"); - RETURN_CASE(DebugSubsectionKind, FileChecksums, "checksums"); - RETURN_CASE(DebugSubsectionKind, FrameData, "frames"); - RETURN_CASE(DebugSubsectionKind, InlineeLines, "inlinee lines"); - RETURN_CASE(DebugSubsectionKind, CrossScopeImports, "xmi"); - RETURN_CASE(DebugSubsectionKind, CrossScopeExports, "xme"); - RETURN_CASE(DebugSubsectionKind, ILLines, "il lines"); - RETURN_CASE(DebugSubsectionKind, FuncMDTokenMap, "func md token map"); - RETURN_CASE(DebugSubsectionKind, TypeMDTokenMap, "type md token map"); - RETURN_CASE(DebugSubsectionKind, MergedAssemblyInput, - "merged assembly input"); - RETURN_CASE(DebugSubsectionKind, CoffSymbolRVA, "coff symbol rva"); - } - } else { - switch (Kind) { - RETURN_CASE(DebugSubsectionKind, None, "none"); - RETURN_CASE(DebugSubsectionKind, Symbols, "DEBUG_S_SYMBOLS"); - RETURN_CASE(DebugSubsectionKind, Lines, "DEBUG_S_LINES"); - RETURN_CASE(DebugSubsectionKind, StringTable, "DEBUG_S_STRINGTABLE"); - RETURN_CASE(DebugSubsectionKind, FileChecksums, "DEBUG_S_FILECHKSMS"); - RETURN_CASE(DebugSubsectionKind, FrameData, "DEBUG_S_FRAMEDATA"); - RETURN_CASE(DebugSubsectionKind, InlineeLines, "DEBUG_S_INLINEELINES"); - RETURN_CASE(DebugSubsectionKind, CrossScopeImports, - "DEBUG_S_CROSSSCOPEIMPORTS"); - RETURN_CASE(DebugSubsectionKind, CrossScopeExports, - "DEBUG_S_CROSSSCOPEEXPORTS"); - RETURN_CASE(DebugSubsectionKind, ILLines, "DEBUG_S_IL_LINES"); - RETURN_CASE(DebugSubsectionKind, FuncMDTokenMap, - "DEBUG_S_FUNC_MDTOKEN_MAP"); - RETURN_CASE(DebugSubsectionKind, TypeMDTokenMap, - "DEBUG_S_TYPE_MDTOKEN_MAP"); - RETURN_CASE(DebugSubsectionKind, MergedAssemblyInput, - "DEBUG_S_MERGED_ASSEMBLYINPUT"); - RETURN_CASE(DebugSubsectionKind, CoffSymbolRVA, - "DEBUG_S_COFF_SYMBOL_RVA"); - } - } - return formatUnknownEnum(Kind); -} - -std::string llvm::pdb::formatSymbolKind(SymbolKind K) { - switch (uint32_t(K)) { -#define SYMBOL_RECORD(EnumName, value, name) \ - case EnumName: \ - return #EnumName; -#define CV_SYMBOL(EnumName, value) SYMBOL_RECORD(EnumName, value, EnumName) -#include "llvm/DebugInfo/CodeView/CodeViewSymbols.def" - } - return formatUnknownEnum(K); -} - -std::string llvm::pdb::formatTypeLeafKind(TypeLeafKind K) { - switch (K) { -#define TYPE_RECORD(EnumName, value, name) \ - case EnumName: \ - return #EnumName; -#include "llvm/DebugInfo/CodeView/CodeViewTypes.def" - default: - return formatv("UNKNOWN RECORD ({0:X})", - static_cast<std::underlying_type_t<TypeLeafKind>>(K)) - .str(); - } -} - -std::string llvm::pdb::formatSegmentOffset(uint16_t Segment, uint32_t Offset) { - return std::string(formatv("{0:4}:{1:4}", Segment, Offset)); -} - -#define PUSH_CHARACTERISTIC_FLAG(Enum, TheOpt, Value, Style, Descriptive) \ - PUSH_FLAG(Enum, TheOpt, Value, \ - ((Style == CharacteristicStyle::HeaderDefinition) ? #TheOpt \ - : Descriptive)) - -#define PUSH_MASKED_CHARACTERISTIC_FLAG(Enum, Mask, TheOpt, Value, Style, \ - Descriptive) \ - PUSH_MASKED_FLAG(Enum, Mask, TheOpt, Value, \ - ((Style == CharacteristicStyle::HeaderDefinition) \ - ? #TheOpt \ - : Descriptive)) - -std::string llvm::pdb::formatSectionCharacteristics(uint32_t IndentLevel, - uint32_t C, - uint32_t FlagsPerLine, - StringRef Separator, - CharacteristicStyle Style) { - using SC = COFF::SectionCharacteristics; - std::vector<std::string> Opts; - if (C == COFF::SC_Invalid) - return "invalid"; - if (C == 0) - return "none"; - PUSH_CHARACTERISTIC_FLAG(SC, IMAGE_SCN_TYPE_NOLOAD, C, Style, "noload"); - PUSH_CHARACTERISTIC_FLAG(SC, IMAGE_SCN_TYPE_NO_PAD, C, Style, "no padding"); - PUSH_CHARACTERISTIC_FLAG(SC, IMAGE_SCN_CNT_CODE, C, Style, "code"); - PUSH_CHARACTERISTIC_FLAG(SC, IMAGE_SCN_CNT_INITIALIZED_DATA, C, Style, - "initialized data"); - PUSH_CHARACTERISTIC_FLAG(SC, IMAGE_SCN_CNT_UNINITIALIZED_DATA, C, Style, - "uninitialized data"); - PUSH_CHARACTERISTIC_FLAG(SC, IMAGE_SCN_LNK_OTHER, C, Style, "other"); - PUSH_CHARACTERISTIC_FLAG(SC, IMAGE_SCN_LNK_INFO, C, Style, "info"); - PUSH_CHARACTERISTIC_FLAG(SC, IMAGE_SCN_LNK_REMOVE, C, Style, "remove"); - PUSH_CHARACTERISTIC_FLAG(SC, IMAGE_SCN_LNK_COMDAT, C, Style, "comdat"); - PUSH_CHARACTERISTIC_FLAG(SC, IMAGE_SCN_GPREL, C, Style, "gp rel"); - PUSH_CHARACTERISTIC_FLAG(SC, IMAGE_SCN_MEM_PURGEABLE, C, Style, "purgeable"); - PUSH_CHARACTERISTIC_FLAG(SC, IMAGE_SCN_MEM_16BIT, C, Style, "16-bit"); - PUSH_CHARACTERISTIC_FLAG(SC, IMAGE_SCN_MEM_LOCKED, C, Style, "locked"); - PUSH_CHARACTERISTIC_FLAG(SC, IMAGE_SCN_MEM_PRELOAD, C, Style, "preload"); - PUSH_MASKED_CHARACTERISTIC_FLAG(SC, 0xF00000, IMAGE_SCN_ALIGN_1BYTES, C, - Style, "1 byte align"); - PUSH_MASKED_CHARACTERISTIC_FLAG(SC, 0xF00000, IMAGE_SCN_ALIGN_2BYTES, C, - Style, "2 byte align"); - PUSH_MASKED_CHARACTERISTIC_FLAG(SC, 0xF00000, IMAGE_SCN_ALIGN_4BYTES, C, - Style, "4 byte align"); - PUSH_MASKED_CHARACTERISTIC_FLAG(SC, 0xF00000, IMAGE_SCN_ALIGN_8BYTES, C, - Style, "8 byte align"); - PUSH_MASKED_CHARACTERISTIC_FLAG(SC, 0xF00000, IMAGE_SCN_ALIGN_16BYTES, C, - Style, "16 byte align"); - PUSH_MASKED_CHARACTERISTIC_FLAG(SC, 0xF00000, IMAGE_SCN_ALIGN_32BYTES, C, - Style, "32 byte align"); - PUSH_MASKED_CHARACTERISTIC_FLAG(SC, 0xF00000, IMAGE_SCN_ALIGN_64BYTES, C, - Style, "64 byte align"); - PUSH_MASKED_CHARACTERISTIC_FLAG(SC, 0xF00000, IMAGE_SCN_ALIGN_128BYTES, C, - Style, "128 byte align"); - PUSH_MASKED_CHARACTERISTIC_FLAG(SC, 0xF00000, IMAGE_SCN_ALIGN_256BYTES, C, - Style, "256 byte align"); - PUSH_MASKED_CHARACTERISTIC_FLAG(SC, 0xF00000, IMAGE_SCN_ALIGN_512BYTES, C, - Style, "512 byte align"); - PUSH_MASKED_CHARACTERISTIC_FLAG(SC, 0xF00000, IMAGE_SCN_ALIGN_1024BYTES, C, - Style, "1024 byte align"); - PUSH_MASKED_CHARACTERISTIC_FLAG(SC, 0xF00000, IMAGE_SCN_ALIGN_2048BYTES, C, - Style, "2048 byte align"); - PUSH_MASKED_CHARACTERISTIC_FLAG(SC, 0xF00000, IMAGE_SCN_ALIGN_4096BYTES, C, - Style, "4096 byte align"); - PUSH_MASKED_CHARACTERISTIC_FLAG(SC, 0xF00000, IMAGE_SCN_ALIGN_8192BYTES, C, - Style, "8192 byte align"); - PUSH_CHARACTERISTIC_FLAG(SC, IMAGE_SCN_LNK_NRELOC_OVFL, C, Style, - "noreloc overflow"); - PUSH_CHARACTERISTIC_FLAG(SC, IMAGE_SCN_MEM_DISCARDABLE, C, Style, - "discardable"); - PUSH_CHARACTERISTIC_FLAG(SC, IMAGE_SCN_MEM_NOT_CACHED, C, Style, - "not cached"); - PUSH_CHARACTERISTIC_FLAG(SC, IMAGE_SCN_MEM_NOT_PAGED, C, Style, "not paged"); - PUSH_CHARACTERISTIC_FLAG(SC, IMAGE_SCN_MEM_SHARED, C, Style, "shared"); - PUSH_CHARACTERISTIC_FLAG(SC, IMAGE_SCN_MEM_EXECUTE, C, Style, - "execute permissions"); - PUSH_CHARACTERISTIC_FLAG(SC, IMAGE_SCN_MEM_READ, C, Style, - "read permissions"); - PUSH_CHARACTERISTIC_FLAG(SC, IMAGE_SCN_MEM_WRITE, C, Style, - "write permissions"); - return typesetItemList(Opts, IndentLevel, FlagsPerLine, Separator); -} diff --git a/llvm/tools/llvm-pdbutil/FormatUtil.h b/llvm/tools/llvm-pdbutil/FormatUtil.h deleted file mode 100644 index b99ccec215b5..000000000000 --- a/llvm/tools/llvm-pdbutil/FormatUtil.h +++ /dev/null @@ -1,141 +0,0 @@ -//===- FormatUtil.h ------------------------------------------- *- C++ --*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_TOOLS_LLVMPDBUTIL_FORMAT_UTIL_H -#define LLVM_TOOLS_LLVMPDBUTIL_FORMAT_UTIL_H - -#include "llvm/ADT/ArrayRef.h" -#include "llvm/ADT/StringRef.h" -#include "llvm/DebugInfo/CodeView/CodeView.h" -#include "llvm/Support/Endian.h" -#include "llvm/Support/FormatAdapters.h" -#include "llvm/Support/FormatVariadic.h" - -#include <string> -#include <type_traits> - -namespace llvm { -namespace pdb { - -std::string truncateStringBack(StringRef S, uint32_t MaxLen); -std::string truncateStringMiddle(StringRef S, uint32_t MaxLen); -std::string truncateStringFront(StringRef S, uint32_t MaxLen); -std::string truncateQuotedNameFront(StringRef Label, StringRef Name, - uint32_t MaxLen); -std::string truncateQuotedNameBack(StringRef Label, StringRef Name, - uint32_t MaxLen); - -#define PUSH_MASKED_FLAG(Enum, Mask, TheOpt, Value, Text) \ - if (Enum::TheOpt == (Value & Mask)) \ - Opts.push_back(Text); - -#define PUSH_FLAG(Enum, TheOpt, Value, Text) \ - PUSH_MASKED_FLAG(Enum, Enum::TheOpt, TheOpt, Value, Text) - -#define RETURN_CASE(Enum, X, Ret) \ - case Enum::X: \ - return Ret; - -template <typename T> std::string formatUnknownEnum(T Value) { - return formatv("unknown ({0})", static_cast<std::underlying_type_t<T>>(Value)) - .str(); -} - -std::string formatSegmentOffset(uint16_t Segment, uint32_t Offset); - -enum class CharacteristicStyle { - HeaderDefinition, // format as windows header definition - Descriptive, // format as human readable words -}; -std::string formatSectionCharacteristics( - uint32_t IndentLevel, uint32_t C, uint32_t FlagsPerLine, - StringRef Separator, - CharacteristicStyle Style = CharacteristicStyle::HeaderDefinition); - -std::string typesetItemList(ArrayRef<std::string> Opts, uint32_t IndentLevel, - uint32_t GroupSize, StringRef Sep); - -std::string typesetStringList(uint32_t IndentLevel, - ArrayRef<StringRef> Strings); - -std::string formatChunkKind(codeview::DebugSubsectionKind Kind, - bool Friendly = true); -std::string formatSymbolKind(codeview::SymbolKind K); -std::string formatTypeLeafKind(codeview::TypeLeafKind K); - -/// Returns the number of digits in the given integer. -inline int NumDigits(uint64_t N) { - if (N < 10ULL) - return 1; - if (N < 100ULL) - return 2; - if (N < 1000ULL) - return 3; - if (N < 10000ULL) - return 4; - if (N < 100000ULL) - return 5; - if (N < 1000000ULL) - return 6; - if (N < 10000000ULL) - return 7; - if (N < 100000000ULL) - return 8; - if (N < 1000000000ULL) - return 9; - if (N < 10000000000ULL) - return 10; - if (N < 100000000000ULL) - return 11; - if (N < 1000000000000ULL) - return 12; - if (N < 10000000000000ULL) - return 13; - if (N < 100000000000000ULL) - return 14; - if (N < 1000000000000000ULL) - return 15; - if (N < 10000000000000000ULL) - return 16; - if (N < 100000000000000000ULL) - return 17; - if (N < 1000000000000000000ULL) - return 18; - if (N < 10000000000000000000ULL) - return 19; - return 20; -} - -namespace detail { -template <typename T> -struct EndianAdapter final - : public FormatAdapter<support::detail::packed_endian_specific_integral< - T, support::little, support::unaligned>> { - using EndianType = - support::detail::packed_endian_specific_integral<T, support::little, - support::unaligned>; - - explicit EndianAdapter(EndianType &&Item) - : FormatAdapter<EndianType>(std::move(Item)) {} - - void format(llvm::raw_ostream &Stream, StringRef Style) override { - format_provider<T>::format(static_cast<T>(this->Item), Stream, Style); - } -}; -} // namespace detail - -template <typename T> -detail::EndianAdapter<T> -fmtle(support::detail::packed_endian_specific_integral<T, support::little, - support::unaligned> - Value) { - return detail::EndianAdapter<T>(std::move(Value)); -} -} -} // namespace llvm -#endif diff --git a/llvm/tools/llvm-pdbutil/InputFile.cpp b/llvm/tools/llvm-pdbutil/InputFile.cpp deleted file mode 100644 index 40b35625b6f8..000000000000 --- a/llvm/tools/llvm-pdbutil/InputFile.cpp +++ /dev/null @@ -1,510 +0,0 @@ -//===- InputFile.cpp ------------------------------------------ *- C++ --*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#include "InputFile.h" - -#include "FormatUtil.h" -#include "LinePrinter.h" - -#include "llvm/BinaryFormat/Magic.h" -#include "llvm/DebugInfo/CodeView/CodeView.h" -#include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h" -#include "llvm/DebugInfo/CodeView/StringsAndChecksums.h" -#include "llvm/DebugInfo/PDB/Native/DbiStream.h" -#include "llvm/DebugInfo/PDB/Native/NativeSession.h" -#include "llvm/DebugInfo/PDB/Native/PDBFile.h" -#include "llvm/DebugInfo/PDB/Native/PDBStringTable.h" -#include "llvm/DebugInfo/PDB/Native/RawError.h" -#include "llvm/DebugInfo/PDB/Native/TpiStream.h" -#include "llvm/DebugInfo/PDB/PDB.h" -#include "llvm/Object/COFF.h" -#include "llvm/Support/FileSystem.h" -#include "llvm/Support/FormatVariadic.h" - -using namespace llvm; -using namespace llvm::codeview; -using namespace llvm::object; -using namespace llvm::pdb; - -InputFile::InputFile() {} -InputFile::~InputFile() {} - -static Expected<ModuleDebugStreamRef> -getModuleDebugStream(PDBFile &File, StringRef &ModuleName, uint32_t Index) { - ExitOnError Err("Unexpected error: "); - - 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(); - - uint16_t ModiStream = Modi.getModuleStreamIndex(); - if (ModiStream == kInvalidStreamIndex) - return make_error<RawError>(raw_error_code::no_stream, - "Module stream not present"); - - auto ModStreamData = File.createIndexedStream(ModiStream); - - ModuleDebugStreamRef ModS(Modi, std::move(ModStreamData)); - if (auto EC = ModS.reload()) - return make_error<RawError>(raw_error_code::corrupt_file, - "Invalid module stream"); - - return std::move(ModS); -} - -static inline bool isCodeViewDebugSubsection(object::SectionRef Section, - StringRef Name, - BinaryStreamReader &Reader) { - if (Expected<StringRef> NameOrErr = Section.getName()) { - if (*NameOrErr != Name) - return false; - } else { - consumeError(NameOrErr.takeError()); - return false; - } - - Expected<StringRef> ContentsOrErr = Section.getContents(); - if (!ContentsOrErr) { - consumeError(ContentsOrErr.takeError()); - return false; - } - - Reader = BinaryStreamReader(*ContentsOrErr, support::little); - uint32_t Magic; - if (Reader.bytesRemaining() < sizeof(uint32_t)) - return false; - cantFail(Reader.readInteger(Magic)); - if (Magic != COFF::DEBUG_SECTION_MAGIC) - return false; - return true; -} - -static inline bool isDebugSSection(object::SectionRef Section, - DebugSubsectionArray &Subsections) { - BinaryStreamReader Reader; - if (!isCodeViewDebugSubsection(Section, ".debug$S", Reader)) - return false; - - cantFail(Reader.readArray(Subsections, Reader.bytesRemaining())); - return true; -} - -static bool isDebugTSection(SectionRef Section, CVTypeArray &Types) { - BinaryStreamReader Reader; - if (!isCodeViewDebugSubsection(Section, ".debug$T", Reader) && - !isCodeViewDebugSubsection(Section, ".debug$P", Reader)) - return false; - cantFail(Reader.readArray(Types, Reader.bytesRemaining())); - return true; -} - -static std::string formatChecksumKind(FileChecksumKind Kind) { - switch (Kind) { - RETURN_CASE(FileChecksumKind, None, "None"); - RETURN_CASE(FileChecksumKind, MD5, "MD5"); - RETURN_CASE(FileChecksumKind, SHA1, "SHA-1"); - RETURN_CASE(FileChecksumKind, SHA256, "SHA-256"); - } - return formatUnknownEnum(Kind); -} - -template <typename... Args> -static void formatInternal(LinePrinter &Printer, bool Append, Args &&... args) { - if (Append) - Printer.format(std::forward<Args>(args)...); - else - Printer.formatLine(std::forward<Args>(args)...); -} - -SymbolGroup::SymbolGroup(InputFile *File, uint32_t GroupIndex) : File(File) { - if (!File) - return; - - if (File->isPdb()) - initializeForPdb(GroupIndex); - else { - Name = ".debug$S"; - uint32_t I = 0; - for (const auto &S : File->obj().sections()) { - DebugSubsectionArray SS; - if (!isDebugSSection(S, SS)) - continue; - - if (!SC.hasChecksums() || !SC.hasStrings()) - SC.initialize(SS); - - if (I == GroupIndex) - Subsections = SS; - - if (SC.hasChecksums() && SC.hasStrings()) - break; - } - rebuildChecksumMap(); - } -} - -StringRef SymbolGroup::name() const { return Name; } - -void SymbolGroup::updateDebugS(const codeview::DebugSubsectionArray &SS) { - Subsections = SS; -} - -void SymbolGroup::updatePdbModi(uint32_t Modi) { initializeForPdb(Modi); } - -void SymbolGroup::initializeForPdb(uint32_t Modi) { - assert(File && File->isPdb()); - - // PDB always uses the same string table, but each module has its own - // checksums. So we only set the strings if they're not already set. - if (!SC.hasStrings()) { - auto StringTable = File->pdb().getStringTable(); - if (StringTable) - SC.setStrings(StringTable->getStringTable()); - else - consumeError(StringTable.takeError()); - } - - SC.resetChecksums(); - auto MDS = getModuleDebugStream(File->pdb(), Name, Modi); - if (!MDS) { - consumeError(MDS.takeError()); - return; - } - - DebugStream = std::make_shared<ModuleDebugStreamRef>(std::move(*MDS)); - Subsections = DebugStream->getSubsectionsArray(); - SC.initialize(Subsections); - rebuildChecksumMap(); -} - -void SymbolGroup::rebuildChecksumMap() { - if (!SC.hasChecksums()) - return; - - for (const auto &Entry : SC.checksums()) { - auto S = SC.strings().getString(Entry.FileNameOffset); - if (!S) - continue; - ChecksumsByFile[*S] = Entry; - } -} - -const ModuleDebugStreamRef &SymbolGroup::getPdbModuleStream() const { - assert(File && File->isPdb() && DebugStream); - return *DebugStream; -} - -Expected<StringRef> SymbolGroup::getNameFromStringTable(uint32_t Offset) const { - return SC.strings().getString(Offset); -} - -void SymbolGroup::formatFromFileName(LinePrinter &Printer, StringRef File, - bool Append) const { - auto FC = ChecksumsByFile.find(File); - if (FC == ChecksumsByFile.end()) { - formatInternal(Printer, Append, "- (no checksum) {0}", File); - return; - } - - formatInternal(Printer, Append, "- ({0}: {1}) {2}", - formatChecksumKind(FC->getValue().Kind), - toHex(FC->getValue().Checksum), File); -} - -void SymbolGroup::formatFromChecksumsOffset(LinePrinter &Printer, - uint32_t Offset, - bool Append) const { - if (!SC.hasChecksums()) { - formatInternal(Printer, Append, "(unknown file name offset {0})", Offset); - return; - } - - auto Iter = SC.checksums().getArray().at(Offset); - if (Iter == SC.checksums().getArray().end()) { - formatInternal(Printer, Append, "(unknown file name offset {0})", Offset); - return; - } - - uint32_t FO = Iter->FileNameOffset; - auto ExpectedFile = getNameFromStringTable(FO); - if (!ExpectedFile) { - formatInternal(Printer, Append, "(unknown file name offset {0})", Offset); - consumeError(ExpectedFile.takeError()); - return; - } - if (Iter->Kind == FileChecksumKind::None) { - formatInternal(Printer, Append, "{0} (no checksum)", *ExpectedFile); - } else { - formatInternal(Printer, Append, "{0} ({1}: {2})", *ExpectedFile, - formatChecksumKind(Iter->Kind), toHex(Iter->Checksum)); - } -} - -Expected<InputFile> InputFile::open(StringRef Path, bool AllowUnknownFile) { - InputFile IF; - if (!llvm::sys::fs::exists(Path)) - return make_error<StringError>(formatv("File {0} not found", Path), - inconvertibleErrorCode()); - - file_magic Magic; - if (auto EC = identify_magic(Path, Magic)) - return make_error<StringError>( - formatv("Unable to identify file type for file {0}", Path), EC); - - if (Magic == file_magic::coff_object) { - Expected<OwningBinary<Binary>> BinaryOrErr = createBinary(Path); - if (!BinaryOrErr) - return BinaryOrErr.takeError(); - - IF.CoffObject = std::move(*BinaryOrErr); - IF.PdbOrObj = llvm::cast<COFFObjectFile>(IF.CoffObject.getBinary()); - return std::move(IF); - } - - if (Magic == file_magic::pdb) { - std::unique_ptr<IPDBSession> Session; - if (auto Err = loadDataForPDB(PDB_ReaderType::Native, Path, Session)) - return std::move(Err); - - IF.PdbSession.reset(static_cast<NativeSession *>(Session.release())); - IF.PdbOrObj = &IF.PdbSession->getPDBFile(); - - return std::move(IF); - } - - if (!AllowUnknownFile) - return make_error<StringError>( - formatv("File {0} is not a supported file type", Path), - inconvertibleErrorCode()); - - auto Result = MemoryBuffer::getFile(Path, /*IsText=*/false, - /*RequiresNullTerminator=*/false); - if (!Result) - return make_error<StringError>( - formatv("File {0} could not be opened", Path), Result.getError()); - - IF.UnknownFile = std::move(*Result); - IF.PdbOrObj = IF.UnknownFile.get(); - return std::move(IF); -} - -PDBFile &InputFile::pdb() { - assert(isPdb()); - return *PdbOrObj.get<PDBFile *>(); -} - -const PDBFile &InputFile::pdb() const { - assert(isPdb()); - return *PdbOrObj.get<PDBFile *>(); -} - -object::COFFObjectFile &InputFile::obj() { - assert(isObj()); - return *PdbOrObj.get<object::COFFObjectFile *>(); -} - -const object::COFFObjectFile &InputFile::obj() const { - assert(isObj()); - return *PdbOrObj.get<object::COFFObjectFile *>(); -} - -MemoryBuffer &InputFile::unknown() { - assert(isUnknown()); - return *PdbOrObj.get<MemoryBuffer *>(); -} - -const MemoryBuffer &InputFile::unknown() const { - assert(isUnknown()); - return *PdbOrObj.get<MemoryBuffer *>(); -} - -StringRef InputFile::getFilePath() const { - if (isPdb()) - return pdb().getFilePath(); - if (isObj()) - return obj().getFileName(); - assert(isUnknown()); - return unknown().getBufferIdentifier(); -} - -bool InputFile::hasTypes() const { - if (isPdb()) - return pdb().hasPDBTpiStream(); - - for (const auto &Section : obj().sections()) { - CVTypeArray Types; - if (isDebugTSection(Section, Types)) - return true; - } - return false; -} - -bool InputFile::hasIds() const { - if (isObj()) - return false; - return pdb().hasPDBIpiStream(); -} - -bool InputFile::isPdb() const { return PdbOrObj.is<PDBFile *>(); } - -bool InputFile::isObj() const { - return PdbOrObj.is<object::COFFObjectFile *>(); -} - -bool InputFile::isUnknown() const { return PdbOrObj.is<MemoryBuffer *>(); } - -codeview::LazyRandomTypeCollection & -InputFile::getOrCreateTypeCollection(TypeCollectionKind Kind) { - if (Types && Kind == kTypes) - return *Types; - if (Ids && Kind == kIds) - return *Ids; - - if (Kind == kIds) { - assert(isPdb() && pdb().hasPDBIpiStream()); - } - - // If the collection was already initialized, we should have just returned it - // in step 1. - if (isPdb()) { - TypeCollectionPtr &Collection = (Kind == kIds) ? Ids : Types; - auto &Stream = cantFail((Kind == kIds) ? pdb().getPDBIpiStream() - : pdb().getPDBTpiStream()); - - auto &Array = Stream.typeArray(); - uint32_t Count = Stream.getNumTypeRecords(); - auto Offsets = Stream.getTypeIndexOffsets(); - Collection = - std::make_unique<LazyRandomTypeCollection>(Array, Count, Offsets); - return *Collection; - } - - assert(isObj()); - assert(Kind == kTypes); - assert(!Types); - - for (const auto &Section : obj().sections()) { - CVTypeArray Records; - if (!isDebugTSection(Section, Records)) - continue; - - Types = std::make_unique<LazyRandomTypeCollection>(Records, 100); - return *Types; - } - - Types = std::make_unique<LazyRandomTypeCollection>(100); - return *Types; -} - -codeview::LazyRandomTypeCollection &InputFile::types() { - return getOrCreateTypeCollection(kTypes); -} - -codeview::LazyRandomTypeCollection &InputFile::ids() { - // Object files have only one type stream that contains both types and ids. - // Similarly, some PDBs don't contain an IPI stream, and for those both types - // and IDs are in the same stream. - if (isObj() || !pdb().hasPDBIpiStream()) - return types(); - - return getOrCreateTypeCollection(kIds); -} - -iterator_range<SymbolGroupIterator> InputFile::symbol_groups() { - return make_range<SymbolGroupIterator>(symbol_groups_begin(), - symbol_groups_end()); -} - -SymbolGroupIterator InputFile::symbol_groups_begin() { - return SymbolGroupIterator(*this); -} - -SymbolGroupIterator InputFile::symbol_groups_end() { - return SymbolGroupIterator(); -} - -SymbolGroupIterator::SymbolGroupIterator() : Value(nullptr) {} - -SymbolGroupIterator::SymbolGroupIterator(InputFile &File) : Value(&File) { - if (File.isObj()) { - SectionIter = File.obj().section_begin(); - scanToNextDebugS(); - } -} - -bool SymbolGroupIterator::operator==(const SymbolGroupIterator &R) const { - bool E = isEnd(); - bool RE = R.isEnd(); - if (E || RE) - return E == RE; - - if (Value.File != R.Value.File) - return false; - return Index == R.Index; -} - -const SymbolGroup &SymbolGroupIterator::operator*() const { - assert(!isEnd()); - return Value; -} -SymbolGroup &SymbolGroupIterator::operator*() { - assert(!isEnd()); - return Value; -} - -SymbolGroupIterator &SymbolGroupIterator::operator++() { - assert(Value.File && !isEnd()); - ++Index; - if (isEnd()) - return *this; - - if (Value.File->isPdb()) { - Value.updatePdbModi(Index); - return *this; - } - - scanToNextDebugS(); - return *this; -} - -void SymbolGroupIterator::scanToNextDebugS() { - assert(SectionIter.hasValue()); - auto End = Value.File->obj().section_end(); - auto &Iter = *SectionIter; - assert(!isEnd()); - - while (++Iter != End) { - DebugSubsectionArray SS; - SectionRef SR = *Iter; - if (!isDebugSSection(SR, SS)) - continue; - - Value.updateDebugS(SS); - return; - } -} - -bool SymbolGroupIterator::isEnd() const { - if (!Value.File) - return true; - if (Value.File->isPdb()) { - auto &Dbi = cantFail(Value.File->pdb().getPDBDbiStream()); - uint32_t Count = Dbi.modules().getModuleCount(); - assert(Index <= Count); - return Index == Count; - } - - assert(SectionIter.hasValue()); - return *SectionIter == Value.File->obj().section_end(); -} diff --git a/llvm/tools/llvm-pdbutil/InputFile.h b/llvm/tools/llvm-pdbutil/InputFile.h deleted file mode 100644 index 633ab34a54d4..000000000000 --- a/llvm/tools/llvm-pdbutil/InputFile.h +++ /dev/null @@ -1,154 +0,0 @@ -//===- InputFile.h -------------------------------------------- *- C++ --*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_TOOLS_LLVMPDBDUMP_INPUTFILE_H -#define LLVM_TOOLS_LLVMPDBDUMP_INPUTFILE_H - -#include "llvm/ADT/Optional.h" -#include "llvm/ADT/PointerUnion.h" -#include "llvm/ADT/StringMap.h" -#include "llvm/ADT/iterator.h" -#include "llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h" -#include "llvm/DebugInfo/CodeView/StringsAndChecksums.h" -#include "llvm/DebugInfo/PDB/Native/ModuleDebugStream.h" -#include "llvm/Object/Binary.h" -#include "llvm/Object/ObjectFile.h" -#include "llvm/Support/Error.h" - -namespace llvm { -namespace codeview { -class LazyRandomTypeCollection; -} -namespace object { -class COFFObjectFile; -} // namespace object - -namespace pdb { -class InputFile; -class LinePrinter; -class PDBFile; -class NativeSession; -class SymbolGroupIterator; -class SymbolGroup; - -class InputFile { - InputFile(); - - std::unique_ptr<NativeSession> PdbSession; - object::OwningBinary<object::Binary> CoffObject; - std::unique_ptr<MemoryBuffer> UnknownFile; - PointerUnion<PDBFile *, object::COFFObjectFile *, MemoryBuffer *> PdbOrObj; - - using TypeCollectionPtr = std::unique_ptr<codeview::LazyRandomTypeCollection>; - - TypeCollectionPtr Types; - TypeCollectionPtr Ids; - - enum TypeCollectionKind { kTypes, kIds }; - codeview::LazyRandomTypeCollection & - getOrCreateTypeCollection(TypeCollectionKind Kind); - -public: - ~InputFile(); - InputFile(InputFile &&Other) = default; - - static Expected<InputFile> open(StringRef Path, - bool AllowUnknownFile = false); - - PDBFile &pdb(); - const PDBFile &pdb() const; - object::COFFObjectFile &obj(); - const object::COFFObjectFile &obj() const; - MemoryBuffer &unknown(); - const MemoryBuffer &unknown() const; - - StringRef getFilePath() const; - - bool hasTypes() const; - bool hasIds() const; - - codeview::LazyRandomTypeCollection &types(); - codeview::LazyRandomTypeCollection &ids(); - - iterator_range<SymbolGroupIterator> symbol_groups(); - SymbolGroupIterator symbol_groups_begin(); - SymbolGroupIterator symbol_groups_end(); - - bool isPdb() const; - bool isObj() const; - bool isUnknown() const; -}; - -class SymbolGroup { - friend class SymbolGroupIterator; - -public: - explicit SymbolGroup(InputFile *File, uint32_t GroupIndex = 0); - - Expected<StringRef> getNameFromStringTable(uint32_t Offset) const; - - void formatFromFileName(LinePrinter &Printer, StringRef File, - bool Append = false) const; - - void formatFromChecksumsOffset(LinePrinter &Printer, uint32_t Offset, - bool Append = false) const; - - StringRef name() const; - - codeview::DebugSubsectionArray getDebugSubsections() const { - return Subsections; - } - const ModuleDebugStreamRef &getPdbModuleStream() const; - - const InputFile &getFile() const { return *File; } - InputFile &getFile() { return *File; } - - bool hasDebugStream() const { return DebugStream != nullptr; } - -private: - void initializeForPdb(uint32_t Modi); - void updatePdbModi(uint32_t Modi); - void updateDebugS(const codeview::DebugSubsectionArray &SS); - - void rebuildChecksumMap(); - InputFile *File = nullptr; - StringRef Name; - codeview::DebugSubsectionArray Subsections; - std::shared_ptr<ModuleDebugStreamRef> DebugStream; - codeview::StringsAndChecksumsRef SC; - StringMap<codeview::FileChecksumEntry> ChecksumsByFile; -}; - -class SymbolGroupIterator - : public iterator_facade_base<SymbolGroupIterator, - std::forward_iterator_tag, SymbolGroup> { -public: - SymbolGroupIterator(); - explicit SymbolGroupIterator(InputFile &File); - SymbolGroupIterator(const SymbolGroupIterator &Other) = default; - SymbolGroupIterator &operator=(const SymbolGroupIterator &R) = default; - - const SymbolGroup &operator*() const; - SymbolGroup &operator*(); - - bool operator==(const SymbolGroupIterator &R) const; - SymbolGroupIterator &operator++(); - -private: - void scanToNextDebugS(); - bool isEnd() const; - - uint32_t Index = 0; - Optional<object::section_iterator> SectionIter; - SymbolGroup Value; -}; - -} // namespace pdb -} // namespace llvm - -#endif diff --git a/llvm/tools/llvm-pdbutil/LinePrinter.cpp b/llvm/tools/llvm-pdbutil/LinePrinter.cpp deleted file mode 100644 index dd6ca5bf41b1..000000000000 --- a/llvm/tools/llvm-pdbutil/LinePrinter.cpp +++ /dev/null @@ -1,335 +0,0 @@ -//===- LinePrinter.cpp ------------------------------------------*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#include "LinePrinter.h" - -#include "llvm-pdbutil.h" - -#include "llvm/ADT/STLExtras.h" -#include "llvm/DebugInfo/MSF/MSFCommon.h" -#include "llvm/DebugInfo/MSF/MappedBlockStream.h" -#include "llvm/DebugInfo/PDB/Native/PDBFile.h" -#include "llvm/DebugInfo/PDB/UDTLayout.h" -#include "llvm/Support/BinaryStreamReader.h" -#include "llvm/Support/Format.h" -#include "llvm/Support/FormatAdapters.h" -#include "llvm/Support/FormatVariadic.h" -#include "llvm/Support/Regex.h" - -#include <algorithm> - -using namespace llvm; -using namespace llvm::msf; -using namespace llvm::pdb; - -namespace { -bool IsItemExcluded(llvm::StringRef Item, - std::list<llvm::Regex> &IncludeFilters, - std::list<llvm::Regex> &ExcludeFilters) { - if (Item.empty()) - return false; - - auto match_pred = [Item](llvm::Regex &R) { return R.match(Item); }; - - // Include takes priority over exclude. If the user specified include - // filters, and none of them include this item, them item is gone. - if (!IncludeFilters.empty() && !any_of(IncludeFilters, match_pred)) - return true; - - if (any_of(ExcludeFilters, match_pred)) - return true; - - return false; -} -} - -using namespace llvm; - -LinePrinter::LinePrinter(int Indent, bool UseColor, llvm::raw_ostream &Stream) - : OS(Stream), IndentSpaces(Indent), CurrentIndent(0), UseColor(UseColor) { - SetFilters(ExcludeTypeFilters, opts::pretty::ExcludeTypes.begin(), - opts::pretty::ExcludeTypes.end()); - SetFilters(ExcludeSymbolFilters, opts::pretty::ExcludeSymbols.begin(), - opts::pretty::ExcludeSymbols.end()); - SetFilters(ExcludeCompilandFilters, opts::pretty::ExcludeCompilands.begin(), - opts::pretty::ExcludeCompilands.end()); - - SetFilters(IncludeTypeFilters, opts::pretty::IncludeTypes.begin(), - opts::pretty::IncludeTypes.end()); - SetFilters(IncludeSymbolFilters, opts::pretty::IncludeSymbols.begin(), - opts::pretty::IncludeSymbols.end()); - SetFilters(IncludeCompilandFilters, opts::pretty::IncludeCompilands.begin(), - opts::pretty::IncludeCompilands.end()); -} - -void LinePrinter::Indent(uint32_t Amount) { - if (Amount == 0) - Amount = IndentSpaces; - CurrentIndent += Amount; -} - -void LinePrinter::Unindent(uint32_t Amount) { - if (Amount == 0) - Amount = IndentSpaces; - CurrentIndent = std::max<int>(0, CurrentIndent - Amount); -} - -void LinePrinter::NewLine() { - OS << "\n"; - OS.indent(CurrentIndent); -} - -void LinePrinter::print(const Twine &T) { OS << T; } - -void LinePrinter::printLine(const Twine &T) { - NewLine(); - OS << T; -} - -bool LinePrinter::IsClassExcluded(const ClassLayout &Class) { - if (IsTypeExcluded(Class.getName(), Class.getSize())) - return true; - if (Class.deepPaddingSize() < opts::pretty::PaddingThreshold) - return true; - return false; -} - -void LinePrinter::formatBinary(StringRef Label, ArrayRef<uint8_t> Data, - uint64_t StartOffset) { - NewLine(); - OS << Label << " ("; - if (!Data.empty()) { - OS << "\n"; - OS << format_bytes_with_ascii(Data, StartOffset, 32, 4, - CurrentIndent + IndentSpaces, true); - NewLine(); - } - OS << ")"; -} - -void LinePrinter::formatBinary(StringRef Label, ArrayRef<uint8_t> Data, - uint64_t Base, uint64_t StartOffset) { - NewLine(); - OS << Label << " ("; - if (!Data.empty()) { - OS << "\n"; - Base += StartOffset; - OS << format_bytes_with_ascii(Data, Base, 32, 4, - CurrentIndent + IndentSpaces, true); - NewLine(); - } - OS << ")"; -} - -namespace { -struct Run { - Run() = default; - explicit Run(uint32_t Block) : Block(Block) {} - uint32_t Block = 0; - uint64_t ByteLen = 0; -}; -} // namespace - -static std::vector<Run> computeBlockRuns(uint32_t BlockSize, - const msf::MSFStreamLayout &Layout) { - std::vector<Run> Runs; - if (Layout.Length == 0) - return Runs; - - ArrayRef<support::ulittle32_t> Blocks = Layout.Blocks; - assert(!Blocks.empty()); - uint64_t StreamBytesRemaining = Layout.Length; - uint32_t CurrentBlock = Blocks[0]; - Runs.emplace_back(CurrentBlock); - while (!Blocks.empty()) { - Run *CurrentRun = &Runs.back(); - uint32_t NextBlock = Blocks.front(); - if (NextBlock < CurrentBlock || (NextBlock - CurrentBlock > 1)) { - Runs.emplace_back(NextBlock); - CurrentRun = &Runs.back(); - } - uint64_t Used = - std::min(static_cast<uint64_t>(BlockSize), StreamBytesRemaining); - CurrentRun->ByteLen += Used; - StreamBytesRemaining -= Used; - CurrentBlock = NextBlock; - Blocks = Blocks.drop_front(); - } - return Runs; -} - -static std::pair<Run, uint64_t> findRun(uint64_t Offset, ArrayRef<Run> Runs) { - for (const auto &R : Runs) { - if (Offset < R.ByteLen) - return std::make_pair(R, Offset); - Offset -= R.ByteLen; - } - llvm_unreachable("Invalid offset!"); -} - -void LinePrinter::formatMsfStreamData(StringRef Label, PDBFile &File, - uint32_t StreamIdx, - StringRef StreamPurpose, uint64_t Offset, - uint64_t Size) { - if (StreamIdx >= File.getNumStreams()) { - formatLine("Stream {0}: Not present", StreamIdx); - return; - } - if (Size + Offset > File.getStreamByteSize(StreamIdx)) { - formatLine( - "Stream {0}: Invalid offset and size, range out of stream bounds", - StreamIdx); - return; - } - - auto S = File.createIndexedStream(StreamIdx); - if (!S) { - NewLine(); - formatLine("Stream {0}: Not present", StreamIdx); - return; - } - - uint64_t End = - (Size == 0) ? S->getLength() : std::min(Offset + Size, S->getLength()); - Size = End - Offset; - - formatLine("Stream {0}: {1} (dumping {2:N} / {3:N} bytes)", StreamIdx, - StreamPurpose, Size, S->getLength()); - AutoIndent Indent(*this); - BinaryStreamRef Slice(*S); - BinarySubstreamRef Substream; - Substream.Offset = Offset; - Substream.StreamData = Slice.drop_front(Offset).keep_front(Size); - - auto Layout = File.getStreamLayout(StreamIdx); - formatMsfStreamData(Label, File, Layout, Substream); -} - -void LinePrinter::formatMsfStreamData(StringRef Label, PDBFile &File, - const msf::MSFStreamLayout &Stream, - BinarySubstreamRef Substream) { - BinaryStreamReader Reader(Substream.StreamData); - - auto Runs = computeBlockRuns(File.getBlockSize(), Stream); - - NewLine(); - OS << Label << " ("; - while (Reader.bytesRemaining() > 0) { - OS << "\n"; - - Run FoundRun; - uint64_t RunOffset; - std::tie(FoundRun, RunOffset) = findRun(Substream.Offset, Runs); - assert(FoundRun.ByteLen >= RunOffset); - uint64_t Len = FoundRun.ByteLen - RunOffset; - Len = std::min(Len, Reader.bytesRemaining()); - uint64_t Base = FoundRun.Block * File.getBlockSize() + RunOffset; - ArrayRef<uint8_t> Data; - consumeError(Reader.readBytes(Data, Len)); - OS << format_bytes_with_ascii(Data, Base, 32, 4, - CurrentIndent + IndentSpaces, true); - if (Reader.bytesRemaining() > 0) { - NewLine(); - OS << formatv(" {0}", - fmt_align("<discontinuity>", AlignStyle::Center, 114, '-')); - } - Substream.Offset += Len; - } - NewLine(); - OS << ")"; -} - -void LinePrinter::formatMsfStreamBlocks( - PDBFile &File, const msf::MSFStreamLayout &StreamLayout) { - auto Blocks = makeArrayRef(StreamLayout.Blocks); - uint64_t L = StreamLayout.Length; - - while (L > 0) { - NewLine(); - assert(!Blocks.empty()); - OS << formatv("Block {0} (\n", uint32_t(Blocks.front())); - uint64_t UsedBytes = - std::min(L, static_cast<uint64_t>(File.getBlockSize())); - ArrayRef<uint8_t> BlockData = - cantFail(File.getBlockData(Blocks.front(), File.getBlockSize())); - uint64_t BaseOffset = Blocks.front(); - BaseOffset *= File.getBlockSize(); - OS << format_bytes_with_ascii(BlockData, BaseOffset, 32, 4, - CurrentIndent + IndentSpaces, true); - NewLine(); - OS << ")"; - NewLine(); - L -= UsedBytes; - Blocks = Blocks.drop_front(); - } -} - -bool LinePrinter::IsTypeExcluded(llvm::StringRef TypeName, uint64_t Size) { - if (IsItemExcluded(TypeName, IncludeTypeFilters, ExcludeTypeFilters)) - return true; - if (Size < opts::pretty::SizeThreshold) - return true; - return false; -} - -bool LinePrinter::IsSymbolExcluded(llvm::StringRef SymbolName) { - return IsItemExcluded(SymbolName, IncludeSymbolFilters, ExcludeSymbolFilters); -} - -bool LinePrinter::IsCompilandExcluded(llvm::StringRef CompilandName) { - return IsItemExcluded(CompilandName, IncludeCompilandFilters, - ExcludeCompilandFilters); -} - -WithColor::WithColor(LinePrinter &P, PDB_ColorItem C) - : OS(P.OS), UseColor(P.hasColor()) { - if (UseColor) - applyColor(C); -} - -WithColor::~WithColor() { - if (UseColor) - OS.resetColor(); -} - -void WithColor::applyColor(PDB_ColorItem C) { - switch (C) { - case PDB_ColorItem::None: - OS.resetColor(); - return; - case PDB_ColorItem::Comment: - OS.changeColor(raw_ostream::GREEN, false); - return; - case PDB_ColorItem::Address: - OS.changeColor(raw_ostream::YELLOW, /*bold=*/true); - return; - case PDB_ColorItem::Keyword: - OS.changeColor(raw_ostream::MAGENTA, true); - return; - case PDB_ColorItem::Register: - case PDB_ColorItem::Offset: - OS.changeColor(raw_ostream::YELLOW, false); - return; - case PDB_ColorItem::Type: - OS.changeColor(raw_ostream::CYAN, true); - return; - case PDB_ColorItem::Identifier: - OS.changeColor(raw_ostream::CYAN, false); - return; - case PDB_ColorItem::Path: - OS.changeColor(raw_ostream::CYAN, false); - return; - case PDB_ColorItem::Padding: - case PDB_ColorItem::SectionHeader: - OS.changeColor(raw_ostream::RED, true); - return; - case PDB_ColorItem::LiteralValue: - OS.changeColor(raw_ostream::GREEN, true); - return; - } -} diff --git a/llvm/tools/llvm-pdbutil/LinePrinter.h b/llvm/tools/llvm-pdbutil/LinePrinter.h deleted file mode 100644 index b6bb77280fd5..000000000000 --- a/llvm/tools/llvm-pdbutil/LinePrinter.h +++ /dev/null @@ -1,167 +0,0 @@ -//===- LinePrinter.h ------------------------------------------ *- C++ --*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_TOOLS_LLVMPDBDUMP_LINEPRINTER_H -#define LLVM_TOOLS_LLVMPDBDUMP_LINEPRINTER_H - -#include "llvm/ADT/ArrayRef.h" -#include "llvm/ADT/StringRef.h" -#include "llvm/ADT/Twine.h" -#include "llvm/Support/BinaryStreamRef.h" -#include "llvm/Support/FormatVariadic.h" -#include "llvm/Support/Regex.h" -#include "llvm/Support/raw_ostream.h" - -#include <list> - -namespace llvm { -namespace msf { -class MSFStreamLayout; -} // namespace msf -namespace pdb { - -class ClassLayout; -class PDBFile; - -class LinePrinter { - friend class WithColor; - -public: - LinePrinter(int Indent, bool UseColor, raw_ostream &Stream); - - void Indent(uint32_t Amount = 0); - void Unindent(uint32_t Amount = 0); - void NewLine(); - - void printLine(const Twine &T); - void print(const Twine &T); - template <typename... Ts> void formatLine(const char *Fmt, Ts &&... Items) { - printLine(formatv(Fmt, std::forward<Ts>(Items)...)); - } - template <typename... Ts> void format(const char *Fmt, Ts &&... Items) { - print(formatv(Fmt, std::forward<Ts>(Items)...)); - } - - void formatBinary(StringRef Label, ArrayRef<uint8_t> Data, - uint64_t StartOffset); - void formatBinary(StringRef Label, ArrayRef<uint8_t> Data, uint64_t BaseAddr, - uint64_t StartOffset); - - void formatMsfStreamData(StringRef Label, PDBFile &File, uint32_t StreamIdx, - StringRef StreamPurpose, uint64_t Offset, - uint64_t Size); - void formatMsfStreamData(StringRef Label, PDBFile &File, - const msf::MSFStreamLayout &Stream, - BinarySubstreamRef Substream); - void formatMsfStreamBlocks(PDBFile &File, const msf::MSFStreamLayout &Stream); - - bool hasColor() const { return UseColor; } - raw_ostream &getStream() { return OS; } - int getIndentLevel() const { return CurrentIndent; } - - bool IsClassExcluded(const ClassLayout &Class); - bool IsTypeExcluded(llvm::StringRef TypeName, uint64_t Size); - bool IsSymbolExcluded(llvm::StringRef SymbolName); - bool IsCompilandExcluded(llvm::StringRef CompilandName); - -private: - template <typename Iter> - void SetFilters(std::list<Regex> &List, Iter Begin, Iter End) { - List.clear(); - for (; Begin != End; ++Begin) - List.emplace_back(StringRef(*Begin)); - } - - raw_ostream &OS; - int IndentSpaces; - int CurrentIndent; - bool UseColor; - - std::list<Regex> ExcludeCompilandFilters; - std::list<Regex> ExcludeTypeFilters; - std::list<Regex> ExcludeSymbolFilters; - - std::list<Regex> IncludeCompilandFilters; - std::list<Regex> IncludeTypeFilters; - std::list<Regex> IncludeSymbolFilters; -}; - -struct PrintScope { - explicit PrintScope(LinePrinter &P, uint32_t IndentLevel) - : P(P), IndentLevel(IndentLevel) {} - explicit PrintScope(const PrintScope &Other, uint32_t LabelWidth) - : P(Other.P), IndentLevel(Other.IndentLevel), LabelWidth(LabelWidth) {} - - LinePrinter &P; - uint32_t IndentLevel; - uint32_t LabelWidth = 0; -}; - -inline Optional<PrintScope> withLabelWidth(const Optional<PrintScope> &Scope, - uint32_t W) { - if (!Scope) - return None; - return PrintScope{*Scope, W}; -} - -struct AutoIndent { - explicit AutoIndent(LinePrinter &L, uint32_t Amount = 0) - : L(&L), Amount(Amount) { - L.Indent(Amount); - } - explicit AutoIndent(const Optional<PrintScope> &Scope) { - if (Scope.hasValue()) { - L = &Scope->P; - Amount = Scope->IndentLevel; - } - } - ~AutoIndent() { - if (L) - L->Unindent(Amount); - } - - LinePrinter *L = nullptr; - uint32_t Amount = 0; -}; - -template <class T> -inline raw_ostream &operator<<(LinePrinter &Printer, const T &Item) { - return Printer.getStream() << Item; -} - -enum class PDB_ColorItem { - None, - Address, - Type, - Comment, - Padding, - Keyword, - Offset, - Identifier, - Path, - SectionHeader, - LiteralValue, - Register, -}; - -class WithColor { -public: - WithColor(LinePrinter &P, PDB_ColorItem C); - ~WithColor(); - - raw_ostream &get() { return OS; } - -private: - void applyColor(PDB_ColorItem C); - raw_ostream &OS; - bool UseColor; -}; -} -} - -#endif diff --git a/llvm/tools/llvm-pdbutil/MinimalSymbolDumper.cpp b/llvm/tools/llvm-pdbutil/MinimalSymbolDumper.cpp index e6b5d21f36e5..8e17284871a9 100644 --- a/llvm/tools/llvm-pdbutil/MinimalSymbolDumper.cpp +++ b/llvm/tools/llvm-pdbutil/MinimalSymbolDumper.cpp @@ -8,17 +8,19 @@ #include "MinimalSymbolDumper.h" -#include "FormatUtil.h" -#include "InputFile.h" -#include "LinePrinter.h" - #include "llvm/DebugInfo/CodeView/CVRecord.h" #include "llvm/DebugInfo/CodeView/CodeView.h" #include "llvm/DebugInfo/CodeView/Formatters.h" #include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h" #include "llvm/DebugInfo/CodeView/SymbolRecord.h" #include "llvm/DebugInfo/CodeView/TypeRecord.h" +#include "llvm/DebugInfo/PDB/Native/FormatUtil.h" +#include "llvm/DebugInfo/PDB/Native/InputFile.h" +#include "llvm/DebugInfo/PDB/Native/LinePrinter.h" +#include "llvm/DebugInfo/PDB/Native/NativeSession.h" +#include "llvm/DebugInfo/PDB/Native/PDBFile.h" #include "llvm/DebugInfo/PDB/Native/PDBStringTable.h" +#include "llvm/Object/COFF.h" #include "llvm/Support/FormatVariadic.h" using namespace llvm; diff --git a/llvm/tools/llvm-pdbutil/MinimalTypeDumper.cpp b/llvm/tools/llvm-pdbutil/MinimalTypeDumper.cpp index 08006e9c62d4..be7e487673fb 100644 --- a/llvm/tools/llvm-pdbutil/MinimalTypeDumper.cpp +++ b/llvm/tools/llvm-pdbutil/MinimalTypeDumper.cpp @@ -8,8 +8,6 @@ #include "MinimalTypeDumper.h" -#include "FormatUtil.h" -#include "LinePrinter.h" #include "TypeReferenceTracker.h" #include "llvm-pdbutil.h" @@ -19,8 +17,13 @@ #include "llvm/DebugInfo/CodeView/Formatters.h" #include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h" #include "llvm/DebugInfo/CodeView/TypeRecord.h" +#include "llvm/DebugInfo/PDB/Native/FormatUtil.h" +#include "llvm/DebugInfo/PDB/Native/LinePrinter.h" +#include "llvm/DebugInfo/PDB/Native/NativeSession.h" +#include "llvm/DebugInfo/PDB/Native/PDBFile.h" #include "llvm/DebugInfo/PDB/Native/TpiHashing.h" #include "llvm/DebugInfo/PDB/Native/TpiStream.h" +#include "llvm/Object/COFF.h" #include "llvm/Support/FormatVariadic.h" #include "llvm/Support/MathExtras.h" diff --git a/llvm/tools/llvm-pdbutil/OutputStyle.h b/llvm/tools/llvm-pdbutil/OutputStyle.h index da93c32053f3..8cc9016d79a2 100644 --- a/llvm/tools/llvm-pdbutil/OutputStyle.h +++ b/llvm/tools/llvm-pdbutil/OutputStyle.h @@ -9,9 +9,10 @@ #ifndef LLVM_TOOLS_LLVMPDBDUMP_OUTPUTSTYLE_H #define LLVM_TOOLS_LLVMPDBDUMP_OUTPUTSTYLE_H -#include "llvm/Support/Error.h" - namespace llvm { + +class Error; + namespace pdb { class OutputStyle { diff --git a/llvm/tools/llvm-pdbutil/PrettyBuiltinDumper.cpp b/llvm/tools/llvm-pdbutil/PrettyBuiltinDumper.cpp index cd01a4004819..895066146a9d 100644 --- a/llvm/tools/llvm-pdbutil/PrettyBuiltinDumper.cpp +++ b/llvm/tools/llvm-pdbutil/PrettyBuiltinDumper.cpp @@ -7,8 +7,8 @@ //===----------------------------------------------------------------------===// #include "PrettyBuiltinDumper.h" -#include "LinePrinter.h" +#include "llvm/DebugInfo/PDB/Native/LinePrinter.h" #include "llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h" using namespace llvm; @@ -90,6 +90,8 @@ StringRef BuiltinDumper::getTypeName(const PDBSymbolTypeBuiltin &Symbol) { return "char16_t"; case PDB_BuiltinType::Char32: return "char32_t"; + case PDB_BuiltinType::Char8: + return "char8_t"; case PDB_BuiltinType::None: return "..."; } diff --git a/llvm/tools/llvm-pdbutil/PrettyClassDefinitionDumper.cpp b/llvm/tools/llvm-pdbutil/PrettyClassDefinitionDumper.cpp index b7eccac5988c..2285ed16d2a5 100644 --- a/llvm/tools/llvm-pdbutil/PrettyClassDefinitionDumper.cpp +++ b/llvm/tools/llvm-pdbutil/PrettyClassDefinitionDumper.cpp @@ -8,13 +8,14 @@ #include "PrettyClassDefinitionDumper.h" -#include "LinePrinter.h" #include "PrettyClassLayoutGraphicalDumper.h" #include "llvm-pdbutil.h" #include "llvm/ADT/APFloat.h" #include "llvm/ADT/SmallString.h" +#include "llvm/DebugInfo/PDB/IPDBLineNumber.h" #include "llvm/DebugInfo/PDB/PDBSymbolTypeBaseClass.h" +#include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h" #include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h" #include "llvm/DebugInfo/PDB/UDTLayout.h" diff --git a/llvm/tools/llvm-pdbutil/PrettyClassLayoutGraphicalDumper.cpp b/llvm/tools/llvm-pdbutil/PrettyClassLayoutGraphicalDumper.cpp index a522935e34f1..1ade7f397030 100644 --- a/llvm/tools/llvm-pdbutil/PrettyClassLayoutGraphicalDumper.cpp +++ b/llvm/tools/llvm-pdbutil/PrettyClassLayoutGraphicalDumper.cpp @@ -8,7 +8,6 @@ #include "PrettyClassLayoutGraphicalDumper.h" -#include "LinePrinter.h" #include "PrettyClassDefinitionDumper.h" #include "PrettyEnumDumper.h" #include "PrettyFunctionDumper.h" @@ -17,8 +16,10 @@ #include "PrettyVariableDumper.h" #include "llvm-pdbutil.h" +#include "llvm/DebugInfo/PDB/IPDBLineNumber.h" #include "llvm/DebugInfo/PDB/PDBSymbolData.h" #include "llvm/DebugInfo/PDB/PDBSymbolTypeBaseClass.h" +#include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h" #include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h" #include "llvm/DebugInfo/PDB/UDTLayout.h" #include "llvm/Support/Format.h" diff --git a/llvm/tools/llvm-pdbutil/PrettyCompilandDumper.cpp b/llvm/tools/llvm-pdbutil/PrettyCompilandDumper.cpp index cf769ff66472..591bd4f93702 100644 --- a/llvm/tools/llvm-pdbutil/PrettyCompilandDumper.cpp +++ b/llvm/tools/llvm-pdbutil/PrettyCompilandDumper.cpp @@ -8,7 +8,6 @@ #include "PrettyCompilandDumper.h" -#include "LinePrinter.h" #include "PrettyFunctionDumper.h" #include "llvm-pdbutil.h" diff --git a/llvm/tools/llvm-pdbutil/PrettyEnumDumper.cpp b/llvm/tools/llvm-pdbutil/PrettyEnumDumper.cpp index 9ed5893f252e..64557ff09c72 100644 --- a/llvm/tools/llvm-pdbutil/PrettyEnumDumper.cpp +++ b/llvm/tools/llvm-pdbutil/PrettyEnumDumper.cpp @@ -8,10 +8,11 @@ #include "PrettyEnumDumper.h" -#include "LinePrinter.h" #include "PrettyBuiltinDumper.h" #include "llvm-pdbutil.h" +#include "llvm/DebugInfo/PDB/ConcreteSymbolEnumerator.h" +#include "llvm/DebugInfo/PDB/IPDBLineNumber.h" #include "llvm/DebugInfo/PDB/PDBSymbolData.h" #include "llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h" #include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h" diff --git a/llvm/tools/llvm-pdbutil/PrettyExternalSymbolDumper.cpp b/llvm/tools/llvm-pdbutil/PrettyExternalSymbolDumper.cpp index fede031ec0c0..34436c572c8a 100644 --- a/llvm/tools/llvm-pdbutil/PrettyExternalSymbolDumper.cpp +++ b/llvm/tools/llvm-pdbutil/PrettyExternalSymbolDumper.cpp @@ -7,8 +7,9 @@ //===----------------------------------------------------------------------===// #include "PrettyExternalSymbolDumper.h" -#include "LinePrinter.h" +#include "llvm/DebugInfo/PDB/ConcreteSymbolEnumerator.h" +#include "llvm/DebugInfo/PDB/Native/LinePrinter.h" #include "llvm/DebugInfo/PDB/PDBSymbolExe.h" #include "llvm/DebugInfo/PDB/PDBSymbolPublicSymbol.h" #include "llvm/Support/Format.h" diff --git a/llvm/tools/llvm-pdbutil/PrettyFunctionDumper.cpp b/llvm/tools/llvm-pdbutil/PrettyFunctionDumper.cpp index b820ca333965..83cf4d918322 100644 --- a/llvm/tools/llvm-pdbutil/PrettyFunctionDumper.cpp +++ b/llvm/tools/llvm-pdbutil/PrettyFunctionDumper.cpp @@ -7,16 +7,19 @@ //===----------------------------------------------------------------------===// #include "PrettyFunctionDumper.h" -#include "LinePrinter.h" #include "PrettyBuiltinDumper.h" +#include "llvm/DebugInfo/PDB/ConcreteSymbolEnumerator.h" +#include "llvm/DebugInfo/PDB/IPDBLineNumber.h" #include "llvm/DebugInfo/PDB/IPDBSession.h" +#include "llvm/DebugInfo/PDB/Native/LinePrinter.h" #include "llvm/DebugInfo/PDB/PDBExtras.h" #include "llvm/DebugInfo/PDB/PDBSymbolData.h" #include "llvm/DebugInfo/PDB/PDBSymbolFunc.h" #include "llvm/DebugInfo/PDB/PDBSymbolFuncDebugEnd.h" #include "llvm/DebugInfo/PDB/PDBSymbolFuncDebugStart.h" #include "llvm/DebugInfo/PDB/PDBSymbolTypeArray.h" +#include "llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h" #include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h" #include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionArg.h" #include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h" diff --git a/llvm/tools/llvm-pdbutil/PrettyTypeDumper.cpp b/llvm/tools/llvm-pdbutil/PrettyTypeDumper.cpp index 2f7a39803ca5..9547d4e4ed35 100644 --- a/llvm/tools/llvm-pdbutil/PrettyTypeDumper.cpp +++ b/llvm/tools/llvm-pdbutil/PrettyTypeDumper.cpp @@ -8,7 +8,6 @@ #include "PrettyTypeDumper.h" -#include "LinePrinter.h" #include "PrettyBuiltinDumper.h" #include "PrettyClassDefinitionDumper.h" #include "PrettyEnumDumper.h" @@ -16,6 +15,8 @@ #include "PrettyTypedefDumper.h" #include "llvm-pdbutil.h" +#include "llvm/DebugInfo/PDB/ConcreteSymbolEnumerator.h" +#include "llvm/DebugInfo/PDB/IPDBLineNumber.h" #include "llvm/DebugInfo/PDB/IPDBSession.h" #include "llvm/DebugInfo/PDB/PDBSymbolExe.h" #include "llvm/DebugInfo/PDB/PDBSymbolTypeArray.h" @@ -25,6 +26,7 @@ #include "llvm/DebugInfo/PDB/PDBSymbolTypePointer.h" #include "llvm/DebugInfo/PDB/PDBSymbolTypeTypedef.h" #include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h" +#include "llvm/DebugInfo/PDB/PDBSymbolTypeVTableShape.h" #include "llvm/DebugInfo/PDB/UDTLayout.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/FormatVariadic.h" diff --git a/llvm/tools/llvm-pdbutil/PrettyTypedefDumper.cpp b/llvm/tools/llvm-pdbutil/PrettyTypedefDumper.cpp index ef73a8cdf9c4..197aa07299d1 100644 --- a/llvm/tools/llvm-pdbutil/PrettyTypedefDumper.cpp +++ b/llvm/tools/llvm-pdbutil/PrettyTypedefDumper.cpp @@ -8,13 +8,15 @@ #include "PrettyTypedefDumper.h" -#include "LinePrinter.h" #include "PrettyBuiltinDumper.h" #include "PrettyFunctionDumper.h" #include "PrettyTypeDumper.h" +#include "llvm/DebugInfo/PDB/IPDBLineNumber.h" #include "llvm/DebugInfo/PDB/IPDBSession.h" +#include "llvm/DebugInfo/PDB/Native/LinePrinter.h" #include "llvm/DebugInfo/PDB/PDBExtras.h" +#include "llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h" #include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h" #include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h" #include "llvm/DebugInfo/PDB/PDBSymbolTypePointer.h" diff --git a/llvm/tools/llvm-pdbutil/PrettyVariableDumper.cpp b/llvm/tools/llvm-pdbutil/PrettyVariableDumper.cpp index 6dd7cc384cc9..e9ac6984356c 100644 --- a/llvm/tools/llvm-pdbutil/PrettyVariableDumper.cpp +++ b/llvm/tools/llvm-pdbutil/PrettyVariableDumper.cpp @@ -8,21 +8,23 @@ #include "PrettyVariableDumper.h" -#include "LinePrinter.h" #include "PrettyBuiltinDumper.h" #include "PrettyFunctionDumper.h" #include "llvm-pdbutil.h" +#include "llvm/DebugInfo/PDB/IPDBLineNumber.h" #include "llvm/DebugInfo/PDB/IPDBSession.h" #include "llvm/DebugInfo/PDB/PDBSymbolData.h" #include "llvm/DebugInfo/PDB/PDBSymbolFunc.h" #include "llvm/DebugInfo/PDB/PDBSymbolTypeArray.h" -#include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h" +#include "llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h" #include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h" #include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h" #include "llvm/DebugInfo/PDB/PDBSymbolTypePointer.h" #include "llvm/DebugInfo/PDB/PDBSymbolTypeTypedef.h" #include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h" +#include "llvm/DebugInfo/PDB/PDBSymbolTypeVTable.h" +#include "llvm/DebugInfo/PDB/PDBSymbolTypeVTableShape.h" #include "llvm/DebugInfo/PDB/PDBTypes.h" #include "llvm/Support/Format.h" diff --git a/llvm/tools/llvm-pdbutil/StreamUtil.cpp b/llvm/tools/llvm-pdbutil/StreamUtil.cpp index d0d0a9fbe927..878fb77353fa 100644 --- a/llvm/tools/llvm-pdbutil/StreamUtil.cpp +++ b/llvm/tools/llvm-pdbutil/StreamUtil.cpp @@ -7,13 +7,13 @@ //===----------------------------------------------------------------------===// #include "StreamUtil.h" -#include "FormatUtil.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseMapInfo.h" #include "llvm/DebugInfo/PDB/Native/DbiModuleDescriptor.h" #include "llvm/DebugInfo/PDB/Native/DbiModuleList.h" #include "llvm/DebugInfo/PDB/Native/DbiStream.h" +#include "llvm/DebugInfo/PDB/Native/FormatUtil.h" #include "llvm/DebugInfo/PDB/Native/InfoStream.h" #include "llvm/DebugInfo/PDB/Native/PDBFile.h" #include "llvm/DebugInfo/PDB/Native/TpiStream.h" @@ -95,7 +95,7 @@ void llvm::pdb::discoverStreamPurposes(PDBFile &File, } Streams.resize(StreamCount); - for (uint16_t StreamIdx = 0; StreamIdx < StreamCount; ++StreamIdx) { + for (uint32_t StreamIdx = 0; StreamIdx < StreamCount; ++StreamIdx) { if (StreamIdx == OldMSFDirectory) Streams[StreamIdx] = stream(StreamPurpose::Other, "Old MSF Directory", StreamIdx); diff --git a/llvm/tools/llvm-pdbutil/TypeReferenceTracker.cpp b/llvm/tools/llvm-pdbutil/TypeReferenceTracker.cpp index f184f02e01ee..d813bc22a93c 100644 --- a/llvm/tools/llvm-pdbutil/TypeReferenceTracker.cpp +++ b/llvm/tools/llvm-pdbutil/TypeReferenceTracker.cpp @@ -9,10 +9,12 @@ #include "TypeReferenceTracker.h" #include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h" -#include "llvm/DebugInfo/PDB/Native/PDBFile.h" -#include "llvm/DebugInfo/PDB/Native/TpiStream.h" #include "llvm/DebugInfo/PDB/Native/GlobalsStream.h" +#include "llvm/DebugInfo/PDB/Native/NativeSession.h" +#include "llvm/DebugInfo/PDB/Native/PDBFile.h" #include "llvm/DebugInfo/PDB/Native/SymbolStream.h" +#include "llvm/DebugInfo/PDB/Native/TpiStream.h" +#include "llvm/Object/COFF.h" using namespace llvm; using namespace llvm::pdb; diff --git a/llvm/tools/llvm-pdbutil/TypeReferenceTracker.h b/llvm/tools/llvm-pdbutil/TypeReferenceTracker.h index 8861731ab6ee..c586f6523c57 100644 --- a/llvm/tools/llvm-pdbutil/TypeReferenceTracker.h +++ b/llvm/tools/llvm-pdbutil/TypeReferenceTracker.h @@ -9,14 +9,13 @@ #ifndef LLVM_TOOLS_LLVMPDBDUMP_TYPEREFERENCETRACKER_H #define LLVM_TOOLS_LLVMPDBDUMP_TYPEREFERENCETRACKER_H -#include "InputFile.h" - #include "llvm/ADT/BitVector.h" #include "llvm/ADT/Optional.h" #include "llvm/ADT/SmallVector.h" #include "llvm/DebugInfo/CodeView/CVRecord.h" #include "llvm/DebugInfo/CodeView/TypeIndex.h" #include "llvm/DebugInfo/CodeView/TypeIndexDiscovery.h" +#include "llvm/DebugInfo/PDB/Native/InputFile.h" #include "llvm/Support/Error.h" namespace llvm { diff --git a/llvm/tools/llvm-pdbutil/llvm-pdbutil.cpp b/llvm/tools/llvm-pdbutil/llvm-pdbutil.cpp index b152ebd6dccb..3b922a7bea21 100644 --- a/llvm/tools/llvm-pdbutil/llvm-pdbutil.cpp +++ b/llvm/tools/llvm-pdbutil/llvm-pdbutil.cpp @@ -15,8 +15,6 @@ #include "BytesOutputStyle.h" #include "DumpOutputStyle.h" #include "ExplainOutputStyle.h" -#include "InputFile.h" -#include "LinePrinter.h" #include "OutputStyle.h" #include "PrettyClassDefinitionDumper.h" #include "PrettyCompilandDumper.h" @@ -44,14 +42,18 @@ #include "llvm/DebugInfo/CodeView/StringsAndChecksums.h" #include "llvm/DebugInfo/CodeView/TypeStreamMerger.h" #include "llvm/DebugInfo/MSF/MSFBuilder.h" +#include "llvm/DebugInfo/MSF/MappedBlockStream.h" +#include "llvm/DebugInfo/PDB/ConcreteSymbolEnumerator.h" #include "llvm/DebugInfo/PDB/IPDBEnumChildren.h" #include "llvm/DebugInfo/PDB/IPDBInjectedSource.h" +#include "llvm/DebugInfo/PDB/IPDBLineNumber.h" #include "llvm/DebugInfo/PDB/IPDBRawSymbol.h" #include "llvm/DebugInfo/PDB/IPDBSession.h" #include "llvm/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.h" #include "llvm/DebugInfo/PDB/Native/DbiStreamBuilder.h" #include "llvm/DebugInfo/PDB/Native/InfoStream.h" #include "llvm/DebugInfo/PDB/Native/InfoStreamBuilder.h" +#include "llvm/DebugInfo/PDB/Native/InputFile.h" #include "llvm/DebugInfo/PDB/Native/NativeSession.h" #include "llvm/DebugInfo/PDB/Native/PDBFile.h" #include "llvm/DebugInfo/PDB/Native/PDBFileBuilder.h" @@ -67,6 +69,7 @@ #include "llvm/DebugInfo/PDB/PDBSymbolFunc.h" #include "llvm/DebugInfo/PDB/PDBSymbolPublicSymbol.h" #include "llvm/DebugInfo/PDB/PDBSymbolThunk.h" +#include "llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h" #include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h" #include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionArg.h" #include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h" @@ -195,6 +198,8 @@ static cl::opt<bool> Typedefs("typedefs", cl::desc("Dump typedefs"), cl::sub(DiaDumpSubcommand)); } // namespace diadump +FilterOptions Filters; + namespace pretty { cl::list<std::string> InputFilenames(cl::Positional, cl::desc("<input PDB files>"), @@ -211,7 +216,7 @@ cl::opt<bool> ShowInjectedSourceContent( cl::list<std::string> WithName( "with-name", cl::desc("Display any symbol or type with the specified exact name"), - cl::cat(TypeCategory), cl::ZeroOrMore, cl::sub(PrettySubcommand)); + cl::cat(TypeCategory), cl::sub(PrettySubcommand)); cl::opt<bool> Compilands("compilands", cl::desc("Display compilands"), cl::cat(TypeCategory), cl::sub(PrettySubcommand)); @@ -224,7 +229,7 @@ cl::opt<bool> Externals("externals", cl::desc("Dump external symbols"), cl::cat(TypeCategory), cl::sub(PrettySubcommand)); cl::list<SymLevel> SymTypes( "sym-types", cl::desc("Type of symbols to dump (default all)"), - cl::cat(TypeCategory), cl::sub(PrettySubcommand), cl::ZeroOrMore, + cl::cat(TypeCategory), cl::sub(PrettySubcommand), cl::values( clEnumValN(SymLevel::Thunks, "thunks", "Display thunk symbols"), clEnumValN(SymLevel::Data, "data", "Display data symbols"), @@ -310,28 +315,31 @@ cl::opt<cl::boolOrDefault> ColorOutput("color-output", cl::desc("Override use of color (default = isatty)"), cl::cat(OtherOptions), cl::sub(PrettySubcommand)); -cl::list<std::string> ExcludeTypes( - "exclude-types", cl::desc("Exclude types by regular expression"), - cl::ZeroOrMore, cl::cat(FilterCategory), cl::sub(PrettySubcommand)); -cl::list<std::string> ExcludeSymbols( - "exclude-symbols", cl::desc("Exclude symbols by regular expression"), - cl::ZeroOrMore, cl::cat(FilterCategory), cl::sub(PrettySubcommand)); -cl::list<std::string> ExcludeCompilands( - "exclude-compilands", cl::desc("Exclude compilands by regular expression"), - cl::ZeroOrMore, cl::cat(FilterCategory), cl::sub(PrettySubcommand)); +cl::list<std::string> + ExcludeTypes("exclude-types", + cl::desc("Exclude types by regular expression"), + cl::cat(FilterCategory), cl::sub(PrettySubcommand)); +cl::list<std::string> + ExcludeSymbols("exclude-symbols", + cl::desc("Exclude symbols by regular expression"), + cl::cat(FilterCategory), cl::sub(PrettySubcommand)); +cl::list<std::string> + ExcludeCompilands("exclude-compilands", + cl::desc("Exclude compilands by regular expression"), + cl::cat(FilterCategory), cl::sub(PrettySubcommand)); cl::list<std::string> IncludeTypes( "include-types", cl::desc("Include only types which match a regular expression"), - cl::ZeroOrMore, cl::cat(FilterCategory), cl::sub(PrettySubcommand)); + cl::cat(FilterCategory), cl::sub(PrettySubcommand)); cl::list<std::string> IncludeSymbols( "include-symbols", cl::desc("Include only symbols which match a regular expression"), - cl::ZeroOrMore, cl::cat(FilterCategory), cl::sub(PrettySubcommand)); + cl::cat(FilterCategory), cl::sub(PrettySubcommand)); cl::list<std::string> IncludeCompilands( "include-compilands", cl::desc("Include only compilands those which match a regular expression"), - cl::ZeroOrMore, cl::cat(FilterCategory), cl::sub(PrettySubcommand)); + cl::cat(FilterCategory), cl::sub(PrettySubcommand)); cl::opt<uint32_t> SizeThreshold( "min-type-size", cl::desc("Displays only those types which are greater " "than or equal to the specified size."), @@ -384,7 +392,7 @@ cl::opt<std::string> cl::sub(BytesSubcommand), cl::cat(MsfBytes)); cl::list<std::string> - DumpStreamData("stream-data", cl::CommaSeparated, cl::ZeroOrMore, + DumpStreamData("stream-data", cl::CommaSeparated, cl::desc("Dump binary data from specified streams. Format " "is SN[:Start][@Size]"), cl::sub(BytesSubcommand), cl::cat(MsfBytes)); @@ -407,14 +415,12 @@ cl::opt<bool> TypeServerMap("type-server", cl::desc("Dump type server map"), cl::opt<bool> ECData("ec", cl::desc("Dump edit and continue map"), cl::sub(BytesSubcommand), cl::cat(DbiBytes)); -cl::list<uint32_t> - TypeIndex("type", - cl::desc("Dump the type record with the given type index"), - cl::ZeroOrMore, cl::CommaSeparated, cl::sub(BytesSubcommand), - cl::cat(TypeCategory)); +cl::list<uint32_t> TypeIndex( + "type", cl::desc("Dump the type record with the given type index"), + cl::CommaSeparated, cl::sub(BytesSubcommand), cl::cat(TypeCategory)); cl::list<uint32_t> IdIndex("id", cl::desc("Dump the id record with the given type index"), - cl::ZeroOrMore, cl::CommaSeparated, cl::sub(BytesSubcommand), + cl::CommaSeparated, cl::sub(BytesSubcommand), cl::cat(TypeCategory)); cl::opt<uint32_t> ModuleIndex( @@ -500,7 +506,7 @@ cl::opt<bool> DontResolveForwardRefs( cl::cat(TypeOptions), cl::sub(DumpSubcommand)); cl::list<uint32_t> DumpTypeIndex( - "type-index", cl::ZeroOrMore, cl::CommaSeparated, + "type-index", cl::CommaSeparated, cl::desc("only dump types with the specified hexadecimal type index"), cl::cat(TypeOptions), cl::sub(DumpSubcommand)); @@ -516,7 +522,7 @@ cl::opt<bool> DumpIdExtras("id-extras", cl::desc("dump id hashes and index offsets"), cl::cat(TypeOptions), cl::sub(DumpSubcommand)); cl::list<uint32_t> DumpIdIndex( - "id-index", cl::ZeroOrMore, cl::CommaSeparated, + "id-index", cl::CommaSeparated, cl::desc("only dump ids with the specified hexadecimal type index"), cl::cat(TypeOptions), cl::sub(DumpSubcommand)); @@ -536,7 +542,7 @@ cl::list<std::string> DumpGlobalNames( "global-name", cl::desc( "With -globals, only dump globals whose name matches the given value"), - cl::cat(SymbolOptions), cl::sub(DumpSubcommand), cl::ZeroOrMore); + cl::cat(SymbolOptions), cl::sub(DumpSubcommand)); cl::opt<bool> DumpPublics("publics", cl::desc("dump Publics stream data"), cl::cat(SymbolOptions), cl::sub(DumpSubcommand)); cl::opt<bool> DumpPublicExtras("public-extras", @@ -557,6 +563,27 @@ cl::opt<bool> cl::opt<bool> DumpFpo("fpo", cl::desc("dump FPO records"), cl::cat(SymbolOptions), cl::sub(DumpSubcommand)); +cl::opt<uint32_t> DumpSymbolOffset( + "symbol-offset", cl::Optional, + cl::desc("only dump symbol record with the specified symbol offset"), + cl::cat(SymbolOptions), cl::sub(DumpSubcommand)); +cl::opt<bool> DumpParents("show-parents", + cl::desc("dump the symbols record's all parents."), + cl::cat(SymbolOptions), cl::sub(DumpSubcommand)); +cl::opt<uint32_t> + DumpParentDepth("parent-recurse-depth", cl::Optional, cl::init(-1U), + cl::desc("only recurse to a depth of N when displaying " + "parents of a symbol record."), + cl::cat(SymbolOptions), cl::sub(DumpSubcommand)); +cl::opt<bool> DumpChildren("show-children", + cl::desc("dump the symbols record's all children."), + cl::cat(SymbolOptions), cl::sub(DumpSubcommand)); +cl::opt<uint32_t> + DumpChildrenDepth("children-recurse-depth", cl::Optional, cl::init(-1U), + cl::desc("only recurse to a depth of N when displaying " + "children of a symbol record."), + cl::cat(SymbolOptions), cl::sub(DumpSubcommand)); + // MODULE & FILE OPTIONS cl::opt<bool> DumpModules("modules", cl::desc("dump compiland information"), cl::cat(FileOptions), cl::sub(DumpSubcommand)); @@ -680,7 +707,7 @@ cl::opt<bool> DumpModuleFiles("module-files", cl::desc("dump file information"), cl::cat(FileOptions), cl::sub(PdbToYamlSubcommand)); cl::list<ModuleSubsection> DumpModuleSubsections( - "subsections", cl::ZeroOrMore, cl::CommaSeparated, + "subsections", cl::CommaSeparated, cl::desc("dump subsections from each module's debug stream"), ChunkValues, cl::cat(FileOptions), cl::sub(PdbToYamlSubcommand)); cl::opt<bool> DumpModuleSyms("module-syms", cl::desc("dump module symbols"), @@ -764,7 +791,7 @@ static void yamlToPdb(StringRef Path) { PDBFileBuilder Builder(Allocator); uint32_t BlockSize = 4096; - if (YamlObj.Headers.hasValue()) + if (YamlObj.Headers) BlockSize = YamlObj.Headers->SuperBlock.BlockSize; ExitOnErr(Builder.initialize(BlockSize)); // Add each of the reserved streams. We ignore stream metadata in the @@ -779,7 +806,7 @@ static void yamlToPdb(StringRef Path) { StringsAndChecksums Strings; Strings.setStrings(std::make_shared<DebugStringTableSubsection>()); - if (YamlObj.StringTable.hasValue()) { + if (YamlObj.StringTable) { for (auto S : *YamlObj.StringTable) Strings.strings()->insert(S); } @@ -789,7 +816,7 @@ static void yamlToPdb(StringRef Path) { pdb::yaml::PdbTpiStream DefaultTpiStream; pdb::yaml::PdbTpiStream DefaultIpiStream; - const auto &Info = YamlObj.PdbStream.getValueOr(DefaultInfoStream); + const auto &Info = YamlObj.PdbStream.value_or(DefaultInfoStream); auto &InfoBuilder = Builder.getInfoBuilder(); InfoBuilder.setAge(Info.Age); @@ -799,7 +826,7 @@ static void yamlToPdb(StringRef Path) { for (auto F : Info.Features) InfoBuilder.addFeature(F); - const auto &Dbi = YamlObj.DbiStream.getValueOr(DefaultDbiStream); + const auto &Dbi = YamlObj.DbiStream.value_or(DefaultDbiStream); auto &DbiBuilder = Builder.getDbiBuilder(); DbiBuilder.setAge(Dbi.Age); DbiBuilder.setBuildNumber(Dbi.BuildNumber); @@ -814,7 +841,7 @@ static void yamlToPdb(StringRef Path) { for (auto S : MI.SourceFiles) ExitOnErr(DbiBuilder.addModuleSourceFile(ModiBuilder, S)); - if (MI.Modi.hasValue()) { + if (MI.Modi) { const auto &ModiStream = *MI.Modi; for (auto Symbol : ModiStream.Symbols) { ModiBuilder.addSymbol( @@ -834,7 +861,7 @@ static void yamlToPdb(StringRef Path) { } auto &TpiBuilder = Builder.getTpiBuilder(); - const auto &Tpi = YamlObj.TpiStream.getValueOr(DefaultTpiStream); + const auto &Tpi = YamlObj.TpiStream.value_or(DefaultTpiStream); TpiBuilder.setVersionHeader(Tpi.Version); AppendingTypeTableBuilder TS(Allocator); for (const auto &R : Tpi.Records) { @@ -842,7 +869,7 @@ static void yamlToPdb(StringRef Path) { TpiBuilder.addTypeRecord(Type.RecordData, None); } - const auto &Ipi = YamlObj.IpiStream.getValueOr(DefaultIpiStream); + const auto &Ipi = YamlObj.IpiStream.value_or(DefaultIpiStream); auto &IpiBuilder = Builder.getIpiBuilder(); IpiBuilder.setVersionHeader(Ipi.Version); for (const auto &R : Ipi.Records) { @@ -1068,7 +1095,7 @@ static void dumpPretty(StringRef Path) { const bool UseColor = opts::pretty::ColorOutput == cl::BOU_UNSET ? Stream.has_colors() : opts::pretty::ColorOutput == cl::BOU_TRUE; - LinePrinter Printer(2, UseColor, Stream); + LinePrinter Printer(2, UseColor, Stream, opts::Filters); auto GlobalScope(Session->getGlobalScope()); if (!GlobalScope) @@ -1506,6 +1533,44 @@ int main(int Argc, const char **Argv) { llvm::sys::InitializeCOMRAII COM(llvm::sys::COMThreadingMode::MultiThreaded); + // Initialize the filters for LinePrinter. + auto propagate = [&](auto &Target, auto &Reference) { + for (std::string &Option : Reference) + Target.push_back(Option); + }; + + propagate(opts::Filters.ExcludeTypes, opts::pretty::ExcludeTypes); + propagate(opts::Filters.ExcludeTypes, opts::pretty::ExcludeTypes); + propagate(opts::Filters.ExcludeSymbols, opts::pretty::ExcludeSymbols); + propagate(opts::Filters.ExcludeCompilands, opts::pretty::ExcludeCompilands); + propagate(opts::Filters.IncludeTypes, opts::pretty::IncludeTypes); + propagate(opts::Filters.IncludeSymbols, opts::pretty::IncludeSymbols); + propagate(opts::Filters.IncludeCompilands, opts::pretty::IncludeCompilands); + opts::Filters.PaddingThreshold = opts::pretty::PaddingThreshold; + opts::Filters.SizeThreshold = opts::pretty::SizeThreshold; + opts::Filters.JustMyCode = opts::dump::JustMyCode; + if (opts::dump::DumpModi.getNumOccurrences() > 0) { + if (opts::dump::DumpModi.getNumOccurrences() != 1) { + errs() << "argument '-modi' specified more than once.\n"; + errs().flush(); + exit(1); + } + opts::Filters.DumpModi = opts::dump::DumpModi; + } + if (opts::dump::DumpSymbolOffset) { + if (opts::dump::DumpModi.getNumOccurrences() != 1) { + errs() + << "need to specify argument '-modi' when using '-symbol-offset'.\n"; + errs().flush(); + exit(1); + } + opts::Filters.SymbolOffset = opts::dump::DumpSymbolOffset; + if (opts::dump::DumpParents) + opts::Filters.ParentRecurseDepth = opts::dump::DumpParentDepth; + if (opts::dump::DumpChildren) + opts::Filters.ChildrenRecurseDepth = opts::dump::DumpChildrenDepth; + } + if (opts::PdbToYamlSubcommand) { pdb2Yaml(opts::pdb2yaml::InputFilename.front()); } else if (opts::YamlToPdbSubcommand) { @@ -1544,14 +1609,14 @@ int main(int Argc, const char **Argv) { // it needs to be escaped again in the C++. So matching a single \ in the // input requires 4 \es in the C++. if (opts::pretty::ExcludeCompilerGenerated) { - opts::pretty::ExcludeTypes.push_back("__vc_attributes"); - opts::pretty::ExcludeCompilands.push_back("\\* Linker \\*"); + opts::Filters.ExcludeTypes.push_back("__vc_attributes"); + opts::Filters.ExcludeCompilands.push_back("\\* Linker \\*"); } if (opts::pretty::ExcludeSystemLibraries) { - opts::pretty::ExcludeCompilands.push_back( + opts::Filters.ExcludeCompilands.push_back( "f:\\\\binaries\\\\Intermediate\\\\vctools\\\\crt_bld"); - opts::pretty::ExcludeCompilands.push_back("f:\\\\dd\\\\vctools\\\\crt"); - opts::pretty::ExcludeCompilands.push_back( + opts::Filters.ExcludeCompilands.push_back("f:\\\\dd\\\\vctools\\\\crt"); + opts::Filters.ExcludeCompilands.push_back( "d:\\\\th.obj.x86fre\\\\minkernel"); } llvm::for_each(opts::pretty::InputFilenames, dumpPretty); diff --git a/llvm/tools/llvm-pdbutil/llvm-pdbutil.h b/llvm/tools/llvm-pdbutil/llvm-pdbutil.h index 9fe92c2c9d75..455fe5f28191 100644 --- a/llvm/tools/llvm-pdbutil/llvm-pdbutil.h +++ b/llvm/tools/llvm-pdbutil/llvm-pdbutil.h @@ -12,6 +12,7 @@ #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/Optional.h" #include "llvm/ADT/PointerUnion.h" +#include "llvm/DebugInfo/PDB/Native/LinePrinter.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/raw_ostream.h" @@ -50,6 +51,8 @@ enum class ModuleSubsection { All }; +extern FilterOptions Filters; + namespace pretty { enum class ClassDefinitionFormat { None, Layout, All }; |
