diff options
Diffstat (limited to 'REORG.TODO/sysdeps/unix/sysv/linux/powerpc/libc-start.c')
-rw-r--r-- | REORG.TODO/sysdeps/unix/sysv/linux/powerpc/libc-start.c | 105 |
1 files changed, 105 insertions, 0 deletions
diff --git a/REORG.TODO/sysdeps/unix/sysv/linux/powerpc/libc-start.c b/REORG.TODO/sysdeps/unix/sysv/linux/powerpc/libc-start.c new file mode 100644 index 0000000000..ad036c1e4b --- /dev/null +++ b/REORG.TODO/sysdeps/unix/sysv/linux/powerpc/libc-start.c @@ -0,0 +1,105 @@ +/* Copyright (C) 1998-2017 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 + <http://www.gnu.org/licenses/>. */ + +#include <stdlib.h> +#include <unistd.h> +#include <ldsodefs.h> +#include <sysdep.h> + +#ifndef SHARED +#include <hwcapinfo.h> +#endif + +int __cache_line_size attribute_hidden; +/* The main work is done in the generic function. */ +#define LIBC_START_MAIN generic_start_main +#define LIBC_START_DISABLE_INLINE +#define LIBC_START_MAIN_AUXVEC_ARG +#define MAIN_AUXVEC_ARG +#define INIT_MAIN_ARGS +#include <csu/libc-start.c> + +struct startup_info + { + void *sda_base; + int (*main) (int, char **, char **, void *); + int (*init) (int, char **, char **, void *); + void (*fini) (void); + }; + +int +__libc_start_main (int argc, char **argv, + char **ev, + ElfW (auxv_t) * auxvec, + void (*rtld_fini) (void), + struct startup_info *stinfo, + char **stack_on_entry) +{ + /* the PPC SVR4 ABI says that the top thing on the stack will + be a NULL pointer, so if not we assume that we're being called + as a statically-linked program by Linux... */ + if (*stack_on_entry != NULL) + { + char **temp; + /* ...in which case, we have argc as the top thing on the + stack, followed by argv (NULL-terminated), envp (likewise), + and the auxiliary vector. */ + /* 32/64-bit agnostic load from stack */ + argc = *(long int *) stack_on_entry; + argv = stack_on_entry + 1; + ev = argv + argc + 1; +#ifdef HAVE_AUX_VECTOR + temp = ev; + while (*temp != NULL) + ++temp; + auxvec = (ElfW (auxv_t) *)++ temp; +#endif + rtld_fini = NULL; + } + + /* Initialize the __cache_line_size variable from the aux vector. For the + static case, we also need _dl_hwcap, _dl_hwcap2 and _dl_platform, so we + can call __tcb_parse_hwcap_and_convert_at_platform (). */ + for (ElfW (auxv_t) * av = auxvec; av->a_type != AT_NULL; ++av) + switch (av->a_type) + { + case AT_DCACHEBSIZE: + __cache_line_size = av->a_un.a_val; + break; +#ifndef SHARED + case AT_HWCAP: + _dl_hwcap = (unsigned long int) av->a_un.a_val; + break; + case AT_HWCAP2: + _dl_hwcap2 = (unsigned long int) av->a_un.a_val; + break; + case AT_PLATFORM: + _dl_platform = (void *) av->a_un.a_val; + break; +#endif + } + + /* Initialize hwcap/hwcap2 and platform data so it can be copied to + the TCB later in __libc_setup_tls (). (static case only). */ +#ifndef SHARED + __tcb_parse_hwcap_and_convert_at_platform (); +#endif + + return generic_start_main (stinfo->main, argc, argv, auxvec, + stinfo->init, stinfo->fini, rtld_fini, + stack_on_entry); +} |