Skip to content

Conversation

@daniilavdeev
Copy link
Contributor

This patch makes DWARF fission compatible with RISC-V relaxations by using indirect addressing for the DW_AT_high_pc attribute. This eliminates the remaining relocations in .dwo files.

@llvmbot
Copy link
Member

llvmbot commented Oct 23, 2025

@llvm/pr-subscribers-debuginfo

@llvm/pr-subscribers-backend-risc-v

Author: None (dlav-sc)

Changes

This patch makes DWARF fission compatible with RISC-V relaxations by using indirect addressing for the DW_AT_high_pc attribute. This eliminates the remaining relocations in .dwo files.


Full diff: https://github.com/llvm/llvm-project/pull/164813.diff

2 Files Affected:

  • (modified) llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp (+5-3)
  • (modified) llvm/test/DebugInfo/RISCV/relax_dwo_ranges.ll (+30-14)
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
index 518121e200190..12ad5c18e9600 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
@@ -493,10 +493,12 @@ void DwarfCompileUnit::attachLowHighPC(DIE &D, const MCSymbol *Begin,
   assert(End->isDefined() && "Invalid end label");
 
   addLabelAddress(D, dwarf::DW_AT_low_pc, Begin);
-  if (DD->getDwarfVersion() < 4)
-    addLabelAddress(D, dwarf::DW_AT_high_pc, End);
-  else
+  if (DD->getDwarfVersion() >= 4 &&
+      (!isDwoUnit() || !llvm::isRangeRelaxable(Begin, End))) {
     addLabelDelta(D, dwarf::DW_AT_high_pc, End, Begin);
+    return;
+  }
+  addLabelAddress(D, dwarf::DW_AT_high_pc, End);
 }
 
 // Add info for Wasm-global-based relocation.
diff --git a/llvm/test/DebugInfo/RISCV/relax_dwo_ranges.ll b/llvm/test/DebugInfo/RISCV/relax_dwo_ranges.ll
index f8ab7fc5ad900..64f83ba1a7d7f 100644
--- a/llvm/test/DebugInfo/RISCV/relax_dwo_ranges.ll
+++ b/llvm/test/DebugInfo/RISCV/relax_dwo_ranges.ll
@@ -1,12 +1,13 @@
 ; RUN: llc -dwarf-version=5 -split-dwarf-file=foo.dwo -O0 %s -mtriple=riscv64-unknown-linux-gnu -filetype=obj -o %t
 ; RUN: llvm-dwarfdump -v %t | FileCheck --check-prefix=DWARF5 %s
 ; RUN: llvm-dwarfdump --debug-info %t 2> %t.txt
-; RUN: FileCheck --input-file=%t.txt %s --check-prefix=RELOCS --implicit-check-not=warning:
+; RUN: FileCheck --input-file=%t.txt %s --check-prefix=RELOCS --allow-empty --implicit-check-not=warning:
 
 ; RUN: llc -dwarf-version=4 -split-dwarf-file=foo.dwo -O0 %s -mtriple=riscv64-unknown-linux-gnu -filetype=obj -o %t
 ; RUN: llvm-dwarfdump -v %t | FileCheck --check-prefix=DWARF4 %s
 ; RUN: llvm-dwarfdump --debug-info %t 2> %t.txt
-; RUN: FileCheck --input-file=%t.txt %s --check-prefix=RELOCS --implicit-check-not=warning:
+; RUN: FileCheck --input-file=%t.txt %s --check-prefix=RELOCS --allow-empty --implicit-check-not=warning:
+; RUN: llvm-objdump -h %t | FileCheck --check-prefix=HDR %s
 
 ; In the RISC-V architecture, the .text section is subject to
 ; relaxation, meaning the start address of each function can change
@@ -49,60 +50,75 @@
 
 ; clang -g -S -gsplit-dwarf --target=riscv64 -march=rv64gc -O0 relax_dwo_ranges.cpp
 
-; Currently, square() still uses an offset to represent the function's end address,
-; which requires a relocation here.
-; RELOCS: warning: unexpected relocations for dwo section '.debug_info.dwo'
+; RELOCS-NOT: warning: unexpected relocations for dwo section '.debug_info.dwo'
 
+; Make sure we don't produce any relocations in any .dwo section
+; HDR-NOT: .rela.{{.*}}.dwo
+
+; Ensure that 'square()' function uses indexed start and end addresses
 ; DWARF5: .debug_info.dwo contents:
 ; DWARF5: DW_TAG_subprogram
-; DWARF5-NEXT: DW_AT_low_pc [DW_FORM_addrx]    (indexed (00000000) address = 0x0000000000000000 ".text")
-; DWARF5-NEXT: DW_AT_high_pc [DW_FORM_data4] (0x00000000)
+; DWARF5-NEXT: DW_AT_low_pc  [DW_FORM_addrx]    (indexed (00000000) address = 0x0000000000000000 ".text")
+; DWARF5-NEXT: DW_AT_high_pc [DW_FORM_addrx]    (indexed (00000001) address = 0x0000000000000044 ".text")
 ; DWARF5: DW_AT_name {{.*}} "square") 
 ; DWARF5: DW_TAG_formal_parameter
 
+; HDR-NOT: .rela.{{.*}}.dwo
+
 ; Ensure there is no unnecessary addresses in .o file
 ; DWARF5: .debug_addr contents:
 ; DWARF5: Addrs: [
 ; DWARF5-NEXT: 0x0000000000000000
+; DWARF5-NEXT: 0x0000000000000044
 ; DWARF5-NEXT: 0x0000000000000046
 ; DWARF5-NEXT: 0x000000000000006c
 ; DWARF5-NEXT: 0x00000000000000b0
 ; DWARF5-NEXT: ]
 
+; HDR-NOT: .rela.{{.*}}.dwo
+
 ; Ensure that 'boo()' and 'main()' use DW_RLE_startx_length and DW_RLE_startx_endx
 ; entries respectively
 ; DWARF5: .debug_rnglists.dwo contents:
 ; DWARF5: ranges:
-; DWARF5-NEXT: 0x00000014: [DW_RLE_startx_length]:  0x0000000000000001, 0x0000000000000024 => [0x0000000000000046, 0x000000000000006a)
+; DWARF5-NEXT: 0x00000014: [DW_RLE_startx_length]:  0x0000000000000002, 0x0000000000000024 => [0x0000000000000046, 0x000000000000006a)
 ; DWARF5-NEXT: 0x00000017: [DW_RLE_end_of_list  ]
-; DWARF5-NEXT: 0x00000018: [DW_RLE_startx_endx  ]:  0x0000000000000002, 0x0000000000000003 => [0x000000000000006c, 0x00000000000000b0)
+; DWARF5-NEXT: 0x00000018: [DW_RLE_startx_endx  ]:  0x0000000000000003, 0x0000000000000004 => [0x000000000000006c, 0x00000000000000b0)
 ; DWARF5-NEXT: 0x0000001b: [DW_RLE_end_of_list  ]
 ; DWARF5-EMPTY:
 
+; HDR-NOT: .rela.{{.*}}.dwo
+
 ; DWARF4: .debug_info.dwo contents:
 ; DWARF4: DW_TAG_subprogram
-; DWARF4-NEXT: DW_AT_low_pc [DW_FORM_GNU_addr_index]	(indexed (00000000) address = 0x0000000000000000 ".text")
-; DWARF4-NEXT: DW_AT_high_pc [DW_FORM_data4]	(0x00000000)
+; DWARF4-NEXT: DW_AT_low_pc  [DW_FORM_GNU_addr_index]	(indexed (00000000) address = 0x0000000000000000 ".text")
+; DWARF4-NEXT: DW_AT_high_pc [DW_FORM_GNU_addr_index] (indexed (00000001) address = 0x0000000000000044 ".text")
 ; DWARF4: DW_AT_name {{.*}} "square") 
 
 ; DWARF4: DW_TAG_subprogram
-; DWARF4-NEXT: DW_AT_low_pc [DW_FORM_GNU_addr_index]	(indexed (00000001) address = 0x0000000000000046 ".text")
+; DWARF4-NEXT: DW_AT_low_pc [DW_FORM_GNU_addr_index]	(indexed (00000002) address = 0x0000000000000046 ".text")
 ; DWARF4-NEXT: DW_AT_high_pc [DW_FORM_data4]	(0x00000024)
 ; DWARF4: DW_AT_name {{.*}} "boo") 
 
 ; DWARF4: DW_TAG_subprogram
-; DWARF4-NEXT: DW_AT_low_pc [DW_FORM_GNU_addr_index]	(indexed (00000002) address = 0x000000000000006c ".text")
-; DWARF4-NEXT: DW_AT_high_pc [DW_FORM_data4]	(0x00000000)
+; DWARF4-NEXT: DW_AT_low_pc  [DW_FORM_GNU_addr_index] (indexed (00000003) address = 0x000000000000006c ".text")
+; DWARF4-NEXT: DW_AT_high_pc [DW_FORM_GNU_addr_index] (indexed (00000004) address = 0x00000000000000b0 ".text")
 ; DWARF4: DW_AT_name {{.*}} "main") 
 
+; HDR-NOT: .rela.{{.*}}.dwo
+
 ; Ensure there is no unnecessary addresses in .o file
 ; DWARF4: .debug_addr contents:
 ; DWARF4: Addrs: [
 ; DWARF4-NEXT: 0x0000000000000000
+; DWARF4-NEXT: 0x0000000000000044
 ; DWARF4-NEXT: 0x0000000000000046
 ; DWARF4-NEXT: 0x000000000000006c
+; DWARF4-NEXT: 0x00000000000000b0
 ; DWARF4-NEXT: ]
 
+; HDR-NOT: .rela.{{.*}}.dwo
+
 ; Function Attrs: mustprogress noinline optnone
 define dso_local noundef signext i32 @_Z6squarei(i32 noundef signext %0) #0 !dbg !11 {
   %2 = alloca i32, align 4

@daniilavdeev daniilavdeev force-pushed the users/dlav-sc/dwarf_split_relaxable_range branch from c4b1df9 to 0b37999 Compare October 23, 2025 12:35
@daniilavdeev daniilavdeev force-pushed the users/dlav-sc/dwarf_split_high_pc branch from f14d5e7 to edf6aac Compare October 23, 2025 12:36
@daniilavdeev daniilavdeev force-pushed the users/dlav-sc/dwarf_split_relaxable_range branch from 0b37999 to 89367a8 Compare October 23, 2025 14:16
@daniilavdeev daniilavdeev force-pushed the users/dlav-sc/dwarf_split_high_pc branch from edf6aac to 94c0a83 Compare October 23, 2025 14:16
@asb
Copy link
Contributor

asb commented Oct 23, 2025

#56642 is the relevant issue we have open on this. I'd be interested in any thoughts from @MaskRay and/or @dwblaikie

; Currently, square() still uses an offset to represent the function's end address,
; which requires a relocation here.
; RELOCS: warning: unexpected relocations for dwo section '.debug_info.dwo'
; RELOCS-NOT: warning: unexpected relocations for dwo section '.debug_info.dwo'
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For -NOT checks I'd try to keep the text matching as vague as possible, so the check is less likely to bit-rot if someone changes the wording and then the thing regresses.

like maybe RELOCS-NOT: warning:?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, got it

@daniilavdeev daniilavdeev force-pushed the users/dlav-sc/dwarf_split_relaxable_range branch from 89367a8 to aac9a78 Compare November 5, 2025 17:20
@daniilavdeev daniilavdeev force-pushed the users/dlav-sc/dwarf_split_high_pc branch from 94c0a83 to dc7aa18 Compare November 5, 2025 17:21
@daniilavdeev daniilavdeev changed the base branch from users/dlav-sc/dwarf_split_relaxable_range to users/dlav-sc/dwarf_split_relaxable_range_2 November 5, 2025 17:29
@daniilavdeev daniilavdeev force-pushed the users/dlav-sc/dwarf_split_high_pc branch 3 times, most recently from 840273f to 5f9115d Compare November 6, 2025 21:47
@daniilavdeev daniilavdeev force-pushed the users/dlav-sc/dwarf_split_relaxable_range_2 branch from dde52a1 to 6794a76 Compare November 6, 2025 21:49
@daniilavdeev daniilavdeev force-pushed the users/dlav-sc/dwarf_split_high_pc branch from 5f9115d to fbc67cd Compare November 6, 2025 21:49
; RUN: llvm-dwarfdump -v %t | FileCheck --check-prefix=DWARF5 %s
; RUN: llvm-dwarfdump --debug-info %t 2> %t.txt
; RUN: FileCheck --input-file=%t.txt %s --check-prefix=RELOCS --implicit-check-not=warning:
; RUN: FileCheck --input-file=%t.txt %s --check-prefix=RELOCS --allow-empty --implicit-check-not=warning:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

--allow-empty is not useful. If it is really empty, prefer ... 2>&1 | count 0

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done, thanks for the suggestion

This patch makes DWARF fission compatible with RISC-V relaxations by
using indirect addressing for the DW_AT_high_pc attribute. This
eliminates the remaining relocations in .dwo files.
@daniilavdeev daniilavdeev force-pushed the users/dlav-sc/dwarf_split_relaxable_range_2 branch from 6794a76 to 453d7b6 Compare November 21, 2025 04:33
@daniilavdeev daniilavdeev force-pushed the users/dlav-sc/dwarf_split_high_pc branch from fbc67cd to 8624316 Compare November 21, 2025 04:33
Copy link
Member

@lenary lenary left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants