[PATCH] sparc: Fix argument passing to __libc_start_main on SPARC32
Adhemerval Zanella Netto
adhemerval.zanella@linaro.org
Fri Jun 13 13:59:15 GMT 2025
On 13/06/25 07:22, Ludwig Rydberg wrote:
> Use a custom __libc_start_main function so the highest stack address can
> be provided to __libc_start_main_impl without altering the content of
> the stack (as there is no room for adding arguments to the stack).
>
> The __libc_stack_end was written to [%sp+23*4] but that address is
> already in use (holds the pointer to argv) which led to corruption.
>
> Fixes: d952c6efaa87 ("sparc: Fix argument passing to __libc_start_main (BZ 32981)")
> Signed-off-by: Ludwig Rydberg <ludwig.rydberg@gaisler.com>
> ---
> sysdeps/sparc/sparc32/start.S | 6 ++--
> .../sysv/linux/sparc/sparc32/libc-start.c | 30 +++++++++++++++++++
> 2 files changed, 32 insertions(+), 4 deletions(-)
> create mode 100644 sysdeps/unix/sysv/linux/sparc/sparc32/libc-start.c
>
> diff --git a/sysdeps/sparc/sparc32/start.S b/sysdeps/sparc/sparc32/start.S
> index cef7c96cac72..9d97a2943efa 100644
> --- a/sysdeps/sparc/sparc32/start.S
> +++ b/sysdeps/sparc/sparc32/start.S
> @@ -64,18 +64,16 @@ _start:
> xor %o0, %gdop_lox10(main), %o0
> ld [%l7 + %o0], %o0, %gdop(main)
> #endif
> - mov 0, %o3 /* Used to be init. */
> - mov 0, %o4 /* Used to be fini. */
>
> /* When starting a binary via the dynamic linker, %g1 contains the
> address of the shared library termination function, which will be
> registered with atexit(). If we are statically linked, this will
> be NULL. */
> - mov %g1, %o5
> + mov %g1, %o3
>
> /* Provide the highest stack address to update the __libc_stack_end (used
> to enable executable stacks if required). */
> - st %sp, [%sp+23*4]
> + mov %sp, %o4
>
> /* Let libc do the rest of the initialization, and call main. */
> call __libc_start_main
> diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libc-start.c b/sysdeps/unix/sysv/linux/sparc/sparc32/libc-start.c
> new file mode 100644
> index 000000000000..c24c1539a41c
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libc-start.c
> @@ -0,0 +1,30 @@
> +/* Copyright (C) 1998-2025 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/>. */
> +
> +#define LIBC_START_MAIN generic_start_main
> +#include <csu/libc-start.c>
> +
> +STATIC int
> +__libc_start_main_impl (int (*main) (int, char **, char ** MAIN_AUXVEC_DECL),
> + int argc, char **argv, void (*rtld_fini) (void),
> + void *stack_end)
> +{
> + return generic_start_main (main, argc, argv,
> + NULL, NULL, rtld_fini,
> + stack_end);
> +}
> +DEFINE_LIBC_START_MAIN_VERSION
>
Wouldn't be simple we just adjust the initial stack frame to have minimal one:
diff --git a/sysdeps/sparc/sparc32/start.S b/sysdeps/sparc/sparc32/start.S
index cef7c96cac..8393760da6 100644
--- a/sysdeps/sparc/sparc32/start.S
+++ b/sysdeps/sparc/sparc32/start.S
@@ -35,6 +35,7 @@
#include <sysdep.h>
+#define FRAME_SIZE 104
.section ".text"
.align 4
@@ -48,12 +49,12 @@ _start:
/* Terminate the stack frame, and reserve space for functions to
drop their arguments. */
mov %g0, %fp
- sub %sp, 6*4, %sp
+ sub %sp, FRAME_SIZE, %sp
/* Extract the arguments and environment as encoded on the stack. The
argument info starts after one register window (16 words) past the SP. */
- ld [%sp+22*4], %o1
- add %sp, 23*4, %o2
+ ld [%sp+168], %o1
+ add %sp, 172, %o2
/* Load the addresses of the user entry points. */
#ifndef PIC
Sorry about that, I should have run some regressions tests before.
More information about the Libc-alpha
mailing list