| 
 | 1 | +/* Startup support for ELF initializers/finalizers in the main executable.  | 
 | 2 | +   Copyright (C) 2002-2021 Free Software Foundation, Inc.  | 
 | 3 | +   This file is part of the GNU C Library.  | 
 | 4 | +
  | 
 | 5 | +   The GNU C Library is free software; you can redistribute it and/or  | 
 | 6 | +   modify it under the terms of the GNU Lesser General Public  | 
 | 7 | +   License as published by the Free Software Foundation; either  | 
 | 8 | +   version 2.1 of the License, or (at your option) any later version.  | 
 | 9 | +
  | 
 | 10 | +   In addition to the permissions in the GNU Lesser General Public  | 
 | 11 | +   License, the Free Software Foundation gives you unlimited  | 
 | 12 | +   permission to link the compiled version of this file with other  | 
 | 13 | +   programs, and to distribute those programs without any restriction  | 
 | 14 | +   coming from the use of this file. (The GNU Lesser General Public  | 
 | 15 | +   License restrictions do apply in other respects; for example, they  | 
 | 16 | +   cover modification of the file, and distribution when not linked  | 
 | 17 | +   into another program.)  | 
 | 18 | +
  | 
 | 19 | +   Note that people who make modified versions of this file are not  | 
 | 20 | +   obligated to grant this special exception for their modified  | 
 | 21 | +   versions; it is their choice whether to do so. The GNU Lesser  | 
 | 22 | +   General Public License gives permission to release a modified  | 
 | 23 | +   version without this exception; this exception also makes it  | 
 | 24 | +   possible to release a modified version which carries forward this  | 
 | 25 | +   exception.  | 
 | 26 | +
  | 
 | 27 | +   The GNU C Library is distributed in the hope that it will be useful,  | 
 | 28 | +   but WITHOUT ANY WARRANTY; without even the implied warranty of  | 
 | 29 | +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU  | 
 | 30 | +   Lesser General Public License for more details.  | 
 | 31 | +
  | 
 | 32 | +   You should have received a copy of the GNU Lesser General Public  | 
 | 33 | +   License along with the GNU C Library; if not, see  | 
 | 34 | +   <https://www.gnu.org/licenses/>.  */  | 
 | 35 | + | 
 | 36 | +#include <stddef.h>  | 
 | 37 | +#include <elf-initfini.h>  | 
 | 38 | + | 
 | 39 | + | 
 | 40 | +/* These magic symbols are provided by the linker.  */  | 
 | 41 | +extern void (*__preinit_array_start []) (int, char **, char **)  | 
 | 42 | +  attribute_hidden;  | 
 | 43 | +extern void (*__preinit_array_end []) (int, char **, char **)  | 
 | 44 | +  attribute_hidden;  | 
 | 45 | +extern void (*__init_array_start []) (int, char **, char **)  | 
 | 46 | +  attribute_hidden;  | 
 | 47 | +extern void (*__init_array_end []) (int, char **, char **)  | 
 | 48 | +  attribute_hidden;  | 
 | 49 | +extern void (*__fini_array_start []) (void) attribute_hidden;  | 
 | 50 | +extern void (*__fini_array_end []) (void) attribute_hidden;  | 
 | 51 | + | 
 | 52 | + | 
 | 53 | +#if ELF_INITFINI  | 
 | 54 | +/* These function symbols are provided for the .init/.fini section entry  | 
 | 55 | +   points automagically by the linker.  */  | 
 | 56 | +extern void _init (void);  | 
 | 57 | +extern void _fini (void);  | 
 | 58 | +#endif  | 
 | 59 | + | 
 | 60 | + | 
 | 61 | +/* These functions are passed to __libc_start_main by the startup code.  | 
 | 62 | +   These get statically linked into each program.  For dynamically linked  | 
 | 63 | +   programs, this module will come from libc_nonshared.a and differs from  | 
 | 64 | +   the libc.a module in that it doesn't call the preinit array.  */  | 
 | 65 | + | 
 | 66 | + | 
 | 67 | +void  | 
 | 68 | +__libc_csu_init (int argc, char **argv, char **envp)  | 
 | 69 | +{  | 
 | 70 | +  /* For dynamically linked executables the preinit array is executed by  | 
 | 71 | +     the dynamic linker (before initializing any shared object).  */  | 
 | 72 | + | 
 | 73 | +#ifndef LIBC_NONSHARED  | 
 | 74 | +  /* For static executables, preinit happens right before init.  */  | 
 | 75 | +  {  | 
 | 76 | +    const size_t size = __preinit_array_end - __preinit_array_start;  | 
 | 77 | +    size_t i;  | 
 | 78 | +    for (i = 0; i < size; i++)  | 
 | 79 | +      (*__preinit_array_start [i]) (argc, argv, envp);  | 
 | 80 | +  }  | 
 | 81 | +#endif  | 
 | 82 | + | 
 | 83 | +#if ELF_INITFINI  | 
 | 84 | +  _init ();  | 
 | 85 | +#endif  | 
 | 86 | + | 
 | 87 | +  const size_t size = __init_array_end - __init_array_start;  | 
 | 88 | +  for (size_t i = 0; i < size; i++)  | 
 | 89 | +      (*__init_array_start [i]) (argc, argv, envp);  | 
 | 90 | +}  | 
 | 91 | + | 
 | 92 | +/* This function should not be used anymore.  We run the executable's  | 
 | 93 | +   destructor now just like any other.  We cannot remove the function,  | 
 | 94 | +   though.  */  | 
 | 95 | +void  | 
 | 96 | +__libc_csu_fini (void)  | 
 | 97 | +{  | 
 | 98 | +#ifndef LIBC_NONSHARED  | 
 | 99 | +  size_t i = __fini_array_end - __fini_array_start;  | 
 | 100 | +  while (i-- > 0)  | 
 | 101 | +    (*__fini_array_start [i]) ();  | 
 | 102 | + | 
 | 103 | +# if ELF_INITFINI  | 
 | 104 | +  _fini ();  | 
 | 105 | +# endif  | 
 | 106 | +#endif  | 
 | 107 | +}  | 
0 commit comments