[PATCH] sparc: Fix argument passing to __libc_start_main on SPARC32
Ludwig Rydberg
ludwig.rydberg@gaisler.com
Fri Jun 13 10:22:41 GMT 2025
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
base-commit: daab2a6d19f8360248289840408e7d2e5c203c2e
--
2.35.3
More information about the Libc-alpha
mailing list