sparc: Fix argument passing to __libc_start_main on SPARC32

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: d952c6efaa ("sparc: Fix argument passing to __libc_start_main (BZ 32981)")
Signed-off-by: Ludwig Rydberg <ludwig.rydberg@gaisler.com>
(cherry picked from commit c8305ccf787df8b16a5db18254a3737069a390b7)
This commit is contained in:
Ludwig Rydberg
2025-06-13 12:22:41 +02:00
committed by Andreas K. Hüttel
parent 6b0fd5ffad
commit 106d1ac22d
2 changed files with 32 additions and 4 deletions

View File

@@ -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

View File

@@ -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