(root)/
glibc-2.38/
sysdeps/
unix/
sysv/
linux/
powerpc/
libc-start.c
       1  /* Copyright (C) 1998-2023 Free Software Foundation, Inc.
       2     This file is part of the GNU C Library.
       3  
       4     The GNU C Library is free software; you can redistribute it and/or
       5     modify it under the terms of the GNU Lesser General Public
       6     License as published by the Free Software Foundation; either
       7     version 2.1 of the License, or (at your option) any later version.
       8  
       9     The GNU C Library is distributed in the hope that it will be useful,
      10     but WITHOUT ANY WARRANTY; without even the implied warranty of
      11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      12     Lesser General Public License for more details.
      13  
      14     You should have received a copy of the GNU Lesser General Public
      15     License along with the GNU C Library; if not, see
      16     <https://www.gnu.org/licenses/>.  */
      17  
      18  #include <stdlib.h>
      19  #include <unistd.h>
      20  #include <ldsodefs.h>
      21  #include <sysdep.h>
      22  
      23  #ifndef SHARED
      24  #include <hwcapinfo.h>
      25  #endif
      26  #if ENABLE_STATIC_PIE && !defined SHARED
      27  /* For elf_machine_load_address.  */
      28  #include <dl-machine.h>
      29  #endif
      30  
      31  /* The main work is done in the generic function.  */
      32  #define LIBC_START_MAIN generic_start_main
      33  #define LIBC_START_DISABLE_INLINE
      34  #define LIBC_START_MAIN_AUXVEC_ARG
      35  #define MAIN_AUXVEC_ARG
      36  #define INIT_MAIN_ARGS
      37  #include <csu/libc-start.c>
      38  
      39  struct startup_info
      40    {
      41      void *sda_base;
      42      int (*main) (int, char **, char **, void *);
      43      int (*init) (int, char **, char **, void *);
      44      void (*fini) (void);
      45    };
      46  
      47  int
      48  __libc_start_main_impl (int argc, char **argv,
      49  			char **ev,
      50  			ElfW (auxv_t) * auxvec,
      51  			void (*rtld_fini) (void),
      52  			struct startup_info *stinfo,
      53  			char **stack_on_entry)
      54  {
      55    /* the PPC SVR4 ABI says that the top thing on the stack will
      56       be a NULL pointer, so if not we assume that we're being called
      57       as a statically-linked program by Linux...  */
      58    if (*stack_on_entry != NULL)
      59      {
      60        char **temp;
      61        /* ...in which case, we have argc as the top thing on the
      62           stack, followed by argv (NULL-terminated), envp (likewise),
      63           and the auxiliary vector.  */
      64        /* 32/64-bit agnostic load from stack */
      65        argc = *(long int *) stack_on_entry;
      66        argv = stack_on_entry + 1;
      67        ev = argv + argc + 1;
      68  #ifdef HAVE_AUX_VECTOR
      69        temp = ev;
      70        while (*temp != NULL)
      71  	++temp;
      72        auxvec = (ElfW (auxv_t) *)++ temp;
      73  #endif
      74        rtld_fini = NULL;
      75      }
      76  
      77    for (ElfW (auxv_t) * av = auxvec; av->a_type != AT_NULL; ++av)
      78      switch (av->a_type)
      79        {
      80        /* For the static case, we also need _dl_hwcap, _dl_hwcap2 and
      81           _dl_platform, so we can call
      82           __tcb_parse_hwcap_and_convert_at_platform ().  */
      83  #ifndef SHARED
      84        case AT_HWCAP:
      85  	_dl_hwcap = (unsigned long int) av->a_un.a_val;
      86  	break;
      87        case AT_HWCAP2:
      88  	_dl_hwcap2 = (unsigned long int) av->a_un.a_val;
      89  	break;
      90        case AT_PLATFORM:
      91  	_dl_platform = (void *) av->a_un.a_val;
      92  	break;
      93  #endif
      94        }
      95  
      96    /* Initialize hwcap/hwcap2 and platform data so it can be copied to
      97       the TCB later in __libc_setup_tls (). (static case only).  */
      98  #ifndef SHARED
      99    __tcb_parse_hwcap_and_convert_at_platform ();
     100  #endif
     101  
     102    void *stmain = stinfo->main;
     103  #if ENABLE_STATIC_PIE && !defined SHARED
     104    struct link_map *map = _dl_get_dl_main_map ();
     105    if (!map->l_relocated)
     106      stmain = (char *) stmain + elf_machine_load_address ();
     107  #endif
     108  
     109    return generic_start_main (stmain, argc, argv, auxvec,
     110  			     NULL, NULL, rtld_fini,
     111  			     stack_on_entry);
     112  }
     113  DEFINE_LIBC_START_MAIN_VERSION