Skip to content

Commit

Permalink
[llvm-pdbutil] Add options to only dump symbol record at specified of…
Browse files Browse the repository at this point in the history
…fset 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
  • Loading branch information
ZequanWu committed Apr 27, 2022
1 parent 18b9c46 commit a3b7cb0
Show file tree
Hide file tree
Showing 10 changed files with 516 additions and 8 deletions.
8 changes: 8 additions & 0 deletions llvm/include/llvm/DebugInfo/CodeView/CVSymbolVisitor.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,20 @@ class SymbolVisitorCallbacks;

class CVSymbolVisitor {
public:
struct FilterOptions {
llvm::Optional<uint32_t> SymbolOffset;
llvm::Optional<uint32_t> ParentRecursiveDepth;
llvm::Optional<uint32_t> ChildRecursiveDepth;
};

CVSymbolVisitor(SymbolVisitorCallbacks &Callbacks);

Error visitSymbolRecord(CVSymbol &Record);
Error visitSymbolRecord(CVSymbol &Record, uint32_t Offset);
Error visitSymbolStream(const CVSymbolArray &Symbols);
Error visitSymbolStream(const CVSymbolArray &Symbols, uint32_t InitialOffset);
Error visitSymbolStreamFiltered(const CVSymbolArray &Symbols,
const FilterOptions &Filter);

private:
SymbolVisitorCallbacks &Callbacks;
Expand Down
4 changes: 2 additions & 2 deletions llvm/include/llvm/DebugInfo/PDB/Native/InputFile.h
Original file line number Diff line number Diff line change
Expand Up @@ -180,8 +180,8 @@ Error iterateSymbolGroups(InputFile &Input, const PrintScope &HeaderScope,
AutoIndent Indent(HeaderScope);

FilterOptions Filters = HeaderScope.P.getFilters();
if (Filters.NumOccurrences) {
uint32_t Modi = Filters.DumpModi;
if (Filters.DumpModi) {
uint32_t Modi = Filters.DumpModi.getValue();
SymbolGroup SG(&Input, Modi);
return iterateOneModule(Input, withLabelWidth(HeaderScope, NumDigits(Modi)),
SG, Modi, Callback);
Expand Down
6 changes: 4 additions & 2 deletions llvm/include/llvm/DebugInfo/PDB/Native/LinePrinter.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,10 @@ struct FilterOptions {
std::list<std::string> IncludeCompilands;
uint32_t PaddingThreshold;
uint32_t SizeThreshold;
uint32_t DumpModi;
uint32_t NumOccurrences;
llvm::Optional<uint32_t> DumpModi;
llvm::Optional<uint32_t> ParentRecurseDepth;
llvm::Optional<uint32_t> ChildrenRecurseDepth;
llvm::Optional<uint32_t> SymbolOffset;
bool JustMyCode;
};

Expand Down
2 changes: 2 additions & 0 deletions llvm/include/llvm/Support/BinaryStreamArray.h
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,8 @@ class VarStreamArray {

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

bool isOffsetValid(uint32_t Offset) const { return at(Offset) != end(); }

uint32_t skew() const { return Skew; }
Iterator end() const { return Iterator(E); }

Expand Down
72 changes: 72 additions & 0 deletions llvm/lib/DebugInfo/CodeView/CVSymbolVisitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

#include "llvm/DebugInfo/CodeView/CodeView.h"
#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
#include "llvm/DebugInfo/CodeView/SymbolRecordHelpers.h"
#include "llvm/DebugInfo/CodeView/SymbolVisitorCallbacks.h"
#include "llvm/Support/BinaryStreamArray.h"
#include "llvm/Support/ErrorHandling.h"
Expand Down Expand Up @@ -83,3 +84,74 @@ Error CVSymbolVisitor::visitSymbolStream(const CVSymbolArray &Symbols,
}
return Error::success();
}

Error CVSymbolVisitor::visitSymbolStreamFiltered(const CVSymbolArray &Symbols,
const FilterOptions &Filter) {
if (!Filter.SymbolOffset)
return visitSymbolStream(Symbols);
uint32_t SymbolOffset = *Filter.SymbolOffset;
uint32_t ParentRecurseDepth =
Filter.ParentRecursiveDepth ? *Filter.ParentRecursiveDepth : 0;
uint32_t ChildrenRecurseDepth =
Filter.ChildRecursiveDepth ? *Filter.ChildRecursiveDepth : 0;
if (!Symbols.isOffsetValid(SymbolOffset))
return createStringError(inconvertibleErrorCode(), "Invalid symbol offset");
CVSymbol Sym = *Symbols.at(SymbolOffset);
uint32_t SymEndOffset =
symbolOpensScope(Sym.kind()) ? getScopeEndOffset(Sym) : 0;

std::vector<uint32_t> ParentOffsets;
std::vector<uint32_t> ParentEndOffsets;
uint32_t ChildrenDepth = 0;
for (auto Begin = Symbols.begin(), End = Symbols.end(); Begin != End;
++Begin) {
uint32_t BeginOffset = Begin.offset();
CVSymbol BeginSym = *Begin;
if (BeginOffset < SymbolOffset) {
if (symbolOpensScope(Begin->kind())) {
uint32_t EndOffset = getScopeEndOffset(BeginSym);
if (SymbolOffset < EndOffset) {
ParentOffsets.push_back(BeginOffset);
ParentEndOffsets.push_back(EndOffset);
}
}
} else if (BeginOffset == SymbolOffset) {
// Found symbol at offset. Visit its parent up to ParentRecurseDepth.
if (ParentRecurseDepth >= ParentOffsets.size())
ParentRecurseDepth = ParentOffsets.size();
uint32_t StartIndex = ParentOffsets.size() - ParentRecurseDepth;
while (StartIndex < ParentOffsets.size()) {
if (!Symbols.isOffsetValid(ParentOffsets[StartIndex]))
break;
CVSymbol Parent = *Symbols.at(ParentOffsets[StartIndex]);
if (auto EC = visitSymbolRecord(Parent, ParentOffsets[StartIndex]))
return EC;
++StartIndex;
}
if (auto EC = visitSymbolRecord(Sym, SymbolOffset))
return EC;
} else if (BeginOffset <= SymEndOffset) {
if (ChildrenRecurseDepth) {
// Visit children.
if (symbolEndsScope(Begin->kind()))
--ChildrenDepth;
if (ChildrenDepth < ChildrenRecurseDepth ||
BeginOffset == SymEndOffset) {
if (auto EC = visitSymbolRecord(BeginSym, BeginOffset))
return EC;
}
if (symbolOpensScope(Begin->kind()))
++ChildrenDepth;
}
} else {
// Visit parents' ends.
if (ParentRecurseDepth && BeginOffset == ParentEndOffsets.back()) {
if (auto EC = visitSymbolRecord(BeginSym, BeginOffset))
return EC;
ParentEndOffsets.pop_back();
--ParentRecurseDepth;
}
}
}
return Error::success();
}
2 changes: 1 addition & 1 deletion llvm/lib/DebugInfo/PDB/Native/InputFile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -579,7 +579,7 @@ bool llvm::pdb::shouldDumpSymbolGroup(uint32_t Idx, const SymbolGroup &Group,
return false;

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

// Otherwise, only dump if this is the same module specified.
Expand Down
204 changes: 204 additions & 0 deletions llvm/test/tools/llvm-pdbutil/Inputs/symbol-offset.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,204 @@
---
DbiStream:
VerHeader: V70
Age: 1
BuildNumber: 36363
PdbDllVersion: 0
PdbDllRbld: 0
Flags: 0
MachineType: Amd64
Modules:
- Module: '/tmp/test.obj'
Modi:
Signature: 4
Records:
- Kind: S_GPROC32
ProcSym:
PtrParent: 0
PtrEnd: 468
PtrNext: 0
CodeSize: 137
DbgStart: 0
DbgEnd: 0
FunctionType: 4104
Offset: 176
Segment: 1
Flags: [ ]
DisplayName: main
- Kind: S_FRAMEPROC
FrameProcSym:
TotalFrameBytes: 56
PaddingFrameBytes: 0
OffsetToPadding: 0
BytesOfCalleeSavedRegisters: 0
OffsetOfExceptionHandler: 0
SectionIdOfExceptionHandler: 0
Flags: [ ]
- Kind: S_LOCAL
LocalSym:
Type: 116
Flags: [ IsParameter ]
VarName: argc
- Kind: S_DEFRANGE_FRAMEPOINTER_REL
DefRangeFramePointerRelSym:
Offset: 4
Range:
OffsetStart: 197
ISectStart: 1
Range: 116
Gaps: []
- Kind: S_LOCAL
LocalSym:
Type: 4102
Flags: [ IsParameter ]
VarName: argv
- Kind: S_DEFRANGE_FRAMEPOINTER_REL
DefRangeFramePointerRelSym:
Offset: 8
Range:
OffsetStart: 197
ISectStart: 1
Range: 116
Gaps: []
- Kind: S_INLINESITE
InlineSiteSym:
PtrParent: 4
PtrEnd: 464
Inlinee: 4098
- Kind: S_LOCAL
LocalSym:
Type: 116
Flags: [ IsParameter ]
VarName: x
- Kind: S_DEFRANGE_FRAMEPOINTER_REL
DefRangeFramePointerRelSym:
Offset: 24
Range:
OffsetStart: 221
ISectStart: 1
Range: 87
Gaps: []
- Kind: S_LOCAL
LocalSym:
Type: 116
Flags: [ IsParameter ]
VarName: y
- Kind: S_DEFRANGE_FRAMEPOINTER_REL
DefRangeFramePointerRelSym:
Offset: 28
Range:
OffsetStart: 221
ISectStart: 1
Range: 87
Gaps: []
- Kind: S_LOCAL
LocalSym:
Type: 116
Flags: [ IsParameter ]
VarName: z
- Kind: S_DEFRANGE_FRAMEPOINTER_REL
DefRangeFramePointerRelSym:
Offset: 32
Range:
OffsetStart: 221
ISectStart: 1
Range: 87
Gaps: []
- Kind: S_INLINESITE
InlineSiteSym:
PtrParent: 144
PtrEnd: 288
Inlinee: 4096
- Kind: S_LOCAL
LocalSym:
Type: 116
Flags: [ IsParameter ]
VarName: x
- Kind: S_DEFRANGE_FRAMEPOINTER_REL
DefRangeFramePointerRelSym:
Offset: 40
Range:
OffsetStart: 229
ISectStart: 1
Range: 7
Gaps: []
- Kind: S_INLINESITE_END
ScopeEndSym: {}
- Kind: S_INLINESITE
InlineSiteSym:
PtrParent: 144
PtrEnd: 412
Inlinee: 4097
- Kind: S_LOCAL
LocalSym:
Type: 116
Flags: [ IsParameter ]
VarName: x
- Kind: S_DEFRANGE_FRAMEPOINTER_REL
DefRangeFramePointerRelSym:
Offset: 44
Range:
OffsetStart: 260
ISectStart: 1
Range: 19
Gaps: []
- Kind: S_LOCAL
LocalSym:
Type: 116
Flags: [ IsParameter ]
VarName: y
- Kind: S_DEFRANGE_FRAMEPOINTER_REL
DefRangeFramePointerRelSym:
Offset: 48
Range:
OffsetStart: 260
ISectStart: 1
Range: 19
Gaps: []
- Kind: S_INLINESITE
InlineSiteSym:
PtrParent: 292
PtrEnd: 408
Inlinee: 4096
- Kind: S_LOCAL
LocalSym:
Type: 116
Flags: [ IsParameter ]
VarName: x
- Kind: S_DEFRANGE_FRAMEPOINTER_REL
DefRangeFramePointerRelSym:
Offset: 52
Range:
OffsetStart: 272
ISectStart: 1
Range: 7
Gaps: []
- Kind: S_INLINESITE_END
ScopeEndSym: {}
- Kind: S_INLINESITE_END
ScopeEndSym: {}
- Kind: S_INLINESITE
InlineSiteSym:
PtrParent: 144
PtrEnd: 460
Inlinee: 4096
- Kind: S_LOCAL
LocalSym:
Type: 116
Flags: [ IsParameter ]
VarName: x
- Kind: S_DEFRANGE_FRAMEPOINTER_REL
DefRangeFramePointerRelSym:
Offset: 36
Range:
OffsetStart: 299
ISectStart: 1
Range: 7
Gaps: []
- Kind: S_INLINESITE_END
ScopeEndSym: {}
- Kind: S_INLINESITE_END
ScopeEndSym: {}
- Kind: S_END
ScopeEndSym: {}
...
Loading

0 comments on commit a3b7cb0

Please sign in to comment.