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