Dear uclibc-ng devs,

The LLVM linker seems to be quite clever. When resolving relocations, accesses 
to the GOT are potentially replaced by PC
relative addressing to the requested symbol. This breaks the old method of 
calculating the load address by using an
unrelocated GOT entry value. Instead, rely on __ehdr_start having a link 
address of zero.The LLVM linker seems to be quite
clever. When resolving relocations, accesses to the GOT are potentially 
replaced by PC relative addressing to the requested
symbol. This breaks the old method of calculating the load address by using an 
unrelocated GOT entry value. Instead, rely
on __ehdr_start having a link address of zero.

The patch is attached.

Best regards,

 - Marcus


-- 
+++++++++++++++++++


Register now for our workshop "Get to know L4Re in 3 days" on April 8-10. Learn 
to design and deploy secure system
architectures for your product with L4Re: 
https://www.kernkonzept.com/workshop-getting-started-with-l4re/

+++++++++++++++++++

Kernkonzept GmbH
Sitz: Dresden
HRB 31129
Geschäftsführer: Dr.-Ing. Michael Hohmuth


From 2df8a64bb5bb31e9325f0d9157d68eddcd208d40 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jan=20Kl=C3=B6tzke?= <jan.kloet...@kernkonzept.com>
Date: Wed, 19 Mar 2025 08:03:12 +0100
Subject: [PATCH] Do not rely on unrelocated GOT entries

The LLVM linker seems to be quite clever. When resolving relocations,
accesses to the GOT are potentially replaced by PC relative addressing
to the requested symbol. This breaks the old method of calculating the
load address by using an unrelocated GOT entry value. Instead, rely on
__ehdr_start having a link address of zero.

Signed-off-by: Marcus Haehnel <marcus.haeh...@kernkonzept.com>
---
 libc/sysdeps/linux/arm/crt1.S    | 15 ++++++---------
 libc/sysdeps/linux/x86_64/crt1.S |  6 +-----
 2 files changed, 7 insertions(+), 14 deletions(-)

diff --git a/libc/sysdeps/linux/arm/crt1.S b/libc/sysdeps/linux/arm/crt1.S
index 799f11080..040ddfd27 100644
--- a/libc/sysdeps/linux/arm/crt1.S
+++ b/libc/sysdeps/linux/arm/crt1.S
@@ -248,13 +248,9 @@ _start:
 #if defined(__ARCH_USE_MMU__) || defined(__UCLIBC_FORMAT_ELF__)
 #ifdef L_rcrt1
 	/* We don't need to save a1 since no dynamic linker should have run */
-	ldr a1, .L_GOT          /* Get value at .L_GOT + 0  (offset to GOT)*/
-	adr a2, .L_GOT          /* Get address of .L_GOT */
-	ldr a3, .L_GOT+16       /* Get value of _start(GOT) stored in .L_GOT */
-	adr a4, _start          /* Get address of _start after relocation (changes to pc - ~30 or so) */
-	add a1, a1, a2          /* Calculate where the GOT is */
-	ldr a2, [a1, a3]        /* GOT + _start(GOT) = offset of _start from begin of file */
-	sub a1, a4, a2          /* Current addr of _start - offset from beginning of file = load addr */
+	adr a1, .L__ehdr_start_off  /* Get address of .L__ehdr_start_off */
+	ldr a2, .L__ehdr_start_off  /* Offset from .L__ehdr_start_off to __ehdr_start */
+	add a1, a1, a2              /* Address of __ehdr_start = load addr */
 	bl reloc_static_pie
 	mov a1, #0              /* Clean up a1 so that a random address won't get called at the end of program */
 
@@ -325,9 +321,10 @@ _start:
 	.word _fini(GOT)
 	.word _init(GOT)
 	.word main(GOT)
-#ifdef L_rcrt1
-	.word _start(GOT)
 #endif
+#ifdef L_rcrt1
+.L__ehdr_start_off:
+	.word __ehdr_start - .L__ehdr_start_off
 #endif
 #endif
 
diff --git a/libc/sysdeps/linux/x86_64/crt1.S b/libc/sysdeps/linux/x86_64/crt1.S
index 701cbf2f6..151aeffeb 100644
--- a/libc/sysdeps/linux/x86_64/crt1.S
+++ b/libc/sysdeps/linux/x86_64/crt1.S
@@ -83,11 +83,7 @@ _start:
 #ifdef L_rcrt1
 	pushq %rdi                          /* save rdi (but should be 0...) */
 	pushq %rdx                          /* store rdx (rtld_fini) */
-	xorq %rcx, %rcx                     /* ensure rcx is 0 */
-	addq _start@GOTPCREL(%rip), %rcx    /* get offset of _start from beginning of file */
-	movq _start@GOTPCREL(%rip), %rax    /* get run time address of _start */
-	subq %rcx, %rax                     /* calculate run time load offset */
-	movq %rax, %rdi                     /* load offset -> param 1 */
+	lea  __ehdr_start(%rip), %rdi       /* "Calculate" load address... */
 	call reloc_static_pie               /* relocate dynamic addrs */
 	xorq %rax, %rax                     /* cleanup */
 	popq %rdx
-- 
2.47.1

Attachment: signature.asc
Description: This is a digitally signed message part

_______________________________________________
devel mailing list -- devel@uclibc-ng.org
To unsubscribe send an email to devel-le...@uclibc-ng.org

Reply via email to