1 //===- PrettyCompilandDumper.cpp - llvm-pdbutil compiland dumper -*- C++ *-===//
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
7 //===----------------------------------------------------------------------===//
9 #include "PrettyCompilandDumper.h"
11 #include "PrettyFunctionDumper.h"
12 #include "llvm-pdbutil.h"
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"
37 using namespace llvm::pdb
;
39 CompilandDumper::CompilandDumper(LinePrinter
&P
)
40 : PDBSymDumper(true), Printer(P
) {}
42 void CompilandDumper::dump(const PDBSymbolCompilandDetails
&Symbol
) {}
44 void CompilandDumper::dump(const PDBSymbolCompilandEnv
&Symbol
) {}
46 void CompilandDumper::start(const PDBSymbolCompiland
&Symbol
,
47 CompilandDumpFlags opts
) {
48 std::string FullName
= Symbol
.getName();
49 if (Printer
.IsCompilandExcluded(FullName
))
53 WithColor(Printer
, PDB_ColorItem::Path
).get() << FullName
;
55 if (opts
& Flags::Lines
) {
56 const IPDBSession
&Session
= Symbol
.getSession();
57 if (auto Files
= Session
.getSourceFilesForCompiland(Symbol
)) {
59 while (auto File
= Files
->getNext()) {
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
<< ")";
69 auto Lines
= Session
.findLineNumbers(Symbol
, *File
);
74 while (auto Line
= Lines
->getNext()) {
76 uint32_t LineStart
= Line
->getLineNumber();
77 uint32_t LineEnd
= Line
->getLineNumberEnd();
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
;
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
;
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)";
105 uint64_t AddrStart
= Line
->getVirtualAddress();
106 WithColor(Printer
, PDB_ColorItem::Address
).get()
107 << "[" << format_hex(AddrStart
, 10) << "] ";
108 Printer
<< "(0 bytes)";
117 if (opts
& Flags::Children
) {
118 if (auto ChildrenEnum
= Symbol
.findAllChildren()) {
120 while (auto Child
= ChildrenEnum
->getNext())
127 void CompilandDumper::dump(const PDBSymbolData
&Symbol
) {
128 if (!shouldDumpSymLevel(opts::pretty::SymLevel::Data
))
130 if (Printer
.IsSymbolExcluded(Symbol
.getName()))
135 switch (auto LocType
= Symbol
.getLocationType()) {
136 case PDB_LocType::Static
:
138 WithColor(Printer
, PDB_ColorItem::Address
).get()
139 << "[" << format_hex(Symbol
.getVirtualAddress(), 10) << "]";
141 WithColor(Printer
, PDB_ColorItem::Comment
).get()
142 << " [sizeof = " << getTypeLength(Symbol
) << "]";
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
) << "]";
153 Printer
<< "data(unexpected type=" << LocType
<< ")";
157 WithColor(Printer
, PDB_ColorItem::Identifier
).get() << Symbol
.getName();
160 void CompilandDumper::dump(const PDBSymbolFunc
&Symbol
) {
161 if (!shouldDumpSymLevel(opts::pretty::SymLevel::Functions
))
163 if (Symbol
.getLength() == 0)
165 if (Printer
.IsSymbolExcluded(Symbol
.getName()))
169 FunctionDumper
Dumper(Printer
);
170 Dumper
.start(Symbol
, FunctionDumper::PointerType::None
);
173 void CompilandDumper::dump(const PDBSymbolLabel
&Symbol
) {
174 if (Printer
.IsSymbolExcluded(Symbol
.getName()))
179 WithColor(Printer
, PDB_ColorItem::Address
).get()
180 << "[" << format_hex(Symbol
.getVirtualAddress(), 10) << "] ";
181 WithColor(Printer
, PDB_ColorItem::Identifier
).get() << Symbol
.getName();
184 void CompilandDumper::dump(const PDBSymbolThunk
&Symbol
) {
185 if (!shouldDumpSymLevel(opts::pretty::SymLevel::Thunks
))
187 if (Printer
.IsSymbolExcluded(Symbol
.getName()))
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);
198 WithColor(Printer
, PDB_ColorItem::Address
).get() << format_hex(Target
, 10);
200 WithColor(Printer
, PDB_ColorItem::Address
).get()
201 << "[" << format_hex(VA
, 10) << " - "
202 << format_hex(VA
+ Symbol
.getLength(), 10) << "]";
205 WithColor(Printer
, PDB_ColorItem::Register
).get() << Ordinal
;
207 std::string Name
= Symbol
.getName();
209 WithColor(Printer
, PDB_ColorItem::Identifier
).get() << Name
;
212 void CompilandDumper::dump(const PDBSymbolTypeTypedef
&Symbol
) {}
214 void CompilandDumper::dump(const PDBSymbolUnknown
&Symbol
) {
216 Printer
<< "unknown (" << Symbol
.getSymTag() << ")";
219 void CompilandDumper::dump(const PDBSymbolUsingNamespace
&Symbol
) {
220 if (Printer
.IsSymbolExcluded(Symbol
.getName()))
224 Printer
<< "using namespace ";
225 std::string Name
= Symbol
.getName();
226 WithColor(Printer
, PDB_ColorItem::Identifier
).get() << Name
;