[v6,4/4] aarch64: Move ld.so _start to separate file and drop _dl_skip_args
Checks
Context |
Check |
Description |
dj/TryBot-32bit |
success
|
Build for i686
|
dj/TryBot-apply_patch |
success
|
Patch applied to master at the time it was sent
|
Commit Message
A separate asm file is easier to maintain than a macro that expands to
inline asm.
The RTLD_START macro is only needed now because _dl_start is local in
rtld.c, but _start has to call it, if _dl_start was made hidden then it
could be empty.
_dl_skip_args is no longer needed.
---
v4:
- adjust commit message about _dl_skip_args.
v3:
- mention _dl_skip_args
v2:
- fix typo in commit message.
---
sysdeps/aarch64/Makefile | 1 +
sysdeps/aarch64/dl-machine.h | 77 +-----------------------------------
sysdeps/aarch64/dl-start.S | 53 +++++++++++++++++++++++++
3 files changed, 56 insertions(+), 75 deletions(-)
create mode 100644 sysdeps/aarch64/dl-start.S
Comments
On 05/05/2022 10:59, Szabolcs Nagy via Libc-alpha wrote:
> A separate asm file is easier to maintain than a macro that expands to
> inline asm.
>
> The RTLD_START macro is only needed now because _dl_start is local in
> rtld.c, but _start has to call it, if _dl_start was made hidden then it
> could be empty.
>
> _dl_skip_args is no longer needed.
LGTM, thanks.
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
>
> ---
> v4:
> - adjust commit message about _dl_skip_args.
> v3:
> - mention _dl_skip_args
> v2:
> - fix typo in commit message.
> ---
> sysdeps/aarch64/Makefile | 1 +
> sysdeps/aarch64/dl-machine.h | 77 +-----------------------------------
> sysdeps/aarch64/dl-start.S | 53 +++++++++++++++++++++++++
> 3 files changed, 56 insertions(+), 75 deletions(-)
> create mode 100644 sysdeps/aarch64/dl-start.S
>
> diff --git a/sysdeps/aarch64/Makefile b/sysdeps/aarch64/Makefile
> index 7183895d04..17fb1c5b72 100644
> --- a/sysdeps/aarch64/Makefile
> +++ b/sysdeps/aarch64/Makefile
> @@ -33,6 +33,7 @@ tst-audit27-ENV = LD_AUDIT=$(objpfx)tst-auditmod27.so
> endif
>
> ifeq ($(subdir),elf)
> +sysdep-rtld-routines += dl-start
> sysdep-dl-routines += tlsdesc dl-tlsdesc
> gen-as-const-headers += dl-link.sym
>
> diff --git a/sysdeps/aarch64/dl-machine.h b/sysdeps/aarch64/dl-machine.h
> index b40050a981..fe120bb507 100644
> --- a/sysdeps/aarch64/dl-machine.h
> +++ b/sysdeps/aarch64/dl-machine.h
> @@ -105,81 +105,8 @@ elf_machine_runtime_setup (struct link_map *l, struct r_scope_elem *scope[],
> return lazy;
> }
>
> -/* Initial entry point for the dynamic linker. The C function
> - _dl_start is the real entry point, its return value is the user
> - program's entry point */
> -#ifdef __LP64__
> -# define RTLD_START RTLD_START_1 ("x", "3", "sp")
> -#else
> -# define RTLD_START RTLD_START_1 ("w", "2", "wsp")
> -#endif
> -
> -
> -#define RTLD_START_1(PTR, PTR_SIZE_LOG, PTR_SP) asm ("\
> -.text \n\
> -.globl _start \n\
> -.type _start, %function \n\
> -.globl _dl_start_user \n\
> -.type _dl_start_user, %function \n\
> -_start: \n\
> - // bti c \n\
> - hint 34 \n\
> - mov " PTR "0, " PTR_SP " \n\
> - bl _dl_start \n\
> - // returns user entry point in x0 \n\
> - mov x21, x0 \n\
> -_dl_start_user: \n\
> - // get the original arg count \n\
> - ldr " PTR "1, [sp] \n\
> - // get the argv address \n\
> - add " PTR "2, " PTR_SP ", #(1<<" PTR_SIZE_LOG ") \n\
> - // get _dl_skip_args to see if we were \n\
> - // invoked as an executable \n\
> - adrp x4, _dl_skip_args \n\
> - ldr w4, [x4, #:lo12:_dl_skip_args] \n\
> - // do we need to adjust argc/argv \n\
> - cmp w4, 0 \n\
> - beq .L_done_stack_adjust \n\
> - // subtract _dl_skip_args from original arg count \n\
> - sub " PTR "1, " PTR "1, " PTR "4 \n\
> - // store adjusted argc back to stack \n\
> - str " PTR "1, [sp] \n\
> - // find the first unskipped argument \n\
> - mov " PTR "3, " PTR "2 \n\
> - add " PTR "4, " PTR "2, " PTR "4, lsl #" PTR_SIZE_LOG " \n\
> - // shuffle argv down \n\
> -1: ldr " PTR "5, [x4], #(1<<" PTR_SIZE_LOG ") \n\
> - str " PTR "5, [x3], #(1<<" PTR_SIZE_LOG ") \n\
> - cmp " PTR "5, #0 \n\
> - bne 1b \n\
> - // shuffle envp down \n\
> -1: ldr " PTR "5, [x4], #(1<<" PTR_SIZE_LOG ") \n\
> - str " PTR "5, [x3], #(1<<" PTR_SIZE_LOG ") \n\
> - cmp " PTR "5, #0 \n\
> - bne 1b \n\
> - // shuffle auxv down \n\
> -1: ldp " PTR "0, " PTR "5, [x4, #(2<<" PTR_SIZE_LOG ")]! \n\
> - stp " PTR "0, " PTR "5, [x3], #(2<<" PTR_SIZE_LOG ") \n\
> - cmp " PTR "0, #0 \n\
> - bne 1b \n\
> - // Update _dl_argv \n\
> - adrp x3, __GI__dl_argv \n\
> - str " PTR "2, [x3, #:lo12:__GI__dl_argv] \n\
> -.L_done_stack_adjust: \n\
> - // compute envp \n\
> - add " PTR "3, " PTR "2, " PTR "1, lsl #" PTR_SIZE_LOG " \n\
> - add " PTR "3, " PTR "3, #(1<<" PTR_SIZE_LOG ") \n\
> - adrp x16, _rtld_local \n\
> - add " PTR "16, " PTR "16, #:lo12:_rtld_local \n\
> - ldr " PTR "0, [x16] \n\
> - bl _dl_init \n\
> - // load the finalizer function \n\
> - adrp x0, _dl_fini \n\
> - add " PTR "0, " PTR "0, #:lo12:_dl_fini \n\
> - // jump to the user_s entry point \n\
> - mov x16, x21 \n\
> - br x16 \n\
> -");
> +/* In elf/rtld.c _dl_start should be global so dl-start.S can reference it. */
> +#define RTLD_START asm (".globl _dl_start");
>
> #define elf_machine_type_class(type) \
> ((((type) == AARCH64_R(JUMP_SLOT) \
> diff --git a/sysdeps/aarch64/dl-start.S b/sysdeps/aarch64/dl-start.S
> new file mode 100644
> index 0000000000..a3a57bd5a1
> --- /dev/null
> +++ b/sysdeps/aarch64/dl-start.S
> @@ -0,0 +1,53 @@
> +/* ld.so _start code.
> + Copyright (C) 2022 Free Software Foundation, Inc.
> +
> + This file is part of the GNU C Library.
> +
> + The GNU C Library is free software; you can redistribute it and/or
> + modify it under the terms of the GNU Lesser General Public
> + License as published by the Free Software Foundation; either
> + version 2.1 of the License, or (at your option) any later version.
> +
> + The GNU C Library is distributed in the hope that it will be useful,
> + but WITHOUT ANY WARRANTY; without even the implied warranty of
> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + Lesser General Public License for more details.
> +
> + You should have received a copy of the GNU Lesser General Public
> + License along with the GNU C Library; if not, see
> + <https://www.gnu.org/licenses/>. */
> +
> +#include <sysdep.h>
> +
> +ENTRY (_start)
> + /* Create an initial frame with 0 LR and FP */
> + cfi_undefined (x30)
> + mov x29, #0
> + mov x30, #0
> +
> + mov x0, sp
> + PTR_ARG (0)
> + bl _dl_start
> + /* Returns user entry point in x0. */
> + mov PTR_REG (21), PTR_REG (0)
> +.globl _dl_start_user
> +.type _dl_start_user, %function
> +_dl_start_user:
> + /* Get argc. */
> + ldr PTR_REG (1), [sp]
> + /* Get argv. */
> + add x2, sp, PTR_SIZE
> + /* Compute envp. */
> + add PTR_REG (3), PTR_REG (2), PTR_REG (1), lsl PTR_LOG_SIZE
> + add PTR_REG (3), PTR_REG (3), PTR_SIZE
> + adrp x16, _rtld_local
> + add PTR_REG (16), PTR_REG (16), :lo12:_rtld_local
> + ldr PTR_REG (0), [x16]
> + bl _dl_init
> + /* Load the finalizer function. */
> + adrp x0, _dl_fini
> + add PTR_REG (0), PTR_REG (0), :lo12:_dl_fini
> + /* Jump to the user's entry point. */
> + mov x16, x21
> + br x16
> +END (_start)
@@ -33,6 +33,7 @@ tst-audit27-ENV = LD_AUDIT=$(objpfx)tst-auditmod27.so
endif
ifeq ($(subdir),elf)
+sysdep-rtld-routines += dl-start
sysdep-dl-routines += tlsdesc dl-tlsdesc
gen-as-const-headers += dl-link.sym
@@ -105,81 +105,8 @@ elf_machine_runtime_setup (struct link_map *l, struct r_scope_elem *scope[],
return lazy;
}
-/* Initial entry point for the dynamic linker. The C function
- _dl_start is the real entry point, its return value is the user
- program's entry point */
-#ifdef __LP64__
-# define RTLD_START RTLD_START_1 ("x", "3", "sp")
-#else
-# define RTLD_START RTLD_START_1 ("w", "2", "wsp")
-#endif
-
-
-#define RTLD_START_1(PTR, PTR_SIZE_LOG, PTR_SP) asm ("\
-.text \n\
-.globl _start \n\
-.type _start, %function \n\
-.globl _dl_start_user \n\
-.type _dl_start_user, %function \n\
-_start: \n\
- // bti c \n\
- hint 34 \n\
- mov " PTR "0, " PTR_SP " \n\
- bl _dl_start \n\
- // returns user entry point in x0 \n\
- mov x21, x0 \n\
-_dl_start_user: \n\
- // get the original arg count \n\
- ldr " PTR "1, [sp] \n\
- // get the argv address \n\
- add " PTR "2, " PTR_SP ", #(1<<" PTR_SIZE_LOG ") \n\
- // get _dl_skip_args to see if we were \n\
- // invoked as an executable \n\
- adrp x4, _dl_skip_args \n\
- ldr w4, [x4, #:lo12:_dl_skip_args] \n\
- // do we need to adjust argc/argv \n\
- cmp w4, 0 \n\
- beq .L_done_stack_adjust \n\
- // subtract _dl_skip_args from original arg count \n\
- sub " PTR "1, " PTR "1, " PTR "4 \n\
- // store adjusted argc back to stack \n\
- str " PTR "1, [sp] \n\
- // find the first unskipped argument \n\
- mov " PTR "3, " PTR "2 \n\
- add " PTR "4, " PTR "2, " PTR "4, lsl #" PTR_SIZE_LOG " \n\
- // shuffle argv down \n\
-1: ldr " PTR "5, [x4], #(1<<" PTR_SIZE_LOG ") \n\
- str " PTR "5, [x3], #(1<<" PTR_SIZE_LOG ") \n\
- cmp " PTR "5, #0 \n\
- bne 1b \n\
- // shuffle envp down \n\
-1: ldr " PTR "5, [x4], #(1<<" PTR_SIZE_LOG ") \n\
- str " PTR "5, [x3], #(1<<" PTR_SIZE_LOG ") \n\
- cmp " PTR "5, #0 \n\
- bne 1b \n\
- // shuffle auxv down \n\
-1: ldp " PTR "0, " PTR "5, [x4, #(2<<" PTR_SIZE_LOG ")]! \n\
- stp " PTR "0, " PTR "5, [x3], #(2<<" PTR_SIZE_LOG ") \n\
- cmp " PTR "0, #0 \n\
- bne 1b \n\
- // Update _dl_argv \n\
- adrp x3, __GI__dl_argv \n\
- str " PTR "2, [x3, #:lo12:__GI__dl_argv] \n\
-.L_done_stack_adjust: \n\
- // compute envp \n\
- add " PTR "3, " PTR "2, " PTR "1, lsl #" PTR_SIZE_LOG " \n\
- add " PTR "3, " PTR "3, #(1<<" PTR_SIZE_LOG ") \n\
- adrp x16, _rtld_local \n\
- add " PTR "16, " PTR "16, #:lo12:_rtld_local \n\
- ldr " PTR "0, [x16] \n\
- bl _dl_init \n\
- // load the finalizer function \n\
- adrp x0, _dl_fini \n\
- add " PTR "0, " PTR "0, #:lo12:_dl_fini \n\
- // jump to the user_s entry point \n\
- mov x16, x21 \n\
- br x16 \n\
-");
+/* In elf/rtld.c _dl_start should be global so dl-start.S can reference it. */
+#define RTLD_START asm (".globl _dl_start");
#define elf_machine_type_class(type) \
((((type) == AARCH64_R(JUMP_SLOT) \
new file mode 100644
@@ -0,0 +1,53 @@
+/* ld.so _start code.
+ Copyright (C) 2022 Free Software Foundation, Inc.
+
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <sysdep.h>
+
+ENTRY (_start)
+ /* Create an initial frame with 0 LR and FP */
+ cfi_undefined (x30)
+ mov x29, #0
+ mov x30, #0
+
+ mov x0, sp
+ PTR_ARG (0)
+ bl _dl_start
+ /* Returns user entry point in x0. */
+ mov PTR_REG (21), PTR_REG (0)
+.globl _dl_start_user
+.type _dl_start_user, %function
+_dl_start_user:
+ /* Get argc. */
+ ldr PTR_REG (1), [sp]
+ /* Get argv. */
+ add x2, sp, PTR_SIZE
+ /* Compute envp. */
+ add PTR_REG (3), PTR_REG (2), PTR_REG (1), lsl PTR_LOG_SIZE
+ add PTR_REG (3), PTR_REG (3), PTR_SIZE
+ adrp x16, _rtld_local
+ add PTR_REG (16), PTR_REG (16), :lo12:_rtld_local
+ ldr PTR_REG (0), [x16]
+ bl _dl_init
+ /* Load the finalizer function. */
+ adrp x0, _dl_fini
+ add PTR_REG (0), PTR_REG (0), :lo12:_dl_fini
+ /* Jump to the user's entry point. */
+ mov x16, x21
+ br x16
+END (_start)