[v3] powerpc64: Enable static-pie

Message ID Yl+0ehkPwzFibcMW@squeak.grove.modra.org
State New
Headers
Series [v3] powerpc64: Enable static-pie |

Checks

Context Check Description
dj/TryBot-apply_patch success Patch applied to master at the time it was sent
dj/TryBot-32bit success Build for i686
redhat-pt-bot/TryBot-still_applies warning Patch no longer applies to master

Commit Message

Alan Modra April 20, 2022, 7:21 a.m. UTC
  On Thu, Apr 14, 2022 at 10:46:14AM +0930, Alan Modra wrote:
> I'll note that static-pie is enabled in glibc without any user
> --enable-static-pie, ie. it is the default if SUPPORT_STATIC_PIE is
> set.  SUPPORT_STATIC_PIE is enabled unconditionally for x86 and
> aarch64 without any toolchain checks, and I foolishly followed that
> precedent.

Conditionally define SUPPORT_STATIC_PIE if binutils-2.33 or later.
The test ifunc results in .iplt relocations, and with a weak reference
to __rela_iplt_start will cause older linkers to generate that symbol.

PI_STATIC_AND_HIDDEN should be OK with the base binutils-2.25.

	* sysdeps/powerpc/powerpc64/configure.ac (SUPPORT_STATIC_PIE): Define.
	(PI_STATIC_AND_HIDDEN): Define.
	* sysdeps/powerpc/powerpc64/configure: Regenerate.

Regression tested powerpc64le-linux.
  

Patch

diff --git a/sysdeps/powerpc/powerpc64/configure b/sysdeps/powerpc/powerpc64/configure
index fddea0355a..0db93080d3 100644
--- a/sysdeps/powerpc/powerpc64/configure
+++ b/sysdeps/powerpc/powerpc64/configure
@@ -1,6 +1,44 @@ 
 # This file is generated from configure.ac by Autoconf.  DO NOT EDIT!
  # Local configure fragment for sysdeps/powerpc/powerpc64.
 
+$as_echo "#define PI_STATIC_AND_HIDDEN 1" >>confdefs.h
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the toolchain supports static-pie" >&5
+$as_echo_n "checking if the toolchain supports static-pie... " >&6; }
+if ${libc_cv_ppc64_static_pie+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+    cat > conftest.c <<EOF
+static long __foo_0 (long x) { return x; }
+static long __foo_1 (long x) { return x; }
+volatile int select;
+typedef long longf (long);
+static longf *foo_ifunc (void) { return select ? __foo_1 : __foo_0; }
+static long __attribute__ ((ifunc ("foo_ifunc"))) foo (long);
+extern const char *__rela_iplt_start __attribute__ ((weak));
+int _start (void) { return foo ((long) __rela_iplt_start); };
+EOF
+  libc_cv_ppc64_static_pie=no
+  if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS -static-pie -nostdlib -nostartfiles -o conftest conftest.c'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then
+        if ! nm conftest | grep -q __rela_iplt; then
+      libc_cv_ppc64_static_pie=yes
+    fi
+  fi
+  rm -rf conftest.*
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_ppc64_static_pie" >&5
+$as_echo "$libc_cv_ppc64_static_pie" >&6; }
+if test x$libc_cv_ppc64_static_pie = xyes; then
+    $as_echo "#define SUPPORT_STATIC_PIE 1" >>confdefs.h
+
+fi
+
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for support for overlapping .opd entries" >&5
 $as_echo_n "checking for support for overlapping .opd entries... " >&6; }
 if ${libc_cv_overlapping_opd+:} false; then :
diff --git a/sysdeps/powerpc/powerpc64/configure.ac b/sysdeps/powerpc/powerpc64/configure.ac
index 1f3d54414c..7de4de871c 100644
--- a/sysdeps/powerpc/powerpc64/configure.ac
+++ b/sysdeps/powerpc/powerpc64/configure.ac
@@ -1,6 +1,37 @@ 
 GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory.
 # Local configure fragment for sysdeps/powerpc/powerpc64.
 
+dnl It is possible to access static and hidden symbols in a position
+dnl independent way requiring no relocation on powerpc64.  The linker
+dnl edits medium and large model code that uses GOT/TOC entries (which
+dnl would require relocation) to r2 relative accesses.
+AC_DEFINE(PI_STATIC_AND_HIDDEN)
+
+AC_CACHE_CHECK(if the toolchain supports static-pie,
+libc_cv_ppc64_static_pie, [dnl
+  cat > conftest.c <<EOF
+static long __foo_0 (long x) { return x; }
+static long __foo_1 (long x) { return x; }
+volatile int select;
+typedef long longf (long);
+static longf *foo_ifunc (void) { return select ? __foo_1 : __foo_0; }
+static long __attribute__ ((ifunc ("foo_ifunc"))) foo (long);
+extern const char *__rela_iplt_start[] __attribute__ ((weak));
+int _start (void) { return foo ((long) __rela_iplt_start); };
+EOF
+  libc_cv_ppc64_static_pie=no
+  if AC_TRY_COMMAND([${CC-cc} $CFLAGS $CPPFLAGS -static-pie -nostdlib -nostartfiles -o conftest conftest.c]); then
+    dnl binutils-2.33 or newer is needed
+    if ! nm conftest | grep -q __rela_iplt; then
+      libc_cv_ppc64_static_pie=yes
+    fi
+  fi
+  rm -rf conftest.*])
+if test x$libc_cv_ppc64_static_pie = xyes; then
+  dnl Static PIE is supported.
+  AC_DEFINE(SUPPORT_STATIC_PIE)
+fi
+
 AC_CACHE_CHECK(for support for overlapping .opd entries,
 libc_cv_overlapping_opd, [dnl
 libc_cv_overlapping_opd=no