Introduce <elf-initfini.h> and ELF_INITFINI for all architectures

This supersedes the init_array sysdeps directory.  It allows us to
check for ELF_INITFINI in both C and assembler code, and skip DT_INIT
and DT_FINI processing completely on newer architectures.

A new header file is needed because <dl-machine.h> is incompatible
with assembler code.  <sysdep.h> is compatible with assembler code,
but it cannot be included in all assembler files because on some
architectures, it redefines register names, and some assembler files
conflict with that.

<elf-initfini.h> is replicated for legacy architectures which need
DT_INIT/DT_FINI support.  New architectures follow the generic default
and disable it.
This commit is contained in:
Florian Weimer 2020-02-18 14:42:41 +01:00
parent 6e05978f0c
commit f4349837d9
26 changed files with 330 additions and 105 deletions

View File

@ -34,6 +34,7 @@
<https://www.gnu.org/licenses/>. */
#include <stddef.h>
#include <elf-initfini.h>
/* These magic symbols are provided by the linker. */
@ -49,7 +50,7 @@ extern void (*__fini_array_start []) (void) attribute_hidden;
extern void (*__fini_array_end []) (void) attribute_hidden;
#ifndef NO_INITFINI
#if ELF_INITFINI
/* These function symbols are provided for the .init/.fini section entry
points automagically by the linker. */
extern void _init (void);
@ -79,7 +80,7 @@ __libc_csu_init (int argc, char **argv, char **envp)
}
#endif
#ifndef NO_INITFINI
#if ELF_INITFINI
_init ();
#endif
@ -99,7 +100,7 @@ __libc_csu_fini (void)
while (i-- > 0)
(*__fini_array_start [i]) ();
# ifndef NO_INITFINI
# if ELF_INITFINI
_fini ();
# endif
#endif

View File

@ -37,6 +37,7 @@
#include <sys/gmon.h>
#include <stdlib.h>
#include <unistd.h>
#include <elf-initfini.h>
#define __ASSEMBLY__
#include <entry.h>
@ -59,6 +60,13 @@ extern char etext[];
# endif
#endif
#if !ELF_INITFINI
/* Instead of defining __gmon_start__ globally in gcrt1.o, we make it
static and just put a pointer to it into the .preinit_array
section. */
# define GMON_START_ARRAY_SECTION ".preinit_array"
#endif
#ifdef GMON_START_ARRAY_SECTION
static void __gmon_start__ (void);
static void (*const gmon_start_initializer) (void)

View File

@ -19,6 +19,7 @@
#include <assert.h>
#include <string.h>
#include <ldsodefs.h>
#include <elf-initfini.h>
/* Type of the constructor functions. */
@ -117,7 +118,7 @@ _dl_fini (void)
/* Is there a destructor function? */
if (l->l_info[DT_FINI_ARRAY] != NULL
|| l->l_info[DT_FINI] != NULL)
|| (ELF_INITFINI && l->l_info[DT_FINI] != NULL))
{
/* When debugging print a message first. */
if (__builtin_expect (GLRO(dl_debug_mask)
@ -139,7 +140,7 @@ _dl_fini (void)
}
/* Next try the old-style destructor. */
if (l->l_info[DT_FINI] != NULL)
if (ELF_INITFINI && l->l_info[DT_FINI] != NULL)
DL_CALL_DT_FINI
(l, l->l_addr + l->l_info[DT_FINI]->d_un.d_ptr);
}

View File

@ -18,6 +18,7 @@
#include <stddef.h>
#include <ldsodefs.h>
#include <elf-initfini.h>
/* Type of the initializer. */
@ -40,11 +41,6 @@ call_init (struct link_map *l, int argc, char **argv, char **env)
&& l->l_type == lt_executable)
return;
/* Are there any constructors? */
if (l->l_info[DT_INIT] == NULL
&& __builtin_expect (l->l_info[DT_INIT_ARRAY] == NULL, 1))
return;
/* Print a debug message if wanted. */
if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_IMPCALLS))
_dl_debug_printf ("\ncalling init: %s\n\n",
@ -54,7 +50,7 @@ call_init (struct link_map *l, int argc, char **argv, char **env)
- the one named by DT_INIT
- the others in the DT_INIT_ARRAY.
*/
if (l->l_info[DT_INIT] != NULL)
if (ELF_INITFINI && l->l_info[DT_INIT] != NULL)
DL_CALL_DT_INIT(l, l->l_addr + l->l_info[DT_INIT]->d_un.d_ptr, argc, argv, env);
/* Next see whether there is an array with initialization functions. */

View File

@ -33,11 +33,18 @@
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
#include <elf-initfini.h>
/* Arrange for __pthread_initialize_minimal_internal to be called at
libpthread startup, instead of conditionally calling
__gmon_start__. */
#define PREINIT_FUNCTION __pthread_initialize_minimal_internal
#define PREINIT_FUNCTION_WEAK 0
#if ELF_INITFINI
# define PREINIT_FUNCTION __pthread_initialize_minimal_internal
# define PREINIT_FUNCTION_WEAK 0
#include <crti.S>
# include <crti.S>
#else
.section .init_array,"a",%init_array
.dc.a __pthread_initialize_minimal_internal
#endif

View File

@ -0,0 +1,20 @@
/* Determine DT_INIT/DT_FINI support in the dynamic loader. AArch64 version.
Copyright (C) 2020 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/>. */
/* Enable DT_INIT/DT_FINI support. */
#define ELF_INITFINI 1

View File

@ -1,5 +1,5 @@
/* Special initializer support for libpthread.
Copyright (C) 2015-2020 Free Software Foundation, Inc.
/* Determine DT_INIT/DT_FINI support in the dynamic loader. Alpha version.
Copyright (C) 2020 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
@ -16,8 +16,5 @@
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
/* This arranges for libpthread.so's special initializer to be called as
soon as the library is loaded. */
.section .init_array,"a",%init_array
.dc.a __pthread_initialize_minimal_internal
/* Enable DT_INIT/DT_FINI support. */
#define ELF_INITFINI 1

View File

@ -0,0 +1,20 @@
/* Determine DT_INIT/DT_FINI support in the dynamic loader. Arm version.
Copyright (C) 2020 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/>. */
/* Enable DT_INIT/DT_FINI support. */
#define ELF_INITFINI 1

View File

@ -1,4 +1,3 @@
init_array
wordsize-32
# C-SKY uses IEEE 754 floating point.
ieee754/flt-32

View File

@ -12,11 +12,17 @@
toolchains without .init_array support can use this to avoid the
superfluous .init and .fini boilerplate code. */
#include <elf-initfini.h>
#if ELF_INITFINI
# error Cannot use default crti.S because it lacks _init code
#endif
#ifdef PREINIT_FUNCTION
#if PREINIT_FUNCTION_WEAK
# error PREINIT_FUNCTION_WEAK is unsupported
#endif
# if PREINIT_FUNCTION_WEAK
# error PREINIT_FUNCTION_WEAK is unsupported
# endif
/* This arranges for PREINIT_FUNCTION to be called upon loading a library that
contains crti.o. */

View File

@ -11,3 +11,9 @@
But new configurations without compatibility concerns for
toolchains without .init_array support can use this to avoid the
superfluous .init and .fini boilerplate code. */
#include <elf-initfini.h>
#if ELF_INITFINI
# error Cannot use genetric crtn.S because it lacks _fini code
#endif

View File

@ -0,0 +1,24 @@
/* Determine DT_INIT/DT_FINI support in the dynamic loader.
Copyright (C) 2020 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/>. */
/* Legacy platforms define this to 1. If 0, the dynamic linker
ignores the DT_INIT and DT_FINI tags, and static binaries will not
call the _init or _fini functions. If 1, the old constructor
mechanisms are used in addition to the initarray/finiarray
support. */
#define ELF_INITFINI 0

View File

@ -0,0 +1,20 @@
/* Determine DT_INIT/DT_FINI support in the dynamic loader. HPPA version.
Copyright (C) 2020 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/>. */
/* Enable DT_INIT/DT_FINI support. */
#define ELF_INITFINI 1

View File

@ -0,0 +1,20 @@
/* Determine DT_INIT/DT_FINI support in the dynamic loader. IA64 version.
Copyright (C) 2020 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/>. */
/* Enable DT_INIT/DT_FINI support. */
#define ELF_INITFINI 1

View File

@ -1,37 +0,0 @@
/* Startup support for ELF initializers/finalizers in the main executable.
Copyright (C) 2013-2020 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.
In addition to the permissions in the GNU Lesser General Public
License, the Free Software Foundation gives you unlimited
permission to link the compiled version of this file with other
programs, and to distribute those programs without any restriction
coming from the use of this file. (The GNU Lesser General Public
License restrictions do apply in other respects; for example, they
cover modification of the file, and distribution when not linked
into another program.)
Note that people who make modified versions of this file are not
obligated to grant this special exception for their modified
versions; it is their choice whether to do so. The GNU Lesser
General Public License gives permission to release a modified
version without this exception; this exception also makes it
possible to release a modified version which carries forward this
exception.
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 NO_INITFINI
#include <csu/elf-init.c>

View File

@ -1,41 +0,0 @@
/* gmon startup hook using .preinit_array.
Copyright (C) 2013-2020 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.
In addition to the permissions in the GNU Lesser General Public
License, the Free Software Foundation gives you unlimited
permission to link the compiled version of this file with other
programs, and to distribute those programs without any restriction
coming from the use of this file. (The GNU Lesser General Public
License restrictions do apply in other respects; for example, they
cover modification of the file, and distribution when not linked
into another program.)
Note that people who make modified versions of this file are not
obligated to grant this special exception for their modified
versions; it is their choice whether to do so. The GNU Lesser
General Public License gives permission to release a modified
version without this exception; this exception also makes it
possible to release a modified version which carries forward this
exception.
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/>. */
/* Instead of defining __gmon_start__ globally in gcrt1.o, we make it
static and just put a pointer to it into the .preinit_array section. */
#define GMON_START_ARRAY_SECTION ".preinit_array"
#include <csu/gmon-start.c>

View File

@ -0,0 +1,20 @@
/* Determine DT_INIT/DT_FINI support in the dynamic loader. m68k version.
Copyright (C) 2020 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/>. */
/* Enable DT_INIT/DT_FINI support. */
#define ELF_INITFINI 1

View File

@ -0,0 +1,20 @@
/* Determine DT_INIT/DT_FINI support in the dynamic loader, for Microblaze.
Copyright (C) 2020 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/>. */
/* Enable DT_INIT/DT_FINI support. */
#define ELF_INITFINI 1

View File

@ -0,0 +1,20 @@
/* Determine DT_INIT/DT_FINI support in the dynamic loader. MIPS version.
Copyright (C) 2020 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/>. */
/* Enable DT_INIT/DT_FINI support. */
#define ELF_INITFINI 1

View File

@ -0,0 +1,20 @@
/* Determine DT_INIT/DT_FINI support in the dynamic loader. nios2 version.
Copyright (C) 2020 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/>. */
/* Enable DT_INIT/DT_FINI support. */
#define ELF_INITFINI 1

View File

@ -0,0 +1,20 @@
/* Determine DT_INIT/DT_FINI support in the dynamic loader, for powerpc.
Copyright (C) 2020 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/>. */
/* Enable DT_INIT/DT_FINI support. */
#define ELF_INITFINI 1

View File

@ -1,5 +1,3 @@
init_array
ieee754/ldbl-128
ieee754/dbl-64
ieee754/flt-32

View File

@ -0,0 +1,20 @@
/* Determine DT_INIT/DT_FINI support in the dynamic loader. S/390 version.
Copyright (C) 2020 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/>. */
/* Enable DT_INIT/DT_FINI support. */
#define ELF_INITFINI 1

20
sysdeps/sh/elf-initfini.h Normal file
View File

@ -0,0 +1,20 @@
/* Determine DT_INIT/DT_FINI support in the dynamic loader. SH version.
Copyright (C) 2020 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/>. */
/* Enable DT_INIT/DT_FINI support. */
#define ELF_INITFINI 1

View File

@ -0,0 +1,20 @@
/* Determine DT_INIT/DT_FINI support in the dynamic loader. SPARC version.
Copyright (C) 2020 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/>. */
/* Enable DT_INIT/DT_FINI support. */
#define ELF_INITFINI 1

View File

@ -0,0 +1,20 @@
/* Determine DT_INIT/DT_FINI support in the dynamic loader. x86 version.
Copyright (C) 2020 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/>. */
/* Enable DT_INIT/DT_FINI support. */
#define ELF_INITFINI 1