diff --git a/llvm/include/llvm/DebugInfo/CodeView/CVSymbolVisitor.h b/llvm/include/llvm/DebugInfo/CodeView/CVSymbolVisitor.h --- a/llvm/include/llvm/DebugInfo/CodeView/CVSymbolVisitor.h +++ b/llvm/include/llvm/DebugInfo/CodeView/CVSymbolVisitor.h @@ -20,13 +20,27 @@ public: CVSymbolVisitor(SymbolVisitorCallbacks &Callbacks); + void setSymbolOffset(llvm::Optional Offset) { + SymbolOffset = Offset; + } + void setParentRecurseDepth(llvm::Optional Depth) { + ParentRecurseDepth = Depth; + } + void setChildrenRecurseDepth(llvm::Optional Depth) { + ChildrenRecurseDepth = Depth; + } + 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 visitSymbolStreamAtOffset(const CVSymbolArray &Symbols); private: SymbolVisitorCallbacks &Callbacks; + llvm::Optional SymbolOffset; + llvm::Optional ParentRecurseDepth; + llvm::Optional ChildrenRecurseDepth; }; } // end namespace codeview diff --git a/llvm/include/llvm/DebugInfo/PDB/Native/InputFile.h b/llvm/include/llvm/DebugInfo/PDB/Native/InputFile.h --- a/llvm/include/llvm/DebugInfo/PDB/Native/InputFile.h +++ b/llvm/include/llvm/DebugInfo/PDB/Native/InputFile.h @@ -180,8 +180,8 @@ 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 --- a/llvm/include/llvm/DebugInfo/PDB/Native/LinePrinter.h +++ b/llvm/include/llvm/DebugInfo/PDB/Native/LinePrinter.h @@ -30,8 +30,10 @@ 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/lib/DebugInfo/CodeView/CVSymbolVisitor.cpp b/llvm/lib/DebugInfo/CodeView/CVSymbolVisitor.cpp --- 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" @@ -67,6 +68,8 @@ } Error CVSymbolVisitor::visitSymbolStream(const CVSymbolArray &Symbols) { + if (SymbolOffset) + return visitSymbolStreamAtOffset(Symbols); for (auto I : Symbols) { if (auto EC = visitSymbolRecord(I)) return EC; @@ -76,6 +79,8 @@ Error CVSymbolVisitor::visitSymbolStream(const CVSymbolArray &Symbols, uint32_t InitialOffset) { + if (SymbolOffset) + return visitSymbolStreamAtOffset(Symbols); for (auto I : Symbols) { if (auto EC = visitSymbolRecord(I, InitialOffset + Symbols.skew())) return EC; @@ -83,3 +88,72 @@ } return Error::success(); } + +Error CVSymbolVisitor::visitSymbolStreamAtOffset(const CVSymbolArray &Symbols) { + if (Symbols.at(*SymbolOffset) == Symbols.end()) + return createStringError(inconvertibleErrorCode(), "Invalid symbol offset"); + CVSymbol Sym = *Symbols.at(*SymbolOffset); + // Visit parents. + std::vector ParentSymbols; + if (ParentRecurseDepth && *ParentRecurseDepth > 0) { + for (auto Begin = Symbols.begin(), End = Symbols.end(); + Begin.offset() != SymbolOffset && Begin != End; ++Begin) { + uint32_t BeginOffset = Begin.offset(); + if (symbolOpensScope(Begin->kind())) { + uint32_t EndOffset = getScopeEndOffset(*Begin); + if (BeginOffset < SymbolOffset && SymbolOffset < EndOffset) { + ParentSymbols.push_back(BeginOffset); + End = Symbols.at(EndOffset); + } + } + } + size_t StartIndex = *ParentRecurseDepth < ParentSymbols.size() + ? ParentSymbols.size() - *ParentRecurseDepth + : 0; + while (StartIndex < ParentSymbols.size()) { + CVSymbol Parent = *Symbols.at(ParentSymbols[StartIndex]); + if (auto EC = visitSymbolRecord(Parent, ParentSymbols[StartIndex])) + return EC; + ++StartIndex; + } + } + // Visit symbol and its children. + if (ChildrenRecurseDepth && symbolOpensScope(Sym.kind())) { + uint32_t EndOffset = getScopeEndOffset(Sym); + int64_t CurDepth = 0; + for (uint32_t Offset = *SymbolOffset; Offset <= EndOffset;) { + CVSymbol Sym = *Symbols.at(Offset); + if (auto EC = visitSymbolRecord(Sym, Offset)) + return EC; + if (symbolOpensScope(Sym.kind())) + ++CurDepth; + else if (symbolEndsScope(Sym.kind())) + --CurDepth; + if (CurDepth > *ChildrenRecurseDepth) + Offset = getScopeEndOffset(Sym); + else + Offset += Sym.length(); + } + } else { + if (auto EC = visitSymbolRecord(Sym, *SymbolOffset)) + return EC; + } + // Visit parents' end. + if (ParentSymbols.size() > 0) { + size_t StartIndex = ParentSymbols.size() - 1; + size_t EndIndex = *ParentRecurseDepth < ParentSymbols.size() + ? ParentSymbols.size() - *ParentRecurseDepth + : 0; + while (StartIndex >= EndIndex) { + uint32_t ParentEndOffset = + getScopeEndOffset(*Symbols.at(ParentSymbols[StartIndex])); + CVSymbol ParentEnd = *Symbols.at(ParentEndOffset); + if (auto EC = visitSymbolRecord(ParentEnd, ParentEndOffset)) + return EC; + if (StartIndex == 0) + break; + --StartIndex; + } + } + return Error::success(); +} diff --git a/llvm/lib/DebugInfo/PDB/Native/InputFile.cpp b/llvm/lib/DebugInfo/PDB/Native/InputFile.cpp --- a/llvm/lib/DebugInfo/PDB/Native/InputFile.cpp +++ b/llvm/lib/DebugInfo/PDB/Native/InputFile.cpp @@ -579,7 +579,7 @@ 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 --- /dev/null +++ b/llvm/test/tools/llvm-pdbutil/Inputs/symbol-offset.yaml @@ -0,0 +1,210 @@ +--- +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: 476 + PtrNext: 0 + CodeSize: 173 + DbgStart: 0 + DbgEnd: 0 + FunctionType: 4104 + Offset: 368 + Segment: 1 + Flags: [ ] + DisplayName: main + - Kind: S_FRAMEPROC + FrameProcSym: + TotalFrameBytes: 64 + 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: 389 + ISectStart: 1 + Range: 152 + Gaps: [] + - Kind: S_LOCAL + LocalSym: + Type: 4102 + Flags: [ IsParameter ] + VarName: argv + - Kind: S_DEFRANGE_FRAMEPOINTER_REL + DefRangeFramePointerRelSym: + Offset: 8 + Range: + OffsetStart: 389 + ISectStart: 1 + Range: 152 + Gaps: [] + - Kind: S_INLINESITE + InlineSiteSym: + PtrParent: 4 + PtrEnd: 472 + Inlinee: 4099 + - Kind: S_LOCAL + LocalSym: + Type: 116 + Flags: [ IsParameter ] + VarName: x + - Kind: S_DEFRANGE_FRAMEPOINTER_REL + DefRangeFramePointerRelSym: + Offset: 20 + Range: + OffsetStart: 413 + ISectStart: 1 + Range: 123 + Gaps: [] + - Kind: S_LOCAL + LocalSym: + Type: 116 + Flags: [ IsParameter ] + VarName: y + - Kind: S_DEFRANGE_FRAMEPOINTER_REL + DefRangeFramePointerRelSym: + Offset: 24 + Range: + OffsetStart: 413 + ISectStart: 1 + Range: 123 + Gaps: [] + - Kind: S_LOCAL + LocalSym: + Type: 116 + Flags: [ IsParameter ] + VarName: z + - Kind: S_DEFRANGE_FRAMEPOINTER_REL + DefRangeFramePointerRelSym: + Offset: 28 + Range: + OffsetStart: 413 + ISectStart: 1 + Range: 123 + Gaps: [] + - Kind: S_INLINESITE + InlineSiteSym: + PtrParent: 144 + PtrEnd: 468 + Inlinee: 4098 + - Kind: S_LOCAL + LocalSym: + Type: 116 + Flags: [ IsParameter ] + VarName: x + - Kind: S_DEFRANGE_FRAMEPOINTER_REL + DefRangeFramePointerRelSym: + Offset: 32 + Range: + OffsetStart: 437 + ISectStart: 1 + Range: 99 + Gaps: [] + - Kind: S_LOCAL + LocalSym: + Type: 116 + Flags: [ IsParameter ] + VarName: y + - Kind: S_DEFRANGE_FRAMEPOINTER_REL + DefRangeFramePointerRelSym: + Offset: 36 + Range: + OffsetStart: 437 + ISectStart: 1 + Range: 99 + Gaps: [] + - Kind: S_LOCAL + LocalSym: + Type: 116 + Flags: [ IsParameter ] + VarName: z + - Kind: S_DEFRANGE_FRAMEPOINTER_REL + DefRangeFramePointerRelSym: + Offset: 40 + Range: + OffsetStart: 437 + ISectStart: 1 + Range: 99 + Gaps: [] + - Kind: S_INLINESITE + InlineSiteSym: + PtrParent: 244 + PtrEnd: 464 + Inlinee: 4097 + - Kind: S_LOCAL + LocalSym: + Type: 116 + Flags: [ IsParameter ] + VarName: x + - Kind: S_DEFRANGE_FRAMEPOINTER_REL + DefRangeFramePointerRelSym: + Offset: 48 + Range: + OffsetStart: 484 + ISectStart: 1 + Range: 44 + Gaps: [] + - Kind: S_LOCAL + LocalSym: + Type: 116 + Flags: [ IsParameter ] + VarName: y + - Kind: S_DEFRANGE_FRAMEPOINTER_REL + DefRangeFramePointerRelSym: + Offset: 52 + Range: + OffsetStart: 484 + ISectStart: 1 + Range: 44 + Gaps: [] + - Kind: S_INLINESITE + InlineSiteSym: + PtrParent: 344 + PtrEnd: 460 + Inlinee: 4096 + - Kind: S_LOCAL + LocalSym: + Type: 116 + Flags: [ IsParameter ] + VarName: x + - Kind: S_DEFRANGE_FRAMEPOINTER_REL + DefRangeFramePointerRelSym: + Offset: 60 + Range: + OffsetStart: 503 + ISectStart: 1 + Range: 4 + Gaps: [] + - Kind: S_INLINESITE_END + ScopeEndSym: {} + - Kind: S_INLINESITE_END + ScopeEndSym: {} + - 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 --- /dev/null +++ b/llvm/test/tools/llvm-pdbutil/symbol-offset.test @@ -0,0 +1,150 @@ +; 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=160 --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=344 --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=344 --show-children\ +; RUN: --children-recurse-depth=2 %t.pdb \ +; RUN: | FileCheck --check-prefix=SHOW-CHILDREN-DEPTH2 %s + +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 = 476, addr = 0001:0368, code size = 173 +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 = 476, addr = 0001:0368, code size = 173 +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: 476 | S_END [size = 4] + +SHOW-PARENT3: 4 | S_GPROC32 [size = 44] `main` +SHOW-PARENT3-NEXT: parent = 0, end = 476, addr = 0001:0368, code size = 173 +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 = 0x1003 (), parent = 4, end = 472 +SHOW-PARENT3-NEXT: 160 | S_LOCAL [size = 12] `x` +SHOW-PARENT3-NEXT: type=0x0074 (int), flags = param +SHOW-PARENT3-NEXT: 472 | S_INLINESITE_END [size = 4] +SHOW-PARENT3-NEXT: 476 | S_END [size = 4] + +SHOW-PARENT-DEPTH1: 244 | S_INLINESITE [size = 16] +SHOW-PARENT-DEPTH1-NEXT: inlinee = 0x1002 (), parent = 144, end = 468 +SHOW-PARENT-DEPTH1-NEXT: 260 | S_LOCAL [size = 12] `x` +SHOW-PARENT-DEPTH1-NEXT: type=0x0074 (int), flags = param +SHOW-PARENT-DEPTH1-NEXT: 468 | S_INLINESITE_END [size = 4] + +SHOW-PARENT-DEPTH2: 144 | S_INLINESITE [size = 16] +SHOW-PARENT-DEPTH2-NEXT: inlinee = 0x1003 (), parent = 4, end = 472 +SHOW-PARENT-DEPTH2-NEXT: 244 | S_INLINESITE [size = 16] +SHOW-PARENT-DEPTH2-NEXT: inlinee = 0x1002 (), parent = 144, end = 468 +SHOW-PARENT-DEPTH2-NEXT: 260 | S_LOCAL [size = 12] `x` +SHOW-PARENT-DEPTH2-NEXT: type=0x0074 (int), flags = param +SHOW-PARENT-DEPTH2-NEXT: 468 | S_INLINESITE_END [size = 4] +SHOW-PARENT-DEPTH2-NEXT: 472 | S_INLINESITE_END [size = 4] + +SHOW-CHILDREN1: 416 | S_INLINESITE [size = 16] +SHOW-CHILDREN1-NEXT: inlinee = 0x1000 (), parent = 344, 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 = 60, range = [0001:0503,+4) +SHOW-CHILDREN1-NEXT: gaps = [] +SHOW-CHILDREN1-NEXT: 460 | S_INLINESITE_END [size = 4] + +SHOW-CHILDREN2: 344 | S_INLINESITE [size = 16] +SHOW-CHILDREN2-NEXT: inlinee = 0x1001 (), parent = 244, end = 464 +SHOW-CHILDREN2-NEXT: 360 | S_LOCAL [size = 12] `x` +SHOW-CHILDREN2-NEXT: type=0x0074 (int), flags = param +SHOW-CHILDREN2-NEXT: 372 | S_DEFRANGE_FRAMEPOINTER_REL [size = 16] +SHOW-CHILDREN2-NEXT: offset = 48, range = [0001:0484,+44) +SHOW-CHILDREN2-NEXT: gaps = [] +SHOW-CHILDREN2-NEXT: 388 | S_LOCAL [size = 12] `y` +SHOW-CHILDREN2-NEXT: type=0x0074 (int), flags = param +SHOW-CHILDREN2-NEXT: 400 | S_DEFRANGE_FRAMEPOINTER_REL [size = 16] +SHOW-CHILDREN2-NEXT: offset = 52, range = [0001:0484,+44) +SHOW-CHILDREN2-NEXT: gaps = [] +SHOW-CHILDREN2-NEXT: 416 | S_INLINESITE [size = 16] +SHOW-CHILDREN2-NEXT: inlinee = 0x1000 (), parent = 344, end = 460 +SHOW-CHILDREN2-NEXT: 432 | S_LOCAL [size = 12] `x` +SHOW-CHILDREN2-NEXT: type=0x0074 (int), flags = param +SHOW-CHILDREN2-NEXT: 444 | S_DEFRANGE_FRAMEPOINTER_REL [size = 16] +SHOW-CHILDREN2-NEXT: offset = 60, range = [0001:0503,+4) +SHOW-CHILDREN2-NEXT: gaps = [] +SHOW-CHILDREN2-NEXT: 460 | S_INLINESITE_END [size = 4] +SHOW-CHILDREN2-NEXT: 464 | S_INLINESITE_END [size = 4] + +SHOW-CHILDREN-DEPTH1: 4 | S_GPROC32 [size = 44] `main` +SHOW-CHILDREN-DEPTH1-NEXT: parent = 0, end = 476, addr = 0001:0368, code size = 173 +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 = 64, 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:0389,+152) +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:0389,+152) +SHOW-CHILDREN-DEPTH1-NEXT: gaps = [] +SHOW-CHILDREN-DEPTH1-NEXT: 144 | S_INLINESITE [size = 16] +SHOW-CHILDREN-DEPTH1-NEXT: inlinee = 0x1003 (), parent = 4, end = 472 +SHOW-CHILDREN-DEPTH1-NEXT: 472 | S_INLINESITE_END [size = 4] +SHOW-CHILDREN-DEPTH1-NEXT: 476 | S_END [size = 4] + +SHOW-CHILDREN-DEPTH2: 344 | S_INLINESITE [size = 16] +SHOW-CHILDREN-DEPTH2-NEXT: inlinee = 0x1001 (), parent = 244, end = 464 +SHOW-CHILDREN-DEPTH2-NEXT: 360 | S_LOCAL [size = 12] `x` +SHOW-CHILDREN-DEPTH2-NEXT: type=0x0074 (int), flags = param +SHOW-CHILDREN-DEPTH2-NEXT: 372 | S_DEFRANGE_FRAMEPOINTER_REL [size = 16] +SHOW-CHILDREN-DEPTH2-NEXT: offset = 48, range = [0001:0484,+44) +SHOW-CHILDREN-DEPTH2-NEXT: gaps = [] +SHOW-CHILDREN-DEPTH2-NEXT: 388 | S_LOCAL [size = 12] `y` +SHOW-CHILDREN-DEPTH2-NEXT: type=0x0074 (int), flags = param +SHOW-CHILDREN-DEPTH2-NEXT: 400 | S_DEFRANGE_FRAMEPOINTER_REL [size = 16] +SHOW-CHILDREN-DEPTH2-NEXT: offset = 52, range = [0001:0484,+44) +SHOW-CHILDREN-DEPTH2-NEXT: gaps = [] +SHOW-CHILDREN-DEPTH2-NEXT: 416 | S_INLINESITE [size = 16] +SHOW-CHILDREN-DEPTH2-NEXT: inlinee = 0x1000 (), parent = 344, end = 460 +SHOW-CHILDREN-DEPTH2-NEXT: 432 | S_LOCAL [size = 12] `x` +SHOW-CHILDREN-DEPTH2-NEXT: type=0x0074 (int), flags = param +SHOW-CHILDREN-DEPTH2-NEXT: 444 | S_DEFRANGE_FRAMEPOINTER_REL [size = 16] +SHOW-CHILDREN-DEPTH2-NEXT: offset = 60, range = [0001:0503,+4) +SHOW-CHILDREN-DEPTH2-NEXT: gaps = [] +SHOW-CHILDREN-DEPTH2-NEXT: 460 | S_INLINESITE_END [size = 4] +SHOW-CHILDREN-DEPTH2-NEXT: 464 | S_INLINESITE_END [size = 4] diff --git a/llvm/tools/llvm-pdbutil/DumpOutputStyle.cpp b/llvm/tools/llvm-pdbutil/DumpOutputStyle.cpp --- a/llvm/tools/llvm-pdbutil/DumpOutputStyle.cpp +++ b/llvm/tools/llvm-pdbutil/DumpOutputStyle.cpp @@ -1484,6 +1484,9 @@ Pipeline.addCallbackToPipeline(Deserializer); Pipeline.addCallbackToPipeline(Dumper); CVSymbolVisitor Visitor(Pipeline); + Visitor.setSymbolOffset(opts::Filters.SymbolOffset); + Visitor.setParentRecurseDepth(opts::Filters.ParentRecurseDepth); + Visitor.setChildrenRecurseDepth(opts::Filters.ChildrenRecurseDepth); auto SS = ModS.getSymbolsSubstream(); if (auto EC = Visitor.visitSymbolStream(ModS.getSymbolArray(), SS.Offset)) { diff --git a/llvm/tools/llvm-pdbutil/llvm-pdbutil.cpp b/llvm/tools/llvm-pdbutil/llvm-pdbutil.cpp --- a/llvm/tools/llvm-pdbutil/llvm-pdbutil.cpp +++ b/llvm/tools/llvm-pdbutil/llvm-pdbutil.cpp @@ -562,6 +562,27 @@ 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 @@ errs().flush(); exit(1); } - opts::Filters.NumOccurrences = opts::dump::DumpModi.getNumOccurrences(); opts::Filters.DumpModi = opts::dump::DumpModi; } + if (opts::dump::DumpSymbolOffset) { + if (!opts::Filters.DumpModi) { + errs() + << "need to specify argument '-modi' when using '-symbol-index'.\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());