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/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"
38 using namespace llvm::pdb
;
40 CompilandDumper::CompilandDumper(LinePrinter
&P
)
41 : PDBSymDumper(true), Printer(P
) {}
43 void CompilandDumper::dump(const PDBSymbolCompilandDetails
&Symbol
) {}
45 void CompilandDumper::dump(const PDBSymbolCompilandEnv
&Symbol
) {}
47 void CompilandDumper::start(const PDBSymbolCompiland
&Symbol
,
48 CompilandDumpFlags opts
) {
49 std::string FullName
= Symbol
.getName();
50 if (Printer
.IsCompilandExcluded(FullName
))
54 WithColor(Printer
, PDB_ColorItem::Path
).get() << FullName
;
56 if (opts
& Flags::Lines
) {
57 const IPDBSession
&Session
= Symbol
.getSession();
58 if (auto Files
= Session
.getSourceFilesForCompiland(Symbol
)) {
60 while (auto File
= Files
->getNext()) {
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
<< ")";
70 auto Lines
= Session
.findLineNumbers(Symbol
, *File
);
75 while (auto Line
= Lines
->getNext()) {
77 uint32_t LineStart
= Line
->getLineNumber();
78 uint32_t LineEnd
= Line
->getLineNumberEnd();
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
;
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
;
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)";
106 uint64_t AddrStart
= Line
->getVirtualAddress();
107 WithColor(Printer
, PDB_ColorItem::Address
).get()
108 << "[" << format_hex(AddrStart
, 10) << "] ";
109 Printer
<< "(0 bytes)";
118 if (opts
& Flags::Children
) {
119 if (auto ChildrenEnum
= Symbol
.findAllChildren()) {
121 while (auto Child
= ChildrenEnum
->getNext())
128 void CompilandDumper::dump(const PDBSymbolData
&Symbol
) {
129 if (!shouldDumpSymLevel(opts::pretty::SymLevel::Data
))
131 if (Printer
.IsSymbolExcluded(Symbol
.getName()))
136 switch (auto LocType
= Symbol
.getLocationType()) {
137 case PDB_LocType::Static
:
139 WithColor(Printer
, PDB_ColorItem::Address
).get()
140 << "[" << format_hex(Symbol
.getVirtualAddress(), 10) << "]";
142 WithColor(Printer
, PDB_ColorItem::Comment
).get()
143 << " [sizeof = " << getTypeLength(Symbol
) << "]";
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
) << "]";
154 Printer
<< "data(unexpected type=" << LocType
<< ")";
158 WithColor(Printer
, PDB_ColorItem::Identifier
).get() << Symbol
.getName();
161 void CompilandDumper::dump(const PDBSymbolFunc
&Symbol
) {
162 if (!shouldDumpSymLevel(opts::pretty::SymLevel::Functions
))
164 if (Symbol
.getLength() == 0)
166 if (Printer
.IsSymbolExcluded(Symbol
.getName()))
170 FunctionDumper
Dumper(Printer
);
171 Dumper
.start(Symbol
, FunctionDumper::PointerType::None
);
174 void CompilandDumper::dump(const PDBSymbolLabel
&Symbol
) {
175 if (Printer
.IsSymbolExcluded(Symbol
.getName()))
180 WithColor(Printer
, PDB_ColorItem::Address
).get()
181 << "[" << format_hex(Symbol
.getVirtualAddress(), 10) << "] ";
182 WithColor(Printer
, PDB_ColorItem::Identifier
).get() << Symbol
.getName();
185 void CompilandDumper::dump(const PDBSymbolThunk
&Symbol
) {
186 if (!shouldDumpSymLevel(opts::pretty::SymLevel::Thunks
))
188 if (Printer
.IsSymbolExcluded(Symbol
.getName()))
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);
199 WithColor(Printer
, PDB_ColorItem::Address
).get() << format_hex(Target
, 10);
201 WithColor(Printer
, PDB_ColorItem::Address
).get()
202 << "[" << format_hex(VA
, 10) << " - "
203 << format_hex(VA
+ Symbol
.getLength(), 10) << "]";
206 WithColor(Printer
, PDB_ColorItem::Register
).get() << Ordinal
;
208 std::string Name
= Symbol
.getName();
210 WithColor(Printer
, PDB_ColorItem::Identifier
).get() << Name
;
213 void CompilandDumper::dump(const PDBSymbolTypeTypedef
&Symbol
) {}
215 void CompilandDumper::dump(const PDBSymbolUnknown
&Symbol
) {
217 Printer
<< "unknown (" << Symbol
.getSymTag() << ")";
220 void CompilandDumper::dump(const PDBSymbolUsingNamespace
&Symbol
) {
221 if (Printer
.IsSymbolExcluded(Symbol
.getName()))
225 Printer
<< "using namespace ";
226 std::string Name
= Symbol
.getName();
227 WithColor(Printer
, PDB_ColorItem::Identifier
).get() << Name
;