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