diff --git a/elf/Makefile b/elf/Makefile
index 0b4d78c874..93b378e461 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -25,7 +25,7 @@ headers		= elf.h bits/elfclass.h link.h bits/link.h
 routines	= $(all-dl-routines) dl-support dl-iteratephdr \
 		  dl-addr dl-addr-obj enbl-secure dl-profstub \
 		  dl-origin dl-libc dl-sym dl-sysdep dl-error \
-		  dl-reloc-static-pie libc_early_init
+		  dl-reloc-static-pie libc_early_init libc_vars
 
 # The core dynamic linking functions are in libc for the static and
 # profiled libraries.
@@ -35,7 +35,7 @@ dl-routines	= $(addprefix dl-,load lookup object reloc deps \
 				  execstack open close trampoline \
 				  exception sort-maps lookup-direct \
 				  call-libc-early-init write \
-				  thread_gscope_wait)
+				  thread_gscope_wait libc_vars libc_vars_init)
 ifeq (yes,$(use-ldconfig))
 dl-routines += dl-cache
 endif
@@ -186,9 +186,14 @@ tests-internal := tst-tls1 tst-tls2 $(tests-static-internal)
 tests-static := $(tests-static-normal) $(tests-static-internal)
 
 ifeq (yes,$(build-shared))
-tests-static += tst-tls9-static tst-single_threaded-static-dlopen
+tests-static += \
+  tst-getauxval-static \
+  tst-single_threaded-static-dlopen \
+  tst-tls9-static \
+
 static-dlopen-environment = \
   LD_LIBRARY_PATH=$(ld-library-path):$(common-objpfx)dlfcn
+tst-getauxval-static-ENV = $(static-dlopen-environment)
 tst-tls9-static-ENV = $(static-dlopen-environment)
 tst-single_threaded-static-dlopen-ENV = $(static-dlopen-environment)
 
@@ -343,6 +348,7 @@ modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \
 		libmarkermod2-1 libmarkermod2-2 \
 		libmarkermod3-1 libmarkermod3-2 libmarkermod3-3 \
 		libmarkermod4-1 libmarkermod4-2 libmarkermod4-3 libmarkermod4-4 \
+		tst-auxvalmod \
 
 # Most modules build with _ISOMAC defined, but those filtered out
 # depend on internal headers.
@@ -1894,3 +1900,6 @@ $(objpfx)tst-glibc-hwcaps-mask.out: \
 # Generic dependency for sysdeps implementation of
 # tst-glibc-hwcaps-cache.
 $(objpfx)tst-glibc-hwcaps-cache.out: $(objpfx)tst-glibc-hwcaps
+
+$(objpfx)tst-getauxval-static: $(common-objpfx)dlfcn/libdl.a
+$(objpfx)tst-getauxval-static.out: $(objpfx)tst-auxvalmod.so
diff --git a/elf/Versions b/elf/Versions
index be88c48e6d..94e6daadf5 100644
--- a/elf/Versions
+++ b/elf/Versions
@@ -31,6 +31,8 @@ libc {
     # Internal error handling support.  Interposes the functions in ld.so.
     _dl_signal_exception; _dl_catch_exception;
     _dl_signal_error; _dl_catch_error;
+
+    __libc_vars;
   }
 }
 
diff --git a/elf/dl-call-libc-early-init.c b/elf/dl-call-libc-early-init.c
index 9a84680a1c..135fa57bed 100644
--- a/elf/dl-call-libc-early-init.c
+++ b/elf/dl-call-libc-early-init.c
@@ -19,9 +19,12 @@
 #include <assert.h>
 #include <ldsodefs.h>
 #include <libc-early-init.h>
+#include <libc-vars.h>
 #include <link.h>
 #include <stddef.h>
 
+#include <libc-vars-init.h>
+
 void
 _dl_call_libc_early_init (struct link_map *libc_map, _Bool initial)
 {
@@ -39,3 +42,23 @@ _dl_call_libc_early_init (struct link_map *libc_map, _Bool initial)
     = DL_SYMBOL_ADDRESS (libc_map, sym);
   early_init (initial);
 }
+
+void
+_dl_call_libc_vars_init (struct link_map *libc_map)
+{
+  /* There is nothing to do if we did not actually load libc.so.  */
+  if (libc_map == NULL)
+    return;
+
+  const ElfW (Sym) *sym
+    = _dl_lookup_direct (libc_map, "__libc_vars",
+                         0x59f05378, /* dl_new_hash output.  */
+                         "GLIBC_PRIVATE",
+                         0x0963cf85); /* _dl_elf_hash output.  */
+  assert (sym != NULL);
+  assert (sym->st_size == sizeof (struct libc_vars));
+  struct libc_vars *vars = DL_SYMBOL_ADDRESS (libc_map, sym);
+
+  _dl_libc_vars_init (vars);
+  _dl_call_libc_vars_init_cpu (libc_map);
+}
diff --git a/elf/dl-libc_vars.c b/elf/dl-libc_vars.c
new file mode 100644
index 0000000000..6d9d96ec63
--- /dev/null
+++ b/elf/dl-libc_vars.c
@@ -0,0 +1,19 @@
+/* Local copy of __libc_vars for ld.so.
+   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/>.  */
+
+#include "libc_vars.c"
diff --git a/elf/dl-libc_vars_init.c b/elf/dl-libc_vars_init.c
new file mode 100644
index 0000000000..71cb0446fb
--- /dev/null
+++ b/elf/dl-libc_vars_init.c
@@ -0,0 +1,31 @@
+/* Update __libc_vars in libc.so with the data from ld.so.
+   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/>.  */
+
+#include <libc-vars.h>
+
+#include <libc-vars-init.h>
+
+void
+_dl_libc_vars_init (struct libc_vars *vars)
+{
+#ifdef HAVE_AUX_VECTOR
+  vars->auxv = __libc_vars.auxv;
+#endif
+
+  _dl_libc_vars_init_cpu (vars);
+}
diff --git a/elf/dl-open.c b/elf/dl-open.c
index 6710ea04cd..d5f9e61858 100644
--- a/elf/dl-open.c
+++ b/elf/dl-open.c
@@ -35,6 +35,7 @@
 #include <libc-internal.h>
 #include <array_length.h>
 #include <libc-early-init.h>
+#include <libc-vars.h>
 
 #include <dl-dst.h>
 #include <dl-prop.h>
@@ -590,6 +591,15 @@ dl_open_worker (void *a)
       (void) _dl_check_map_versions (new->l_searchlist.r_list[i]->l_real,
 				     0, 0);
 
+  /* Initialize __libc_vars before relocation.  This has to come after
+     the call to _dl_check_map_versions, so that lookups of versioned
+     symbols work.  */
+  if (!args->libc_already_loaded)
+    {
+      struct link_map *libc_map = GL (dl_ns)[args->nsid].libc_map;
+      _dl_call_libc_vars_init (libc_map);
+    }
+
 #ifdef SHARED
   /* Auditing checkpoint: we have added all objects.  */
   if (__glibc_unlikely (GLRO(dl_naudit) > 0))
diff --git a/elf/dl-support.c b/elf/dl-support.c
index 250e4cd092..6f6b20cb4e 100644
--- a/elf/dl-support.c
+++ b/elf/dl-support.c
@@ -37,6 +37,7 @@
 #include <dl-vdso.h>
 #include <dl-vdso-setup.h>
 #include <dl-auxv.h>
+#include <libc-vars.h>
 
 extern char *__progname;
 char **_dl_argv = &__progname;	/* This is checked for some error messages.  */
@@ -154,7 +155,6 @@ int _dl_debug_fd = STDERR_FILENO;
 
 int _dl_correct_cache_id = _DL_CACHE_DEFAULT_ID;
 
-ElfW(auxv_t) *_dl_auxv;
 const ElfW(Phdr) *_dl_phdr;
 size_t _dl_phnum;
 uint64_t _dl_hwcap __attribute__ ((nocommon));
@@ -232,7 +232,7 @@ _dl_aux_init (ElfW(auxv_t) *av)
   uid_t uid = 0;
   gid_t gid = 0;
 
-  _dl_auxv = av;
+  __libc_vars.auxv = av;
   for (; av->a_type != AT_NULL; ++av)
     switch (av->a_type)
       {
diff --git a/elf/dl-sysdep.c b/elf/dl-sysdep.c
index 6cc4a76560..0969773127 100644
--- a/elf/dl-sysdep.c
+++ b/elf/dl-sysdep.c
@@ -42,6 +42,7 @@
 #include <dl-procinfo.h>
 #include <dl-osinfo.h>
 #include <libc-internal.h>
+#include <libc-vars.h>
 #include <tls.h>
 
 #include <dl-tunables.h>
@@ -110,12 +111,12 @@ _dl_sysdep_start (void **start_argptr,
 
   __libc_stack_end = DL_STACK_END (start_argptr);
   DL_FIND_ARG_COMPONENTS (start_argptr, _dl_argc, _dl_argv, _environ,
-			  GLRO(dl_auxv));
+			  __libc_vars.auxv);
 
   user_entry = (ElfW(Addr)) ENTRY_POINT;
   GLRO(dl_platform) = NULL; /* Default to nothing known about the platform.  */
 
-  for (av = GLRO(dl_auxv); av->a_type != AT_NULL; set_seen (av++))
+  for (av = __libc_vars.auxv; av->a_type != AT_NULL; set_seen (av++))
     switch (av->a_type)
       {
       case AT_PHDR:
@@ -247,7 +248,7 @@ _dl_sysdep_start (void **start_argptr,
   if (__builtin_expect (__libc_enable_secure, 0))
     __libc_check_standard_fds ();
 
-  (*dl_main) (phdr, phnum, &user_entry, GLRO(dl_auxv));
+  (*dl_main) (phdr, phnum, &user_entry, __libc_vars.auxv);
   return user_entry;
 }
 
@@ -270,7 +271,7 @@ _dl_show_auxv (void)
      close by (otherwise the array will be too large).  In case we have
      to support a platform where these requirements are not fulfilled
      some alternative implementation has to be used.  */
-  for (av = GLRO(dl_auxv); av->a_type != AT_NULL; ++av)
+  for (av = __libc_vars.auxv; av->a_type != AT_NULL; ++av)
     {
       static const struct
       {
diff --git a/elf/libc_vars.c b/elf/libc_vars.c
new file mode 100644
index 0000000000..538de7fa56
--- /dev/null
+++ b/elf/libc_vars.c
@@ -0,0 +1,22 @@
+/* Definition of __libc_vars for libc.
+   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/>.  */
+
+#include <libc-vars.h>
+
+struct libc_vars __libc_vars attribute_relro;
+hidden_def (__libc_vars)
diff --git a/elf/rtld.c b/elf/rtld.c
index 38f11f5b73..69b5b114ed 100644
--- a/elf/rtld.c
+++ b/elf/rtld.c
@@ -50,6 +50,7 @@
 #include <dl-main.h>
 #include <list.h>
 #include <gnu/lib-names.h>
+#include <libc-vars.h>
 
 #include <assert.h>
 
@@ -2311,6 +2312,10 @@ dl_main (const ElfW(Phdr) *phdr,
 
   _rtld_main_check (main_map, _dl_argv[0]);
 
+  /* We are about to perform relocation.  Make sure that __libc_vars
+     has been initialized.  */
+  _dl_call_libc_vars_init (GL (dl_ns)[LM_ID_BASE].libc_map);
+
   if (prelinked)
     {
       if (main_map->l_info [ADDRIDX (DT_GNU_CONFLICT)] != NULL)
diff --git a/elf/tst-auxvalmod.c b/elf/tst-auxvalmod.c
new file mode 100644
index 0000000000..d695c9df91
--- /dev/null
+++ b/elf/tst-auxvalmod.c
@@ -0,0 +1,31 @@
+/* Wrapper for getauxval testing.
+   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/>.  */
+
+#include <errno.h>
+#include <sys/auxv.h>
+
+#include "tst-auxvalmod.h"
+
+unsigned long int
+getauxval_wrapper (unsigned long int type, int *errnop)
+{
+  errno = *errnop;
+  unsigned long int result = getauxval (type);
+  *errnop = errno;
+  return result;
+}
diff --git a/elf/tst-auxvalmod.h b/elf/tst-auxvalmod.h
new file mode 100644
index 0000000000..f030326394
--- /dev/null
+++ b/elf/tst-auxvalmod.h
@@ -0,0 +1,23 @@
+/* Wrapper for getauxval testing.
+   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/>.  */
+
+/* Call getauxval, write errno value after the call to ERRNOP, and
+   return the getauxval result.  ERRNOP is needed because across a
+   static dlopen boundary, errno might have a different address, and
+   the caller would never see the intended value.  */
+unsigned long int getauxval_wrapper (unsigned long int type, int *errnop);
diff --git a/elf/tst-getauxval-static.c b/elf/tst-getauxval-static.c
new file mode 100644
index 0000000000..ee5ce54629
--- /dev/null
+++ b/elf/tst-getauxval-static.c
@@ -0,0 +1,54 @@
+/* Test getauxval from a dynamic library after static dlopen.
+   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/>.  */
+
+#include <errno.h>
+#include <support/check.h>
+#include <support/test-driver.h>
+#include <support/xdlfcn.h>
+#include <sys/auxv.h>
+
+#include "tst-auxvalmod.h"
+
+static int
+do_test (void)
+{
+  unsigned long missing_auxv_type;
+  for (missing_auxv_type = 0; ; ++missing_auxv_type)
+    {
+      errno = 0;
+      if (getauxval (missing_auxv_type) == 0 && errno != 0)
+        break;
+    }
+  TEST_COMPARE (errno, ENOENT);
+
+  void *handle = xdlopen ("tst-auxvalmod.so", RTLD_LAZY);
+
+  __typeof__ (getauxval_wrapper) *wrapper
+    = xdlsym (handle, "getauxval_wrapper");
+  int inner_errno = 0;
+  TEST_COMPARE (getauxval (AT_RANDOM), wrapper (AT_RANDOM, &inner_errno));
+
+  inner_errno = 0;
+  TEST_COMPARE (wrapper (missing_auxv_type, &inner_errno), 0);
+  TEST_COMPARE (inner_errno, ENOENT);
+
+  xdlclose (handle);
+  return 0;
+}
+
+#include <support/test-driver.c>
diff --git a/misc/getauxval.c b/misc/getauxval.c
index e96d4dfa20..5820884ad1 100644
--- a/misc/getauxval.c
+++ b/misc/getauxval.c
@@ -19,6 +19,7 @@
 #include <errno.h>
 #include <ldsodefs.h>
 #include <stdbool.h>
+#include <libc-vars.h>
 
 bool
 __getauxval2 (unsigned long int type, unsigned long int *result)
@@ -39,7 +40,7 @@ __getauxval2 (unsigned long int type, unsigned long int *result)
     }
 
 #ifdef HAVE_AUX_VECTOR
-  for (p = GLRO(dl_auxv); p->a_type != AT_NULL; p++)
+  for (p = __libc_vars.auxv; p->a_type != AT_NULL; p++)
     if (p->a_type == type)
       {
         *result = p->a_un.a_val;
diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
index 933cda117d..48837434b5 100644
--- a/sysdeps/generic/ldsodefs.h
+++ b/sysdeps/generic/ldsodefs.h
@@ -575,11 +575,6 @@ struct rtld_global_ro
   EXTERN uint64_t _dl_hwcap_mask;
 #endif
 
-#ifdef HAVE_AUX_VECTOR
-  /* Pointer to the auxv list supplied to the program at startup.  */
-  EXTERN ElfW(auxv_t) *_dl_auxv;
-#endif
-
   /* Get architecture specific definitions.  */
 #include <dl-procinfo.c>
 
diff --git a/sysdeps/generic/libc-vars-cpu.h b/sysdeps/generic/libc-vars-cpu.h
new file mode 100644
index 0000000000..fc9065b195
--- /dev/null
+++ b/sysdeps/generic/libc-vars-cpu.h
@@ -0,0 +1,28 @@
+/* CPU-specific extensions for __libc_vars.  Generic 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/>.  */
+
+#ifndef _LIBC_VARS_CPU_H
+#define _LIBC_VARS_CPU_H
+
+/* The generic version does not have CPU-specific extensions.  */
+#define HAVE_LIBC_VARS_CPU 0
+
+struct libc_vars;
+struct link_map;
+
+#endif /* _LIBC_VARS_CPU_H */
diff --git a/sysdeps/generic/libc-vars-init.h b/sysdeps/generic/libc-vars-init.h
new file mode 100644
index 0000000000..e5cd6ba659
--- /dev/null
+++ b/sysdeps/generic/libc-vars-init.h
@@ -0,0 +1,32 @@
+/* Initialization of __libc_vars.  Generic 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/>.  */
+
+/* This file is included from elf/dl-libc_vars_init.c
+   and elf/dl-call-libc-early-init.c.
+
+   The generic version does not perform any extra initialization.  */
+
+static inline void
+_dl_libc_vars_init_cpu (struct libc_vars *vars)
+{
+}
+
+static inline void
+_dl_call_libc_vars_init_cpu (struct link_map *libc_map)
+{
+}
diff --git a/sysdeps/generic/libc-vars.h b/sysdeps/generic/libc-vars.h
new file mode 100644
index 0000000000..378c51cc82
--- /dev/null
+++ b/sysdeps/generic/libc-vars.h
@@ -0,0 +1,59 @@
+/* Definition of __libc_vars and related update functionality.
+   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/>.  */
+
+#ifndef _LIBC_VARS_H
+#define _LIBC_VARS_H
+
+#include <ldsodefs.h>
+#include <libc-vars-cpu.h>
+#include <link.h>
+#include <stdint.h>
+
+struct libc_vars
+{
+#ifdef HAVE_AUX_VECTOR
+  /* Pointer to the auxv list supplied to the program at startup.  */
+  ElfW (auxv_t) *auxv;
+#endif
+#if HAVE_LIBC_VARS_CPU
+  struct libc_vars_cpu cpu;
+#endif
+};
+
+/* Initialized by ld.so immediate after loading libc.so.6, prior to
+   relocation.  The variable is duplicated in ld.so, where it is set
+   up by the startup code.  It is only exported (under GLIBC_PRIVATE)
+   in libc.so, and this copy is updated in _dl_libc_vars_init.
+
+   In the static case, the initialization has to be put into the
+   startup code, __libc_vars is part of libc.a.  */
+extern struct libc_vars __libc_vars attribute_relro;
+#if IS_IN (libc) || IS_IN (rtld)
+hidden_proto (__libc_vars)
+#endif
+
+/* Called by the dynamic linker to initialize __libc_vars prior to
+   relocation.  This function resides in ld.so, but updates the data
+   in libc.so.  The similar function __libc_early_init resides in
+   libc.so and performs post-relocation initialization.  */
+void _dl_libc_vars_init (struct libc_vars *vars) attribute_hidden;
+
+/* Invoke _dl_libc_vars_init for __libc_vars in LIBC_MAP.  */
+void _dl_call_libc_vars_init (struct link_map *libc_map) attribute_hidden;
+
+#endif /* _LIBC_VARS_H */
diff --git a/sysdeps/unix/sysv/linux/powerpc/dl-static.c b/sysdeps/unix/sysv/linux/powerpc/dl-static.c
index a77e07b503..cab84e5753 100644
--- a/sysdeps/unix/sysv/linux/powerpc/dl-static.c
+++ b/sysdeps/unix/sysv/linux/powerpc/dl-static.c
@@ -23,21 +23,11 @@
 void
 _dl_var_init (void *array[])
 {
-  /* It has to match "variables" below. */
-  enum
-    {
-      DL_PAGESIZE = 0,
-      DL_AUXV = 1,
-      DL_HWCAP = 2,
-      DL_HWCAP2 = 3,
-      DL_CACHE_LINE_SIZE = 4
-    };
-
-  GLRO(dl_pagesize) = *((size_t *) array[DL_PAGESIZE]);
-  GLRO(dl_auxv) = (ElfW(auxv_t) *) *((size_t *) array[DL_AUXV]);
-  GLRO(dl_hwcap)  = *((unsigned long int *) array[DL_HWCAP]);
-  GLRO(dl_hwcap2) = *((unsigned long int *) array[DL_HWCAP2]);
-  GLRO(dl_cache_line_size) = (int) *((int *) array[DL_CACHE_LINE_SIZE]);
+  int index = 0;
+  GLRO(dl_pagesize) = *((size_t *) array[index++]);
+  GLRO(dl_hwcap)  = *((unsigned long int *) array[index++]);
+  GLRO(dl_hwcap2) = *((unsigned long int *) array[index++]);
+  GLRO(dl_cache_line_size) = (int) *((int *) array[index++]);
 }
 
 #else
@@ -45,7 +35,6 @@ _dl_var_init (void *array[])
 static void *variables[] =
 {
   &GLRO(dl_pagesize),
-  &GLRO(dl_auxv),
   &GLRO(dl_hwcap),
   &GLRO(dl_hwcap2),
   &GLRO(dl_cache_line_size)
