[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