Quellcode durchsuchen

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.haehnel@kernkonzept.com>
Jan Klötzke vor 1 Monat
Ursprung
Commit
b99b775622
2 geänderte Dateien mit 7 neuen und 14 gelöschten Zeilen
  1. 6 9
      libc/sysdeps/linux/arm/crt1.S
  2. 1 5
      libc/sysdeps/linux/x86_64/crt1.S

+ 6 - 9
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
 

+ 1 - 5
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