//===- PrettyCompilandDumper.cpp - llvm-pdbutil compiland dumper -*- 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 "PrettyCompilandDumper.h" #include "PrettyFunctionDumper.h" #include "llvm-pdbutil.h" #include "llvm/DebugInfo/PDB/IPDBEnumChildren.h" #include "llvm/DebugInfo/PDB/IPDBLineNumber.h" #include "llvm/DebugInfo/PDB/IPDBSession.h" #include "llvm/DebugInfo/PDB/IPDBSourceFile.h" #include "llvm/DebugInfo/PDB/PDBExtras.h" #include "llvm/DebugInfo/PDB/PDBSymbol.h" #include "llvm/DebugInfo/PDB/PDBSymbolCompiland.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/PDBSymbolLabel.h" #include "llvm/DebugInfo/PDB/PDBSymbolThunk.h" #include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h" #include "llvm/DebugInfo/PDB/PDBSymbolUnknown.h" #include "llvm/DebugInfo/PDB/PDBSymbolUsingNamespace.h" #include "llvm/Support/Format.h" #include "llvm/Support/Path.h" #include "llvm/Support/raw_ostream.h" #include using namespace llvm; using namespace llvm::pdb; CompilandDumper::CompilandDumper(LinePrinter &P) : PDBSymDumper(true), Printer(P) {} void CompilandDumper::dump(const PDBSymbolCompilandDetails &Symbol) {} void CompilandDumper::dump(const PDBSymbolCompilandEnv &Symbol) {} void CompilandDumper::start(const PDBSymbolCompiland &Symbol, CompilandDumpFlags opts) { std::string FullName = Symbol.getName(); if (Printer.IsCompilandExcluded(FullName)) return; Printer.NewLine(); WithColor(Printer, PDB_ColorItem::Path).get() << FullName; if (opts & Flags::Lines) { const IPDBSession &Session = Symbol.getSession(); if (auto Files = Session.getSourceFilesForCompiland(Symbol)) { Printer.Indent(); while (auto File = Files->getNext()) { Printer.NewLine(); WithColor(Printer, PDB_ColorItem::Path).get() << File->getFileName(); if (File->getChecksumType() != PDB_Checksum::None) { auto ChecksumType = File->getChecksumType(); auto ChecksumHexString = toHex(File->getChecksum()); WithColor(Printer, PDB_ColorItem::Comment).get() << " (" << ChecksumType << ": " << ChecksumHexString << ")"; } auto Lines = Session.findLineNumbers(Symbol, *File); if (!Lines) continue; Printer.Indent(); while (auto Line = Lines->getNext()) { Printer.NewLine(); uint32_t LineStart = Line->getLineNumber(); uint32_t LineEnd = Line->getLineNumberEnd(); Printer << "Line "; PDB_ColorItem StatementColor = Line->isStatement() ? PDB_ColorItem::Keyword : PDB_ColorItem::LiteralValue; WithColor(Printer, StatementColor).get() << LineStart; if (LineStart != LineEnd) WithColor(Printer, StatementColor).get() << " - " << LineEnd; uint32_t ColumnStart = Line->getColumnNumber(); uint32_t ColumnEnd = Line->getColumnNumberEnd(); if (ColumnStart != 0 || ColumnEnd != 0) { Printer << ", Column: "; WithColor(Printer, StatementColor).get() << ColumnStart; if (ColumnEnd != ColumnStart) WithColor(Printer, StatementColor).get() << " - " << ColumnEnd; } Printer << ", Address: "; if (Line->getLength() > 0) { uint64_t AddrStart = Line->getVirtualAddress(); uint64_t AddrEnd = AddrStart + Line->getLength() - 1; WithColor(Printer, PDB_ColorItem::Address).get() << "[" << format_hex(AddrStart, 10) << " - " << format_hex(AddrEnd, 10) << "]"; Printer << " (" << Line->getLength() << " bytes)"; } else { uint64_t AddrStart = Line->getVirtualAddress(); WithColor(Printer, PDB_ColorItem::Address).get() << "[" << format_hex(AddrStart, 10) << "] "; Printer << "(0 bytes)"; } } Printer.Unindent(); } Printer.Unindent(); } } if (opts & Flags::Children) { if (auto ChildrenEnum = Symbol.findAllChildren()) { Printer.Indent(); while (auto Child = ChildrenEnum->getNext()) Child->dump(*this); Printer.Unindent(); } } } void CompilandDumper::dump(const PDBSymbolData &Symbol) { if (!shouldDumpSymLevel(opts::pretty::SymLevel::Data)) return; if (Printer.IsSymbolExcluded(Symbol.getName())) return; Printer.NewLine(); switch (auto LocType = Symbol.getLocationType()) { case PDB_LocType::Static: Printer << "data: "; WithColor(Printer, PDB_ColorItem::Address).get() << "[" << format_hex(Symbol.getVirtualAddress(), 10) << "]"; WithColor(Printer, PDB_ColorItem::Comment).get() << " [sizeof = " << getTypeLength(Symbol) << "]"; break; case PDB_LocType::Constant: Printer << "constant: "; WithColor(Printer, PDB_ColorItem::LiteralValue).get() << "[" << Symbol.getValue() << "]"; WithColor(Printer, PDB_ColorItem::Comment).get() << " [sizeof = " << getTypeLength(Symbol) << "]"; break; default: Printer << "data(unexpected type=" << LocType << ")"; } Printer << " "; WithColor(Printer, PDB_ColorItem::Identifier).get() << Symbol.getName(); } void CompilandDumper::dump(const PDBSymbolFunc &Symbol) { if (!shouldDumpSymLevel(opts::pretty::SymLevel::Functions)) return; if (Symbol.getLength() == 0) return; if (Printer.IsSymbolExcluded(Symbol.getName())) return; Printer.NewLine(); FunctionDumper Dumper(Printer); Dumper.start(Symbol, FunctionDumper::PointerType::None); } void CompilandDumper::dump(const PDBSymbolLabel &Symbol) { if (Printer.IsSymbolExcluded(Symbol.getName())) return; Printer.NewLine(); Printer << "label "; WithColor(Printer, PDB_ColorItem::Address).get() << "[" << format_hex(Symbol.getVirtualAddress(), 10) << "] "; WithColor(Printer, PDB_ColorItem::Identifier).get() << Symbol.getName(); } void CompilandDumper::dump(const PDBSymbolThunk &Symbol) { if (!shouldDumpSymLevel(opts::pretty::SymLevel::Thunks)) return; if (Printer.IsSymbolExcluded(Symbol.getName())) return; Printer.NewLine(); Printer << "thunk "; codeview::ThunkOrdinal Ordinal = Symbol.getThunkOrdinal(); uint64_t VA = Symbol.getVirtualAddress(); if (Ordinal == codeview::ThunkOrdinal::TrampIncremental) { uint64_t Target = Symbol.getTargetVirtualAddress(); WithColor(Printer, PDB_ColorItem::Address).get() << format_hex(VA, 10); Printer << " -> "; WithColor(Printer, PDB_ColorItem::Address).get() << format_hex(Target, 10); } else { WithColor(Printer, PDB_ColorItem::Address).get() << "[" << format_hex(VA, 10) << " - " << format_hex(VA + Symbol.getLength(), 10) << "]"; } Printer << " ("; WithColor(Printer, PDB_ColorItem::Register).get() << Ordinal; Printer << ") "; std::string Name = Symbol.getName(); if (!Name.empty()) WithColor(Printer, PDB_ColorItem::Identifier).get() << Name; } void CompilandDumper::dump(const PDBSymbolTypeTypedef &Symbol) {} void CompilandDumper::dump(const PDBSymbolUnknown &Symbol) { Printer.NewLine(); Printer << "unknown (" << Symbol.getSymTag() << ")"; } void CompilandDumper::dump(const PDBSymbolUsingNamespace &Symbol) { if (Printer.IsSymbolExcluded(Symbol.getName())) return; Printer.NewLine(); Printer << "using namespace "; std::string Name = Symbol.getName(); WithColor(Printer, PDB_ColorItem::Identifier).get() << Name; }