Skip to content

Commit 02a6ff6

Browse files
CarlosAlbertoEncisopfez
authored andcommitted
[llvm-pdbutil] Move InputFile/FormatUtil/LinePrinter to PDB library.
At Sony we are developing llvm-dva https://lists.llvm.org/pipermail/llvm-dev/2020-August/144174.html For its PDB support, it requires functionality already present in llvm-pdbutil. We intend to move that functionaly into the PDB library to be shared by both tools. That change will be done in 2 steps, that will be submitted as 2 patches: (1) Replace 'ExitOnError' with explicit error handling. (2) Move the intended shared code to the PDB library. Patch for step (1): https://reviews.llvm.org/D121801 This patch is for step (2). Move InputFile.cpp[h], FormatUtil.cpp[h] and LinePrinter.cpp[h] files to the debug PDB library. It exposes the following functionality that can be used by tools: - Open a PDB file. - Get module debug stream. - Traverse module sections. - Traverse module subsections. Most of the needed functionality is in InputFile, but there are dependencies from LinePrinter and FormatUtil. Some other functionality is in the following functions in DumpOutputStyle.cpp file: - iterateModuleSubsections - getModuleDebugStream - iterateOneModule - iterateSymbolGroups - iterateModuleSubsections Only these specific functions from DumpOutputStyle are moved to the PDB library. Reviewed By: aganea, dblaikie, rnk Differential Revision: https://reviews.llvm.org/D122226
1 parent 2e117de commit 02a6ff6

31 files changed

+294
-203
lines changed

llvm/tools/llvm-pdbutil/FormatUtil.h renamed to llvm/include/llvm/DebugInfo/PDB/Native/FormatUtil.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
//
77
//===----------------------------------------------------------------------===//
88

9-
#ifndef LLVM_TOOLS_LLVMPDBUTIL_FORMAT_UTIL_H
10-
#define LLVM_TOOLS_LLVMPDBUTIL_FORMAT_UTIL_H
9+
#ifndef LLVM_DEBUGINFO_PDB_NATIVE_FORMATUTIL_H
10+
#define LLVM_DEBUGINFO_PDB_NATIVE_FORMATUTIL_H
1111

1212
#include "llvm/ADT/ArrayRef.h"
1313
#include "llvm/ADT/StringRef.h"
@@ -136,6 +136,6 @@ fmtle(support::detail::packed_endian_specific_integral<T, support::little,
136136
Value) {
137137
return detail::EndianAdapter<T>(std::move(Value));
138138
}
139-
}
139+
} // namespace pdb
140140
} // namespace llvm
141141
#endif

llvm/tools/llvm-pdbutil/InputFile.h renamed to llvm/include/llvm/DebugInfo/PDB/Native/InputFile.h

Lines changed: 81 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,16 @@
66
//
77
//===----------------------------------------------------------------------===//
88

9-
#ifndef LLVM_TOOLS_LLVMPDBDUMP_INPUTFILE_H
10-
#define LLVM_TOOLS_LLVMPDBDUMP_INPUTFILE_H
9+
#ifndef LLVM_DEBUGINFO_PDB_NATIVE_INPUTFILE_H
10+
#define LLVM_DEBUGINFO_PDB_NATIVE_INPUTFILE_H
1111

1212
#include "llvm/ADT/Optional.h"
1313
#include "llvm/ADT/PointerUnion.h"
1414
#include "llvm/ADT/StringMap.h"
1515
#include "llvm/ADT/iterator.h"
1616
#include "llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h"
1717
#include "llvm/DebugInfo/CodeView/StringsAndChecksums.h"
18+
#include "llvm/DebugInfo/PDB/Native/LinePrinter.h"
1819
#include "llvm/DebugInfo/PDB/Native/ModuleDebugStream.h"
1920
#include "llvm/Object/Binary.h"
2021
#include "llvm/Object/ObjectFile.h"
@@ -55,6 +56,9 @@ class InputFile {
5556
getOrCreateTypeCollection(TypeCollectionKind Kind);
5657

5758
public:
59+
InputFile(PDBFile *Pdb) { PdbOrObj = Pdb; }
60+
InputFile(object::COFFObjectFile *Obj) { PdbOrObj = Obj; }
61+
InputFile(MemoryBuffer *Buffer) { PdbOrObj = Buffer; }
5862
~InputFile();
5963
InputFile(InputFile &&Other) = default;
6064

@@ -92,6 +96,7 @@ class SymbolGroup {
9296
explicit SymbolGroup(InputFile *File, uint32_t GroupIndex = 0);
9397

9498
Expected<StringRef> getNameFromStringTable(uint32_t Offset) const;
99+
Expected<StringRef> getNameFromChecksums(uint32_t Offset) const;
95100

96101
void formatFromFileName(LinePrinter &Printer, StringRef File,
97102
bool Append = false) const;
@@ -149,6 +154,80 @@ class SymbolGroupIterator
149154
SymbolGroup Value;
150155
};
151156

157+
Expected<ModuleDebugStreamRef>
158+
getModuleDebugStream(PDBFile &File, StringRef &ModuleName, uint32_t Index);
159+
Expected<ModuleDebugStreamRef> getModuleDebugStream(PDBFile &File,
160+
uint32_t Index);
161+
162+
bool shouldDumpSymbolGroup(uint32_t Idx, const SymbolGroup &Group);
163+
164+
// TODO: Change these callbacks to be function_refs (de-templatify them).
165+
template <typename CallbackT>
166+
Error iterateOneModule(InputFile &File, const Optional<PrintScope> &HeaderScope,
167+
const SymbolGroup &SG, uint32_t Modi,
168+
CallbackT Callback) {
169+
if (HeaderScope) {
170+
HeaderScope->P.formatLine(
171+
"Mod {0:4} | `{1}`: ",
172+
fmt_align(Modi, AlignStyle::Right, HeaderScope->LabelWidth), SG.name());
173+
}
174+
175+
AutoIndent Indent(HeaderScope);
176+
return Callback(Modi, SG);
177+
}
178+
179+
template <typename CallbackT>
180+
Error iterateSymbolGroups(InputFile &Input,
181+
const Optional<PrintScope> &HeaderScope,
182+
CallbackT Callback) {
183+
AutoIndent Indent(HeaderScope);
184+
185+
if (llvm::pdb::Filters.DumpModi > 0) {
186+
assert(llvm::pdb::Filters.DumpModi == 1);
187+
uint32_t Modi = llvm::pdb::Filters.DumpModi;
188+
SymbolGroup SG(&Input, Modi);
189+
return iterateOneModule(Input, withLabelWidth(HeaderScope, NumDigits(Modi)),
190+
SG, Modi, Callback);
191+
}
192+
193+
uint32_t I = 0;
194+
195+
for (const auto &SG : Input.symbol_groups()) {
196+
if (shouldDumpSymbolGroup(I, SG))
197+
if (auto Err =
198+
iterateOneModule(Input, withLabelWidth(HeaderScope, NumDigits(I)),
199+
SG, I, Callback))
200+
return Err;
201+
202+
++I;
203+
}
204+
return Error::success();
205+
}
206+
207+
template <typename SubsectionT>
208+
Error iterateModuleSubsections(
209+
InputFile &File, const Optional<PrintScope> &HeaderScope,
210+
llvm::function_ref<Error(uint32_t, const SymbolGroup &, SubsectionT &)>
211+
Callback) {
212+
213+
return iterateSymbolGroups(
214+
File, HeaderScope, [&](uint32_t Modi, const SymbolGroup &SG) -> Error {
215+
for (const auto &SS : SG.getDebugSubsections()) {
216+
SubsectionT Subsection;
217+
218+
if (SS.kind() != Subsection.kind())
219+
continue;
220+
221+
BinaryStreamReader Reader(SS.getRecordData());
222+
if (auto Err = Subsection.initialize(Reader))
223+
continue;
224+
if (auto Err = Callback(Modi, SG, Subsection))
225+
return Err;
226+
}
227+
return Error::success();
228+
});
229+
}
230+
152231
} // namespace pdb
153232
} // namespace llvm
154233

llvm/tools/llvm-pdbutil/LinePrinter.h renamed to llvm/include/llvm/DebugInfo/PDB/Native/LinePrinter.h

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,45 +6,63 @@
66
//
77
//===----------------------------------------------------------------------===//
88

9-
#ifndef LLVM_TOOLS_LLVMPDBDUMP_LINEPRINTER_H
10-
#define LLVM_TOOLS_LLVMPDBDUMP_LINEPRINTER_H
9+
#ifndef LLVM_DEBUGINFO_PDB_NATIVE_LINEPRINTER_H
10+
#define LLVM_DEBUGINFO_PDB_NATIVE_LINEPRINTER_H
1111

1212
#include "llvm/ADT/ArrayRef.h"
1313
#include "llvm/ADT/StringRef.h"
1414
#include "llvm/ADT/Twine.h"
15+
#include "llvm/DebugInfo/PDB/Native/FormatUtil.h"
1516
#include "llvm/Support/BinaryStreamRef.h"
1617
#include "llvm/Support/FormatVariadic.h"
1718
#include "llvm/Support/Regex.h"
1819
#include "llvm/Support/raw_ostream.h"
1920

2021
#include <list>
2122

23+
// Container for filter options to control which elements will be printed.
24+
struct FilterOptions {
25+
std::list<std::string> ExcludeTypes;
26+
std::list<std::string> ExcludeSymbols;
27+
std::list<std::string> ExcludeCompilands;
28+
std::list<std::string> IncludeTypes;
29+
std::list<std::string> IncludeSymbols;
30+
std::list<std::string> IncludeCompilands;
31+
uint32_t PaddingThreshold;
32+
uint32_t SizeThreshold;
33+
uint32_t DumpModi;
34+
bool JustMyCode;
35+
};
36+
2237
namespace llvm {
2338
class BinaryStreamReader;
2439
namespace msf {
2540
class MSFStreamLayout;
2641
} // namespace msf
2742
namespace pdb {
2843

44+
extern FilterOptions Filters;
45+
2946
class ClassLayout;
3047
class PDBFile;
3148

3249
class LinePrinter {
3350
friend class WithColor;
3451

3552
public:
36-
LinePrinter(int Indent, bool UseColor, raw_ostream &Stream);
53+
LinePrinter(int Indent, bool UseColor, raw_ostream &Stream,
54+
FilterOptions &Filters);
3755

3856
void Indent(uint32_t Amount = 0);
3957
void Unindent(uint32_t Amount = 0);
4058
void NewLine();
4159

4260
void printLine(const Twine &T);
4361
void print(const Twine &T);
44-
template <typename... Ts> void formatLine(const char *Fmt, Ts &&... Items) {
62+
template <typename... Ts> void formatLine(const char *Fmt, Ts &&...Items) {
4563
printLine(formatv(Fmt, std::forward<Ts>(Items)...));
4664
}
47-
template <typename... Ts> void format(const char *Fmt, Ts &&... Items) {
65+
template <typename... Ts> void format(const char *Fmt, Ts &&...Items) {
4866
print(formatv(Fmt, std::forward<Ts>(Items)...));
4967
}
5068

@@ -162,7 +180,7 @@ class WithColor {
162180
raw_ostream &OS;
163181
bool UseColor;
164182
};
165-
}
166-
}
183+
} // namespace pdb
184+
} // namespace llvm
167185

168186
#endif

llvm/lib/DebugInfo/PDB/CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,12 +47,15 @@ add_pdb_impl_folder(Native
4747
Native/DbiStream.cpp
4848
Native/DbiStreamBuilder.cpp
4949
Native/EnumTables.cpp
50+
Native/FormatUtil.cpp
5051
Native/GlobalsStream.cpp
5152
Native/Hash.cpp
5253
Native/HashTable.cpp
5354
Native/InfoStream.cpp
5455
Native/InfoStreamBuilder.cpp
5556
Native/InjectedSourceStream.cpp
57+
Native/InputFile.cpp
58+
Native/LinePrinter.cpp
5659
Native/ModuleDebugStream.cpp
5760
Native/NativeCompilandSymbol.cpp
5861
Native/NativeEnumGlobals.cpp

llvm/tools/llvm-pdbutil/FormatUtil.cpp renamed to llvm/lib/DebugInfo/PDB/Native/FormatUtil.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66
//
77
//===----------------------------------------------------------------------===//
88

9-
#include "FormatUtil.h"
9+
#include "llvm/DebugInfo/PDB/Native/FormatUtil.h"
10+
1011
#include "llvm/ADT/STLExtras.h"
1112
#include "llvm/ADT/StringExtras.h"
1213
#include "llvm/BinaryFormat/COFF.h"

llvm/tools/llvm-pdbutil/InputFile.cpp renamed to llvm/lib/DebugInfo/PDB/Native/InputFile.cpp

Lines changed: 81 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,15 @@
66
//
77
//===----------------------------------------------------------------------===//
88

9-
#include "InputFile.h"
10-
11-
#include "FormatUtil.h"
12-
#include "LinePrinter.h"
9+
#include "llvm/DebugInfo/PDB/Native/InputFile.h"
1310

1411
#include "llvm/BinaryFormat/Magic.h"
1512
#include "llvm/DebugInfo/CodeView/CodeView.h"
1613
#include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h"
1714
#include "llvm/DebugInfo/CodeView/StringsAndChecksums.h"
1815
#include "llvm/DebugInfo/PDB/Native/DbiStream.h"
16+
#include "llvm/DebugInfo/PDB/Native/FormatUtil.h"
17+
#include "llvm/DebugInfo/PDB/Native/LinePrinter.h"
1918
#include "llvm/DebugInfo/PDB/Native/NativeSession.h"
2019
#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
2120
#include "llvm/DebugInfo/PDB/Native/PDBStringTable.h"
@@ -34,8 +33,9 @@ using namespace llvm::pdb;
3433
InputFile::InputFile() {}
3534
InputFile::~InputFile() {}
3635

37-
static Expected<ModuleDebugStreamRef>
38-
getModuleDebugStream(PDBFile &File, StringRef &ModuleName, uint32_t Index) {
36+
Expected<ModuleDebugStreamRef>
37+
llvm::pdb::getModuleDebugStream(PDBFile &File, StringRef &ModuleName,
38+
uint32_t Index) {
3939
Expected<DbiStream &> DbiOrErr = File.getPDBDbiStream();
4040
if (!DbiOrErr)
4141
return DbiOrErr.takeError();
@@ -64,6 +64,30 @@ getModuleDebugStream(PDBFile &File, StringRef &ModuleName, uint32_t Index) {
6464
return std::move(ModS);
6565
}
6666

67+
Expected<ModuleDebugStreamRef> llvm::pdb::getModuleDebugStream(PDBFile &File,
68+
uint32_t Index) {
69+
Expected<DbiStream &> DbiOrErr = File.getPDBDbiStream();
70+
if (!DbiOrErr)
71+
return DbiOrErr.takeError();
72+
DbiStream &Dbi = *DbiOrErr;
73+
const auto &Modules = Dbi.modules();
74+
auto Modi = Modules.getModuleDescriptor(Index);
75+
76+
uint16_t ModiStream = Modi.getModuleStreamIndex();
77+
if (ModiStream == kInvalidStreamIndex)
78+
return make_error<RawError>(raw_error_code::no_stream,
79+
"Module stream not present");
80+
81+
auto ModStreamData = File.createIndexedStream(ModiStream);
82+
83+
ModuleDebugStreamRef ModS(Modi, std::move(ModStreamData));
84+
if (Error Err = ModS.reload())
85+
return make_error<RawError>(raw_error_code::corrupt_file,
86+
"Invalid module stream");
87+
88+
return std::move(ModS);
89+
}
90+
6791
static inline bool isCodeViewDebugSubsection(object::SectionRef Section,
6892
StringRef Name,
6993
BinaryStreamReader &Reader) {
@@ -121,7 +145,7 @@ static std::string formatChecksumKind(FileChecksumKind Kind) {
121145
}
122146

123147
template <typename... Args>
124-
static void formatInternal(LinePrinter &Printer, bool Append, Args &&... args) {
148+
static void formatInternal(LinePrinter &Printer, bool Append, Args &&...args) {
125149
if (Append)
126150
Printer.format(std::forward<Args>(args)...);
127151
else
@@ -210,6 +234,26 @@ Expected<StringRef> SymbolGroup::getNameFromStringTable(uint32_t Offset) const {
210234
return SC.strings().getString(Offset);
211235
}
212236

237+
Expected<StringRef> SymbolGroup::getNameFromChecksums(uint32_t Offset) const {
238+
StringRef Name;
239+
if (!SC.hasChecksums()) {
240+
return std::move(Name);
241+
}
242+
243+
auto Iter = SC.checksums().getArray().at(Offset);
244+
if (Iter == SC.checksums().getArray().end()) {
245+
return std::move(Name);
246+
}
247+
248+
uint32_t FO = Iter->FileNameOffset;
249+
auto ExpectedFile = getNameFromStringTable(FO);
250+
if (!ExpectedFile) {
251+
return std::move(Name);
252+
}
253+
254+
return *ExpectedFile;
255+
}
256+
213257
void SymbolGroup::formatFromFileName(LinePrinter &Printer, StringRef File,
214258
bool Append) const {
215259
auto FC = ChecksumsByFile.find(File);
@@ -508,3 +552,33 @@ bool SymbolGroupIterator::isEnd() const {
508552
assert(SectionIter.hasValue());
509553
return *SectionIter == Value.File->obj().section_end();
510554
}
555+
556+
static bool isMyCode(const SymbolGroup &Group) {
557+
if (Group.getFile().isObj())
558+
return true;
559+
560+
StringRef Name = Group.name();
561+
if (Name.startswith("Import:"))
562+
return false;
563+
if (Name.endswith_lower(".dll"))
564+
return false;
565+
if (Name.equals_lower("* linker *"))
566+
return false;
567+
if (Name.startswith_lower("f:\\binaries\\Intermediate\\vctools"))
568+
return false;
569+
if (Name.startswith_lower("f:\\dd\\vctools\\crt"))
570+
return false;
571+
return true;
572+
}
573+
574+
bool llvm::pdb::shouldDumpSymbolGroup(uint32_t Idx, const SymbolGroup &Group) {
575+
if (llvm::pdb::Filters.JustMyCode && !isMyCode(Group))
576+
return false;
577+
578+
// If the arg was not specified on the command line, always dump all modules.
579+
if (llvm::pdb::Filters.DumpModi == 0)
580+
return true;
581+
582+
// Otherwise, only dump if this is the same module specified.
583+
return (llvm::pdb::Filters.DumpModi == Idx);
584+
}

0 commit comments

Comments
 (0)