Skip to content

Commit 7511213

Browse files
[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 5035455 commit 7511213

31 files changed

+291
-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"
@@ -54,6 +55,9 @@ class InputFile {
5455
getOrCreateTypeCollection(TypeCollectionKind Kind);
5556

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

@@ -91,6 +95,7 @@ class SymbolGroup {
9195
explicit SymbolGroup(InputFile *File, uint32_t GroupIndex = 0);
9296

9397
Expected<StringRef> getNameFromStringTable(uint32_t Offset) const;
98+
Expected<StringRef> getNameFromChecksums(uint32_t Offset) const;
9499

95100
void formatFromFileName(LinePrinter &Printer, StringRef File,
96101
bool Append = false) const;
@@ -148,6 +153,80 @@ class SymbolGroupIterator
148153
SymbolGroup Value;
149154
};
150155

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

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,44 +6,62 @@
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
namespace msf {
2439
class MSFStreamLayout;
2540
} // namespace msf
2641
namespace pdb {
2742

43+
extern FilterOptions Filters;
44+
2845
class ClassLayout;
2946
class PDBFile;
3047

3148
class LinePrinter {
3249
friend class WithColor;
3350

3451
public:
35-
LinePrinter(int Indent, bool UseColor, raw_ostream &Stream);
52+
LinePrinter(int Indent, bool UseColor, raw_ostream &Stream,
53+
FilterOptions &Filters);
3654

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

4159
void printLine(const Twine &T);
4260
void print(const Twine &T);
43-
template <typename... Ts> void formatLine(const char *Fmt, Ts &&... Items) {
61+
template <typename... Ts> void formatLine(const char *Fmt, Ts &&...Items) {
4462
printLine(formatv(Fmt, std::forward<Ts>(Items)...));
4563
}
46-
template <typename... Ts> void format(const char *Fmt, Ts &&... Items) {
64+
template <typename... Ts> void format(const char *Fmt, Ts &&...Items) {
4765
print(formatv(Fmt, std::forward<Ts>(Items)...));
4866
}
4967

@@ -161,7 +179,7 @@ class WithColor {
161179
raw_ostream &OS;
162180
bool UseColor;
163181
};
164-
}
165-
}
182+
} // namespace pdb
183+
} // namespace llvm
166184

167185
#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,17 +6,16 @@
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/MSF/MappedBlockStream.h"
1916
#include "llvm/DebugInfo/PDB/Native/DbiStream.h"
17+
#include "llvm/DebugInfo/PDB/Native/FormatUtil.h"
18+
#include "llvm/DebugInfo/PDB/Native/LinePrinter.h"
2019
#include "llvm/DebugInfo/PDB/Native/NativeSession.h"
2120
#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
2221
#include "llvm/DebugInfo/PDB/Native/PDBStringTable.h"
@@ -35,8 +34,9 @@ using namespace llvm::pdb;
3534
InputFile::InputFile() {}
3635
InputFile::~InputFile() {}
3736

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

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

124148
template <typename... Args>
125-
static void formatInternal(LinePrinter &Printer, bool Append, Args &&... args) {
149+
static void formatInternal(LinePrinter &Printer, bool Append, Args &&...args) {
126150
if (Append)
127151
Printer.format(std::forward<Args>(args)...);
128152
else
@@ -211,6 +235,26 @@ Expected<StringRef> SymbolGroup::getNameFromStringTable(uint32_t Offset) const {
211235
return SC.strings().getString(Offset);
212236
}
213237

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

0 commit comments

Comments
 (0)