227 lines · cpp
1//===- PrettyCompilandDumper.cpp - llvm-pdbutil compiland dumper -*- C++ *-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "PrettyCompilandDumper.h"10 11#include "PrettyFunctionDumper.h"12#include "llvm-pdbutil.h"13 14#include "llvm/ADT/StringExtras.h"15#include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"16#include "llvm/DebugInfo/PDB/IPDBLineNumber.h"17#include "llvm/DebugInfo/PDB/IPDBSession.h"18#include "llvm/DebugInfo/PDB/IPDBSourceFile.h"19#include "llvm/DebugInfo/PDB/PDBExtras.h"20#include "llvm/DebugInfo/PDB/PDBSymbol.h"21#include "llvm/DebugInfo/PDB/PDBSymbolCompiland.h"22#include "llvm/DebugInfo/PDB/PDBSymbolData.h"23#include "llvm/DebugInfo/PDB/PDBSymbolFunc.h"24#include "llvm/DebugInfo/PDB/PDBSymbolFuncDebugEnd.h"25#include "llvm/DebugInfo/PDB/PDBSymbolFuncDebugStart.h"26#include "llvm/DebugInfo/PDB/PDBSymbolLabel.h"27#include "llvm/DebugInfo/PDB/PDBSymbolThunk.h"28#include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h"29#include "llvm/DebugInfo/PDB/PDBSymbolUnknown.h"30#include "llvm/DebugInfo/PDB/PDBSymbolUsingNamespace.h"31#include "llvm/Support/Format.h"32#include "llvm/Support/Path.h"33#include "llvm/Support/raw_ostream.h"34 35using namespace llvm;36using namespace llvm::pdb;37 38CompilandDumper::CompilandDumper(LinePrinter &P)39 : PDBSymDumper(true), Printer(P) {}40 41void CompilandDumper::dump(const PDBSymbolCompilandDetails &Symbol) {}42 43void CompilandDumper::dump(const PDBSymbolCompilandEnv &Symbol) {}44 45void CompilandDumper::start(const PDBSymbolCompiland &Symbol,46 CompilandDumpFlags opts) {47 std::string FullName = Symbol.getName();48 if (Printer.IsCompilandExcluded(FullName))49 return;50 51 Printer.NewLine();52 WithColor(Printer, PDB_ColorItem::Path).get() << FullName;53 54 if (opts & Flags::Lines) {55 const IPDBSession &Session = Symbol.getSession();56 if (auto Files = Session.getSourceFilesForCompiland(Symbol)) {57 Printer.Indent();58 while (auto File = Files->getNext()) {59 Printer.NewLine();60 WithColor(Printer, PDB_ColorItem::Path).get() << File->getFileName();61 if (File->getChecksumType() != PDB_Checksum::None) {62 auto ChecksumType = File->getChecksumType();63 auto ChecksumHexString = toHex(File->getChecksum());64 WithColor(Printer, PDB_ColorItem::Comment).get()65 << " (" << ChecksumType << ": " << ChecksumHexString << ")";66 }67 68 auto Lines = Session.findLineNumbers(Symbol, *File);69 if (!Lines)70 continue;71 72 Printer.Indent();73 while (auto Line = Lines->getNext()) {74 Printer.NewLine();75 uint32_t LineStart = Line->getLineNumber();76 uint32_t LineEnd = Line->getLineNumberEnd();77 78 Printer << "Line ";79 PDB_ColorItem StatementColor = Line->isStatement()80 ? PDB_ColorItem::Keyword81 : PDB_ColorItem::LiteralValue;82 WithColor(Printer, StatementColor).get() << LineStart;83 if (LineStart != LineEnd)84 WithColor(Printer, StatementColor).get() << " - " << LineEnd;85 86 uint32_t ColumnStart = Line->getColumnNumber();87 uint32_t ColumnEnd = Line->getColumnNumberEnd();88 if (ColumnStart != 0 || ColumnEnd != 0) {89 Printer << ", Column: ";90 WithColor(Printer, StatementColor).get() << ColumnStart;91 if (ColumnEnd != ColumnStart)92 WithColor(Printer, StatementColor).get() << " - " << ColumnEnd;93 }94 95 Printer << ", Address: ";96 if (Line->getLength() > 0) {97 uint64_t AddrStart = Line->getVirtualAddress();98 uint64_t AddrEnd = AddrStart + Line->getLength() - 1;99 WithColor(Printer, PDB_ColorItem::Address).get()100 << "[" << format_hex(AddrStart, 10) << " - "101 << format_hex(AddrEnd, 10) << "]";102 Printer << " (" << Line->getLength() << " bytes)";103 } else {104 uint64_t AddrStart = Line->getVirtualAddress();105 WithColor(Printer, PDB_ColorItem::Address).get()106 << "[" << format_hex(AddrStart, 10) << "] ";107 Printer << "(0 bytes)";108 }109 }110 Printer.Unindent();111 }112 Printer.Unindent();113 }114 }115 116 if (opts & Flags::Children) {117 if (auto ChildrenEnum = Symbol.findAllChildren()) {118 Printer.Indent();119 while (auto Child = ChildrenEnum->getNext())120 Child->dump(*this);121 Printer.Unindent();122 }123 }124}125 126void CompilandDumper::dump(const PDBSymbolData &Symbol) {127 if (!shouldDumpSymLevel(opts::pretty::SymLevel::Data))128 return;129 if (Printer.IsSymbolExcluded(Symbol.getName()))130 return;131 132 Printer.NewLine();133 134 switch (auto LocType = Symbol.getLocationType()) {135 case PDB_LocType::Static:136 Printer << "data: ";137 WithColor(Printer, PDB_ColorItem::Address).get()138 << "[" << format_hex(Symbol.getVirtualAddress(), 10) << "]";139 140 WithColor(Printer, PDB_ColorItem::Comment).get()141 << " [sizeof = " << getTypeLength(Symbol) << "]";142 143 break;144 case PDB_LocType::Constant:145 Printer << "constant: ";146 WithColor(Printer, PDB_ColorItem::LiteralValue).get()147 << "[" << Symbol.getValue() << "]";148 WithColor(Printer, PDB_ColorItem::Comment).get()149 << " [sizeof = " << getTypeLength(Symbol) << "]";150 break;151 default:152 Printer << "data(unexpected type=" << LocType << ")";153 }154 155 Printer << " ";156 WithColor(Printer, PDB_ColorItem::Identifier).get() << Symbol.getName();157}158 159void CompilandDumper::dump(const PDBSymbolFunc &Symbol) {160 if (!shouldDumpSymLevel(opts::pretty::SymLevel::Functions))161 return;162 if (Symbol.getLength() == 0)163 return;164 if (Printer.IsSymbolExcluded(Symbol.getName()))165 return;166 167 Printer.NewLine();168 FunctionDumper Dumper(Printer);169 Dumper.start(Symbol, FunctionDumper::PointerType::None);170}171 172void CompilandDumper::dump(const PDBSymbolLabel &Symbol) {173 if (Printer.IsSymbolExcluded(Symbol.getName()))174 return;175 176 Printer.NewLine();177 Printer << "label ";178 WithColor(Printer, PDB_ColorItem::Address).get()179 << "[" << format_hex(Symbol.getVirtualAddress(), 10) << "] ";180 WithColor(Printer, PDB_ColorItem::Identifier).get() << Symbol.getName();181}182 183void CompilandDumper::dump(const PDBSymbolThunk &Symbol) {184 if (!shouldDumpSymLevel(opts::pretty::SymLevel::Thunks))185 return;186 if (Printer.IsSymbolExcluded(Symbol.getName()))187 return;188 189 Printer.NewLine();190 Printer << "thunk ";191 codeview::ThunkOrdinal Ordinal = Symbol.getThunkOrdinal();192 uint64_t VA = Symbol.getVirtualAddress();193 if (Ordinal == codeview::ThunkOrdinal::TrampIncremental) {194 uint64_t Target = Symbol.getTargetVirtualAddress();195 WithColor(Printer, PDB_ColorItem::Address).get() << format_hex(VA, 10);196 Printer << " -> ";197 WithColor(Printer, PDB_ColorItem::Address).get() << format_hex(Target, 10);198 } else {199 WithColor(Printer, PDB_ColorItem::Address).get()200 << "[" << format_hex(VA, 10) << " - "201 << format_hex(VA + Symbol.getLength(), 10) << "]";202 }203 Printer << " (";204 WithColor(Printer, PDB_ColorItem::Register).get() << Ordinal;205 Printer << ") ";206 std::string Name = Symbol.getName();207 if (!Name.empty())208 WithColor(Printer, PDB_ColorItem::Identifier).get() << Name;209}210 211void CompilandDumper::dump(const PDBSymbolTypeTypedef &Symbol) {}212 213void CompilandDumper::dump(const PDBSymbolUnknown &Symbol) {214 Printer.NewLine();215 Printer << "unknown (" << Symbol.getSymTag() << ")";216}217 218void CompilandDumper::dump(const PDBSymbolUsingNamespace &Symbol) {219 if (Printer.IsSymbolExcluded(Symbol.getName()))220 return;221 222 Printer.NewLine();223 Printer << "using namespace ";224 std::string Name = Symbol.getName();225 WithColor(Printer, PDB_ColorItem::Identifier).get() << Name;226}227