[RFC] aarch64: fix start code for static pie

Message ID 5A1812F4.1050904@arm.com
State New, archived
Headers

Commit Message

Szabolcs Nagy Nov. 24, 2017, 12:39 p.m. UTC
  with upcoming static pie patches there are three flavors of the crt startup code:

1) crt1.o used for non-pie static linking (executable has no relocs),
2) Scrt1.o used for dynamic linking (dynamic linker relocates),
3) rcrt1.o used for static pie linking (self relocation is needed)

when crt1.o and rcrt1.o is built in the --enable-static-pie case -DPIC is passed,
when Scrt1.o is built then -DPIC -DSHARED is passed.

(crt1.o gets a dummy _dl_relocate_static_pie that interposes the one in
libc so no self-relocation is done in that case in __libc_start_main)

the Scrt1.o code is position independent but it relies on GOT entries that
need to be relocated which happens later and the static linker cannot relax
the GOT loads, so rcrt1.o needs separate implementation.

This implementation works with .text <= 4G files, which is fine, currently
the toolchain does not support larger position independent executables.

tests pass with ld/22269 and ld/22263 binutils bugs fixed.
this patch is on top of master but assumes the static pie patches.

2017-11-24  Szabolcs Nagy  <szabolcs.nagy@arm.com>

	* sysdeps/aarch64/start.S (_start): Handle PIC && !SHARED case.
  

Comments

Szabolcs Nagy Dec. 18, 2017, 10:22 a.m. UTC | #1
On 24/11/17 12:39, Szabolcs Nagy wrote:
> 2017-11-24  Szabolcs Nagy  <szabolcs.nagy@arm.com>
> 
> 	* sysdeps/aarch64/start.S (_start): Handle PIC && !SHARED case.
> 

committed with updated commit message:

There are three flavors of the crt startup code:

1) crt1.o used for non-pie,
2) Scrt1.o used for dynamic linked pie (dynamic linker relocates),
3) rcrt1.o used for static linked pie (self relocation is needed)

In the --enable-static-pie case crt1.o is built with -DPIC and in case
of static linking it interposes _dl_relocate_static_pie in libc to
avoid self relocation.

Scrt1.o is built with -DPIC -DSHARED and it relies on GOT entries that
the static linker cannot relax and thus need relocation before the
start code is executed, so rcrt1.o needs separate implementation.

This implementation does not work for .text > 4G position independent
executables, which is fine since the toolchain does not support
-mcmodel=large with -fPIE.

Tests pass with ld/22269 and ld/22263 binutils bugs fixed.

        * sysdeps/aarch64/start.S (_start): Handle PIC && !SHARED case.
  
H.J. Lu Dec. 18, 2017, 11:21 a.m. UTC | #2
On Mon, Dec 18, 2017 at 2:22 AM, Szabolcs Nagy <szabolcs.nagy@arm.com> wrote:
> On 24/11/17 12:39, Szabolcs Nagy wrote:
>> 2017-11-24  Szabolcs Nagy  <szabolcs.nagy@arm.com>
>>
>>       * sysdeps/aarch64/start.S (_start): Handle PIC && !SHARED case.
>>
>
> committed with updated commit message:
>
> There are three flavors of the crt startup code:
>
> 1) crt1.o used for non-pie,
> 2) Scrt1.o used for dynamic linked pie (dynamic linker relocates),
> 3) rcrt1.o used for static linked pie (self relocation is needed)
>
> In the --enable-static-pie case crt1.o is built with -DPIC and in case
> of static linking it interposes _dl_relocate_static_pie in libc to
> avoid self relocation.
>
> Scrt1.o is built with -DPIC -DSHARED and it relies on GOT entries that
> the static linker cannot relax and thus need relocation before the
> start code is executed, so rcrt1.o needs separate implementation.
>
> This implementation does not work for .text > 4G position independent
> executables, which is fine since the toolchain does not support
> -mcmodel=large with -fPIE.
>
> Tests pass with ld/22269 and ld/22263 binutils bugs fixed.
>
>         * sysdeps/aarch64/start.S (_start): Handle PIC && !SHARED case.
>

Can you update NEWS to add aarch64 to static PIE?

Thanks.
  

Patch

diff --git a/sysdeps/aarch64/start.S b/sysdeps/aarch64/start.S
index c20433ad73..cd7ba7df3e 100644
--- a/sysdeps/aarch64/start.S
+++ b/sysdeps/aarch64/start.S
@@ -60,7 +60,8 @@  _start:
 	/* Setup stack limit in argument register */
 	mov	x6, sp
 
-#ifdef SHARED
+#ifdef PIC
+# ifdef SHARED
         adrp    x0, :got:main
 	ldr     PTR_REG (0), [x0, #:got_lo12:main]
 
@@ -69,6 +70,15 @@  _start:
 
         adrp    x4, :got:__libc_csu_fini
 	ldr     PTR_REG (4), [x4, #:got_lo12:__libc_csu_fini]
+
+# else
+	adrp	x0, main
+	add	x0, x0, :lo12:main
+	adrp	x3, __libc_csu_init
+	add	x3, x3, :lo12:__libc_csu_init
+	adrp	x4, __libc_csu_fini
+	add	x4, x4, :lo12:__libc_csu_fini
+# endif
 #else
 	/* Set up the other arguments in registers */
 	MOVL (0, main)