[2/3] Check compiler support for -fno-direct-extern-access

Message ID 20211007200813.1626777-3-hjl.tools@gmail.com
State New
Headers show
Series
  • Update tests for protected symbol access
Related show

Commit Message

Carlos O'Donell via Libc-alpha Oct. 7, 2021, 8:08 p.m.
Compiler with -fno-direct-extern-access does:
1. Generate an indirect external access marker in relocatable objects.
  a. Always use GOT to access undefined data and function symbols,
  including in PIE and non-PIE.  These will avoid copy relocations in
  executables.
  b. This is compatible with existing executables and shared libraries.
2. In executable and shared library, bind symbols with the STV_PROTECTED
   visibility locally:
  a. The address of data symbol is the address of data body.
  b. For systems without function descriptor, the function pointer is
  the address of function body.
  c. The resulting shared libraries may not be incompatible with
   executables which have copy relocations on protected symbols.

Size comparison of non-PIE builds with GCC 12 -O2:

1. On x86-64:
   text	   data	    bss	    dec	    hex	filename
 189958	   9304	    416	 199678	  30bfe	ld.so (original)
 189974	   9304	    416	 199694	  30c0e ld.so (-fno-direct-extern-access)
1922458	  20240	  52432	1995130	 1e717a	libc.so (original)
1922474	  20240	  52432	1995146	 1e718a	libc.so (-fno-direct-extern-access)
  49321	   1363	    192	  50876	   c6bc iconv_prog (original)
  47053	   3638	    120	  50811	   c67b	iconv_prog (-fno-direct-extern-access)
 261978	  10339	    744	 273061	  42aa5	localedef (original)
 233344	  41734	    648	 275726	  4350e	localedef (-fno-direct-extern-access)

The size difference in localedef mainly comes from .data.rel.ro
 .data.rel.ro  0x000005	 (original)
 .data.rel.ro  0x007a88  (-fno-direct-extern-access)

For example, with -fno-direct-extern-access, localedef.o has 172
relocation entries against section '.rela.data.rel.ro.local' vs none
without -fno-direct-extern-access.
---
 configure    | 27 +++++++++++++++++++++++++++
 configure.ac | 16 ++++++++++++++++
 2 files changed, 43 insertions(+)

-- 
2.31.1

Patch

diff --git a/configure b/configure
index ac24218009..fb79301e72 100755
--- a/configure
+++ b/configure
@@ -5851,6 +5851,33 @@  $as_echo "$libc_cv_z_indirect_extern_access" >&6; }
 config_vars="$config_vars
 have-z-indirect-extern-access = $libc_cv_z_indirect_extern_access"
 
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for -fno-direct-extern-access" >&5
+$as_echo_n "checking for -fno-direct-extern-access... " >&6; }
+if ${libc_cv_fno_direct_extern_access+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat > conftest.c <<EOF
+int foo;
+EOF
+		if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS -S
+			-fno-direct-extern-access
+			conftest.c 1>&5'
+  { { 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
+		  libc_cv_fno_direct_extern_access=yes
+		else
+		  libc_cv_fno_direct_extern_access=no
+		fi
+		rm -f conftest*
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_fno_direct_extern_access" >&5
+$as_echo "$libc_cv_fno_direct_extern_access" >&6; }
+config_vars="$config_vars
+have-fno-direct-extern-access = $libc_cv_fno_direct_extern_access"
+
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for broken __attribute__((alias()))" >&5
 $as_echo_n "checking for broken __attribute__((alias()))... " >&6; }
 if ${libc_cv_broken_alias_attribute+:} false; then :
diff --git a/configure.ac b/configure.ac
index 8bb0d1a838..e9f9038f25 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1256,6 +1256,22 @@  EOF
 LIBC_CONFIG_VAR([have-z-indirect-extern-access],
 		[$libc_cv_z_indirect_extern_access])
 
+AC_CACHE_CHECK(for -fno-direct-extern-access,
+	       libc_cv_fno_direct_extern_access,
+	       [cat > conftest.c <<EOF
+int foo;
+EOF
+		if AC_TRY_COMMAND([${CC-cc} $CFLAGS $CPPFLAGS -S
+			-fno-direct-extern-access
+			conftest.c 1>&AS_MESSAGE_LOG_FD]); then
+		  libc_cv_fno_direct_extern_access=yes
+		else
+		  libc_cv_fno_direct_extern_access=no
+		fi
+		rm -f conftest*])
+LIBC_CONFIG_VAR([have-fno-direct-extern-access],
+		[$libc_cv_fno_direct_extern_access])
+
 AC_CACHE_CHECK(for broken __attribute__((alias())),
 	       libc_cv_broken_alias_attribute,
 	       [cat > conftest.c <<EOF