diff --git a/csu/Makefile b/csu/Makefile
index f3498960f8..4fcdcfbba9 100644
--- a/csu/Makefile
+++ b/csu/Makefile
@@ -27,10 +27,9 @@ subdir := csu
 include ../Makeconfig
 
 routines = init-first libc-start $(libc-init) sysdep version check_fds \
-	   libc-tls elf-init dso_handle
+	   libc-tls dso_handle
 aux	 = errno
 elide-routines.os = libc-tls
-static-only-routines = elf-init
 csu-dummies = $(filter-out $(start-installed-name),crt1.o Mcrt1.o)
 extra-objs = start.o \
 	     $(start-installed-name) g$(start-installed-name) $(csu-dummies) \
diff --git a/csu/Versions b/csu/Versions
index 43010c3443..8fb2e360a9 100644
--- a/csu/Versions
+++ b/csu/Versions
@@ -7,6 +7,9 @@ libc {
     # New special glibc functions.
     gnu_get_libc_release; gnu_get_libc_version;
   }
+  GLIBC_2.28 {
+    __libc_start_main;
+  }
   GLIBC_PRIVATE {
     errno;
   }
diff --git a/csu/elf-init.c b/csu/elf-init.c
deleted file mode 100644
index 8bde25a340..0000000000
--- a/csu/elf-init.c
+++ /dev/null
@@ -1,107 +0,0 @@
-/* Startup support for ELF initializers/finalizers in the main executable.
-   Copyright (C) 2002-2018 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
-   <http://www.gnu.org/licenses/>.  */
-
-#include <stddef.h>
-#include <platform-params.h>
-
-
-/* These magic symbols are provided by the linker.  */
-extern void (*__preinit_array_start []) (int, char **, char **)
-  attribute_hidden;
-extern void (*__preinit_array_end []) (int, char **, char **)
-  attribute_hidden;
-extern void (*__init_array_start []) (int, char **, char **)
-  attribute_hidden;
-extern void (*__init_array_end []) (int, char **, char **)
-  attribute_hidden;
-extern void (*__fini_array_start []) (void) attribute_hidden;
-extern void (*__fini_array_end []) (void) attribute_hidden;
-
-
-#if ELF_INITFINI
-/* These function symbols are provided for the .init/.fini section entry
-   points automagically by the linker.  */
-extern void _init (void);
-extern void _fini (void);
-#endif
-
-
-/* These functions are passed to __libc_start_main by the startup code.
-   These get statically linked into each program.  For dynamically linked
-   programs, this module will come from libc_nonshared.a and differs from
-   the libc.a module in that it doesn't call the preinit array.  */
-
-
-void
-__libc_csu_init (int argc, char **argv, char **envp)
-{
-  /* For dynamically linked executables the preinit array is executed by
-     the dynamic linker (before initializing any shared object).  */
-
-#ifndef LIBC_NONSHARED
-  /* For static executables, preinit happens right before init.  */
-  {
-    const size_t size = __preinit_array_end - __preinit_array_start;
-    size_t i;
-    for (i = 0; i < size; i++)
-      (*__preinit_array_start [i]) (argc, argv, envp);
-  }
-#endif
-
-#if ELF_INITFINI
-  _init ();
-#endif
-
-  const size_t size = __init_array_end - __init_array_start;
-  for (size_t i = 0; i < size; i++)
-      (*__init_array_start [i]) (argc, argv, envp);
-}
-
-/* This function should not be used anymore.  We run the executable's
-   destructor now just like any other.  We cannot remove the function,
-   though.  */
-void
-__libc_csu_fini (void)
-{
-#ifndef LIBC_NONSHARED
-  size_t i = __fini_array_end - __fini_array_start;
-  while (i-- > 0)
-    (*__fini_array_start [i]) ();
-
-# if ELF_INITFINI
-  _fini ();
-# endif
-#endif
-}
diff --git a/csu/libc-start.c b/csu/libc-start.c
index 494132368f..0faa4242d8 100644
--- a/csu/libc-start.c
+++ b/csu/libc-start.c
@@ -1,4 +1,5 @@
-/* Copyright (C) 1998-2018 Free Software Foundation, Inc.
+/* Perform initialization and invoke main.
+   Copyright (C) 1998-2018 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
@@ -15,6 +16,10 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
+/* Note: This code is only part of the startup code proper for
+   statically linked binaries.  For dynamically linked binaries, it
+   resides in libc.so.  */
+
 #include <assert.h>
 #include <stdlib.h>
 #include <stdio.h>
@@ -22,6 +27,8 @@
 #include <ldsodefs.h>
 #include <exit-thread.h>
 #include <libc-internal.h>
+#include <platform-params.h>
+#include <shlib-compat.h>
 
 #include <elf/dl-tunables.h>
 
@@ -88,9 +95,11 @@ apply_irel (void)
 # else
 #  define STATIC static inline __attribute__ ((always_inline))
 # endif
+# define DO_DEFINE_LIBC_START_MAIN_VERSION 0
 #else
 # define STATIC
 # define LIBC_START_MAIN __libc_start_main
+# define DO_DEFINE_LIBC_START_MAIN_VERSION 1
 #endif
 
 #ifdef MAIN_AUXVEC_ARG
@@ -106,6 +115,92 @@ apply_irel (void)
 # define ARCH_INIT_CPU_FEATURES()
 #endif
 
+#ifdef SHARED
+/* Initialization for dynamic executables.  Find the main executable
+   link map and run its init functions.  */
+static void
+call_init (int argc, char **argv, char **env)
+{
+  /* Obtain the main map of the executable.  */
+  struct link_map *l = GL(dl_ns)[LM_ID_BASE]._ns_loaded;
+
+  /* DT_PREINIT_ARRAY is not processed here.  It is already handled in
+     _dl_init in elf/dl-init.c.  Also see the call_init function in
+     the same file.  */
+
+  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);
+
+  ElfW(Dyn) *init_array = l->l_info[DT_INIT_ARRAY];
+  if (init_array != NULL)
+    {
+      unsigned int jm
+	= l->l_info[DT_INIT_ARRAYSZ]->d_un.d_val / sizeof (ElfW(Addr));
+      ElfW(Addr) *addrs = (void *) (init_array->d_un.d_ptr + l->l_addr);
+      for (unsigned int j = 0; j < jm; ++j)
+	((dl_init_t) addrs[j]) (argc, argv, env);
+    }
+}
+
+#else /* !SHARED */
+
+/* These magic symbols are provided by the linker.  */
+extern void (*__preinit_array_start []) (int, char **, char **)
+  attribute_hidden;
+extern void (*__preinit_array_end []) (int, char **, char **)
+  attribute_hidden;
+extern void (*__init_array_start []) (int, char **, char **)
+  attribute_hidden;
+extern void (*__init_array_end []) (int, char **, char **)
+  attribute_hidden;
+extern void (*__fini_array_start []) (void) attribute_hidden;
+extern void (*__fini_array_end []) (void) attribute_hidden;
+
+# if ELF_INITFINI
+/* These function symbols are provided for the .init/.fini section entry
+   points automagically by the linker.  */
+extern void _init (void);
+extern void _fini (void);
+# endif
+
+/* Initialization for static executables.  There is no dynamic
+   segment, so we access the symbols directly.  */
+static void
+call_init (int argc, char **argv, char **envp)
+{
+  /* For static executables, preinit happens right before init.  */
+  {
+    const size_t size = __preinit_array_end - __preinit_array_start;
+    size_t i;
+    for (i = 0; i < size; i++)
+      (*__preinit_array_start [i]) (argc, argv, envp);
+  }
+
+# if ELF_INITFINI
+  _init ();
+# endif
+
+  const size_t size = __init_array_end - __init_array_start;
+  for (size_t i = 0; i < size; i++)
+      (*__init_array_start [i]) (argc, argv, envp);
+}
+
+/* Likewise for the destructor.  */
+static void
+call_fini (void *unused)
+{
+  size_t i = __fini_array_end - __fini_array_start;
+  while (i-- > 0)
+    (*__fini_array_start [i]) ();
+
+# if ELF_INITFINI
+  _fini ();
+# endif
+}
+
+#endif /* !SHARED */
+
 #include <libc-start.h>
 
 STATIC int LIBC_START_MAIN (int (*main) (int, char **, char **
@@ -122,9 +217,16 @@ STATIC int LIBC_START_MAIN (int (*main) (int, char **, char **
      __attribute__ ((noreturn));
 
 
-/* Note: the fini parameter is ignored here for shared library.  It
-   is registered with __cxa_atexit.  This had the disadvantage that
-   finalizers were called in more than one place.  */
+/* Note: The init and fini parameters are no longer used.  fini is
+   completely unused, init is still called if not NULL, but the
+   current startup code always passes NULL.  (In the future, it would
+   be possible to use fini to pass a version code if init is NULL, to
+   indicate the link-time glibc without introducing a hard
+   incompatibility for new programs with older glibc versions.)
+
+   For dynamically linked executables, the dynamic segment is used to
+   locate constructors and destructors.  For statically linked
+   executables, the relevant symbols are access directly.  */
 STATIC int
 LIBC_START_MAIN (int (*main) (int, char **, char ** MAIN_AUXVEC_DECL),
 		 int argc, char **argv,
@@ -243,9 +345,8 @@ LIBC_START_MAIN (int (*main) (int, char **, char ** MAIN_AUXVEC_DECL),
      run the constructors in `_dl_start_user'.  */
   __libc_init_first (argc, argv, __environ);
 
-  /* Register the destructor of the program, if any.  */
-  if (fini)
-    __cxa_atexit ((void (*) (void *)) fini, NULL, NULL);
+  /* Register the destructor of the statically-linked program.  */
+  __cxa_atexit (call_fini, NULL, NULL);
 
   /* Some security at this point.  Prevent starting a SUID binary where
      the standard file descriptors are not opened.  We have to do this
@@ -253,15 +354,24 @@ LIBC_START_MAIN (int (*main) (int, char **, char ** MAIN_AUXVEC_DECL),
      loader did the work already.  */
   if (__builtin_expect (__libc_enable_secure, 0))
     __libc_check_standard_fds ();
-#endif
+#endif /* !SHARED */
 
   /* Call the initializer of the program, if any.  */
 #ifdef SHARED
   if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_IMPCALLS, 0))
     GLRO(dl_debug_printf) ("\ninitialize program: %s\n\n", argv[0]);
-#endif
-  if (init)
+
+  if (init != NULL)
+    /* This is a legacy program which supplied its own init
+       routine.  */
     (*init) (argc, argv, __environ MAIN_AUXVEC_PARAM);
+  else
+    /* This is a current program.  Use the dynamic segment to find
+       constructors.  */
+    call_init (argc, argv, __environ);
+#else /* !SHARED */
+  call_init (argc, argv, __environ);
+#endif /* SHARED */
 
 #ifdef SHARED
   /* Auditing checkpoint: we have a new object.  */
@@ -341,3 +451,28 @@ LIBC_START_MAIN (int (*main) (int, char **, char ** MAIN_AUXVEC_DECL),
 
   exit (result);
 }
+
+#ifdef SHARED
+/* Starting with glibc 2.28, the init parameter is always NULL.  Older
+   libcs are not prepared to handle that.  */
+# define DEFINE_LIBC_START_MAIN_VERSION \
+  DEFINE_LIBC_START_MAIN_VERSION_1 \
+  versioned_symbol (libc, __libc_start_main, __libc_start_main, GLIBC_2_28);
+
+# if SHLIB_COMPAT(libc, GLIBC_2_0, GLIBC_2_28)
+#  define DEFINE_LIBC_START_MAIN_VERSION_1 \
+  strong_alias (__libc_start_main, __libc_start_main_alias)		\
+  compat_symbol (libc, __libc_start_main_alias, __libc_start_main, GLIBC_2_0);
+#  else
+#  define DEFINE_LIBC_START_MAIN_VERSION_1
+# endif
+#else
+# define DEFINE_LIBC_START_MAIN_VERSION
+#endif
+
+/* Only define the version information if LIBC_START_MAIN was not set.
+   If there is a wrapper file, it must expand
+   DEFINE_LIBC_START_MAIN_VERSION on its own.  */
+#if DO_DEFINE_LIBC_START_MAIN_VERSION
+DEFINE_LIBC_START_MAIN_VERSION
+#endif
diff --git a/elf/dl-init.c b/elf/dl-init.c
index 31eb12b974..dad3902254 100644
--- a/elf/dl-init.c
+++ b/elf/dl-init.c
@@ -21,10 +21,6 @@
 #include <platform-params.h>
 
 
-/* Type of the initializer.  */
-typedef void (*init_t) (int, char **, char **);
-
-
 static void
 call_init (struct link_map *l, int argc, char **argv, char **env)
 {
@@ -71,7 +67,7 @@ call_init (struct link_map *l, int argc, char **argv, char **env)
 
       addrs = (ElfW(Addr) *) (init_array->d_un.d_ptr + l->l_addr);
       for (j = 0; j < jm; ++j)
-	((init_t) addrs[j]) (argc, argv, env);
+	((dl_init_t) addrs[j]) (argc, argv, env);
     }
 }
 
@@ -103,7 +99,7 @@ _dl_init (struct link_map *main_map, int argc, char **argv, char **env)
 
       addrs = (ElfW(Addr) *) (preinit_array->d_un.d_ptr + main_map->l_addr);
       for (cnt = 0; cnt < i; ++cnt)
-	((init_t) addrs[cnt]) (argc, argv, env);
+	((dl_init_t) addrs[cnt]) (argc, argv, env);
     }
 
   /* Stupid users forced the ELF specification to be changed.  It now
diff --git a/sysdeps/aarch64/start.S b/sysdeps/aarch64/start.S
index bad000f555..2c22b6ff27 100644
--- a/sysdeps/aarch64/start.S
+++ b/sysdeps/aarch64/start.S
@@ -64,26 +64,16 @@ _start:
 # ifdef SHARED
         adrp    x0, :got:main
 	ldr     PTR_REG (0), [x0, #:got_lo12:main]
-
-        adrp    x3, :got:__libc_csu_init
-	ldr     PTR_REG (3), [x3, #:got_lo12:__libc_csu_init]
-
-        adrp    x4, :got:__libc_csu_fini
-	ldr     PTR_REG (4), [x4, #:got_lo12:__libc_csu_fini]
 # else
 	adrp	x0, __wrap_main
 	add	x0, x0, :lo12:__wrap_main
-	adrp	x3, __libc_csu_init
-	add	x3, x3, :lo12:__libc_csu_init
-	adrp	x4, __libc_csu_fini
-	add	x4, x4, :lo12:__libc_csu_fini
 # endif
 #else
 	/* Set up the other arguments in registers */
 	MOVL (0, main)
-	MOVL (3, __libc_csu_init)
-	MOVL (4, __libc_csu_fini)
 #endif
+	mov	x3, #0		/* Used to be init.  */
+	mov	x4, #0		/* Used to be fini.  */
 
 	/* __libc_start_main (main, argc, argv, init, fini, rtld_fini,
 			      stack_end) */
diff --git a/sysdeps/alpha/start.S b/sysdeps/alpha/start.S
index 5de8ceeca7..57ea0d67f7 100644
--- a/sysdeps/alpha/start.S
+++ b/sysdeps/alpha/start.S
@@ -55,9 +55,8 @@ _start:
 	ldl	a1, 16(sp)	/* get argc */
 	lda	a2, 24(sp)	/* get argv */
 
-  /* Load address of our own entry points to .fini and .init.  */
-	lda	a3, __libc_csu_init
-	lda	a4, __libc_csu_fini
+	mov	$r31, a3 	/* Used to be init.  */
+	mov	$r31, a4 	/* Used to be init.  */
 
   /* Store address of the shared library termination function.  */
 	mov	v0, a5
diff --git a/sysdeps/arm/start.S b/sysdeps/arm/start.S
index adef090717..ad2b25c2e1 100644
--- a/sysdeps/arm/start.S
+++ b/sysdeps/arm/start.S
@@ -94,30 +94,20 @@ _start:
 	adr a4, .L_GOT
 	add sl, sl, a4
 
-	ldr ip, .L_GOT+4	/* __libc_csu_fini */
-	ldr ip, [sl, ip]
+	mov a4, #0		/* Used to be init.  */
+	push { a4 }		/* Used to be fini.  */
 
-	push { ip }		/* Push __libc_csu_fini */
-
-	ldr a4, .L_GOT+8	/* __libc_csu_init */
-	ldr a4, [sl, a4]
-
-	ldr a1, .L_GOT+12	/* main */
+	ldr a1, .L_GOT+4	/* main */
 	ldr a1, [sl, a1]
 
 	/* __libc_start_main (main, argc, argv, init, fini, rtld_fini, stack_end) */
 	/* Let the libc call main and exit with its return code.  */
 	bl __libc_start_main(PLT)
 #else
-	/* Fetch address of __libc_csu_fini */
-	ldr ip, =__libc_csu_fini
 
-	/* Push __libc_csu_fini */
-	push { ip }
-
-	/* Set up the other arguments in registers */
+	mov a4, #0		/* Used to init.  */
+	push { a4 }		/* Used to fini.  */
 	ldr a1, =main
-	ldr a4, =__libc_csu_init
 
 	/* __libc_start_main (main, argc, argv, init, fini, rtld_fini, stack_end) */
 	/* Let the libc call main and exit with its return code.  */
@@ -131,8 +121,6 @@ _start:
 	.align 2
 .L_GOT:
 	.word _GLOBAL_OFFSET_TABLE_ - .L_GOT
-	.word __libc_csu_fini(GOT)
-	.word __libc_csu_init(GOT)
 	.word main(GOT)
 #endif
 
diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
index 95dc87519b..76a1f0dd56 100644
--- a/sysdeps/generic/ldsodefs.h
+++ b/sysdeps/generic/ldsodefs.h
@@ -75,6 +75,10 @@ typedef struct link_map *lookup_t;
    : (__glibc_unlikely ((ref)->st_shndx == SHN_ABS) ? 0			\
       : LOOKUP_VALUE_ADDRESS (map, map_set)) + (ref)->st_value)
 
+/* Type of a constructor function, in DT_INIT, DT_INIT_ARRAY,
+   DT_PREINIT_ARRAY.  */
+typedef void (*dl_init_t) (int, char **, char **);
+
 /* On some architectures a pointer to a function is not just a pointer
    to the actual code of the function but rather an architecture
    specific descriptor. */
@@ -83,7 +87,7 @@ typedef struct link_map *lookup_t;
  (void *) SYMBOL_ADDRESS (map, ref, false)
 # define DL_LOOKUP_ADDRESS(addr) ((ElfW(Addr)) (addr))
 # define DL_CALL_DT_INIT(map, start, argc, argv, env) \
- ((init_t) (start)) (argc, argv, env)
+ ((dl_init_t) (start)) (argc, argv, env)
 # define DL_CALL_DT_FINI(map, start) ((fini_t) (start)) ()
 #endif
 
diff --git a/sysdeps/hppa/dl-lookupcfg.h b/sysdeps/hppa/dl-lookupcfg.h
index 38db345936..f9ef78d856 100644
--- a/sysdeps/hppa/dl-lookupcfg.h
+++ b/sysdeps/hppa/dl-lookupcfg.h
@@ -56,7 +56,7 @@ void attribute_hidden _dl_unmap (struct link_map *map);
 {							\
   ElfW(Addr) addr;					\
   DL_DT_FUNCTION_ADDRESS(map, start, , addr)		\
-  init_t init = (init_t) addr; 				\
+  dl_init_t init = (dl_init_t) addr; 			\
   init (argc, argv, env);				\
 }
 
diff --git a/sysdeps/hppa/start.S b/sysdeps/hppa/start.S
index c1d2bd4bb7..8ffc247827 100644
--- a/sysdeps/hppa/start.S
+++ b/sysdeps/hppa/start.S
@@ -36,8 +36,6 @@
 	.import main, code
 	.import $global$, data
 	.import __libc_start_main, code
-	.import __libc_csu_fini, code
-	.import __libc_csu_init, code
 
 	/* Have the linker create plabel words so we get PLABEL32
 	   relocs and not 21/14.  The use of 21/14 relocs is only
@@ -52,10 +50,6 @@
 	.word P%main
 .Lp__libc_start_main:
 	.word P%__libc_start_main
-.Lp__libc_csu_fini:
-	.word P%__libc_csu_fini
-.Lp__libc_csu_init:
-	.word P%__libc_csu_init
 
 	.text
 	.align 4
@@ -77,8 +71,8 @@ _start:
 		1. r26 - Application main
 		2. r25 - argc
 		3. r24 - argv
-		4. r23 - __libc_csu_init
-		5. sp-52 - __libc_csu_fini
+		4. r23 - init (unused)
+		5. sp-52 - fini (unused)
 		6. sp-56 - rtld_fini
 		7. sp-60 - stackend  */
 
@@ -108,14 +102,6 @@ _start:
 	addil	LT'.Lpmain, %r19
 	ldw	RT'.Lpmain(%r1), %r26
 	ldw	0(%r26),%r26
-	/* void (*init) (void) (4th argument) */
-	addil	LT'.Lp__libc_csu_init, %r19
-	ldw	RT'.Lp__libc_csu_init(%r1), %r23
-	ldw	0(%r23), %r23
-	/* void (*fini) (void) (5th argument) */
-	addil	LT'.Lp__libc_csu_fini, %r19
-	ldw	RT'.Lp__libc_csu_fini(%r1), %r22
-	ldw	0(%r22), %r22
 #else
 	/* Load $global$ address into %dp */
 	ldil	L%$global$, %dp
@@ -124,13 +110,9 @@ _start:
 	/* load main (1st argument) */
 	ldil	LR'.Lpmain, %r26
 	ldw	RR'.Lpmain(%r26), %r26
-	/* void (*init) (void) (4th argument) */
-	ldil	LR'.Lp__libc_csu_init, %r23
-	ldw	RR'.Lp__libc_csu_init(%r23), %r23
-	/* void (*fini) (void) (5th argument) */
-	ldil	LR'.Lp__libc_csu_fini, %r22
-	ldw	RR'.Lp__libc_csu_fini(%r22), %r22
 #endif
+	ldi	0,%r23		/* Used to be init.  */
+	ldi	0,%r22		/* Used to be fini.  */
 	/* Store 5th argument */
 	stw	%r22, -52(%sp)
 	/* void *stack_end (7th argument) */
diff --git a/sysdeps/i386/start.S b/sysdeps/i386/start.S
index 91035fa83f..92781dc121 100644
--- a/sysdeps/i386/start.S
+++ b/sysdeps/i386/start.S
@@ -86,11 +86,9 @@ _start:
 	call 1f
 	addl $_GLOBAL_OFFSET_TABLE_, %ebx
 
-	/* Push address of our own entry points to .fini and .init.  */
-	leal __libc_csu_fini@GOTOFF(%ebx), %eax
-	pushl %eax
-	leal __libc_csu_init@GOTOFF(%ebx), %eax
-	pushl %eax
+	/* This used to be the addresses of .fini and .init.  */
+	pushl $0
+	pushl $0
 
 	pushl %ecx		/* Push second argument: argv.  */
 	pushl %esi		/* Push first argument: argc.  */
@@ -111,9 +109,9 @@ _start:
 	   But let the libc call main.    */
 	call __libc_start_main@PLT
 #else
-	/* Push address of our own entry points to .fini and .init.  */
-	pushl $__libc_csu_fini
-	pushl $__libc_csu_init
+	/* This used to be the addresses of .fini and .init.  */
+	pushl $0
+	pushl $0
 
 	pushl %ecx		/* Push second argument: argv.  */
 	pushl %esi		/* Push first argument: argc.  */
diff --git a/sysdeps/ia64/dl-lookupcfg.h b/sysdeps/ia64/dl-lookupcfg.h
index 48f91202c4..83734a9562 100644
--- a/sysdeps/ia64/dl-lookupcfg.h
+++ b/sysdeps/ia64/dl-lookupcfg.h
@@ -50,7 +50,7 @@ extern void attribute_hidden _dl_unmap (struct link_map *map);
 {							\
   ElfW(Addr) addr;					\
   DL_DT_FUNCTION_ADDRESS(map, start, , addr)		\
-  init_t init = (init_t) addr; 				\
+  dl_init_t init = (dl_init_t) addr; 			\
   init (argc, argv, env);				\
 }
 
diff --git a/sysdeps/ia64/start.S b/sysdeps/ia64/start.S
index 04205aa94f..6c3e468bcb 100644
--- a/sysdeps/ia64/start.S
+++ b/sysdeps/ia64/start.S
@@ -83,20 +83,15 @@ _start:
 	{
 	  addl r11 = @ltoff(__libc_ia64_register_backing_store_base), gp
 	  addl out0 = @ltoff(@fptr(main)), gp
-	  addl out3 = @ltoff(@fptr(__libc_csu_init)), gp
+	  mov out3 = r0		/* Used to be init.  */
 	  ;;
 	}
 	{ .mmi
 	  ld8 r3 = [r11]	/* pointer to __libc_ia64_register_backing_store_base */
 	  ld8 out0 = [out0]	/* pointer to `main' function descriptor */
-	  addl out4 = @ltoff(@fptr(__libc_csu_fini)), gp
+	  mov out4 = r0		/* Used to be fini.  */
 	  ;;
 	}
-	{ .mmi
-	  ld8 out3 = [out3]	/* pointer to `init' function descriptor */
-	  ld8 out4 = [out4]	/* pointer to `fini' function descriptor */
-	  nop 0
-	}
 	.body
 	{ .mib
 	  st8 [r3] = r10
diff --git a/sysdeps/m68k/start.S b/sysdeps/m68k/start.S
index 7bab3e1cde..7d151a3205 100644
--- a/sysdeps/m68k/start.S
+++ b/sysdeps/m68k/start.S
@@ -76,15 +76,14 @@ _start:
 	pea (%a1)		/* Push address of the shared library
 				   termination function.  */
 
+	/* These used to be addresses of the .fini and .init entry points.  */
+	clr.l -(%sp)
+	clr.l -(%sp)
+
 #ifdef PIC
 	/* Load PIC register.  */
 	LOAD_GOT (%a5)
 
-	/* Push the address of our own entry points to `.fini' and
-	   `.init'.  */
-	move.l __libc_csu_fini@GOT(%a5), -(%sp)
-	move.l __libc_csu_init@GOT(%a5), -(%sp)
-
 	pea (%a0)		/* Push second argument: argv.  */
 	move.l %d0, -(%sp)	/* Push first argument: argc.  */
 
@@ -94,10 +93,6 @@ _start:
 	   let the libc call main.  */
 	jbsr __libc_start_main@PLTPC
 #else
-	/* Push the address of our own entry points to `.fini' and
-	   `.init'.  */
-	pea __libc_csu_fini
-	pea __libc_csu_init
 
 	pea (%a0)		/* Push second argument: argv.  */
 	move.l %d0, -(%sp)	/* Push first argument: argc.  */
diff --git a/sysdeps/mach/hurd/i386/libc.abilist b/sysdeps/mach/hurd/i386/libc.abilist
index 2cb507052b..7bd93814eb 100644
--- a/sysdeps/mach/hurd/i386/libc.abilist
+++ b/sysdeps/mach/hurd/i386/libc.abilist
@@ -2033,6 +2033,7 @@ GLIBC_2.27 wcstof64 F
 GLIBC_2.27 wcstof64_l F
 GLIBC_2.27 wcstof64x F
 GLIBC_2.27 wcstof64x_l F
+GLIBC_2.28 __libc_start_main F
 GLIBC_2.3 __ctype_b_loc F
 GLIBC_2.3 __ctype_tolower_loc F
 GLIBC_2.3 __ctype_toupper_loc F
diff --git a/sysdeps/microblaze/start.S b/sysdeps/microblaze/start.S
index cc8dd13fe4..39f858ab71 100644
--- a/sysdeps/microblaze/start.S
+++ b/sysdeps/microblaze/start.S
@@ -63,14 +63,14 @@ _start:
     mfs     r20,rpc
     addik   r20,r20,_GLOBAL_OFFSET_TABLE_+8
     lwi     r5,r20,main@GOT
-    lwi     r8,r20,__libc_csu_init@GOT
-    lwi     r9,r20,__libc_csu_fini@GOT
+    addk    r8,r0,r0		/* Used to be init.  */
+    addk    r8,r0,r0		/* Used to be fini.  */
     brid    __libc_start_main@PLT
     addk    r10,r0,r0
 #else
     addik   r5,r0,main
-    addik   r8,r0,__libc_csu_init
-    addik   r9,r0,__libc_csu_fini
+    addk    r8,r0,r0		/* Used to be init.  */
+    addk    r8,r0,r0		/* Used to be fini.  */
     brid    __libc_start_main
     addk    r10,r0,r0
 #endif
diff --git a/sysdeps/mips/start.S b/sysdeps/mips/start.S
index a4c4ef0fae..f1ba04bc97 100644
--- a/sysdeps/mips/start.S
+++ b/sysdeps/mips/start.S
@@ -96,10 +96,9 @@ ENTRY_POINT:
 # if _MIPS_SIM == _ABIO32
 	PTR_SUBIU $29, 32
 # endif
-	PTR_LA $7, __libc_csu_init		/* init */
-	PTR_LA $8, __libc_csu_fini
+	move  $7, $0			/* init */
 # if _MIPS_SIM == _ABIO32
-	PTR_S $8, 16($29)		/* fini */
+	PTR_S $0, 16($29)		/* fini */
 	PTR_S $2, 20($29)		/* rtld_fini */
 	PTR_S $29, 24($29)		/* stack_end */
 # else
@@ -143,19 +142,17 @@ ENTRY_POINT:
 	/* Lay out last arguments, and call __libc_start_main().  */
 # ifdef __PIC__
 	sw	$7, 24($sp)			/* stack_end */
-	lw	$4, %got(__libc_csu_fini)($3)
-	lw	$7, %got(__libc_csu_init)($3)	/* init */
-	sw	$4, 16($sp)			/* fini */
+	move	$4, $0				/* Used to be ini.  */
+	sw	$0, 16($sp)			/* Used to be fini.  */
 	lw	$4, %got(main)($3)		/* main */
 	lw	$3, %call16(__libc_start_main)($3)
 	sw	$2, 20($sp)			/* rtld_fini */
 	move	$25, $3
 	jalr	$3
 # else
-	lw	$4, 1f
 	sw	$7, 24($sp)			/* stack_end */
-	lw	$7, 2f				/* init */
-	sw	$4, 16($sp)			/* fini */
+	move	$7, $0				/* Used to be init.  */
+	sw	$0, 16($sp)			/* Used to be fini.  */
 	lw	$4, 3f				/* main */
 	sw	$2, 20($sp)			/* rtld_fini */
 	/* Load and call __libc_start_main().  */
@@ -165,8 +162,6 @@ ENTRY_POINT:
 hlt:	b	hlt		/* Crash if somehow it does return.  */
 # ifndef __PIC__
 	.align	2
-1:	.word	__libc_csu_fini
-2:	.word	__libc_csu_init
 3:	.word	main
 4:	.word	__libc_start_main
 # endif
diff --git a/sysdeps/nios2/start.S b/sysdeps/nios2/start.S
index fa224ef75c..51a0757d78 100644
--- a/sysdeps/nios2/start.S
+++ b/sysdeps/nios2/start.S
@@ -92,18 +92,11 @@ _start:
 	addi	r2, r2, %lo(_gp_got - 1b)
 	add	r22, r22, r2
 
-	/* Push fini */
-	movhi	r8, %call_hiadj(__libc_csu_fini)
-	addi	r8, r8, %call_lo(__libc_csu_fini)
-	add	r8, r8, r22
-	ldw	r8, 0(r8)
-	stw	r8, 0(sp)
+	/* Used to be fini.  */
+	stw	zero, 0(sp)
 
-	/* r7 == init */
-	movhi	r7, %call_hiadj(__libc_csu_init)
-	addi	r7, r7, %call_lo(__libc_csu_init)
-	add	r7, r7, r22
-	ldw	r7, 0(r7)
+	/* Used to be init.  */
+	mov	r7, zero
 
 	/* r6 == argv */
 	addi	r6, sp, 16
diff --git a/sysdeps/powerpc/powerpc32/start.S b/sysdeps/powerpc/powerpc32/start.S
index 5c10a22f8a..0be6aed543 100644
--- a/sysdeps/powerpc/powerpc32/start.S
+++ b/sysdeps/powerpc/powerpc32/start.S
@@ -52,8 +52,8 @@
 L(start_addresses):
 	.long	_SDA_BASE_
 	.long	main
-	.long 	__libc_csu_init
-	.long 	__libc_csu_fini
+	.long 	0 /* Used to be init.  */
+	.long 	0 /* Used to be fini.  */
 	ASM_SIZE_DIRECTIVE(L(start_addresses))
 
 	.section ".text"
diff --git a/sysdeps/powerpc/powerpc64/start.S b/sysdeps/powerpc/powerpc64/start.S
index bd7189310c..149afbeab1 100644
--- a/sysdeps/powerpc/powerpc64/start.S
+++ b/sysdeps/powerpc/powerpc64/start.S
@@ -53,8 +53,8 @@ L(start_addresses):
 	.quad	0 /* was _SDA_BASE_  but not in 64-bit ABI*/
 /*     function descriptors so don't need JUMPTARGET */
 	.quad	main
-	.quad 	__libc_csu_init
-	.quad 	__libc_csu_fini
+	.quad 	0 /* Used to be init.  */
+	.quad 	0 /* Used to be fini.  */
 
 	ASM_SIZE_DIRECTIVE(L(start_addresses))
 
diff --git a/sysdeps/riscv/start.S b/sysdeps/riscv/start.S
index 4635ddb5eb..9dd4714910 100644
--- a/sysdeps/riscv/start.S
+++ b/sysdeps/riscv/start.S
@@ -50,8 +50,8 @@ ENTRY (ENTRY_POINT)
 	REG_L a1, 0(sp)      /* argc.  */
 	addi  a2, sp, SZREG  /* argv.  */
 	andi  sp, sp, ALMASK /* Align stack. */
-	lla   a3, __libc_csu_init
-	lla   a4, __libc_csu_fini
+	li    a3, 0	     /* Used to be init.  */
+	li    a4, 0	     /* Used to be fini.  */
 	mv    a6, sp  /* stack_end.  */
 
 	tail  __libc_start_main@plt
diff --git a/sysdeps/s390/s390-32/start.S b/sysdeps/s390/s390-32/start.S
index 1483642985..4587b2de5e 100644
--- a/sysdeps/s390/s390-32/start.S
+++ b/sysdeps/s390/s390-32/start.S
@@ -175,18 +175,16 @@ _start:
 	 */
 	stm     %r14,%r15,96(%r15)      # store rtld_fini/stack_end to parameter area
 	la      %r7,96(%r15)
-	l       %r6,.L2-.Llit(%r13)     # load pointer to __libc_csu_fini
-	l       %r5,.L1-.Llit(%r13)     # load pointer to __libc_csu_init
 	l       %r2,.L3-.Llit(%r13)     # load pointer to main
 	l       %r1,.L4-.Llit(%r13)	# load pointer to __libc_start_main
 #ifdef PIC
 	l       %r12,.L5-.Llit(%r13)    # load .got pointer
-	la	%r6,0(%r13,%r6)
-	la	%r5,0(%r13,%r5)
 	la	%r12,0(%r13,%r12)
 	l	%r2,0(%r12,%r2)
 	la	%r1,0(%r13,%r1)
 #endif
+	lhi	%r6, 0			# Used to fini.
+	lhi	%r5, 0			# Used to init.
 
 	/* ok, now branch to the libc main routine */
 	basr    %r14,%r1
@@ -197,13 +195,9 @@ _start:
 	cfi_endproc
 .Llit:
 #ifndef PIC
-.L1:    .long  __libc_csu_init
-.L2:    .long  __libc_csu_fini
 .L3:    .long  main
 .L4:    .long  __libc_start_main
 #else
-.L1:    .long  __libc_csu_init-.Llit
-.L2:    .long  __libc_csu_fini-.Llit
 .L3:    .long  main@GOT
 .L4:    .long  __libc_start_main@plt-.Llit
 .L5:    .long  _GLOBAL_OFFSET_TABLE_-.Llit
diff --git a/sysdeps/s390/s390-64/start.S b/sysdeps/s390/s390-64/start.S
index 79e7b69f1d..518dfd989e 100644
--- a/sysdeps/s390/s390-64/start.S
+++ b/sysdeps/s390/s390-64/start.S
@@ -80,8 +80,8 @@ _start:
 	 */
 	stmg	%r14,%r15,160(%r15)	# store rtld_fini/stack_end to parameter area
 	la	%r7,160(%r15)
-	larl	%r6,__libc_csu_fini	# load pointer to __libc_csu_fini
-	larl	%r5,__libc_csu_init	# load pointer to __libc_csu_init
+	lghi	%r6,0			# Used to be fini.
+	lghi	%r5,0			# Used to be init.
 
 	/* Ok, now branch to the libc main routine.  */
 #ifdef PIC
diff --git a/sysdeps/sh/start.S b/sysdeps/sh/start.S
index f52077abca..4b0aad511b 100644
--- a/sysdeps/sh/start.S
+++ b/sysdeps/sh/start.S
@@ -70,12 +70,11 @@ _start:
 
 	/* Push the last arguments to main() onto the stack */
 	mov.l r4,@-r15
-	mov.l L_fini,r0
-	mov.l r0,@-r15
+	mov.l r14,@-r15		/* Used to be fini.  */
 
 	/* Set up the other arguments for main() that go in registers */
 	mov.l L_main,r4
-	mov.l L_init,r7
+	mov #0,r7		/* Used to be init.  */
 
 	/* __libc_start_main (main, argc, argv, init, fini, rtld_fini) */
 
@@ -90,10 +89,6 @@ _start:
 	.align	2
 L_main:
 	.long	main
-L_init:
-	.long	__libc_csu_init
-L_fini:
-	.long	__libc_csu_fini
 L_libc_start_main:
 	.long	__libc_start_main
 L_abort:
diff --git a/sysdeps/sparc/sparc32/start.S b/sysdeps/sparc/sparc32/start.S
index 46ba8b6afa..48b30a3fb5 100644
--- a/sysdeps/sparc/sparc32/start.S
+++ b/sysdeps/sparc/sparc32/start.S
@@ -59,22 +59,14 @@ _start:
   /* Load the addresses of the user entry points.  */
 #ifndef PIC
 	sethi	%hi(main), %o0
-	sethi	%hi(__libc_csu_init), %o3
-	sethi	%hi(__libc_csu_fini), %o4
 	or	%o0, %lo(main), %o0
-	or	%o3, %lo(__libc_csu_init), %o3
-	or	%o4, %lo(__libc_csu_fini), %o4
 #else
 	sethi	%gdop_hix22(main), %o0
-	sethi	%gdop_hix22(__libc_csu_init), %o3
-	sethi	%gdop_hix22(__libc_csu_fini), %o4
 	xor	%o0, %gdop_lox10(main), %o0
-	xor	%o3, %gdop_lox10(__libc_csu_init), %o3
-	xor	%o4, %gdop_lox10(__libc_csu_fini), %o4
 	ld	[%l7 + %o0], %o0, %gdop(main)
-	ld	[%l7 + %o3], %o3, %gdop(__libc_csu_init)
-	ld	[%l7 + %o4], %o4, %gdop(__libc_csu_fini)
 #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
diff --git a/sysdeps/sparc/sparc64/start.S b/sysdeps/sparc/sparc64/start.S
index 75ff5093dc..73395df40a 100644
--- a/sysdeps/sparc/sparc64/start.S
+++ b/sysdeps/sparc/sparc64/start.S
@@ -60,22 +60,14 @@ _start:
   /* Load the addresses of the user entry points.  */
 #ifndef PIC
 	sethi	%hi(main), %o0
-	sethi	%hi(__libc_csu_init), %o3
-	sethi	%hi(__libc_csu_fini), %o4
 	or	%o0, %lo(main), %o0
-	or	%o3, %lo(__libc_csu_init), %o3
-	or	%o4, %lo(__libc_csu_fini), %o4
 #else
 	sethi	%gdop_hix22(main), %o0
-	sethi	%gdop_hix22(__libc_csu_init), %o3
-	sethi	%gdop_hix22(__libc_csu_fini), %o4
 	xor	%o0, %gdop_lox10(main), %o0
-	xor	%o3, %gdop_lox10(__libc_csu_init), %o3
-	xor	%o4, %gdop_lox10(__libc_csu_fini), %o4
 	ldx	[%l7 + %o0], %o0, %gdop(main)
-	ldx	[%l7 + %o3], %o3, %gdop(__libc_csu_init)
-	ldx	[%l7 + %o4], %o4, %gdop(__libc_csu_fini)
 #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
diff --git a/sysdeps/unix/sysv/linux/aarch64/libc.abilist b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
index 80cdb98e1c..e5bcea397f 100644
--- a/sysdeps/unix/sysv/linux/aarch64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
@@ -2131,3 +2131,4 @@ GLIBC_2.27 wcstof64 F
 GLIBC_2.27 wcstof64_l F
 GLIBC_2.27 wcstof64x F
 GLIBC_2.27 wcstof64x_l F
+GLIBC_2.28 __libc_start_main F
diff --git a/sysdeps/unix/sysv/linux/alpha/libc.abilist b/sysdeps/unix/sysv/linux/alpha/libc.abilist
index c761f61c43..ec3716e631 100644
--- a/sysdeps/unix/sysv/linux/alpha/libc.abilist
+++ b/sysdeps/unix/sysv/linux/alpha/libc.abilist
@@ -2026,6 +2026,7 @@ GLIBC_2.27 wcstof64 F
 GLIBC_2.27 wcstof64_l F
 GLIBC_2.27 wcstof64x F
 GLIBC_2.27 wcstof64x_l F
+GLIBC_2.28 __libc_start_main F
 GLIBC_2.3 __ctype_b_loc F
 GLIBC_2.3 __ctype_tolower_loc F
 GLIBC_2.3 __ctype_toupper_loc F
diff --git a/sysdeps/unix/sysv/linux/arm/libc.abilist b/sysdeps/unix/sysv/linux/arm/libc.abilist
index 6aa58c3ca7..59d91ab2f3 100644
--- a/sysdeps/unix/sysv/linux/arm/libc.abilist
+++ b/sysdeps/unix/sysv/linux/arm/libc.abilist
@@ -115,6 +115,7 @@ GLIBC_2.27 wcstof32x F
 GLIBC_2.27 wcstof32x_l F
 GLIBC_2.27 wcstof64 F
 GLIBC_2.27 wcstof64_l F
+GLIBC_2.28 __libc_start_main F
 GLIBC_2.4 _Exit F
 GLIBC_2.4 _IO_2_1_stderr_ D 0xa0
 GLIBC_2.4 _IO_2_1_stdin_ D 0xa0
diff --git a/sysdeps/unix/sysv/linux/hppa/libc.abilist b/sysdeps/unix/sysv/linux/hppa/libc.abilist
index d10695b7d3..4c468d6eb5 100644
--- a/sysdeps/unix/sysv/linux/hppa/libc.abilist
+++ b/sysdeps/unix/sysv/linux/hppa/libc.abilist
@@ -1872,6 +1872,7 @@ GLIBC_2.27 wcstof32x F
 GLIBC_2.27 wcstof32x_l F
 GLIBC_2.27 wcstof64 F
 GLIBC_2.27 wcstof64_l F
+GLIBC_2.28 __libc_start_main F
 GLIBC_2.3 __ctype_b_loc F
 GLIBC_2.3 __ctype_tolower_loc F
 GLIBC_2.3 __ctype_toupper_loc F
diff --git a/sysdeps/unix/sysv/linux/i386/libc.abilist b/sysdeps/unix/sysv/linux/i386/libc.abilist
index 23092ab6d7..64729ea4ea 100644
--- a/sysdeps/unix/sysv/linux/i386/libc.abilist
+++ b/sysdeps/unix/sysv/linux/i386/libc.abilist
@@ -2037,6 +2037,7 @@ GLIBC_2.27 wcstof64 F
 GLIBC_2.27 wcstof64_l F
 GLIBC_2.27 wcstof64x F
 GLIBC_2.27 wcstof64x_l F
+GLIBC_2.28 __libc_start_main F
 GLIBC_2.3 __ctype_b_loc F
 GLIBC_2.3 __ctype_tolower_loc F
 GLIBC_2.3 __ctype_toupper_loc F
diff --git a/sysdeps/unix/sysv/linux/ia64/libc.abilist b/sysdeps/unix/sysv/linux/ia64/libc.abilist
index 7bf259e86c..909d742540 100644
--- a/sysdeps/unix/sysv/linux/ia64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/ia64/libc.abilist
@@ -1907,6 +1907,7 @@ GLIBC_2.27 wcstof64 F
 GLIBC_2.27 wcstof64_l F
 GLIBC_2.27 wcstof64x F
 GLIBC_2.27 wcstof64x_l F
+GLIBC_2.28 __libc_start_main F
 GLIBC_2.3 __ctype_b_loc F
 GLIBC_2.3 __ctype_tolower_loc F
 GLIBC_2.3 __ctype_toupper_loc F
diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
index 4673bcd79b..d848fb4f13 100644
--- a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
@@ -116,6 +116,7 @@ GLIBC_2.27 wcstof32x F
 GLIBC_2.27 wcstof32x_l F
 GLIBC_2.27 wcstof64 F
 GLIBC_2.27 wcstof64_l F
+GLIBC_2.28 __libc_start_main F
 GLIBC_2.4 _Exit F
 GLIBC_2.4 _IO_2_1_stderr_ D 0x98
 GLIBC_2.4 _IO_2_1_stdin_ D 0x98
diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
index 1f8ac40399..30280266e4 100644
--- a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
@@ -1981,6 +1981,7 @@ GLIBC_2.27 wcstof32x F
 GLIBC_2.27 wcstof32x_l F
 GLIBC_2.27 wcstof64 F
 GLIBC_2.27 wcstof64_l F
+GLIBC_2.28 __libc_start_main F
 GLIBC_2.3 __ctype_b_loc F
 GLIBC_2.3 __ctype_tolower_loc F
 GLIBC_2.3 __ctype_toupper_loc F
diff --git a/sysdeps/unix/sysv/linux/microblaze/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/libc.abilist
index 09277f5954..2eb49d6dc1 100644
--- a/sysdeps/unix/sysv/linux/microblaze/libc.abilist
+++ b/sysdeps/unix/sysv/linux/microblaze/libc.abilist
@@ -2122,3 +2122,4 @@ GLIBC_2.27 wcstof32x F
 GLIBC_2.27 wcstof32x_l F
 GLIBC_2.27 wcstof64 F
 GLIBC_2.27 wcstof64_l F
+GLIBC_2.28 __libc_start_main F
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
index f562e20f23..b273754592 100644
--- a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
@@ -1959,6 +1959,7 @@ GLIBC_2.27 wcstof32x F
 GLIBC_2.27 wcstof32x_l F
 GLIBC_2.27 wcstof64 F
 GLIBC_2.27 wcstof64_l F
+GLIBC_2.28 __libc_start_main F
 GLIBC_2.3 __ctype_b_loc F
 GLIBC_2.3 __ctype_tolower_loc F
 GLIBC_2.3 __ctype_toupper_loc F
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
index ceb7388829..4a0a6b6545 100644
--- a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
@@ -1957,6 +1957,7 @@ GLIBC_2.27 wcstof32x F
 GLIBC_2.27 wcstof32x_l F
 GLIBC_2.27 wcstof64 F
 GLIBC_2.27 wcstof64_l F
+GLIBC_2.28 __libc_start_main F
 GLIBC_2.3 __ctype_b_loc F
 GLIBC_2.3 __ctype_tolower_loc F
 GLIBC_2.3 __ctype_toupper_loc F
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
index 5765f487a2..04ef0ea835 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
@@ -1965,6 +1965,7 @@ GLIBC_2.27 wcstof64 F
 GLIBC_2.27 wcstof64_l F
 GLIBC_2.27 wcstof64x F
 GLIBC_2.27 wcstof64x_l F
+GLIBC_2.28 __libc_start_main F
 GLIBC_2.3 __ctype_b_loc F
 GLIBC_2.3 __ctype_tolower_loc F
 GLIBC_2.3 __ctype_toupper_loc F
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
index a84bb45a38..df5c75a986 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
@@ -1961,6 +1961,7 @@ GLIBC_2.27 wcstof64 F
 GLIBC_2.27 wcstof64_l F
 GLIBC_2.27 wcstof64x F
 GLIBC_2.27 wcstof64x_l F
+GLIBC_2.28 __libc_start_main F
 GLIBC_2.3 __ctype_b_loc F
 GLIBC_2.3 __ctype_tolower_loc F
 GLIBC_2.3 __ctype_toupper_loc F
diff --git a/sysdeps/unix/sysv/linux/nios2/libc.abilist b/sysdeps/unix/sysv/linux/nios2/libc.abilist
index e43295986c..e9bc514407 100644
--- a/sysdeps/unix/sysv/linux/nios2/libc.abilist
+++ b/sysdeps/unix/sysv/linux/nios2/libc.abilist
@@ -2163,3 +2163,4 @@ GLIBC_2.27 wcstof32x F
 GLIBC_2.27 wcstof32x_l F
 GLIBC_2.27 wcstof64 F
 GLIBC_2.27 wcstof64_l F
+GLIBC_2.28 __libc_start_main F
diff --git a/sysdeps/unix/sysv/linux/powerpc/libc-start.c b/sysdeps/unix/sysv/linux/powerpc/libc-start.c
index f2ad0c355d..522926604b 100644
--- a/sysdeps/unix/sysv/linux/powerpc/libc-start.c
+++ b/sysdeps/unix/sysv/linux/powerpc/libc-start.c
@@ -103,3 +103,4 @@ __libc_start_main (int argc, char **argv,
 			     stinfo->init, stinfo->fini, rtld_fini,
 			     stack_on_entry);
 }
+DEFINE_LIBC_START_MAIN_VERSION
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
index a5f2b23068..20ad9f97a1 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
@@ -1985,6 +1985,7 @@ GLIBC_2.27 wcstof32x F
 GLIBC_2.27 wcstof32x_l F
 GLIBC_2.27 wcstof64 F
 GLIBC_2.27 wcstof64_l F
+GLIBC_2.28 __libc_start_main F
 GLIBC_2.3 __ctype_b_loc F
 GLIBC_2.3 __ctype_tolower_loc F
 GLIBC_2.3 __ctype_toupper_loc F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
index e4cbe36279..2bb053f087 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
@@ -1989,6 +1989,7 @@ GLIBC_2.27 wcstof32x F
 GLIBC_2.27 wcstof32x_l F
 GLIBC_2.27 wcstof64 F
 GLIBC_2.27 wcstof64_l F
+GLIBC_2.28 __libc_start_main F
 GLIBC_2.3 __ctype_b_loc F
 GLIBC_2.3 __ctype_tolower_loc F
 GLIBC_2.3 __ctype_toupper_loc F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist
index 9869feb56b..a9154afddb 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist
@@ -2221,3 +2221,4 @@ GLIBC_2.27 wcstof64 F
 GLIBC_2.27 wcstof64_l F
 GLIBC_2.27 wcstof64x F
 GLIBC_2.27 wcstof64x_l F
+GLIBC_2.28 __libc_start_main F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist
index e526dc4627..cd0afdbd7f 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist
@@ -116,6 +116,7 @@ GLIBC_2.27 wcstof32x F
 GLIBC_2.27 wcstof32x_l F
 GLIBC_2.27 wcstof64 F
 GLIBC_2.27 wcstof64_l F
+GLIBC_2.28 __libc_start_main F
 GLIBC_2.3 _Exit F
 GLIBC_2.3 _IO_2_1_stderr_ D 0xe0
 GLIBC_2.3 _IO_2_1_stdin_ D 0xe0
diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
index e6319eef8d..8605c56a2c 100644
--- a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
@@ -2093,3 +2093,4 @@ GLIBC_2.27 xdrstdio_create F
 GLIBC_2.27 xencrypt F
 GLIBC_2.27 xprt_register F
 GLIBC_2.27 xprt_unregister F
+GLIBC_2.28 __libc_start_main F
diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
index 41cdda0c2e..87ca6db77a 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
@@ -1994,6 +1994,7 @@ GLIBC_2.27 wcstof64 F
 GLIBC_2.27 wcstof64_l F
 GLIBC_2.27 wcstof64x F
 GLIBC_2.27 wcstof64x_l F
+GLIBC_2.28 __libc_start_main F
 GLIBC_2.3 __ctype_b_loc F
 GLIBC_2.3 __ctype_tolower_loc F
 GLIBC_2.3 __ctype_toupper_loc F
diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
index 8a756cf287..68789b381a 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
@@ -1900,6 +1900,7 @@ GLIBC_2.27 wcstof64 F
 GLIBC_2.27 wcstof64_l F
 GLIBC_2.27 wcstof64x F
 GLIBC_2.27 wcstof64x_l F
+GLIBC_2.28 __libc_start_main F
 GLIBC_2.3 __ctype_b_loc F
 GLIBC_2.3 __ctype_tolower_loc F
 GLIBC_2.3 __ctype_toupper_loc F
diff --git a/sysdeps/unix/sysv/linux/sh/libc.abilist b/sysdeps/unix/sysv/linux/sh/libc.abilist
index 999bddd1db..7d3c96bb42 100644
--- a/sysdeps/unix/sysv/linux/sh/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sh/libc.abilist
@@ -1876,6 +1876,7 @@ GLIBC_2.27 wcstof32x F
 GLIBC_2.27 wcstof32x_l F
 GLIBC_2.27 wcstof64 F
 GLIBC_2.27 wcstof64_l F
+GLIBC_2.28 __libc_start_main F
 GLIBC_2.3 __ctype_b_loc F
 GLIBC_2.3 __ctype_tolower_loc F
 GLIBC_2.3 __ctype_toupper_loc F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
index 7c4296fc10..4f180a0608 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
@@ -1988,6 +1988,7 @@ GLIBC_2.27 wcstof64 F
 GLIBC_2.27 wcstof64_l F
 GLIBC_2.27 wcstof64x F
 GLIBC_2.27 wcstof64x_l F
+GLIBC_2.28 __libc_start_main F
 GLIBC_2.3 __ctype_b_loc F
 GLIBC_2.3 __ctype_tolower_loc F
 GLIBC_2.3 __ctype_toupper_loc F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
index dafe9d74b7..50b9bf70ca 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
@@ -1930,6 +1930,7 @@ GLIBC_2.27 wcstof64 F
 GLIBC_2.27 wcstof64_l F
 GLIBC_2.27 wcstof64x F
 GLIBC_2.27 wcstof64x_l F
+GLIBC_2.28 __libc_start_main F
 GLIBC_2.3 __ctype_b_loc F
 GLIBC_2.3 __ctype_tolower_loc F
 GLIBC_2.3 __ctype_toupper_loc F
diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
index f72d494920..5648d8ffda 100644
--- a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
@@ -1888,6 +1888,7 @@ GLIBC_2.27 wcstof64 F
 GLIBC_2.27 wcstof64_l F
 GLIBC_2.27 wcstof64x F
 GLIBC_2.27 wcstof64x_l F
+GLIBC_2.28 __libc_start_main F
 GLIBC_2.3 __ctype_b_loc F
 GLIBC_2.3 __ctype_tolower_loc F
 GLIBC_2.3 __ctype_toupper_loc F
diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
index 96c9fa050e..ada4314f7c 100644
--- a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
@@ -2139,3 +2139,4 @@ GLIBC_2.27 wcstof64 F
 GLIBC_2.27 wcstof64_l F
 GLIBC_2.27 wcstof64x F
 GLIBC_2.27 wcstof64x_l F
+GLIBC_2.28 __libc_start_main F
diff --git a/sysdeps/x86_64/start.S b/sysdeps/x86_64/start.S
index 354d2e6ec7..8060586b5c 100644
--- a/sysdeps/x86_64/start.S
+++ b/sysdeps/x86_64/start.S
@@ -96,17 +96,13 @@ ENTRY (_start)
 	   which grow downwards).  */
 	pushq %rsp
 
+	/* These used to be the addresses of .fini and .init.  */
+	xor %R8_LP, %R8_LP
+	xor %RCX_LP, %RCX_LP
+
 #ifdef PIC
-	/* Pass address of our own entry points to .fini and .init.  */
-	mov __libc_csu_fini@GOTPCREL(%rip), %R8_LP
-	mov __libc_csu_init@GOTPCREL(%rip), %RCX_LP
-
 	mov main@GOTPCREL(%rip), %RDI_LP
 #else
-	/* Pass address of our own entry points to .fini and .init.  */
-	mov $__libc_csu_fini, %R8_LP
-	mov $__libc_csu_init, %RCX_LP
-
 	mov $main, %RDI_LP
 #endif
 
