[llvm] 48911ca - [llvm-debuginfo-analyzer] Support `S_DEFRANGE_REGISTER_REL_INDIR` (#187531)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Mar 26 02:56:30 PDT 2026
Author: Nerixyz
Date: 2026-03-26T10:56:24+01:00
New Revision: 48911ca1439156074ceef290754a7180c37e6930
URL: https://github.com/llvm/llvm-project/commit/48911ca1439156074ceef290754a7180c37e6930
DIFF: https://github.com/llvm/llvm-project/commit/48911ca1439156074ceef290754a7180c37e6930.diff
LOG: [llvm-debuginfo-analyzer] Support `S_DEFRANGE_REGISTER_REL_INDIR` (#187531)
#186410 added support for reading `S_DEFRANGE_REGISTER_REL_INDIR` in
LLVM's CodeView. This adds support for printing it in
llvm-debuginfo-analyzer. This record is not (yet) generated by LLVM. It
encodes an indirect location like `S_REGREL32_INDIR` but for a range (so
it's conceptually a child of `S_LOCAL` which only encodes _some_
variable in a function).
---------
Co-authored-by: Javier Lopez-Gomez <javier.lopez.gomez at proton.me>
Added:
llvm/test/tools/llvm-debuginfo-analyzer/COFF/07-coff-regrel-indir.test
llvm/test/tools/llvm-debuginfo-analyzer/COFF/Inputs/defrange-regrel-indir-clang.yaml
Modified:
llvm/include/llvm/DebugInfo/LogicalView/Core/LVSupport.h
llvm/include/llvm/DebugInfo/LogicalView/Readers/LVCodeViewVisitor.h
llvm/lib/DebugInfo/LogicalView/Core/LVLocation.cpp
llvm/lib/DebugInfo/LogicalView/Readers/LVCodeViewVisitor.cpp
Removed:
################################################################################
diff --git a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVSupport.h b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVSupport.h
index 058ca2da9a960..eec5df19ff843 100644
--- a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVSupport.h
+++ b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVSupport.h
@@ -263,6 +263,7 @@ LLVM_ABI std::string getScopedName(const LVStringRefs &Components,
// S_DEFRANGE_SUBFIELD_REGISTER 0x1143
// S_DEFRANGE_FRAMEPOINTER_REL_FULL_SCOPE 0x1144
// S_DEFRANGE_REGISTER_REL 0x1145
+// S_DEFRANGE_REGISTER_REL_INDIR 0x1177
// When recording CodeView debug location, the above values are truncated
// to a uint8_t value in order to fit the 'OpCode' used for the logical
// debug location operations.
diff --git a/llvm/include/llvm/DebugInfo/LogicalView/Readers/LVCodeViewVisitor.h b/llvm/include/llvm/DebugInfo/LogicalView/Readers/LVCodeViewVisitor.h
index 86baf084f7c39..76b372efb632a 100644
--- a/llvm/include/llvm/DebugInfo/LogicalView/Readers/LVCodeViewVisitor.h
+++ b/llvm/include/llvm/DebugInfo/LogicalView/Readers/LVCodeViewVisitor.h
@@ -208,6 +208,9 @@ class LVSymbolVisitor final : public SymbolVisitorCallbacks {
DefRangeFramePointerRelSym &DefRangeFramePointerRel) override;
Error visitKnownRecord(CVSymbol &Record,
DefRangeRegisterRelSym &DefRangeRegisterRel) override;
+ Error visitKnownRecord(
+ CVSymbol &Record,
+ DefRangeRegisterRelIndirSym &DefRangeRegisterRelIndir) override;
Error visitKnownRecord(CVSymbol &Record,
DefRangeRegisterSym &DefRangeRegister) override;
Error visitKnownRecord(
diff --git a/llvm/lib/DebugInfo/LogicalView/Core/LVLocation.cpp b/llvm/lib/DebugInfo/LogicalView/Core/LVLocation.cpp
index 3c078d8ee74b8..5cb017903675a 100644
--- a/llvm/lib/DebugInfo/LogicalView/Core/LVLocation.cpp
+++ b/llvm/lib/DebugInfo/LogicalView/Core/LVLocation.cpp
@@ -374,6 +374,12 @@ std::string LVOperation::getOperandsCodeViewInfo() {
Stream << "register_rel " << getReader().getRegisterName(Opcode, Operands)
<< " offset " << int(Operands[1]);
break;
+ // Operands: [Register, Offset, OffsetInUdt].
+ case codeview::SymbolKind::S_DEFRANGE_REGISTER_REL_INDIR:
+ Stream << "register_rel_indir "
+ << getReader().getRegisterName(Opcode, Operands) << " offset "
+ << int(Operands[1]) << " offset_in_udt " << int(Operands[2]);
+ break;
// Operands: [Program].
case codeview::SymbolKind::S_DEFRANGE:
diff --git a/llvm/lib/DebugInfo/LogicalView/Readers/LVCodeViewVisitor.cpp b/llvm/lib/DebugInfo/LogicalView/Readers/LVCodeViewVisitor.cpp
index f3b4a8c273536..3818dc3b9a026 100644
--- a/llvm/lib/DebugInfo/LogicalView/Readers/LVCodeViewVisitor.cpp
+++ b/llvm/lib/DebugInfo/LogicalView/Readers/LVCodeViewVisitor.cpp
@@ -1141,6 +1141,47 @@ Error LVSymbolVisitor::visitKnownRecord(
return Error::success();
}
+// S_DEFRANGE_REGISTER_REL_INDIR
+Error LVSymbolVisitor::visitKnownRecord(
+ CVSymbol &Record, DefRangeRegisterRelIndirSym &DefRangeRegisterRelIndir) {
+ // DefRanges don't have types, just registers and code offsets.
+ LLVM_DEBUG({
+ if (LocalSymbol)
+ W.getOStream() << formatv("Symbol: {0}, ", LocalSymbol->getName());
+
+ W.printBoolean("HasSpilledUDTMember",
+ DefRangeRegisterRelIndir.hasSpilledUDTMember());
+ W.printNumber("OffsetInParent", DefRangeRegisterRelIndir.offsetInParent());
+ W.printNumber("BasePointerOffset",
+ DefRangeRegisterRelIndir.Hdr.BasePointerOffset);
+ W.printNumber("OffsetInUdt", DefRangeRegisterRelIndir.Hdr.OffsetInUdt);
+ printLocalVariableAddrRange(DefRangeRegisterRelIndir.Range,
+ DefRangeRegisterRelIndir.getRelocationOffset());
+ printLocalVariableAddrGap(DefRangeRegisterRelIndir.Gaps);
+ });
+
+ if (LVSymbol *Symbol = LocalSymbol) {
+ Symbol->setHasCodeViewLocation();
+ LocalSymbol = nullptr;
+
+ // Add location debug location. Operands: [Register, Offset, OffsetInUdt].
+ dwarf::Attribute Attr =
+ dwarf::Attribute(SymbolKind::S_DEFRANGE_REGISTER_REL_INDIR);
+ const uint64_t Operand1 = DefRangeRegisterRelIndir.Hdr.Register;
+ const uint64_t Operand2 = DefRangeRegisterRelIndir.Hdr.BasePointerOffset;
+ const uint64_t Operand3 = DefRangeRegisterRelIndir.Hdr.OffsetInUdt;
+
+ const LocalVariableAddrRange Range = DefRangeRegisterRelIndir.Range;
+ const LVAddress Address =
+ Reader->linearAddress(Range.ISectStart, Range.OffsetStart);
+
+ Symbol->addLocation(Attr, Address, Address + Range.Range, 0, 0);
+ Symbol->addLocationOperands(LVSmall(Attr), {Operand1, Operand2, Operand3});
+ }
+
+ return Error::success();
+}
+
// S_DEFRANGE_REGISTER
Error LVSymbolVisitor::visitKnownRecord(CVSymbol &Record,
DefRangeRegisterSym &DefRangeRegister) {
diff --git a/llvm/test/tools/llvm-debuginfo-analyzer/COFF/07-coff-regrel-indir.test b/llvm/test/tools/llvm-debuginfo-analyzer/COFF/07-coff-regrel-indir.test
new file mode 100644
index 0000000000000..8a4aa885029e7
--- /dev/null
+++ b/llvm/test/tools/llvm-debuginfo-analyzer/COFF/07-coff-regrel-indir.test
@@ -0,0 +1,40 @@
+; REQUIRES: x86-registered-target
+
+; Test case 7 - S_DEFRANGE_REGREL_INDIR
+
+; t.cpp
+; 1 struct Foo {
+; 2 bool a;
+; 3 short b;
+; 4 int c;
+; 5 };
+; 6
+; 7 int main() {
+; 8 Foo f{1, 2, 3};
+; 9 auto &[a, b, c] = f;
+; 10 return b + c;
+; 11 }
+
+; RUN: yaml2obj %p/Inputs/defrange-regrel-indir-clang.yaml -o - | \
+; RUN: llvm-debuginfo-analyzer --attribute=register \
+; RUN: --print=symbols \
+; RUN: - 2>&1 | \
+; RUN: FileCheck --strict-whitespace %s
+
+; CHECK: Logical View:
+; CHECK-NEXT: {File} '-'
+; CHECK-EMPTY:
+; CHECK-NEXT: {CompileUnit} 't.cpp'
+; CHECK-NEXT: {Function} extern not_inlined 'main' -> 'int'
+; CHECK-NEXT: {Variable} 'a' -> 'bool'
+; CHECK-NEXT: {Location} Lines ?:?
+; CHECK-NEXT: {Entry} register_rel_indir RSP offset 0 offset_in_udt 0
+; CHECK-NEXT: {Variable} 'b' -> 'short'
+; CHECK-NEXT: {Location} Lines ?:?
+; CHECK-NEXT: {Entry} register_rel_indir RSP offset 0 offset_in_udt 2
+; CHECK-NEXT: {Variable} 'c' -> 'int'
+; CHECK-NEXT: {Location} Lines ?:?
+; CHECK-NEXT: {Entry} register_rel_indir RSP offset 0 offset_in_udt 4
+; CHECK-NEXT: {Variable} 'f' -> 'Foo'
+; CHECK-NEXT: {Location} Lines ?:?
+; CHECK-NEXT: {Entry} frame_pointer_rel 12
diff --git a/llvm/test/tools/llvm-debuginfo-analyzer/COFF/Inputs/defrange-regrel-indir-clang.yaml b/llvm/test/tools/llvm-debuginfo-analyzer/COFF/Inputs/defrange-regrel-indir-clang.yaml
new file mode 100644
index 0000000000000..e0b30998879be
--- /dev/null
+++ b/llvm/test/tools/llvm-debuginfo-analyzer/COFF/Inputs/defrange-regrel-indir-clang.yaml
@@ -0,0 +1,301 @@
+--- !COFF
+header:
+ Machine: IMAGE_FILE_MACHINE_AMD64
+ Characteristics: [ ]
+sections:
+ - Name: .text
+ Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
+ Alignment: 16
+ SectionData: 4883EC18C744241400000000488B0500000000488944240C488D44240C48890424488B04240FBF4002488B0C240341044883C418C3
+ SizeOfRawData: 53
+ Relocations:
+ - Name: '.debug$S'
+ Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
+ Alignment: 4
+ Subsections:
+ - !Symbols
+ Records:
+ - Kind: S_OBJNAME
+ ObjNameSym:
+ Signature: 0
+ ObjectName: 'F:\Dev\dummy\t.obj'
+ - Kind: S_COMPILE3
+ Compile3Sym:
+ Flags: [ ]
+ Machine: X64
+ FrontendMajor: 23
+ FrontendMinor: 0
+ FrontendBuild: 0
+ FrontendQFE: 0
+ BackendMajor: 23000
+ BackendMinor: 0
+ BackendBuild: 0
+ BackendQFE: 0
+ Version: 'clang version 23.0.0git (https://github.com/Nerixyz/llvm-project.git ec2af1a892629f17c76fad23c5c1a0496aff4662)'
+ - !Symbols
+ Records:
+ - Kind: S_GPROC32_ID
+ ProcSym:
+ CodeSize: 53
+ DbgStart: 0
+ DbgEnd: 0
+ FunctionType: 4098
+ Flags: [ IsNoInline, HasOptimizedDebugInfo ]
+ DisplayName: main
+ - Kind: S_FRAMEPROC
+ FrameProcSym:
+ TotalFrameBytes: 24
+ PaddingFrameBytes: 0
+ OffsetToPadding: 0
+ BytesOfCalleeSavedRegisters: 0
+ OffsetOfExceptionHandler: 0
+ SectionIdOfExceptionHandler: 0
+ Flags: [ SafeBuffers ]
+ - Kind: S_LOCAL
+ LocalSym:
+ Type: 4101
+ Flags: [ ]
+ VarName: f
+ - Kind: S_DEFRANGE_FRAMEPOINTER_REL
+ DefRangeFramePointerRelSym:
+ Offset: 12
+ Range:
+ OffsetStart: 12
+ ISectStart: 0
+ Range: 41
+ Gaps: []
+ - Kind: S_LOCAL
+ LocalSym:
+ Type: 48
+ Flags: [ ]
+ VarName: a
+ - Kind: S_DEFRANGE_REGISTER_REL_INDIR
+ DefRangeRegisterRelIndirSym:
+ Register: 335
+ Flags: 0
+ BasePointerOffset: 0
+ OffsetInUdt: 0
+ Range:
+ OffsetStart: 12
+ ISectStart: 0
+ Range: 41
+ Gaps: []
+ - Kind: S_LOCAL
+ LocalSym:
+ Type: 17
+ Flags: [ ]
+ VarName: b
+ - Kind: S_DEFRANGE_REGISTER_REL_INDIR
+ DefRangeRegisterRelIndirSym:
+ Register: 335
+ Flags: 0
+ BasePointerOffset: 0
+ OffsetInUdt: 2
+ Range:
+ OffsetStart: 12
+ ISectStart: 0
+ Range: 41
+ Gaps: []
+ - Kind: S_LOCAL
+ LocalSym:
+ Type: 116
+ Flags: [ ]
+ VarName: c
+ - Kind: S_DEFRANGE_REGISTER_REL_INDIR
+ DefRangeRegisterRelIndirSym:
+ Register: 335
+ Flags: 0
+ BasePointerOffset: 0
+ OffsetInUdt: 4
+ Range:
+ OffsetStart: 12
+ ISectStart: 0
+ Range: 41
+ Gaps: []
+ - Kind: S_PROC_ID_END
+ ScopeEndSym: {}
+ - !Lines
+ CodeSize: 53
+ Flags: [ ]
+ RelocOffset: 0
+ RelocSegment: 0
+ Blocks:
+ - FileName: 'F:\Dev\dummy\t.cpp'
+ Lines:
+ - Offset: 0
+ LineStart: 7
+ IsStatement: false
+ EndDelta: 0
+ - Offset: 12
+ LineStart: 8
+ IsStatement: false
+ EndDelta: 0
+ - Offset: 24
+ LineStart: 9
+ IsStatement: false
+ EndDelta: 0
+ - Offset: 33
+ LineStart: 10
+ IsStatement: false
+ EndDelta: 0
+ Columns: []
+ - !Symbols
+ Records:
+ - Kind: S_UDT
+ UDTSym:
+ Type: 4101
+ UDTName: Foo
+ - !FileChecksums
+ Checksums:
+ - FileName: 'F:\Dev\dummy\t.cpp'
+ Kind: MD5
+ Checksum: 0F1D77932744955224E6CF67B46A8F99
+ - !StringTable
+ Strings:
+ - 'F:\Dev\dummy\t.cpp'
+ - !Symbols
+ Records:
+ - Kind: S_BUILDINFO
+ BuildInfoSym:
+ BuildId: 4109
+ SizeOfRawData: 564
+ Relocations:
+ - VirtualAddress: 220
+ SymbolName: main
+ Type: IMAGE_REL_AMD64_SECREL
+ - Name: '.debug$T'
+ Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
+ Alignment: 4
+ Types:
+ - Kind: LF_ARGLIST
+ ArgList:
+ ArgIndices: [ ]
+ - Kind: LF_PROCEDURE
+ Procedure:
+ ReturnType: 116
+ CallConv: NearC
+ Options: [ None ]
+ ParameterCount: 0
+ ArgumentList: 4096
+ - Kind: LF_FUNC_ID
+ FuncId:
+ ParentScope: 0
+ FunctionType: 4097
+ Name: main
+ - Kind: LF_STRUCTURE
+ Class:
+ MemberCount: 0
+ Options: [ None, ForwardReference, HasUniqueName ]
+ FieldList: 0
+ Name: Foo
+ UniqueName: '.?AUFoo@@'
+ DerivationList: 0
+ VTableShape: 0
+ Size: 0
+ - Kind: LF_FIELDLIST
+ FieldList:
+ - Kind: LF_MEMBER
+ DataMember:
+ Attrs: 3
+ Type: 48
+ FieldOffset: 0
+ Name: a
+ - Kind: LF_MEMBER
+ DataMember:
+ Attrs: 3
+ Type: 17
+ FieldOffset: 2
+ Name: b
+ - Kind: LF_MEMBER
+ DataMember:
+ Attrs: 3
+ Type: 116
+ FieldOffset: 4
+ Name: c
+ - Kind: LF_STRUCTURE
+ Class:
+ MemberCount: 3
+ Options: [ None, HasUniqueName ]
+ FieldList: 4100
+ Name: Foo
+ UniqueName: '.?AUFoo@@'
+ DerivationList: 0
+ VTableShape: 0
+ Size: 8
+ - Kind: LF_STRING_ID
+ StringId:
+ Id: 0
+ String: 'F:\Dev\dummy\t.cpp'
+ - Kind: LF_UDT_SRC_LINE
+ UdtSourceLine:
+ UDT: 4101
+ SourceFile: 4102
+ LineNumber: 1
+ - Kind: LF_STRING_ID
+ StringId:
+ Id: 0
+ String: 'F:\Dev\dummy'
+ - Kind: LF_STRING_ID
+ StringId:
+ Id: 0
+ String: t.cpp
+ - Kind: LF_STRING_ID
+ StringId:
+ Id: 0
+ String: ''
+ - Kind: LF_STRING_ID
+ StringId:
+ Id: 0
+ String: 'F:\Dev\llvm-project\build\bin\clang-cl.exe'
+ - Kind: LF_STRING_ID
+ StringId:
+ Id: 0
+ String: ''
+ - Kind: LF_BUILDINFO
+ BuildInfo:
+ ArgIndices: [ 4104, 4107, 4105, 4106, 4108 ]
+ SizeOfRawData: 2120
+symbols:
+ - Name: .text
+ Value: 0
+ SectionNumber: 1
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_STATIC
+ SectionDefinition:
+ Length: 53
+ NumberOfRelocations: 1
+ NumberOfLinenumbers: 0
+ CheckSum: 142096877
+ Number: 1
+ - Name: '.debug$S'
+ Value: 0
+ SectionNumber: 7
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_STATIC
+ SectionDefinition:
+ Length: 564
+ NumberOfRelocations: 12
+ NumberOfLinenumbers: 0
+ CheckSum: 3837595763
+ Number: 7
+ - Name: '.debug$T'
+ Value: 0
+ SectionNumber: 8
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_STATIC
+ SectionDefinition:
+ Length: 2120
+ NumberOfRelocations: 0
+ NumberOfLinenumbers: 0
+ CheckSum: 1067981291
+ Number: 8
+ - Name: main
+ Value: 0
+ SectionNumber: 1
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_FUNCTION
+ StorageClass: IMAGE_SYM_CLASS_EXTERNAL
+...
More information about the llvm-commits
mailing list