diff --git a/llvm/include/llvm/DebugInfo/CodeView/CVSymbolVisitor.h b/llvm/include/llvm/DebugInfo/CodeView/CVSymbolVisitor.h index d1c06573b3980..ef44b622d955a 100644 --- a/llvm/include/llvm/DebugInfo/CodeView/CVSymbolVisitor.h +++ b/llvm/include/llvm/DebugInfo/CodeView/CVSymbolVisitor.h @@ -18,12 +18,20 @@ class SymbolVisitorCallbacks; class CVSymbolVisitor { public: + struct FilterOptions { + llvm::Optional SymbolOffset; + llvm::Optional ParentRecursiveDepth; + llvm::Optional 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; diff --git a/llvm/include/llvm/DebugInfo/PDB/Native/InputFile.h b/llvm/include/llvm/DebugInfo/PDB/Native/InputFile.h index 5b0f433f118af..392f183f002f8 100644 --- a/llvm/include/llvm/DebugInfo/PDB/Native/InputFile.h +++ b/llvm/include/llvm/DebugInfo/PDB/Native/InputFile.h @@ -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); diff --git a/llvm/include/llvm/DebugInfo/PDB/Native/LinePrinter.h b/llvm/include/llvm/DebugInfo/PDB/Native/LinePrinter.h index e65bfc19fd206..0db21309f593d 100644 --- a/llvm/include/llvm/DebugInfo/PDB/Native/LinePrinter.h +++ b/llvm/include/llvm/DebugInfo/PDB/Native/LinePrinter.h @@ -30,8 +30,10 @@ struct FilterOptions { std::list IncludeCompilands; uint32_t PaddingThreshold; uint32_t SizeThreshold; - uint32_t DumpModi; - uint32_t NumOccurrences; + llvm::Optional DumpModi; + llvm::Optional ParentRecurseDepth; + llvm::Optional ChildrenRecurseDepth; + llvm::Optional SymbolOffset; bool JustMyCode; }; diff --git a/llvm/include/llvm/Support/BinaryStreamArray.h b/llvm/include/llvm/Support/BinaryStreamArray.h index c3e0db4dcff09..ef2233c53ec2c 100644 --- a/llvm/include/llvm/Support/BinaryStreamArray.h +++ b/llvm/include/llvm/Support/BinaryStreamArray.h @@ -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); } diff --git a/llvm/lib/DebugInfo/CodeView/CVSymbolVisitor.cpp b/llvm/lib/DebugInfo/CodeView/CVSymbolVisitor.cpp index 31af9a1bd848d..162f1db0189bd 100644 --- a/llvm/lib/DebugInfo/CodeView/CVSymbolVisitor.cpp +++ b/llvm/lib/DebugInfo/CodeView/CVSymbolVisitor.cpp @@ -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" @@ -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 ParentOffsets; + std::vector 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(); +} diff --git a/llvm/lib/DebugInfo/PDB/Native/InputFile.cpp b/llvm/lib/DebugInfo/PDB/Native/InputFile.cpp index 99dd1316dd8fe..ec7c4e1e3353c 100644 --- a/llvm/lib/DebugInfo/PDB/Native/InputFile.cpp +++ b/llvm/lib/DebugInfo/PDB/Native/InputFile.cpp @@ -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. diff --git a/llvm/test/tools/llvm-pdbutil/Inputs/symbol-offset.yaml b/llvm/test/tools/llvm-pdbutil/Inputs/symbol-offset.yaml new file mode 100644 index 0000000000000..ca574347b07cc --- /dev/null +++ b/llvm/test/tools/llvm-pdbutil/Inputs/symbol-offset.yaml @@ -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: {} +... diff --git a/llvm/test/tools/llvm-pdbutil/symbol-offset.test b/llvm/test/tools/llvm-pdbutil/symbol-offset.test new file mode 100644 index 0000000000000..175aaaca5874d --- /dev/null +++ b/llvm/test/tools/llvm-pdbutil/symbol-offset.test @@ -0,0 +1,176 @@ +; RUN: llvm-pdbutil yaml2pdb %p/Inputs/symbol-offset.yaml --pdb=%t.pdb + +; RUN: llvm-pdbutil dump --symbols --modi=0 --symbol-offset=80 %t.pdb \ +; RUN: | FileCheck --check-prefix=OFFSET %s + +; RUN: llvm-pdbutil dump --symbols --modi=0 --symbol-offset=4 --show-parents \ +; RUN: %t.pdb | FileCheck --check-prefix=SHOW-PARENT1 %s + +; RUN: llvm-pdbutil dump --symbols --modi=0 --symbol-offset=80 --show-parents \ +; RUN: %t.pdb | FileCheck --check-prefix=SHOW-PARENT2 %s + +; RUN: llvm-pdbutil dump --symbols --modi=0 --symbol-offset=308 --show-parents \ +; RUN: %t.pdb | FileCheck --check-prefix=SHOW-PARENT3 %s + +; RUN: llvm-pdbutil dump --symbols --modi=0 --symbol-offset=260 --show-parents \ +; RUN: --parent-recurse-depth=1 %t.pdb \ +; RUN: | FileCheck --check-prefix=SHOW-PARENT-DEPTH1 %s + +; RUN: llvm-pdbutil dump --symbols --modi=0 --symbol-offset=260 --show-parents \ +; RUN: --parent-recurse-depth=2 %t.pdb \ +; RUN: | FileCheck --check-prefix=SHOW-PARENT-DEPTH2 %s + +; RUN: llvm-pdbutil dump --symbols --modi=0 --symbol-offset=416 --show-children\ +; RUN: %t.pdb | FileCheck --check-prefix=SHOW-CHILDREN1 %s + +; RUN: llvm-pdbutil dump --symbols --modi=0 --symbol-offset=292 --show-children\ +; RUN: %t.pdb | FileCheck --check-prefix=SHOW-CHILDREN2 %s + +; RUN: llvm-pdbutil dump --symbols --modi=0 --symbol-offset=4 --show-children \ +; RUN: --children-recurse-depth=1 %t.pdb \ +; RUN: | FileCheck --check-prefix=SHOW-CHILDREN-DEPTH1 %s + +; RUN: llvm-pdbutil dump --symbols --modi=0 --symbol-offset=292 --show-children\ +; RUN: --children-recurse-depth=2 %t.pdb \ +; RUN: | FileCheck --check-prefix=SHOW-CHILDREN-DEPTH2 %s + +The pdb file is generate from following cpp file and use llvm-pdbutil's pdb2yaml +functionality to convert pdb to yaml. Unrelated information was removed from the +yaml test file. +; [[clang::always_inline]] int func1(int x) { +; return x * 2; +; } +; +; [[clang::always_inline]] int func2(int x, int y) { +; return func1(x + y); +; } +; +; [[clang::always_inline]] int func3(int x, int y, int z) { +; y += func1(x); +; x += func2(y, z); +; return x + func1(x); +; } +; +; int main(int argc, char** argv) { +; return func3(argc, 1, 2); +; } + + +OFFSET: 80 | S_LOCAL [size = 16] `argc` +OFFSET-NEXT: type=0x0074 (int), flags = param + +SHOW-PARENT1: 4 | S_GPROC32 [size = 44] `main` +SHOW-PARENT1-NEXT: parent = 0, end = 468, addr = 0001:0176, code size = 137 +SHOW-PARENT1-NEXT: type = `0x1008 ()`, debug start = 0, debug end = 0, flags = none + +SHOW-PARENT2: 4 | S_GPROC32 [size = 44] `main` +SHOW-PARENT2-NEXT: parent = 0, end = 468, addr = 0001:0176, code size = 137 +SHOW-PARENT2-NEXT: type = `0x1008 ()`, debug start = 0, debug end = 0, flags = none +SHOW-PARENT2-NEXT: 80 | S_LOCAL [size = 16] `argc` +SHOW-PARENT2-NEXT: type=0x0074 (int), flags = param +SHOW-PARENT2-NEXT: 468 | S_END [size = 4] + +SHOW-PARENT3: 4 | S_GPROC32 [size = 44] `main` +SHOW-PARENT3-NEXT: parent = 0, end = 468, addr = 0001:0176, code size = 137 +SHOW-PARENT3-NEXT: type = `0x1008 ()`, debug start = 0, debug end = 0, flags = none +SHOW-PARENT3-NEXT: 144 | S_INLINESITE [size = 16] +SHOW-PARENT3-NEXT: inlinee = 0x1002 (), parent = 4, end = 464 +SHOW-PARENT3-NEXT: 292 | S_INLINESITE [size = 16] +SHOW-PARENT3-NEXT: inlinee = 0x1001 (), parent = 144, end = 412 +SHOW-PARENT3-NEXT: 308 | S_LOCAL [size = 12] `x` +SHOW-PARENT3-NEXT: type=0x0074 (int), flags = param +SHOW-PARENT3-NEXT: 412 | S_INLINESITE_END [size = 4] +SHOW-PARENT3-NEXT: 464 | S_INLINESITE_END [size = 4] +SHOW-PARENT3-NEXT: 468 | S_END [size = 4] + + +SHOW-PARENT-DEPTH1: 244 | S_INLINESITE [size = 16] +SHOW-PARENT-DEPTH1-NEXT: inlinee = 0x1000 (), parent = 144, end = 288 +SHOW-PARENT-DEPTH1-NEXT: 260 | S_LOCAL [size = 12] `x` +SHOW-PARENT-DEPTH1-NEXT: type=0x0074 (int), flags = param +SHOW-PARENT-DEPTH1-NEXT: 288 | S_INLINESITE_END [size = 4] + +SHOW-PARENT-DEPTH2: 144 | S_INLINESITE [size = 16] +SHOW-PARENT-DEPTH2-NEXT: inlinee = 0x1002 (), parent = 4, end = 464 +SHOW-PARENT-DEPTH2-NEXT: 244 | S_INLINESITE [size = 16] +SHOW-PARENT-DEPTH2-NEXT: inlinee = 0x1000 (), parent = 144, end = 288 +SHOW-PARENT-DEPTH2-NEXT: 260 | S_LOCAL [size = 12] `x` +SHOW-PARENT-DEPTH2-NEXT: type=0x0074 (int), flags = param +SHOW-PARENT-DEPTH2-NEXT: 288 | S_INLINESITE_END [size = 4] +SHOW-PARENT-DEPTH2-NEXT: 464 | S_INLINESITE_END [size = 4] + +SHOW-CHILDREN1: 416 | S_INLINESITE [size = 16] +SHOW-CHILDREN1-NEXT: inlinee = 0x1000 (), parent = 144, end = 460 +SHOW-CHILDREN1-NEXT: 432 | S_LOCAL [size = 12] `x` +SHOW-CHILDREN1-NEXT: type=0x0074 (int), flags = param +SHOW-CHILDREN1-NEXT: 444 | S_DEFRANGE_FRAMEPOINTER_REL [size = 16] +SHOW-CHILDREN1-NEXT: offset = 36, range = [0001:0299,+7) +SHOW-CHILDREN1-NEXT: gaps = [] +SHOW-CHILDREN1-NEXT: 460 | S_INLINESITE_END [size = 4] + +SHOW-CHILDREN2: 292 | S_INLINESITE [size = 16] +SHOW-CHILDREN2-NEXT: inlinee = 0x1001 (), parent = 144, end = 412 +SHOW-CHILDREN2-NEXT: 308 | S_LOCAL [size = 12] `x` +SHOW-CHILDREN2-NEXT: type=0x0074 (int), flags = param +SHOW-CHILDREN2-NEXT: 320 | S_DEFRANGE_FRAMEPOINTER_REL [size = 16] +SHOW-CHILDREN2-NEXT: offset = 44, range = [0001:0260,+19) +SHOW-CHILDREN2-NEXT: gaps = [] +SHOW-CHILDREN2-NEXT: 336 | S_LOCAL [size = 12] `y` +SHOW-CHILDREN2-NEXT: type=0x0074 (int), flags = param +SHOW-CHILDREN2-NEXT: 348 | S_DEFRANGE_FRAMEPOINTER_REL [size = 16] +SHOW-CHILDREN2-NEXT: offset = 48, range = [0001:0260,+19) +SHOW-CHILDREN2-NEXT: gaps = [] +SHOW-CHILDREN2-NEXT: 364 | S_INLINESITE [size = 16] +SHOW-CHILDREN2-NEXT: inlinee = 0x1000 (), parent = 292, end = 408 +SHOW-CHILDREN2-NEXT: 380 | S_LOCAL [size = 12] `x` +SHOW-CHILDREN2-NEXT: type=0x0074 (int), flags = param +SHOW-CHILDREN2-NEXT: 392 | S_DEFRANGE_FRAMEPOINTER_REL [size = 16] +SHOW-CHILDREN2-NEXT: offset = 52, range = [0001:0272,+7) +SHOW-CHILDREN2-NEXT: gaps = [] +SHOW-CHILDREN2-NEXT: 408 | S_INLINESITE_END [size = 4] +SHOW-CHILDREN2-NEXT: 412 | S_INLINESITE_END [size = 4] + +SHOW-CHILDREN-DEPTH1: 4 | S_GPROC32 [size = 44] `main` +SHOW-CHILDREN-DEPTH1-NEXT: parent = 0, end = 468, addr = 0001:0176, code size = 137 +SHOW-CHILDREN-DEPTH1-NEXT: type = `0x1008 ()`, debug start = 0, debug end = 0, flags = none +SHOW-CHILDREN-DEPTH1-NEXT: 48 | S_FRAMEPROC [size = 32] +SHOW-CHILDREN-DEPTH1-NEXT: size = 56, padding size = 0, offset to padding = 0 +SHOW-CHILDREN-DEPTH1-NEXT: bytes of callee saved registers = 0, exception handler addr = 0000:0000 +SHOW-CHILDREN-DEPTH1-NEXT: local fp reg = NONE, param fp reg = NONE +SHOW-CHILDREN-DEPTH1-NEXT: flags = none +SHOW-CHILDREN-DEPTH1-NEXT: 80 | S_LOCAL [size = 16] `argc` +SHOW-CHILDREN-DEPTH1-NEXT: type=0x0074 (int), flags = param +SHOW-CHILDREN-DEPTH1-NEXT: 96 | S_DEFRANGE_FRAMEPOINTER_REL [size = 16] +SHOW-CHILDREN-DEPTH1-NEXT: offset = 4, range = [0001:0197,+116) +SHOW-CHILDREN-DEPTH1-NEXT: gaps = [] +SHOW-CHILDREN-DEPTH1-NEXT: 112 | S_LOCAL [size = 16] `argv` +SHOW-CHILDREN-DEPTH1-NEXT: type=0x1006 (), flags = param +SHOW-CHILDREN-DEPTH1-NEXT: 128 | S_DEFRANGE_FRAMEPOINTER_REL [size = 16] +SHOW-CHILDREN-DEPTH1-NEXT: offset = 8, range = [0001:0197,+116) +SHOW-CHILDREN-DEPTH1-NEXT: gaps = [] +SHOW-CHILDREN-DEPTH1-NEXT: 144 | S_INLINESITE [size = 16] +SHOW-CHILDREN-DEPTH1-NEXT: inlinee = 0x1002 (), parent = 4, end = 464 +SHOW-CHILDREN-DEPTH1-NEXT: 464 | S_INLINESITE_END [size = 4] +SHOW-CHILDREN-DEPTH1-NEXT: 468 | S_END [size = 4] + +SHOW-CHILDREN-DEPTH2: 292 | S_INLINESITE [size = 16] +SHOW-CHILDREN-DEPTH2-NEXT: inlinee = 0x1001 (), parent = 144, end = 412 +SHOW-CHILDREN-DEPTH2-NEXT: 308 | S_LOCAL [size = 12] `x` +SHOW-CHILDREN-DEPTH2-NEXT: type=0x0074 (int), flags = param +SHOW-CHILDREN-DEPTH2-NEXT: 320 | S_DEFRANGE_FRAMEPOINTER_REL [size = 16] +SHOW-CHILDREN-DEPTH2-NEXT: offset = 44, range = [0001:0260,+19) +SHOW-CHILDREN-DEPTH2-NEXT: gaps = [] +SHOW-CHILDREN-DEPTH2-NEXT: 336 | S_LOCAL [size = 12] `y` +SHOW-CHILDREN-DEPTH2-NEXT: type=0x0074 (int), flags = param +SHOW-CHILDREN-DEPTH2-NEXT: 348 | S_DEFRANGE_FRAMEPOINTER_REL [size = 16] +SHOW-CHILDREN-DEPTH2-NEXT: offset = 48, range = [0001:0260,+19) +SHOW-CHILDREN-DEPTH2-NEXT: gaps = [] +SHOW-CHILDREN-DEPTH2-NEXT: 364 | S_INLINESITE [size = 16] +SHOW-CHILDREN-DEPTH2-NEXT: inlinee = 0x1000 (), parent = 292, end = 408 +SHOW-CHILDREN-DEPTH2-NEXT: 380 | S_LOCAL [size = 12] `x` +SHOW-CHILDREN-DEPTH2-NEXT: type=0x0074 (int), flags = param +SHOW-CHILDREN-DEPTH2-NEXT: 392 | S_DEFRANGE_FRAMEPOINTER_REL [size = 16] +SHOW-CHILDREN-DEPTH2-NEXT: offset = 52, range = [0001:0272,+7) +SHOW-CHILDREN-DEPTH2-NEXT: gaps = [] +SHOW-CHILDREN-DEPTH2-NEXT: 408 | S_INLINESITE_END [size = 4] +SHOW-CHILDREN-DEPTH2-NEXT: 412 | S_INLINESITE_END [size = 4] \ No newline at end of file diff --git a/llvm/tools/llvm-pdbutil/DumpOutputStyle.cpp b/llvm/tools/llvm-pdbutil/DumpOutputStyle.cpp index 12cda106c036d..a173eb1faa627 100644 --- a/llvm/tools/llvm-pdbutil/DumpOutputStyle.cpp +++ b/llvm/tools/llvm-pdbutil/DumpOutputStyle.cpp @@ -1485,8 +1485,19 @@ Error DumpOutputStyle::dumpModuleSymsForPdb() { Pipeline.addCallbackToPipeline(Dumper); CVSymbolVisitor Visitor(Pipeline); auto SS = ModS.getSymbolsSubstream(); - if (auto EC = - Visitor.visitSymbolStream(ModS.getSymbolArray(), SS.Offset)) { + if (opts::Filters.SymbolOffset) { + CVSymbolVisitor::FilterOptions Filter; + Filter.SymbolOffset = opts::Filters.SymbolOffset; + Filter.ParentRecursiveDepth = opts::Filters.ParentRecurseDepth; + Filter.ChildRecursiveDepth = opts::Filters.ChildrenRecurseDepth; + if (auto EC = Visitor.visitSymbolStreamFiltered(ModS.getSymbolArray(), + Filter)) { + P.formatLine("Error while processing symbol records. {0}", + toString(std::move(EC))); + return EC; + } + } else if (auto EC = Visitor.visitSymbolStream(ModS.getSymbolArray(), + SS.Offset)) { P.formatLine("Error while processing symbol records. {0}", toString(std::move(EC))); return EC; diff --git a/llvm/tools/llvm-pdbutil/llvm-pdbutil.cpp b/llvm/tools/llvm-pdbutil/llvm-pdbutil.cpp index 7258a7f0ecd8d..c995c7975737b 100644 --- a/llvm/tools/llvm-pdbutil/llvm-pdbutil.cpp +++ b/llvm/tools/llvm-pdbutil/llvm-pdbutil.cpp @@ -562,6 +562,27 @@ cl::opt cl::opt DumpFpo("fpo", cl::desc("dump FPO records"), cl::cat(SymbolOptions), cl::sub(DumpSubcommand)); +cl::opt DumpSymbolOffset( + "symbol-offset", cl::Optional, + cl::desc("only dump symbol record with the specified symbol offset"), + cl::cat(SymbolOptions), cl::sub(DumpSubcommand)); +cl::opt DumpParents("show-parents", + cl::desc("dump the symbols record's all parents."), + cl::cat(SymbolOptions), cl::sub(DumpSubcommand)); +cl::opt + DumpParentDepth("parent-recurse-depth", cl::Optional, cl::init(-1U), + cl::desc("only recurse to a depth of N when displaying " + "parents of a symbol record."), + cl::cat(SymbolOptions), cl::sub(DumpSubcommand)); +cl::opt DumpChildren("show-children", + cl::desc("dump the symbols record's all children."), + cl::cat(SymbolOptions), cl::sub(DumpSubcommand)); +cl::opt + DumpChildrenDepth("children-recurse-depth", cl::Optional, cl::init(-1U), + cl::desc("only recurse to a depth of N when displaying " + "children of a symbol record."), + cl::cat(SymbolOptions), cl::sub(DumpSubcommand)); + // MODULE & FILE OPTIONS cl::opt DumpModules("modules", cl::desc("dump compiland information"), cl::cat(FileOptions), cl::sub(DumpSubcommand)); @@ -1533,9 +1554,21 @@ int main(int Argc, const char **Argv) { errs().flush(); exit(1); } - opts::Filters.NumOccurrences = opts::dump::DumpModi.getNumOccurrences(); opts::Filters.DumpModi = opts::dump::DumpModi; } + if (opts::dump::DumpSymbolOffset) { + if (opts::dump::DumpModi.getNumOccurrences() != 1) { + errs() + << "need to specify argument '-modi' when using '-symbol-offset'.\n"; + errs().flush(); + exit(1); + } + opts::Filters.SymbolOffset = opts::dump::DumpSymbolOffset; + if (opts::dump::DumpParents) + opts::Filters.ParentRecurseDepth = opts::dump::DumpParentDepth; + if (opts::dump::DumpChildren) + opts::Filters.ChildrenRecurseDepth = opts::dump::DumpChildrenDepth; + } if (opts::PdbToYamlSubcommand) { pdb2Yaml(opts::pdb2yaml::InputFilename.front());