]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
x32: Allow R_X86_64_PC64 for SFrame V3
authorH.J. Lu <hjl.tools@gmail.com>
Sun, 18 Jan 2026 01:24:48 +0000 (09:24 +0800)
committerH.J. Lu <hjl.tools@gmail.com>
Fri, 23 Jan 2026 07:02:15 +0000 (15:02 +0800)
SFrame V3 generates R_X86_64_PC64 relocation, instead of R_X86_64_PC32,
in .sframe section for x86-64.  Although x32 doesn't support SFrame,
.sframe section can be found in x32 object converted from x86-64 object
with objcopy, which only changes the ELF file class from ELFCLASS64 to
ELFCLASS32 with all section contents unchanged.

Update elf_x86_64_scan_relocs to allow R_X86_64_PC64 for x32 so that
x32 object file with .sframe section can be used as x32 linker input.

bfd/

PR ld/33807
* elf64-x86-64.c (elf_x86_64_scan_relocs): Allow R_X86_64_PC64
for x32.

ld/

PR ld/33807
* testsuite/ld-x86-64/sframe.rd: New file.
* testsuite/ld-x86-64/sframe.s: Likewise.
* testsuite/ld-x86-64/x86-64.exp: Run PR ld/33807 tests.

Signed-off-by: H.J. Lu <hjl.tools@gmail.com>
bfd/elf64-x86-64.c
ld/testsuite/ld-x86-64/sframe.rd [new file with mode: 0644]
ld/testsuite/ld-x86-64/sframe.s [new file with mode: 0644]
ld/testsuite/ld-x86-64/x86-64.exp

index 84c558fd157c100ce89fbddcb3f81758223364ab..55102f833657c9ab16ca5b920303d5f5a2661873 100644 (file)
@@ -2629,7 +2629,6 @@ elf_x86_64_scan_relocs (bfd *abfd, struct bfd_link_info *info,
 
          case R_X86_64_DTPOFF64:
          case R_X86_64_TPOFF64:
-         case R_X86_64_PC64:
          case R_X86_64_GOTOFF64:
          case R_X86_64_GOT64:
          case R_X86_64_GOTPCREL64:
diff --git a/ld/testsuite/ld-x86-64/sframe.rd b/ld/testsuite/ld-x86-64/sframe.rd
new file mode 100644 (file)
index 0000000..cbdec3e
--- /dev/null
@@ -0,0 +1,16 @@
+Contents of the SFrame section .sframe:
+  Header :
+
+    Version: SFRAME_VERSION_3
+    Flags: SFRAME_F_FDE_SORTED,
+           SFRAME_F_FDE_FUNC_START_PCREL
+    CFA fixed RA offset: -8
+    Num FDEs: 1
+    Num FREs: 1
+
+  Function Index :
+
+    func idx \[0\]: pc = 0x1000, size = 1 bytes
+    STARTPC         CFA       FP        RA           
+    0000000000001000  sp\+8      u         f            
+#pass
diff --git a/ld/testsuite/ld-x86-64/sframe.s b/ld/testsuite/ld-x86-64/sframe.s
new file mode 100644 (file)
index 0000000..59eedc8
--- /dev/null
@@ -0,0 +1,10 @@
+       .text
+       .p2align 4
+       .globl  foo
+       .type   foo, @function
+foo:
+       .cfi_startproc
+       ret
+       .cfi_endproc
+       .size   foo, .-foo
+       .section        .note.GNU-stack,"",@progbits
index aa5c90f8ca252698566d8bbfa58f3c473529fdbf..657805d5a3a1f1e24f05aaa354b5b5eb9e02101b 100644 (file)
@@ -651,6 +651,36 @@ if ![ld_assemble $as "--64 $srcdir/$subdir/foo.s" tmpdir/foo64.o] {
     return
 }
 
+run_ld_link_tests [list \
+    [list \
+       "Build sframe.o" \
+       "" \
+       "" \
+       "--64 --gsframe" \
+       {sframe.s} \
+    ] \
+]
+
+set cmd "$objcopy -O elf32-x86-64 tmpdir/sframe.o tmpdir/sframe-x32.o"
+send_log "$cmd\n"
+set got [remote_exec host "$cmd"]
+if { [lindex $got 0] != 0 || ![string match "" [lindex $got 1]] } then {
+    send_log "$got\n"
+    fail "Convert x86-64 sframe.o to x32"
+} else {
+    run_ld_link_tests [list \
+       [list \
+           "X32 DSO from x86-64 sframe.o" \
+           "-shared --hash-style=both --no-rosegment -melf32_x86_64" \
+           "tmpdir/sframe-x32.o" \
+           "--x32 -mx86-used-note=yes" \
+           {dummy.s} \
+           {{readelf --sframe sframe.rd}} \
+           "sframe-x32" \
+       ] \
+    ]
+}
+
 run_dump_test "compressed1"
 run_dump_test "ilp32-1"
 run_dump_test "ilp32-2"