diff --git a/csu/libc-start.c b/csu/libc-start.c
index 5b9ce1d158..a2f6e12728 100644
--- a/csu/libc-start.c
+++ b/csu/libc-start.c
@@ -15,6 +15,10 @@
License along with the GNU C Library; if not, see
. */
+/* Mark symbols hidden in static PIE for early self relocation to work. */
+#if BUILD_PIE_DEFAULT
+# pragma GCC visibility push(hidden)
+#endif
#include
#include
#include
diff --git a/elf/dl-reloc-static-pie.c b/elf/dl-reloc-static-pie.c
index a8d964061e..d5bd2f31e9 100644
--- a/elf/dl-reloc-static-pie.c
+++ b/elf/dl-reloc-static-pie.c
@@ -17,6 +17,8 @@
. */
#if ENABLE_STATIC_PIE
+/* Mark symbols hidden in static PIE for early self relocation to work. */
+# pragma GCC visibility push(hidden)
#include
#include
#include "dynamic-link.h"
diff --git a/elf/dl-support.c b/elf/dl-support.c
index 2434c470c7..7abb65d8e3 100644
--- a/elf/dl-support.c
+++ b/elf/dl-support.c
@@ -19,6 +19,12 @@
/* This file defines some things that for the dynamic linker are defined in
rtld.c and dl-sysdep.c in ways appropriate to bootstrap dynamic linking. */
+#include
+/* Mark symbols hidden in static PIE for early self relocation to work.
+ Note: string.h may have ifuncs which cannot be hidden on i686. */
+#if BUILD_PIE_DEFAULT
+# pragma GCC visibility push(hidden)
+#endif
#include
#include
#include
diff --git a/elf/dl-tunables.c b/elf/dl-tunables.c
index e44476f204..b1a50b8469 100644
--- a/elf/dl-tunables.c
+++ b/elf/dl-tunables.c
@@ -18,6 +18,10 @@
License along with the GNU C Library; if not, see
. */
+/* Mark symbols hidden in static PIE for early self relocation to work. */
+#if BUILD_PIE_DEFAULT
+# pragma GCC visibility push(hidden)
+#endif
#include
#include
#include
diff --git a/elf/enbl-secure.c b/elf/enbl-secure.c
index 5dcf649626..9e47526bd3 100644
--- a/elf/enbl-secure.c
+++ b/elf/enbl-secure.c
@@ -19,6 +19,10 @@
/* This file is used in the static libc. For the shared library,
dl-sysdep.c defines and initializes __libc_enable_secure. */
+/* Mark symbols hidden in static PIE for early self relocation to work. */
+#if BUILD_PIE_DEFAULT
+# pragma GCC visibility push(hidden)
+#endif
#include
#include
diff --git a/misc/sbrk.c b/misc/sbrk.c
index 99b3fb517e..95800b32aa 100644
--- a/misc/sbrk.c
+++ b/misc/sbrk.c
@@ -15,6 +15,10 @@
License along with the GNU C Library; if not, see
. */
+/* Mark symbols hidden in static PIE for early self relocation to work. */
+#if BUILD_PIE_DEFAULT
+# pragma GCC visibility push(hidden)
+#endif
#include
#include
#include
diff --git a/sysdeps/unix/sysv/linux/aarch64/libc-start.c b/sysdeps/unix/sysv/linux/aarch64/libc-start.c
index f816f04ee1..e1604a6ed0 100644
--- a/sysdeps/unix/sysv/linux/aarch64/libc-start.c
+++ b/sysdeps/unix/sysv/linux/aarch64/libc-start.c
@@ -17,6 +17,11 @@
. */
#ifndef SHARED
+
+/* Mark symbols hidden in static PIE for early self relocation to work. */
+# if BUILD_PIE_DEFAULT
+# pragma GCC visibility push(hidden)
+# endif
# include
# include
diff --git a/sysdeps/x86/libc-start.c b/sysdeps/x86/libc-start.c
index 4bbd7d555b..d30aec2aa1 100644
--- a/sysdeps/x86/libc-start.c
+++ b/sysdeps/x86/libc-start.c
@@ -16,6 +16,11 @@
. */
#ifndef SHARED
+
+/* Mark symbols hidden in static PIE for early self relocation to work. */
+# if BUILD_PIE_DEFAULT
+# pragma GCC visibility push(hidden)
+# endif
/* Define I386_USE_SYSENTER to support syscall during startup in static
PIE. */
# include