Skip to content

Commit a3b7cb0

Browse files
committed
[llvm-pdbutil] Add options to only dump symbol record at specified offset and its parents or children with spcified depth.
Right now, if we want to dump symbol at specified offset, we need to use `grep`. And it can only show surrounding symbols in layout (not in lexical scope sense). This adds similar options to `dump` command as `llvm-dwarfdump` to allow users to dump symbol record at specified offset and its parents or children with spcified depth. `--symbol-offset=` must be used with `--modi` to dump only one symbol at given offset. `--show-parents`/`--show-children` must be used with `--symbol-offset` to dump all symbols that are parents/children of the symbol at given offset. `--parent-recurse-depth`/`--children-recurse-depth` must be used with `--show-parents`/`--show-children` to specify the max up/down depth. Reviewed By: rnk Differential Revision: https://reviews.llvm.org/D124317
1 parent 18b9c46 commit a3b7cb0

File tree

10 files changed

+516
-8
lines changed

10 files changed

+516
-8
lines changed

llvm/include/llvm/DebugInfo/CodeView/CVSymbolVisitor.h

+8
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,20 @@ class SymbolVisitorCallbacks;
1818

1919
class CVSymbolVisitor {
2020
public:
21+
struct FilterOptions {
22+
llvm::Optional<uint32_t> SymbolOffset;
23+
llvm::Optional<uint32_t> ParentRecursiveDepth;
24+
llvm::Optional<uint32_t> ChildRecursiveDepth;
25+
};
26+
2127
CVSymbolVisitor(SymbolVisitorCallbacks &Callbacks);
2228

2329
Error visitSymbolRecord(CVSymbol &Record);
2430
Error visitSymbolRecord(CVSymbol &Record, uint32_t Offset);
2531
Error visitSymbolStream(const CVSymbolArray &Symbols);
2632
Error visitSymbolStream(const CVSymbolArray &Symbols, uint32_t InitialOffset);
33+
Error visitSymbolStreamFiltered(const CVSymbolArray &Symbols,
34+
const FilterOptions &Filter);
2735

2836
private:
2937
SymbolVisitorCallbacks &Callbacks;

llvm/include/llvm/DebugInfo/PDB/Native/InputFile.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -180,8 +180,8 @@ Error iterateSymbolGroups(InputFile &Input, const PrintScope &HeaderScope,
180180
AutoIndent Indent(HeaderScope);
181181

182182
FilterOptions Filters = HeaderScope.P.getFilters();
183-
if (Filters.NumOccurrences) {
184-
uint32_t Modi = Filters.DumpModi;
183+
if (Filters.DumpModi) {
184+
uint32_t Modi = Filters.DumpModi.getValue();
185185
SymbolGroup SG(&Input, Modi);
186186
return iterateOneModule(Input, withLabelWidth(HeaderScope, NumDigits(Modi)),
187187
SG, Modi, Callback);

llvm/include/llvm/DebugInfo/PDB/Native/LinePrinter.h

+4-2
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,10 @@ struct FilterOptions {
3030
std::list<std::string> IncludeCompilands;
3131
uint32_t PaddingThreshold;
3232
uint32_t SizeThreshold;
33-
uint32_t DumpModi;
34-
uint32_t NumOccurrences;
33+
llvm::Optional<uint32_t> DumpModi;
34+
llvm::Optional<uint32_t> ParentRecurseDepth;
35+
llvm::Optional<uint32_t> ChildrenRecurseDepth;
36+
llvm::Optional<uint32_t> SymbolOffset;
3537
bool JustMyCode;
3638
};
3739

llvm/include/llvm/Support/BinaryStreamArray.h

+2
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,8 @@ class VarStreamArray {
111111

112112
bool valid() const { return Stream.valid(); }
113113

114+
bool isOffsetValid(uint32_t Offset) const { return at(Offset) != end(); }
115+
114116
uint32_t skew() const { return Skew; }
115117
Iterator end() const { return Iterator(E); }
116118

llvm/lib/DebugInfo/CodeView/CVSymbolVisitor.cpp

+72
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
#include "llvm/DebugInfo/CodeView/CodeView.h"
1212
#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
13+
#include "llvm/DebugInfo/CodeView/SymbolRecordHelpers.h"
1314
#include "llvm/DebugInfo/CodeView/SymbolVisitorCallbacks.h"
1415
#include "llvm/Support/BinaryStreamArray.h"
1516
#include "llvm/Support/ErrorHandling.h"
@@ -83,3 +84,74 @@ Error CVSymbolVisitor::visitSymbolStream(const CVSymbolArray &Symbols,
8384
}
8485
return Error::success();
8586
}
87+
88+
Error CVSymbolVisitor::visitSymbolStreamFiltered(const CVSymbolArray &Symbols,
89+
const FilterOptions &Filter) {
90+
if (!Filter.SymbolOffset)
91+
return visitSymbolStream(Symbols);
92+
uint32_t SymbolOffset = *Filter.SymbolOffset;
93+
uint32_t ParentRecurseDepth =
94+
Filter.ParentRecursiveDepth ? *Filter.ParentRecursiveDepth : 0;
95+
uint32_t ChildrenRecurseDepth =
96+
Filter.ChildRecursiveDepth ? *Filter.ChildRecursiveDepth : 0;
97+
if (!Symbols.isOffsetValid(SymbolOffset))
98+
return createStringError(inconvertibleErrorCode(), "Invalid symbol offset");
99+
CVSymbol Sym = *Symbols.at(SymbolOffset);
100+
uint32_t SymEndOffset =
101+
symbolOpensScope(Sym.kind()) ? getScopeEndOffset(Sym) : 0;
102+
103+
std::vector<uint32_t> ParentOffsets;
104+
std::vector<uint32_t> ParentEndOffsets;
105+
uint32_t ChildrenDepth = 0;
106+
for (auto Begin = Symbols.begin(), End = Symbols.end(); Begin != End;
107+
++Begin) {
108+
uint32_t BeginOffset = Begin.offset();
109+
CVSymbol BeginSym = *Begin;
110+
if (BeginOffset < SymbolOffset) {
111+
if (symbolOpensScope(Begin->kind())) {
112+
uint32_t EndOffset = getScopeEndOffset(BeginSym);
113+
if (SymbolOffset < EndOffset) {
114+
ParentOffsets.push_back(BeginOffset);
115+
ParentEndOffsets.push_back(EndOffset);
116+
}
117+
}
118+
} else if (BeginOffset == SymbolOffset) {
119+
// Found symbol at offset. Visit its parent up to ParentRecurseDepth.
120+
if (ParentRecurseDepth >= ParentOffsets.size())
121+
ParentRecurseDepth = ParentOffsets.size();
122+
uint32_t StartIndex = ParentOffsets.size() - ParentRecurseDepth;
123+
while (StartIndex < ParentOffsets.size()) {
124+
if (!Symbols.isOffsetValid(ParentOffsets[StartIndex]))
125+
break;
126+
CVSymbol Parent = *Symbols.at(ParentOffsets[StartIndex]);
127+
if (auto EC = visitSymbolRecord(Parent, ParentOffsets[StartIndex]))
128+
return EC;
129+
++StartIndex;
130+
}
131+
if (auto EC = visitSymbolRecord(Sym, SymbolOffset))
132+
return EC;
133+
} else if (BeginOffset <= SymEndOffset) {
134+
if (ChildrenRecurseDepth) {
135+
// Visit children.
136+
if (symbolEndsScope(Begin->kind()))
137+
--ChildrenDepth;
138+
if (ChildrenDepth < ChildrenRecurseDepth ||
139+
BeginOffset == SymEndOffset) {
140+
if (auto EC = visitSymbolRecord(BeginSym, BeginOffset))
141+
return EC;
142+
}
143+
if (symbolOpensScope(Begin->kind()))
144+
++ChildrenDepth;
145+
}
146+
} else {
147+
// Visit parents' ends.
148+
if (ParentRecurseDepth && BeginOffset == ParentEndOffsets.back()) {
149+
if (auto EC = visitSymbolRecord(BeginSym, BeginOffset))
150+
return EC;
151+
ParentEndOffsets.pop_back();
152+
--ParentRecurseDepth;
153+
}
154+
}
155+
}
156+
return Error::success();
157+
}

llvm/lib/DebugInfo/PDB/Native/InputFile.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -579,7 +579,7 @@ bool llvm::pdb::shouldDumpSymbolGroup(uint32_t Idx, const SymbolGroup &Group,
579579
return false;
580580

581581
// If the arg was not specified on the command line, always dump all modules.
582-
if (Filters.NumOccurrences == 0)
582+
if (!Filters.DumpModi)
583583
return true;
584584

585585
// Otherwise, only dump if this is the same module specified.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,204 @@
1+
---
2+
DbiStream:
3+
VerHeader: V70
4+
Age: 1
5+
BuildNumber: 36363
6+
PdbDllVersion: 0
7+
PdbDllRbld: 0
8+
Flags: 0
9+
MachineType: Amd64
10+
Modules:
11+
- Module: '/tmp/test.obj'
12+
Modi:
13+
Signature: 4
14+
Records:
15+
- Kind: S_GPROC32
16+
ProcSym:
17+
PtrParent: 0
18+
PtrEnd: 468
19+
PtrNext: 0
20+
CodeSize: 137
21+
DbgStart: 0
22+
DbgEnd: 0
23+
FunctionType: 4104
24+
Offset: 176
25+
Segment: 1
26+
Flags: [ ]
27+
DisplayName: main
28+
- Kind: S_FRAMEPROC
29+
FrameProcSym:
30+
TotalFrameBytes: 56
31+
PaddingFrameBytes: 0
32+
OffsetToPadding: 0
33+
BytesOfCalleeSavedRegisters: 0
34+
OffsetOfExceptionHandler: 0
35+
SectionIdOfExceptionHandler: 0
36+
Flags: [ ]
37+
- Kind: S_LOCAL
38+
LocalSym:
39+
Type: 116
40+
Flags: [ IsParameter ]
41+
VarName: argc
42+
- Kind: S_DEFRANGE_FRAMEPOINTER_REL
43+
DefRangeFramePointerRelSym:
44+
Offset: 4
45+
Range:
46+
OffsetStart: 197
47+
ISectStart: 1
48+
Range: 116
49+
Gaps: []
50+
- Kind: S_LOCAL
51+
LocalSym:
52+
Type: 4102
53+
Flags: [ IsParameter ]
54+
VarName: argv
55+
- Kind: S_DEFRANGE_FRAMEPOINTER_REL
56+
DefRangeFramePointerRelSym:
57+
Offset: 8
58+
Range:
59+
OffsetStart: 197
60+
ISectStart: 1
61+
Range: 116
62+
Gaps: []
63+
- Kind: S_INLINESITE
64+
InlineSiteSym:
65+
PtrParent: 4
66+
PtrEnd: 464
67+
Inlinee: 4098
68+
- Kind: S_LOCAL
69+
LocalSym:
70+
Type: 116
71+
Flags: [ IsParameter ]
72+
VarName: x
73+
- Kind: S_DEFRANGE_FRAMEPOINTER_REL
74+
DefRangeFramePointerRelSym:
75+
Offset: 24
76+
Range:
77+
OffsetStart: 221
78+
ISectStart: 1
79+
Range: 87
80+
Gaps: []
81+
- Kind: S_LOCAL
82+
LocalSym:
83+
Type: 116
84+
Flags: [ IsParameter ]
85+
VarName: y
86+
- Kind: S_DEFRANGE_FRAMEPOINTER_REL
87+
DefRangeFramePointerRelSym:
88+
Offset: 28
89+
Range:
90+
OffsetStart: 221
91+
ISectStart: 1
92+
Range: 87
93+
Gaps: []
94+
- Kind: S_LOCAL
95+
LocalSym:
96+
Type: 116
97+
Flags: [ IsParameter ]
98+
VarName: z
99+
- Kind: S_DEFRANGE_FRAMEPOINTER_REL
100+
DefRangeFramePointerRelSym:
101+
Offset: 32
102+
Range:
103+
OffsetStart: 221
104+
ISectStart: 1
105+
Range: 87
106+
Gaps: []
107+
- Kind: S_INLINESITE
108+
InlineSiteSym:
109+
PtrParent: 144
110+
PtrEnd: 288
111+
Inlinee: 4096
112+
- Kind: S_LOCAL
113+
LocalSym:
114+
Type: 116
115+
Flags: [ IsParameter ]
116+
VarName: x
117+
- Kind: S_DEFRANGE_FRAMEPOINTER_REL
118+
DefRangeFramePointerRelSym:
119+
Offset: 40
120+
Range:
121+
OffsetStart: 229
122+
ISectStart: 1
123+
Range: 7
124+
Gaps: []
125+
- Kind: S_INLINESITE_END
126+
ScopeEndSym: {}
127+
- Kind: S_INLINESITE
128+
InlineSiteSym:
129+
PtrParent: 144
130+
PtrEnd: 412
131+
Inlinee: 4097
132+
- Kind: S_LOCAL
133+
LocalSym:
134+
Type: 116
135+
Flags: [ IsParameter ]
136+
VarName: x
137+
- Kind: S_DEFRANGE_FRAMEPOINTER_REL
138+
DefRangeFramePointerRelSym:
139+
Offset: 44
140+
Range:
141+
OffsetStart: 260
142+
ISectStart: 1
143+
Range: 19
144+
Gaps: []
145+
- Kind: S_LOCAL
146+
LocalSym:
147+
Type: 116
148+
Flags: [ IsParameter ]
149+
VarName: y
150+
- Kind: S_DEFRANGE_FRAMEPOINTER_REL
151+
DefRangeFramePointerRelSym:
152+
Offset: 48
153+
Range:
154+
OffsetStart: 260
155+
ISectStart: 1
156+
Range: 19
157+
Gaps: []
158+
- Kind: S_INLINESITE
159+
InlineSiteSym:
160+
PtrParent: 292
161+
PtrEnd: 408
162+
Inlinee: 4096
163+
- Kind: S_LOCAL
164+
LocalSym:
165+
Type: 116
166+
Flags: [ IsParameter ]
167+
VarName: x
168+
- Kind: S_DEFRANGE_FRAMEPOINTER_REL
169+
DefRangeFramePointerRelSym:
170+
Offset: 52
171+
Range:
172+
OffsetStart: 272
173+
ISectStart: 1
174+
Range: 7
175+
Gaps: []
176+
- Kind: S_INLINESITE_END
177+
ScopeEndSym: {}
178+
- Kind: S_INLINESITE_END
179+
ScopeEndSym: {}
180+
- Kind: S_INLINESITE
181+
InlineSiteSym:
182+
PtrParent: 144
183+
PtrEnd: 460
184+
Inlinee: 4096
185+
- Kind: S_LOCAL
186+
LocalSym:
187+
Type: 116
188+
Flags: [ IsParameter ]
189+
VarName: x
190+
- Kind: S_DEFRANGE_FRAMEPOINTER_REL
191+
DefRangeFramePointerRelSym:
192+
Offset: 36
193+
Range:
194+
OffsetStart: 299
195+
ISectStart: 1
196+
Range: 7
197+
Gaps: []
198+
- Kind: S_INLINESITE_END
199+
ScopeEndSym: {}
200+
- Kind: S_INLINESITE_END
201+
ScopeEndSym: {}
202+
- Kind: S_END
203+
ScopeEndSym: {}
204+
...

0 commit comments

Comments
 (0)