[PATCH] x86-64: Save and restore R10 in _dl_runtime_resolve [BZ #27279]

Jackson Stogel jtstogel@gmail.com
Fri Dec 12 00:39:14 GMT 2025


As described in https://sourceware.org/bugzilla/show_bug.cgi?id=27279,
Clang's `preserve_most` calling convention isn't compatible with lazy
PLT resolution. Calls to functions marked with `preserve_most` are
expected to leave r10 unaffected, but lazy PLT resolution
clobbers r10 in `_dl_runtime_resolve` during a call to `_dl_fixup`.

While not a bug, the r10 clobber can lead to surprising, difficult to
debug behavior. This patch updates `_dl_runtime_resolve` to preserve
r10, expanding compatibility with non-standard calling conventions.

Tested: Ran make check on x86_64 linux and no new tests fail.
If preferred, happy to add a test for this behavior as well.

Signed-off-by: Jackson Stogel <jtstogel@gmail.com>
---
 sysdeps/x86/sysdep.h           | 4 ++--
 sysdeps/x86_64/dl-trampoline.S | 1 +
 sysdeps/x86_64/dl-trampoline.h | 2 ++
 3 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/sysdeps/x86/sysdep.h b/sysdeps/x86/sysdep.h
index b8e963b654..3d6471a00d 100644
--- a/sysdeps/x86/sysdep.h
+++ b/sysdeps/x86/sysdep.h
@@ -48,7 +48,7 @@
    |                  |<-
    |                  |<-
    |------------------|<- xsave buffer start at STATE_SAVE_OFFSET(%rsp)
-   |                  |<- 8-byte padding for 64-byte alignment
+   |                  |<- R10
    |                  |<- R9
    |                  |<- R8
    |                  |<- RDI
@@ -59,7 +59,7 @@
    +==================+<- RSP aligned at 64 bytes
 
  */
-# define STATE_SAVE_OFFSET (8 * 7 + 8)
+# define STATE_SAVE_OFFSET (8 * 8)
 
 /* _dl_tlsdesc_dynamic preserves RDI, RSI and RBX before realigning
    stack.  After realigning stack, it saves RCX, RDX, R8, R9, R10 and
diff --git a/sysdeps/x86_64/dl-trampoline.S b/sysdeps/x86_64/dl-trampoline.S
index ac85f96794..1616b9f5d7 100644
--- a/sysdeps/x86_64/dl-trampoline.S
+++ b/sysdeps/x86_64/dl-trampoline.S
@@ -32,6 +32,7 @@
 #define REGISTER_SAVE_RDI	(REGISTER_SAVE_RSI + 8)
 #define REGISTER_SAVE_R8	(REGISTER_SAVE_RDI + 8)
 #define REGISTER_SAVE_R9	(REGISTER_SAVE_R8 + 8)
+#define REGISTER_SAVE_R10	(REGISTER_SAVE_R9 + 8)
 
 #define RESTORE_AVX
 
diff --git a/sysdeps/x86_64/dl-trampoline.h b/sysdeps/x86_64/dl-trampoline.h
index 5b54d4e2c0..aa089e2e85 100644
--- a/sysdeps/x86_64/dl-trampoline.h
+++ b/sysdeps/x86_64/dl-trampoline.h
@@ -69,6 +69,7 @@ _dl_runtime_resolve:
 	movq %rdi, REGISTER_SAVE_RDI(%rsp)
 	movq %r8, REGISTER_SAVE_R8(%rsp)
 	movq %r9, REGISTER_SAVE_R9(%rsp)
+	movq %r10, REGISTER_SAVE_R10(%rsp)
 # ifdef USE_FXSAVE
 	fxsave STATE_SAVE_OFFSET(%rsp)
 # else
@@ -105,6 +106,7 @@ _dl_runtime_resolve:
 	xorl %edx, %edx
 	xrstor STATE_SAVE_OFFSET(%rsp)
 # endif
+	movq REGISTER_SAVE_R10(%rsp), %r10
 	movq REGISTER_SAVE_R9(%rsp), %r9
 	movq REGISTER_SAVE_R8(%rsp), %r8
 	movq REGISTER_SAVE_RDI(%rsp), %rdi

base-commit: 0f0a5cd338998f4b603f52f3ce2163df0db7b814
-- 
2.52.0



More information about the Libc-alpha mailing list