1 //===- CompilandDumper.cpp - llvm-pdbdump compiland symbol dumper *- C++ *-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "CompilandDumper.h"
11 #include "LinePrinter.h"
12 #include "llvm-pdbdump.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/Support/Format.h"
30 #include "llvm/Support/Path.h"
31 #include "llvm/Support/raw_ostream.h"
32 
33 #include "FunctionDumper.h"
34 
35 #include <utility>
36 
37 using namespace llvm;
38 using namespace llvm::pdb;
39 
CompilandDumper(LinePrinter & P)40 CompilandDumper::CompilandDumper(LinePrinter &P)
41     : PDBSymDumper(true), Printer(P) {}
42 
dump(const PDBSymbolCompilandDetails & Symbol)43 void CompilandDumper::dump(const PDBSymbolCompilandDetails &Symbol) {}
44 
dump(const PDBSymbolCompilandEnv & Symbol)45 void CompilandDumper::dump(const PDBSymbolCompilandEnv &Symbol) {}
46 
start(const PDBSymbolCompiland & Symbol,CompilandDumpFlags opts)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     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 
64       auto Lines = Session.findLineNumbers(Symbol, *File);
65       Printer.Indent();
66       while (auto Line = Lines->getNext()) {
67         Printer.NewLine();
68         uint32_t LineStart = Line->getLineNumber();
69         uint32_t LineEnd = Line->getLineNumberEnd();
70 
71         Printer << "Line ";
72         PDB_ColorItem StatementColor = Line->isStatement()
73                                            ? PDB_ColorItem::Keyword
74                                            : PDB_ColorItem::LiteralValue;
75         WithColor(Printer, StatementColor).get() << LineStart;
76         if (LineStart != LineEnd)
77           WithColor(Printer, StatementColor).get() << " - " << LineEnd;
78 
79         Printer << ", Address: ";
80         if (Line->getLength() > 0) {
81           uint64_t AddrStart = Line->getVirtualAddress();
82           uint64_t AddrEnd = AddrStart + Line->getLength() - 1;
83           WithColor(Printer, PDB_ColorItem::Address).get()
84               << "[" << format_hex(AddrStart, 10) << " - "
85               << format_hex(AddrEnd, 10) << "]";
86           Printer << " (" << Line->getLength() << " bytes)";
87         } else {
88           uint64_t AddrStart = Line->getVirtualAddress();
89           WithColor(Printer, PDB_ColorItem::Address).get()
90               << "[" << format_hex(AddrStart, 10) << "] ";
91           Printer << "(0 bytes)";
92         }
93       }
94       Printer.Unindent();
95     }
96     Printer.Unindent();
97   }
98 
99   if (opts & Flags::Children) {
100     auto ChildrenEnum = Symbol.findAllChildren();
101     Printer.Indent();
102     while (auto Child = ChildrenEnum->getNext())
103       Child->dump(*this);
104     Printer.Unindent();
105   }
106 }
107 
dump(const PDBSymbolData & Symbol)108 void CompilandDumper::dump(const PDBSymbolData &Symbol) {
109   if (Printer.IsSymbolExcluded(Symbol.getName()))
110     return;
111 
112   Printer.NewLine();
113 
114   switch (auto LocType = Symbol.getLocationType()) {
115   case PDB_LocType::Static:
116     Printer << "data: ";
117     WithColor(Printer, PDB_ColorItem::Address).get()
118         << "[" << format_hex(Symbol.getVirtualAddress(), 10) << "]";
119     break;
120   case PDB_LocType::Constant:
121     Printer << "constant: ";
122     WithColor(Printer, PDB_ColorItem::LiteralValue).get()
123         << "[" << Symbol.getValue() << "]";
124     break;
125   default:
126     Printer << "data(unexpected type=" << LocType << ")";
127   }
128 
129   Printer << " ";
130   WithColor(Printer, PDB_ColorItem::Identifier).get() << Symbol.getName();
131 }
132 
dump(const PDBSymbolFunc & Symbol)133 void CompilandDumper::dump(const PDBSymbolFunc &Symbol) {
134   if (Symbol.getLength() == 0)
135     return;
136   if (Printer.IsSymbolExcluded(Symbol.getName()))
137     return;
138 
139   Printer.NewLine();
140   FunctionDumper Dumper(Printer);
141   Dumper.start(Symbol, FunctionDumper::PointerType::None);
142 }
143 
dump(const PDBSymbolLabel & Symbol)144 void CompilandDumper::dump(const PDBSymbolLabel &Symbol) {
145   if (Printer.IsSymbolExcluded(Symbol.getName()))
146     return;
147 
148   Printer.NewLine();
149   Printer << "label ";
150   WithColor(Printer, PDB_ColorItem::Address).get()
151       << "[" << format_hex(Symbol.getVirtualAddress(), 10) << "] ";
152   WithColor(Printer, PDB_ColorItem::Identifier).get() << Symbol.getName();
153 }
154 
dump(const PDBSymbolThunk & Symbol)155 void CompilandDumper::dump(const PDBSymbolThunk &Symbol) {
156   if (Printer.IsSymbolExcluded(Symbol.getName()))
157     return;
158 
159   Printer.NewLine();
160   Printer << "thunk ";
161   codeview::ThunkOrdinal Ordinal = Symbol.getThunkOrdinal();
162   uint64_t VA = Symbol.getVirtualAddress();
163   if (Ordinal == codeview::ThunkOrdinal::TrampIncremental) {
164     uint64_t Target = Symbol.getTargetVirtualAddress();
165     WithColor(Printer, PDB_ColorItem::Address).get() << format_hex(VA, 10);
166     Printer << " -> ";
167     WithColor(Printer, PDB_ColorItem::Address).get() << format_hex(Target, 10);
168   } else {
169     WithColor(Printer, PDB_ColorItem::Address).get()
170         << "[" << format_hex(VA, 10) << " - "
171         << format_hex(VA + Symbol.getLength(), 10) << "]";
172   }
173   Printer << " (";
174   WithColor(Printer, PDB_ColorItem::Register).get() << Ordinal;
175   Printer << ") ";
176   std::string Name = Symbol.getName();
177   if (!Name.empty())
178     WithColor(Printer, PDB_ColorItem::Identifier).get() << Name;
179 }
180 
dump(const PDBSymbolTypeTypedef & Symbol)181 void CompilandDumper::dump(const PDBSymbolTypeTypedef &Symbol) {}
182 
dump(const PDBSymbolUnknown & Symbol)183 void CompilandDumper::dump(const PDBSymbolUnknown &Symbol) {
184   Printer.NewLine();
185   Printer << "unknown (" << Symbol.getSymTag() << ")";
186 }
187