[v2,2/4] Check -z indirect-extern-access and -fno-direct-extern-access
Checks
Context |
Check |
Description |
dj/TryBot-apply_patch |
success
|
Patch applied to master at the time it was sent
|
Commit Message
1. Check linker support for -z indirect-extern-access. If
GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS is set on any input
relocatable files:
a. Don't generate copy relocations.
b. Turn off extern_protected_data since it implies
GNU_PROPERTY_NO_COPY_ON_PROTECTED.
c. Treate reference to protected symbols with indirect external access
as local.
d. Set GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS on output.
e. When generating executable, clear this bit when there are non-GOT
or non-PLT relocations in input relocatable files without the bit set.
f. Add -z [no]indirect-extern-access to control indirect external access.
2. Check compiler support for -fno-direct-extern-access:
a. Generate an indirect external access marker in relocatable objects.
i. Always use GOT to access undefined data and function symbols,
including in PIE and non-PIE. These will avoid copy relocations in
executables.
ii. This is compatible with existing executables and shared libraries.
b. In executable and shared library, bind symbols with the STV_PROTECTED
visibility locally:
i. The address of data symbol is the address of data body.
ii. For systems without function descriptor, the function pointer is
the address of function body.
iii. 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 | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++++
configure.ac | 37 ++++++++++++++++++++++++++++++++
2 files changed, 96 insertions(+)
@@ -5746,6 +5746,65 @@ fi
$as_echo "$libc_cv_insert" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking -z indirect-extern-access" >&5
+$as_echo_n "checking -z indirect-extern-access... " >&6; }
+if ${libc_cv_z_indirect_extern_access+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat > conftest.c <<EOF
+ __attribute__ ((visibility ("protected")))
+ void bar (void) {}
+ void *bar_p (void) { return &bar; }
+EOF
+ libc_cv_z_indirect_extern_access=no
+ if { ac_try='${CC-cc} -Wl,-z,indirect-extern-access
+ -nostdlib -nostartfiles $CFLAGS $CPPFLAGS $LDFLAGS
+ -fPIC -shared $no_ssp -o conftest.so 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_z_indirect_extern_access=yes
+ else
+ libc_cv_z_indirect_extern_access=no
+ fi
+ rm -f conftest.*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_z_indirect_extern_access" >&5
+$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 :
@@ -1222,6 +1222,43 @@ EOF
])
AC_SUBST(libc_cv_insert)
+AC_CACHE_CHECK(-z indirect-extern-access,
+ libc_cv_z_indirect_extern_access,
+ [cat > conftest.c <<EOF
+ __attribute__ ((visibility ("protected")))
+ void bar (void) {}
+ void *bar_p (void) { return &bar; }
+EOF
+ libc_cv_z_indirect_extern_access=no
+ if AC_TRY_COMMAND([${CC-cc} -Wl,-z,indirect-extern-access
+ -nostdlib -nostartfiles $CFLAGS $CPPFLAGS $LDFLAGS
+ -fPIC -shared $no_ssp -o conftest.so conftest.c
+ 1>&AS_MESSAGE_LOG_FD]); then
+ libc_cv_z_indirect_extern_access=yes
+ else
+ libc_cv_z_indirect_extern_access=no
+ fi
+ rm -f conftest.*
+ ])
+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