From 6901def689b5c77465d34f07822989ec67e80c1e Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Tue, 24 May 2016 08:44:10 -0700 Subject: Avoid an extra branch to PLT for -z now When --enable-bind-now is used to configure glibc build, we can avoid an extra branch to the PLT entry by using indirect branch via the GOT slot instead, which is similar to the first instructuon in the PLT entry. Changes in the shared library sizes in text sections: Shared library Before (bytes) After (bytes) libm.so 1060813 1060797 libmvec.so 160881 160805 libpthread.so 94992 94984 librt.so 25064 25048 * config.h.in (BIND_NOW): New. * configure.ac (BIND_NOW): New. Defined for --enable-bind-now. * configure: Regenerated. * sysdeps/x86_64/sysdep.h (JUMPTARGET)[BIND_NOW]: Defined to indirect branch via the GOT slot. --- configure.ac | 3 +++ 1 file changed, 3 insertions(+) (limited to 'configure.ac') diff --git a/configure.ac b/configure.ac index 3c766b7409..123f0d26ee 100644 --- a/configure.ac +++ b/configure.ac @@ -231,6 +231,9 @@ AC_ARG_ENABLE([bind-now], [bindnow=$enableval], [bindnow=no]) AC_SUBST(bindnow) +if test "x$bindnow" = xyes; then + AC_DEFINE(BIND_NOW) +fi dnl On some platforms we cannot use dynamic loading. We must provide dnl static NSS modules. -- cgit v1.2.3 From 61655555aa8c2cd5f5351ef7d0aea6dfce046135 Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Tue, 12 Jul 2016 06:29:54 -0700 Subject: x86-64: Properly align stack in _dl_tlsdesc_dynamic [BZ #20309] Since _dl_tlsdesc_dynamic is called via PLT, we need to add 8 bytes for push in the PLT entry to align the stack. [BZ #20309] * configure.ac (have-mtls-dialect-gnu2): Set to yes if -mtls-dialect=gnu2 works. * configure: Regenerated. * elf/Makefile [have-mtls-dialect-gnu2 = yes] (tests): Add tst-gnu2-tls1. (modules-names): Add tst-gnu2-tls1mod. ($(objpfx)tst-gnu2-tls1): New. (tst-gnu2-tls1mod.so-no-z-defs): Likewise. (CFLAGS-tst-gnu2-tls1mod.c): Likewise. * elf/tst-gnu2-tls1.c: New file. * elf/tst-gnu2-tls1mod.c: Likewise. * sysdeps/x86_64/dl-tlsdesc.S (_dl_tlsdesc_dynamic): Add 8 bytes for push in the PLT entry to align the stack. --- ChangeLog | 17 ++++++++++++++ configure | 33 ++++++++++++++++++++++++++ configure.ac | 20 ++++++++++++++++ elf/Makefile | 7 ++++++ elf/tst-gnu2-tls1.c | 52 +++++++++++++++++++++++++++++++++++++++++ elf/tst-gnu2-tls1mod.c | 56 +++++++++++++++++++++++++++++++++++++++++++++ sysdeps/x86_64/dl-tlsdesc.S | 13 ++++++----- 7 files changed, 192 insertions(+), 6 deletions(-) create mode 100644 elf/tst-gnu2-tls1.c create mode 100644 elf/tst-gnu2-tls1mod.c (limited to 'configure.ac') diff --git a/ChangeLog b/ChangeLog index 8ef71cc294..af245d9416 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,20 @@ +2016-07-12 H.J. Lu + + [BZ #20309] + * configure.ac (have-mtls-dialect-gnu2): Set to yes if + -mtls-dialect=gnu2 works. + * configure: Regenerated. + * elf/Makefile [have-mtls-dialect-gnu2 = yes] + (tests): Add tst-gnu2-tls1. + (modules-names): Add tst-gnu2-tls1mod. + ($(objpfx)tst-gnu2-tls1): New. + (tst-gnu2-tls1mod.so-no-z-defs): Likewise. + (CFLAGS-tst-gnu2-tls1mod.c): Likewise. + * elf/tst-gnu2-tls1.c: New file. + * elf/tst-gnu2-tls1mod.c: Likewise. + * sysdeps/x86_64/dl-tlsdesc.S (_dl_tlsdesc_dynamic): Add 8 + bytes for push in the PLT entry to align the stack. + 2016-07-11 H.J. Lu [BZ #20349] diff --git a/configure b/configure index 19a4829466..17625e1041 100755 --- a/configure +++ b/configure @@ -619,6 +619,7 @@ LIBGD libc_cv_cc_loop_to_function libc_cv_cc_submachine libc_cv_cc_nofma +libc_cv_mtls_dialect_gnu2 stack_protector fno_unit_at_a_time libc_cv_output_format @@ -5824,6 +5825,38 @@ elif test "$libc_cv_ssp" = "yes"; then fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for -mtls-dialect=gnu2" >&5 +$as_echo_n "checking for -mtls-dialect=gnu2... " >&6; } +if ${libc_cv_mtls_dialect_gnu2+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat > conftest.c <&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_mtls_dialect_gnu2=yes +else + libc_cv_mtls_dialect_gnu2=no +fi +rm -f conftest* +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_mtls_dialect_gnu2" >&5 +$as_echo "$libc_cv_mtls_dialect_gnu2" >&6; } + +config_vars="$config_vars +have-mtls-dialect-gnu2 = $libc_cv_mtls_dialect_gnu2" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether cc puts quotes around section names" >&5 $as_echo_n "checking whether cc puts quotes around section names... " >&6; } if ${libc_cv_have_section_quotes+:} false; then : diff --git a/configure.ac b/configure.ac index 123f0d26ee..33bcd62180 100644 --- a/configure.ac +++ b/configure.ac @@ -1412,6 +1412,26 @@ elif test "$libc_cv_ssp" = "yes"; then fi AC_SUBST(stack_protector) +AC_CACHE_CHECK([for -mtls-dialect=gnu2], libc_cv_mtls_dialect_gnu2, +[dnl +cat > conftest.c <&AS_MESSAGE_LOG_FD]) +then + libc_cv_mtls_dialect_gnu2=yes +else + libc_cv_mtls_dialect_gnu2=no +fi +rm -f conftest*]) +AC_SUBST(libc_cv_mtls_dialect_gnu2) +LIBC_CONFIG_VAR([have-mtls-dialect-gnu2], [$libc_cv_mtls_dialect_gnu2]) + AC_CACHE_CHECK(whether cc puts quotes around section names, libc_cv_have_section_quotes, [cat > conftest.c <. */ + +#include +#include + +extern int * get_gd (void); +extern void set_gd (int); +extern int test_gd (int); +extern int * get_ld (void); +extern void set_ld (int); +extern int test_ld (int); + +__thread int gd = 1; + +static int +do_test (void) +{ + int *p; + + p = get_gd (); + set_gd (3); + if (*p != 3 || !test_gd (3)) + abort (); + + p = get_ld (); + set_ld (4); + if (*p != 4 || !test_ld (4)) + abort (); + + printf ("PASS\n"); + + return 0; +} + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" diff --git a/elf/tst-gnu2-tls1mod.c b/elf/tst-gnu2-tls1mod.c new file mode 100644 index 0000000000..45c48164b2 --- /dev/null +++ b/elf/tst-gnu2-tls1mod.c @@ -0,0 +1,56 @@ +/* DSO used by tst-gnu2-tls1. + Copyright (C) 2016 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 + . */ + +static __thread int ld; + +int * +get_ld (void) +{ + return &ld; +} + +void +set_ld (int i) +{ + ld = i; +} + +int +test_ld (int i) +{ + return ld == i; +} +extern __thread int gd; + +int * +get_gd (void) +{ + return &gd; +} + +void +set_gd (int i) +{ + gd = i; +} + +int +test_gd (int i) +{ + return gd == i; +} diff --git a/sysdeps/x86_64/dl-tlsdesc.S b/sysdeps/x86_64/dl-tlsdesc.S index 3cb7c3d031..777f30beab 100644 --- a/sysdeps/x86_64/dl-tlsdesc.S +++ b/sysdeps/x86_64/dl-tlsdesc.S @@ -163,14 +163,15 @@ _dl_tlsdesc_dynamic: /* The PLT entry will have pushed the link_map pointer. */ _dl_tlsdesc_resolve_rela: cfi_adjust_cfa_offset (8) - /* Save all call-clobbered registers. */ - subq $72, %rsp - cfi_adjust_cfa_offset (72) + /* Save all call-clobbered registers. Add 8 bytes for push in + the PLT entry to align the stack. */ + subq $80, %rsp + cfi_adjust_cfa_offset (80) movq %rax, (%rsp) movq %rdi, 8(%rsp) movq %rax, %rdi /* Pass tlsdesc* in %rdi. */ movq %rsi, 16(%rsp) - movq 72(%rsp), %rsi /* Pass link_map* in %rsi. */ + movq 80(%rsp), %rsi /* Pass link_map* in %rsi. */ movq %r8, 24(%rsp) movq %r9, 32(%rsp) movq %r10, 40(%rsp) @@ -187,8 +188,8 @@ _dl_tlsdesc_resolve_rela: movq 48(%rsp), %r11 movq 56(%rsp), %rdx movq 64(%rsp), %rcx - addq $80, %rsp - cfi_adjust_cfa_offset (-80) + addq $88, %rsp + cfi_adjust_cfa_offset (-88) jmp *(%rax) cfi_endproc .size _dl_tlsdesc_resolve_rela, .-_dl_tlsdesc_resolve_rela -- cgit v1.2.3 From fc3e1337be1c6935ab58bd13520f97a535cf70cc Mon Sep 17 00:00:00 2001 From: Florian Weimer Date: Wed, 21 Sep 2016 10:45:32 +0200 Subject: Avoid running $(CXX) during build to obtain header file paths This reduces the build time somewhat and is particularly noticeable during rebuilds with few code changes. --- ChangeLog | 9 +++++++++ Makerules | 8 ++------ config.make.in | 2 ++ configure | 14 ++++++++++++++ configure.ac | 12 ++++++++++++ 5 files changed, 39 insertions(+), 6 deletions(-) (limited to 'configure.ac') diff --git a/ChangeLog b/ChangeLog index 71fed8f741..12a217af31 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2016-09-21 Florian Weimer + + Avoid running $(CXX) during build to obtain header file paths. + * configure.ac (CXX_SYSINCLUDES, CXX_CMATH_HEADER): Set. + * config.make.in (c++-cstdlib-header, c++-cmath-header): Define. + * Makerules (cstdlib, cmath): Remove variables. Use + $(c++-cstdlib-header), $(c++-cmath-header) instead. + * configure: Regenerate. + 2016-09-21 Florian Weimer * Makeconfig (all-object-suffixes): Include .op only if diff --git a/Makerules b/Makerules index 748790b591..e865782b43 100644 --- a/Makerules +++ b/Makerules @@ -121,14 +121,10 @@ ifneq (,$(CXX)) # will be used instead of /usr/include/stdlib.h and /usr/include/math.h. before-compile := $(common-objpfx)cstdlib $(common-objpfx)cmath \ $(before-compile) -cstdlib=$(shell echo "\#include " | $(CXX) -M -MP -x c++ - \ - | sed -n "/cstdlib:/{s/:$$//;p}") -$(common-objpfx)cstdlib: $(cstdlib) +$(common-objpfx)cstdlib: $(c++-cstdlib-header) $(INSTALL_DATA) $< $@T $(move-if-change) $@T $@ -cmath=$(shell echo "\#include " | $(CXX) -M -MP -x c++ - \ - | sed -n "/cmath:/{s/:$$//;p}") -$(common-objpfx)cmath: $(cmath) +$(common-objpfx)cmath: $(c++-cmath-header) $(INSTALL_DATA) $< $@T $(move-if-change) $@T $@ endif diff --git a/config.make.in b/config.make.in index 95c6f36876..04a8b3ed7f 100644 --- a/config.make.in +++ b/config.make.in @@ -45,6 +45,8 @@ defines = @DEFINES@ sysheaders = @sysheaders@ sysincludes = @SYSINCLUDES@ c++-sysincludes = @CXX_SYSINCLUDES@ +c++-cstdlib-header = @CXX_CSTDLIB_HEADER@ +c++-cmath-header = @CXX_CMATH_HEADER@ all-warnings = @all_warnings@ enable-werror = @enable_werror@ diff --git a/configure b/configure index 17625e1041..6ff252744b 100755 --- a/configure +++ b/configure @@ -635,6 +635,8 @@ BISON INSTALL_INFO PERL BASH_SHELL +CXX_CMATH_HEADER +CXX_CSTDLIB_HEADER CXX_SYSINCLUDES SYSINCLUDES AUTOCONF @@ -5054,6 +5056,18 @@ fi +# Obtain some C++ header file paths. This is used to make a local +# copy of those headers in Makerules. +if test -n "$CXX"; then + find_cxx_header () { + echo "#include <$1>" | $CXX -M -MP -x c++ - | sed -n "/$1:/{s/:\$//;p}" + } + CXX_CSTDLIB_HEADER="$(find_cxx_header cstdlib)" + CXX_CMATH_HEADER="$(find_cxx_header cmath)" +fi + + + # Test if LD_LIBRARY_PATH contains the notation for the current directory # since this would lead to problems installing/building glibc. # LD_LIBRARY_PATH contains the current directory if one of the following diff --git a/configure.ac b/configure.ac index 33bcd62180..9938ab0dc2 100644 --- a/configure.ac +++ b/configure.ac @@ -1039,6 +1039,18 @@ fi AC_SUBST(SYSINCLUDES) AC_SUBST(CXX_SYSINCLUDES) +# Obtain some C++ header file paths. This is used to make a local +# copy of those headers in Makerules. +if test -n "$CXX"; then + find_cxx_header () { + echo "#include <$1>" | $CXX -M -MP -x c++ - | sed -n "/$1:/{s/:\$//;p}" + } + CXX_CSTDLIB_HEADER="$(find_cxx_header cstdlib)" + CXX_CMATH_HEADER="$(find_cxx_header cmath)" +fi +AC_SUBST(CXX_CSTDLIB_HEADER) +AC_SUBST(CXX_CMATH_HEADER) + # Test if LD_LIBRARY_PATH contains the notation for the current directory # since this would lead to problems installing/building glibc. # LD_LIBRARY_PATH contains the current directory if one of the following -- cgit v1.2.3 From 022dfdce000374b60aadfb0a5ed9a5c4c1dbd29b Mon Sep 17 00:00:00 2001 From: Stefan Liebler Date: Fri, 7 Oct 2016 09:56:46 +0200 Subject: Add configure check to test if gcc supports attribute ifunc. This patch adds a configure check to test if gcc supports attribute ifunc. The support can either be enabled in /gcc/config.gcc for one architecture in general by setting default_gnu_indirect_function variable to yes or by configuring gcc with --enable-gnu-indirect-function. The next patch rewrites libc_ifunc macro to use gcc attribute ifunc instead of inline assembly to generate the IFUNC symbols due to false debuginfo. If gcc does not support attribute ifunc, the old approach for generating ifunc'ed symbols is used. Then the debug-information is false. Thus it is recommended to use a gcc with indirect function support (See notes in INSTALL). After this patch-series these inline assemblies for ifunc-handling are not scattered in multiple files but are used only indirect via ifunc-macros and can simply removed in libc-symbols.h in future. If glibc is configured with --enable-multi-arch and gcc does not support attribute ifunc, a configure warning is dumped! ChangeLog: * config.h.in (HAVE_GCC_IFUNC): New undef. * configure.ac: Add check if gcc supports attribute ifunc feature. * configure: Regenerated. * manual/install.texi: Add recommendation for gcc with indirect-function support. * INSTALL: Regenerated. --- ChangeLog | 9 +++++++++ INSTALL | 9 +++++++++ NEWS | 9 +++++++++ config.h.in | 3 +++ configure | 42 ++++++++++++++++++++++++++++++++++++++++++ configure.ac | 33 +++++++++++++++++++++++++++++++++ manual/install.texi | 8 ++++++++ 7 files changed, 113 insertions(+) (limited to 'configure.ac') diff --git a/ChangeLog b/ChangeLog index 437667385a..bc0c75c3d1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2016-10-07 Stefan Liebler + + * config.h.in (HAVE_GCC_IFUNC): New undef. + * configure.ac: Add check if gcc supports attribute ifunc feature. + * configure: Regenerated. + * manual/install.texi: Add recommendation for gcc with + indirect-function support. + * INSTALL: Regenerated. + 2016-10-06 Joseph Myers * math/math.h [__GLIBC_USE (IEC_60559_BFP_EXT)] (iseqsig): New diff --git a/INSTALL b/INSTALL index 51f26bf962..b5acedcc96 100644 --- a/INSTALL +++ b/INSTALL @@ -359,6 +359,15 @@ build the GNU C Library: better code. As of release time, GCC 5.3 is the newest compiler verified to work to build the GNU C Library. + For multi-arch support it is recommended to use a GCC which has + been built with support for GNU indirect functions. This ensures + that correct debugging information is generated for functions + selected by IFUNC resolvers. This support can either be enabled by + configuring GCC with '--enable-gnu-indirect-function', or by + enabling it by default by setting 'default_gnu_indirect_function' + variable for a particular architecture in the GCC source file + 'gcc/config.gcc'. + You can use whatever compiler you like to compile programs that use the GNU C Library. diff --git a/NEWS b/NEWS index b5894afce3..b077d0a078 100644 --- a/NEWS +++ b/NEWS @@ -76,6 +76,15 @@ Version 2.25 The glibc stub resolver did not support these hooks, but the header file did not reflect that. +* For multi-arch support it is recommended to use a GCC which has + been built with support for GNU indirect functions. This ensures + that correct debugging information is generated for functions + selected by IFUNC resolvers. This support can either be enabled by + configuring GCC with '--enable-gnu-indirect-function', or by + enabling it by default by setting 'default_gnu_indirect_function' + variable for a particular architecture in the GCC source file + 'gcc/config.gcc'. + Security related changes: On ARM EABI (32-bit), generating a backtrace for execution contexts which diff --git a/config.h.in b/config.h.in index 8cd08b0e89..33757bd553 100644 --- a/config.h.in +++ b/config.h.in @@ -174,6 +174,9 @@ /* Define to 1 if STT_GNU_IFUNC support actually works. */ #define HAVE_IFUNC 0 +/* Define if gcc supports attribute ifunc. */ +#undef HAVE_GCC_IFUNC + /* Define if the linker defines __ehdr_start. */ #undef HAVE_EHDR_START diff --git a/configure b/configure index 6ff252744b..e80e0ad56c 100755 --- a/configure +++ b/configure @@ -3916,6 +3916,36 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_ld_gnu_indirect_function" >&5 $as_echo "$libc_cv_ld_gnu_indirect_function" >&6; } +# Check if gcc supports attribute ifunc as it is used in libc_ifunc macro. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for gcc attribute ifunc support" >&5 +$as_echo_n "checking for gcc attribute ifunc support... " >&6; } +if ${libc_cv_gcc_indirect_function+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat > conftest.c <&5 \ + 2>&5 ; then + if $READELF -s conftest.o | grep IFUNC >/dev/null 2>&5; then + libc_cv_gcc_indirect_function=yes + fi +fi +rm -f conftest* +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_gcc_indirect_function" >&5 +$as_echo "$libc_cv_gcc_indirect_function" >&6; } + if test x"$libc_cv_ld_gnu_indirect_function" != xyes; then if test x"$multi_arch" = xyes; then as_fn_error $? "--enable-multi-arch support requires assembler and linker support" "$LINENO" 5 @@ -3923,6 +3953,13 @@ if test x"$libc_cv_ld_gnu_indirect_function" != xyes; then multi_arch=no fi fi +if test x"$libc_cv_gcc_indirect_function" != xyes && + test x"$multi_arch" = xyes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: --enable-multi-arch support recommends a gcc with gnu-indirect-function support. +Please use a gcc which supports it by default or configure gcc with --enable-gnu-indirect-function" >&5 +$as_echo "$as_me: WARNING: --enable-multi-arch support recommends a gcc with gnu-indirect-function support. +Please use a gcc which supports it by default or configure gcc with --enable-gnu-indirect-function" >&2;} +fi multi_arch_d= if test x"$multi_arch" != xno; then multi_arch_d=/multiarch @@ -6518,6 +6555,11 @@ if test x"$libc_cv_ld_gnu_indirect_function" = xyes; then fi +if test x"$libc_cv_gcc_indirect_function" = xyes; then + $as_echo "#define HAVE_GCC_IFUNC 1" >>confdefs.h + +fi + # This is far from the AC_ARG_ENABLE that sets it so that a sysdeps # configure fragment can override the value to prevent this AC_DEFINE. diff --git a/configure.ac b/configure.ac index 9938ab0dc2..a64aeb9979 100644 --- a/configure.ac +++ b/configure.ac @@ -634,6 +634,30 @@ if ${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS \ fi rm -f conftest*]) +# Check if gcc supports attribute ifunc as it is used in libc_ifunc macro. +AC_CACHE_CHECK([for gcc attribute ifunc support], + libc_cv_gcc_indirect_function, [dnl +cat > conftest.c <&AS_MESSAGE_LOG_FD \ + 2>&AS_MESSAGE_LOG_FD ; then + if $READELF -s conftest.o | grep IFUNC >/dev/null 2>&AS_MESSAGE_LOG_FD; then + libc_cv_gcc_indirect_function=yes + fi +fi +rm -f conftest*]) + if test x"$libc_cv_ld_gnu_indirect_function" != xyes; then if test x"$multi_arch" = xyes; then AC_MSG_ERROR([--enable-multi-arch support requires assembler and linker support]) @@ -641,6 +665,11 @@ if test x"$libc_cv_ld_gnu_indirect_function" != xyes; then multi_arch=no fi fi +if test x"$libc_cv_gcc_indirect_function" != xyes && + test x"$multi_arch" = xyes; then + AC_MSG_WARN([--enable-multi-arch support recommends a gcc with gnu-indirect-function support. +Please use a gcc which supports it by default or configure gcc with --enable-gnu-indirect-function]) +fi multi_arch_d= if test x"$multi_arch" != xno; then multi_arch_d=/multiarch @@ -1782,6 +1811,10 @@ if test x"$libc_cv_ld_gnu_indirect_function" = xyes; then AC_DEFINE(HAVE_IFUNC) fi +if test x"$libc_cv_gcc_indirect_function" = xyes; then + AC_DEFINE(HAVE_GCC_IFUNC) +fi + # This is far from the AC_ARG_ENABLE that sets it so that a sysdeps # configure fragment can override the value to prevent this AC_DEFINE. AC_SUBST(use_nscd) diff --git a/manual/install.texi b/manual/install.texi index 663f8d59fb..de1c2030d3 100644 --- a/manual/install.texi +++ b/manual/install.texi @@ -402,6 +402,14 @@ the newest version of the compiler that is known to work for building release time, GCC 5.3 is the newest compiler verified to work to build @theglibc{}. +For multi-arch support it is recommended to use a GCC which has been built with +support for GNU indirect functions. This ensures that correct debugging +information is generated for functions selected by IFUNC resolvers. This +support can either be enabled by configuring GCC with +@samp{--enable-gnu-indirect-function}, or by enabling it by default by setting +@samp{default_gnu_indirect_function} variable for a particular architecture in +the GCC source file @file{gcc/config.gcc}. + You can use whatever compiler you like to compile programs that use @theglibc{}. -- cgit v1.2.3 From c7409aded44634411a19b0b7178b7faa237835e6 Mon Sep 17 00:00:00 2001 From: Denis Kaganovich Date: Thu, 20 Oct 2016 22:01:39 +0200 Subject: configure: accept __stack_chk_fail_local for ssp support too [BZ #20662] When glibc is compiled with gcc 6.2 that has been configured with --enable-default-pie and --enable-default-ssp, the configure script fails to detect that the compiler has ssp turned on by default when being built for i686-linux-gnu. This is because gcc is emitting __stack_chk_fail_local but the script is only looking for __stack_chk_fail. Support both. Example output: checking whether x86_64-pc-linux-gnu-gcc -m32 -Wl,-O1 -Wl,--as-needed implicitly enables -fstack-protector... no --- ChangeLog | 9 +++++++++ configure | 8 +++++--- configure.ac | 8 +++++--- 3 files changed, 19 insertions(+), 6 deletions(-) (limited to 'configure.ac') diff --git a/ChangeLog b/ChangeLog index e88b7603ed..7b7c5115a1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2016-10-20 Denis Kaganovich + Magnus Granberg + Mike Frysinger + + [BZ #20662] + * configure.ac (libc_cv_predef_stack_protector): Also check for + __stack_chk_fail_local symbols. + * configure: Regenerated. + 2016-11-15 Florian Weimer * sysdeps/s390/s390-64/setjmp.S (NEED_COMPAT_SYMBOLS): New macro. diff --git a/configure b/configure index e80e0ad56c..d9f8c06bca 100755 --- a/configure +++ b/configure @@ -6340,12 +6340,14 @@ echo >&5 "libc_undefs='$libc_undefs'" # symbols (resolved by the linker), so filter out unknown symbols. # This will fail to produce the correct result if the compiler # defaults to -fstack-protector but this produces an undefined symbol -# other than __stack_chk_fail. However, compilers like that have not -# been encountered in practice. -libc_undefs=`echo "$libc_undefs" | egrep '^(foobar|__stack_chk_fail)$'` +# other than __stack_chk_fail or __stack_chk_fail_local. However, +# compilers like that have not been encountered in practice. +libc_undefs=`echo "$libc_undefs" | \ + egrep '^(foobar|__stack_chk_fail|__stack_chk_fail_local)$'` case "$libc_undefs" in foobar) libc_cv_predef_stack_protector=no ;; '__stack_chk_fail +foobar'|'__stack_chk_fail_local foobar') libc_cv_predef_stack_protector=yes ;; *) as_fn_error $? "unexpected symbols in test: $libc_undefs" "$LINENO" 5 ;; esac diff --git a/configure.ac b/configure.ac index a64aeb9979..de0a40f1a7 100644 --- a/configure.ac +++ b/configure.ac @@ -1667,12 +1667,14 @@ echo >&AS_MESSAGE_LOG_FD "libc_undefs='$libc_undefs'" # symbols (resolved by the linker), so filter out unknown symbols. # This will fail to produce the correct result if the compiler # defaults to -fstack-protector but this produces an undefined symbol -# other than __stack_chk_fail. However, compilers like that have not -# been encountered in practice. -libc_undefs=`echo "$libc_undefs" | egrep '^(foobar|__stack_chk_fail)$'` +# other than __stack_chk_fail or __stack_chk_fail_local. However, +# compilers like that have not been encountered in practice. +libc_undefs=`echo "$libc_undefs" | \ + egrep '^(foobar|__stack_chk_fail|__stack_chk_fail_local)$'` case "$libc_undefs" in foobar) libc_cv_predef_stack_protector=no ;; '__stack_chk_fail +foobar'|'__stack_chk_fail_local foobar') libc_cv_predef_stack_protector=yes ;; *) AC_MSG_ERROR([unexpected symbols in test: $libc_undefs]) ;; esac], -- cgit v1.2.3 From 84aa75162cd5ba73caa76864496fadd2551a5caa Mon Sep 17 00:00:00 2001 From: Carlos O'Donell Date: Fri, 2 Dec 2016 15:39:09 -0500 Subject: Bug 20918 - Building with --enable-nss-crypt fails tst-linkall-static Some configurations may use NSS cryptographic routines but have no static library for those routines. The following changes allow glibc to be built and tested with --enable-nss-crypt, but without having a static NSS library. At a high level the change does two things: (1) Detect at configure time if static NSS crypto libraries are available. Assumes libfreebl3.a (instead of the existing Fedora libfreebl.a which is incomplete) which matches libfreebl3.so. (2) If static NSS crypto libraries are _not_ available then adjust the way in which we build tst-linkall-static. This includes excluding a reference to crypt and not linking against libcrypt.a, all of which will fail otherwise. Testing assumptions: * Static library is named libfreebl3.a (not libfreebl.a as is currently provided in Fedora), matching libfreebl3.so shared link name. Tested on x86_64 on Fedora with: (a) --enable-nss-crypt, with no static NSS library support: PASS (previous FAIL) (b) --enable-nss-crypt, with faked static NSS library support: PASS (unsupported) * Requires changing elf/Makefile to include a stub /lib64/libfreebl3.a for testing purposes. (c) --disable-nss-crypt: PASS (default) No regressions on x86_64. For details see: https://www.sourceware.org/ml/libc-alpha/2016-11/msg00647.html --- ChangeLog | 16 ++++++++++++++++ config.make.in | 1 + configure | 29 +++++++++++++++++++++++++++++ configure.ac | 14 ++++++++++++++ elf/Makefile | 32 ++++++++++++++++++++++++++++++-- elf/tst-linkall-static.c | 2 ++ 6 files changed, 92 insertions(+), 2 deletions(-) (limited to 'configure.ac') diff --git a/ChangeLog b/ChangeLog index 95b5c7eb1a..e4a41d6a3c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,19 @@ +2016-12-02 Carlos O'Donell + + [BZ #20918] + * configure.ac: Test for static NSS cryptographic libraries and set + libc_cv_static_nss_crypt. + * configure: Regenerate. + * config.make.in (static-nss-crypt): Define. + * elf/Makefile (CFLAGS-tst-linkall-static.c): Define. + [ifeq (yesno,$(nss-crypt)$(static-nss-crypt))] + (CFLAGS-tst-linkall-static.c): Define. + ($(objpfx)tst-linkall-static): Remove libcrypt.a. + [ifeq (yesyes,$(nss-crypt)$(static-nss-crypt))] + ($(objpfx)tst-linkall-static): Define. + [ifeq (no,$(nss-crypt))] ($(objpfx)tst-linkall-static): Define. + * elf/tst-linkall-static.c [USE_CRYPT](references): Reference crypt(). + 2016-12-02 Florian Weimer * elf/Makefile [build-shared] (tests): Add tst-latepthread. diff --git a/config.make.in b/config.make.in index 04a8b3ed7f..d2d9b8ab36 100644 --- a/config.make.in +++ b/config.make.in @@ -75,6 +75,7 @@ multi-arch = @multi_arch@ mach-interface-list = @mach_interface_list@ nss-crypt = @libc_cv_nss_crypt@ +static-nss-crypt = @libc_cv_static_nss_crypt@ # Configuration options. build-shared = @shared@ diff --git a/configure b/configure index d9f8c06bca..5cf3230b56 100755 --- a/configure +++ b/configure @@ -665,6 +665,7 @@ add_ons build_pt_chown build_nscd link_obsolete_rpc +libc_cv_static_nss_crypt libc_cv_nss_crypt enable_werror all_warnings @@ -3529,6 +3530,7 @@ cannot find NSS headers with lowlevel hash function interfaces" "$LINENO" 5 fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext old_LIBS="$LIBS" + old_LDFLAGS="$LDFLAGS" LIBS="$LIBS -lfreebl3" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -3551,14 +3553,41 @@ cannot link program using lowlevel NSS hash functions" "$LINENO" 5 fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext + # Check to see if there is a static NSS cryptographic library. + # If there isn't then we can't link anything with libcrypt.a, + # and that might mean disabling some static tests. + LDFLAGS="$LDFLAGS -static" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +typedef int PRBool; +#include +#include +int +main () +{ +NSSLOW_Init(); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + libc_cv_static_nss_crypt=yes +else + libc_cv_static_nss_crypt=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS="$old_LDFLAGS" CFLAGS="$old_CFLAGS" LIBS="$old_LIBS" else libc_cv_nss_crypt=no + libc_cv_static_nss_crypt=no fi + # Check whether --enable-obsolete-rpc was given. if test "${enable_obsolete_rpc+set}" = set; then : enableval=$enable_obsolete_rpc; link_obsolete_rpc=$enableval diff --git a/configure.ac b/configure.ac index de0a40f1a7..d719fadeef 100644 --- a/configure.ac +++ b/configure.ac @@ -321,6 +321,7 @@ void f (void) { NSSLOW_Init (); }])], AC_MSG_ERROR([ cannot find NSS headers with lowlevel hash function interfaces])) old_LIBS="$LIBS" + old_LDFLAGS="$LDFLAGS" LIBS="$LIBS -lfreebl3" AC_LINK_IFELSE([AC_LANG_PROGRAM([typedef int PRBool; #include @@ -329,12 +330,25 @@ cannot find NSS headers with lowlevel hash function interfaces])) libc_cv_nss_crypt=yes, AC_MSG_ERROR([ cannot link program using lowlevel NSS hash functions])) + # Check to see if there is a static NSS cryptographic library. + # If there isn't then we can't link anything with libcrypt.a, + # and that might mean disabling some static tests. + LDFLAGS="$LDFLAGS -static" + AC_LINK_IFELSE([AC_LANG_PROGRAM([typedef int PRBool; +#include +#include ], + [NSSLOW_Init();])], + libc_cv_static_nss_crypt=yes, + libc_cv_static_nss_crypt=no) + LDFLAGS="$old_LDFLAGS" CFLAGS="$old_CFLAGS" LIBS="$old_LIBS" else libc_cv_nss_crypt=no + libc_cv_static_nss_crypt=no fi AC_SUBST(libc_cv_nss_crypt) +AC_SUBST(libc_cv_static_nss_crypt) AC_ARG_ENABLE([obsolete-rpc], diff --git a/elf/Makefile b/elf/Makefile index ebdcbc6ff4..f57927f403 100644 --- a/elf/Makefile +++ b/elf/Makefile @@ -337,6 +337,16 @@ $(objpfx)tst-_dl_addr_inside_object: $(objpfx)dl-addr-obj.os CFLAGS-tst-_dl_addr_inside_object.c += $(PIE-ccflag) endif +# By default tst-linkall-static should try to use crypt routines to test +# static libcrypt use. +CFLAGS-tst-linkall-static.c = -DUSE_CRYPT=1 +# However, if we are using NSS crypto and we don't have a static +# library, then we exclude the use of crypt functions in the test. +# We similarly exclude libcrypt.a from the static link (see below). +ifeq (yesno,$(nss-crypt)$(static-nss-crypt)) +CFLAGS-tst-linkall-static.c = -DUSE_CRYPT=0 +endif + include ../Rules ifeq (yes,$(build-shared)) @@ -1307,12 +1317,30 @@ $(objpfx)tst-ldconfig-X.out : tst-ldconfig-X.sh $(objpfx)ldconfig $(objpfx)tst-dlsym-error: $(libdl) +# Test static linking of all the libraries we can possibly link +# together. Note that in some configurations this may be less than the +# complete list of libraries we build but we try to maxmimize this list. $(objpfx)tst-linkall-static: \ $(common-objpfx)math/libm.a \ - $(common-objpfx)crypt/libcrypt.a \ $(common-objpfx)resolv/libresolv.a \ $(common-objpfx)dlfcn/libdl.a \ $(common-objpfx)login/libutil.a \ $(common-objpfx)rt/librt.a \ $(common-objpfx)resolv/libanl.a \ - $(static-thread-library) \ + $(static-thread-library) + +# If we are using NSS crypto and we have the ability to link statically +# then we include libcrypt.a, otherwise we leave out libcrypt.a and +# link as much as we can into the tst-linkall-static test. This assumes +# that linking with libcrypt.a does everything required to include the +# static NSS crypto library. +ifeq (yesyes,$(nss-crypt)$(static-nss-crypt)) +$(objpfx)tst-linkall-static: \ + $(common-objpfx)crypt/libcrypt.a +endif +# If we are not using NSS crypto then we always have the ability to link +# with libcrypt.a. +ifeq (no,$(nss-crypt)) +$(objpfx)tst-linkall-static: \ + $(common-objpfx)crypt/libcrypt.a +endif diff --git a/elf/tst-linkall-static.c b/elf/tst-linkall-static.c index 7a4aaccf58..cc77f0788e 100644 --- a/elf/tst-linkall-static.c +++ b/elf/tst-linkall-static.c @@ -32,7 +32,9 @@ void *references[] = { &pow, /* libm */ &pthread_create, /* libpthread */ +#if USE_CRYPT &crypt, /* libcrypt */ +#endif &res_send, /* libresolv */ &dlopen, /* libdl */ &login, /* libutil */ -- cgit v1.2.3 From 8ce8299f9458c7fee8554ecd4b97cc5eddba4e4c Mon Sep 17 00:00:00 2001 From: Siddhesh Poyarekar Date: Thu, 22 Dec 2016 23:07:52 +0530 Subject: Add configure check for python program Add a configure check that looks for python3 and python in that order since we had agreed in the past to prefer python3 over python in all our code. The patch also adjusts invocations through the various Makefiles to use the set variable. * configure.ac: Check for python3 or python. * configure: Regenerated. * config.make.in (PYTHON): New variable. * benchtests/Makefile: Don't define PYTHON. (bench): Define target only if PYTHON was defined. * Rules: Don't define PYTHON. Define pretty printer targets only if PYTHON was defined. (tests-printers): Add to tests-unsupported if PYTHON is not found. (python-flags, python-invoke): Remove. (tests-printers-out): Use PYTHON instead of python-invoke. --- ChangeLog | 14 ++++++++++++ Rules | 24 ++++++++++----------- benchtests/Makefile | 10 +++++++-- config.make.in | 1 + configure | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++-- configure.ac | 16 +++++++++++++- 6 files changed, 109 insertions(+), 18 deletions(-) (limited to 'configure.ac') diff --git a/ChangeLog b/ChangeLog index 4f86f7a8cf..1fcd9eda10 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2016-12-22 Siddhesh Poyarekar + + * configure.ac: Check for python3 or python. + * configure: Regenerated. + * config.make.in (PYTHON): New variable. + * benchtests/Makefile: Don't define PYTHON. + (bench): Define target only if PYTHON was defined. + * Rules: Don't define PYTHON. + Define pretty printer targets only if PYTHON was defined. + (tests-printers): Add to tests-unsupported if PYTHON is not + found. + (python-flags, python-invoke): Remove. + (tests-printers-out): Use PYTHON instead of python-invoke. + 2016-12-21 Joseph Myers [BZ #20978] diff --git a/Rules b/Rules index fe18ce55de..558924d653 100644 --- a/Rules +++ b/Rules @@ -114,6 +114,11 @@ tests-printers-programs := $(addprefix $(objpfx),$(tests-printers)) # .out files with the output of running the pretty printer tests. tests-printers-out := $(patsubst %,$(objpfx)%.out,$(tests-printers)) +ifndef PYTHON +# Mark tests-printers tests as unsupported if we don't have PYTHON. +tests-unsupported += $(tests-printers) +endif + ifeq ($(build-programs),yes) others: $(addprefix $(objpfx),$(others) $(sysdep-others) $(extra-objs)) else @@ -124,9 +129,9 @@ endif others: $(py-const) ifeq ($(run-built-tests),no) -tests: $(addprefix $(objpfx),$(filter-out $(tests-unsupported),$(tests)) \ - $(test-srcs)) $(tests-special) \ - $(tests-printers-programs) +tests: $(addprefix $(objpfx),$(filter-out $(tests-unsupported),$(tests) \ + $(tests-printers-programs)) \ + $(test-srcs)) $(tests-special) xtests: tests $(xtests-special) else tests: $(tests:%=$(objpfx)%.out) $(tests-special) $(tests-printers-out) @@ -255,16 +260,8 @@ endif endif # tests +ifdef PYTHON ifneq "$(strip $(tests-printers))" "" -# We're defining this here for now; later it'll be defined at configure time -# inside Makeconfig. -PYTHON := python - -# Invoke Python using -B to avoid generating .pyc files on the source dir, -# so that we can keep it read-only. -python-flags := -B - -python-invoke := $(PYTHON) $(python-flags) # Static pattern rule for building the test programs for the pretty printers. $(tests-printers-programs): %: %.o $(tests-printers-libs) \ @@ -283,9 +280,10 @@ py-env := PYTHONPATH=$(py-const-dir):$(..)scripts:$${PYTHONPATH} $(tests-printers-out): $(objpfx)%.out: $(objpfx)% %.py %.c $(pretty-printers) \ $(..)scripts/test_printers_common.py $(test-wrapper-env) $(py-env) \ - $(python-invoke) $*.py $*.c $(objpfx)$* $(pretty-printers) > $@; \ + $(PYTHON) $*.py $*.c $(objpfx)$* $(pretty-printers) > $@; \ $(evaluate-test) endif +endif .PHONY: distclean realclean subdir_distclean subdir_realclean \ diff --git a/benchtests/Makefile b/benchtests/Makefile index f5d6dac6c7..9eef1e1243 100644 --- a/benchtests/Makefile +++ b/benchtests/Makefile @@ -18,8 +18,6 @@ # Makefile for benchmark tests. The only useful target here is `bench`. # Add benchmark functions in alphabetical order. -PYTHON := python - subdir := benchtests include ../Makeconfig @@ -146,7 +144,15 @@ bench-clean: rm -f $(timing-type) $(addsuffix .o,$(timing-type)) rm -f $(addprefix $(objpfx),$(bench-extra-objs)) +# Define the bench target only if the target has a usable python installation. +ifdef PYTHON bench: bench-build bench-set bench-func bench-malloc +else +bench: + @echo "The bench target needs python to run." + @exit 1 +endif + # Target to only build the benchmark without running it. We generate locales # only if we're building natively. ifeq (no,$(cross-compiling)) diff --git a/config.make.in b/config.make.in index d2d9b8ab36..35e7e59663 100644 --- a/config.make.in +++ b/config.make.in @@ -126,6 +126,7 @@ MSGFMT = @MSGFMT@ BASH = @BASH_SHELL@ AWK = @AWK@ PERL = @PERL@ +PYTHON = @PYTHON@ # Additional libraries. LIBGD = @LIBGD@ diff --git a/configure b/configure index 5cf3230b56..10b0fb7069 100755 --- a/configure +++ b/configure @@ -639,6 +639,8 @@ CXX_CMATH_HEADER CXX_CSTDLIB_HEADER CXX_SYSINCLUDES SYSINCLUDES +PYTHON +PYTHON_PROG AUTOCONF NM AWK @@ -5086,17 +5088,73 @@ else AUTOCONF=no fi +# Check for python3 if available, or else python. +for ac_prog in python3 python +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_PYTHON_PROG+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$PYTHON_PROG"; then + ac_cv_prog_PYTHON_PROG="$PYTHON_PROG" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_PYTHON_PROG="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +PYTHON_PROG=$ac_cv_prog_PYTHON_PROG +if test -n "$PYTHON_PROG"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PYTHON_PROG" >&5 +$as_echo "$PYTHON_PROG" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$PYTHON_PROG" && break +done +test -n "$PYTHON_PROG" || PYTHON_PROG="no" + +case "x$PYTHON_PROG" in +xno|x|x:) PYTHON_PROG=no ;; +*) ;; +esac + +if test "x$PYTHON_PROG" = xno; then + aux_missing="$aux_missing python" +else + PYTHON="$PYTHON_PROG -B" + +fi + test -n "$critic_missing" && as_fn_error $? " *** These critical programs are missing or too old:$critic_missing *** Check the INSTALL file for required versions." "$LINENO" 5 test -n "$aux_missing" && { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: *** These auxiliary programs are missing or incompatible versions:$aux_missing -*** some features will be disabled. +*** some features or tests will be disabled. *** Check the INSTALL file for required versions." >&5 $as_echo "$as_me: WARNING: *** These auxiliary programs are missing or incompatible versions:$aux_missing -*** some features will be disabled. +*** some features or tests will be disabled. *** Check the INSTALL file for required versions." >&2;} # if using special system headers, find out the compiler's sekrit diff --git a/configure.ac b/configure.ac index d719fadeef..aa6e2d7e56 100644 --- a/configure.ac +++ b/configure.ac @@ -1050,13 +1050,27 @@ else AUTOCONF=no fi +# Check for python3 if available, or else python. +AC_CHECK_PROGS(PYTHON_PROG, python3 python,no) +case "x$PYTHON_PROG" in +xno|x|x:) PYTHON_PROG=no ;; +*) ;; +esac + +if test "x$PYTHON_PROG" = xno; then + aux_missing="$aux_missing python" +else + PYTHON="$PYTHON_PROG -B" + AC_SUBST(PYTHON) +fi + test -n "$critic_missing" && AC_MSG_ERROR([ *** These critical programs are missing or too old:$critic_missing *** Check the INSTALL file for required versions.]) test -n "$aux_missing" && AC_MSG_WARN([ *** These auxiliary programs are missing or incompatible versions:$aux_missing -*** some features will be disabled. +*** some features or tests will be disabled. *** Check the INSTALL file for required versions.]) # if using special system headers, find out the compiler's sekrit -- cgit v1.2.3 From 03baef1c9cfb396d76cae20a00aee657871e79c4 Mon Sep 17 00:00:00 2001 From: Nick Alcock Date: Mon, 26 Dec 2016 10:08:18 +0100 Subject: Configure support for --enable-stack-protector [BZ #7065] This adds =all and =strong, with obvious semantics, defaulting to off. We don't validate the value of the option yet: that's in a later patch. Nor do we use it for anything at this stage. We differentiate between 'the compiler understands -fstack-protector' and 'the user wanted -fstack-protector' so that we can pass -fno-stack-protector in appropriate places even if the user didn't want to turn on -fstack-protector for other parts. (This helps us overcome another existing limitation, that glibc doesn't work with GCCs hacked to pass in -fstack-protector by default.) We also arrange to set the STACK_PROTECTOR_LEVEL #define to a value appropriate for the stack-protection level in use for each file in particular. --- ChangeLog | 13 +++++ INSTALL | 11 ++++ config.h.in | 6 +++ configure | 151 +++++++++++++++++++++++++++++++++++----------------- configure.ac | 70 +++++++++++++++++------- manual/install.texi | 11 ++++ 6 files changed, 193 insertions(+), 69 deletions(-) (limited to 'configure.ac') diff --git a/ChangeLog b/ChangeLog index 0dd96f2d0f..f1b95e0e79 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2016-12-26 Nick Alcock + + [BZ #7065] + * configure.ac (libc_cv_ssp): Move up. + (libc_cv_ssp_strong): Likewise. + (libc_cv_ssp_all): New. + (stack_protector): Augment, adding -fstack-protector-all. + (no_stack_protector): New. + (STACK_PROTECTOR_LEVEL): New. + (AC_ARG_ENABLE(stack-protector)): New configure flag. + * manual/install.texi (--enable-stack-protector): Document it. + * config.h.in (STACK_PROTECTOR_LEVEL): New macro. + 2016-12-24 Carlos O'Donell * README.pretty-printers: Must specify CPPFLAGS-* also. diff --git a/INSTALL b/INSTALL index acb622a102..104f36b0bf 100644 --- a/INSTALL +++ b/INSTALL @@ -135,6 +135,17 @@ will be used, and CFLAGS sets optimization options for the compiler. '--enable-lock-elision=yes' Enable lock elision for pthread mutexes by default. +'--enable-stack-protector' +'--enable-stack-protector=strong' +'--enable-stack-protector=all' + Compile the C library and all other parts of the glibc package + (including the threading and math libraries, NSS modules, and + transliteration modules) using the GCC '-fstack-protector', + '-fstack-protector-strong' or '-fstack-protector-all' options to + detect stack overruns. Only the dynamic linker and a small number + of routines called directly from assembler are excluded from this + protection. + '--enable-pt_chown' The file 'pt_chown' is a helper binary for 'grantpt' (*note Pseudo-Terminals: Allocation.) that is installed setuid root to fix diff --git a/config.h.in b/config.h.in index 33757bd553..d96ce0f8cf 100644 --- a/config.h.in +++ b/config.h.in @@ -48,6 +48,12 @@ /* Define if compiler accepts -ftree-loop-distribute-patterns. */ #undef HAVE_CC_INHIBIT_LOOP_TO_LIBCALL +/* The level of stack protection in use for glibc as a whole. + May be overridden on a file-by-file basis. */ +#ifndef STACK_PROTECTOR_LEVEL +#undef STACK_PROTECTOR_LEVEL +#endif + /* Define if the regparm attribute shall be used for local functions (gcc on ix86 only). */ #undef USE_REGPARMS diff --git a/configure b/configure index 10b0fb7069..8c69f09232 100755 --- a/configure +++ b/configure @@ -620,7 +620,6 @@ libc_cv_cc_loop_to_function libc_cv_cc_submachine libc_cv_cc_nofma libc_cv_mtls_dialect_gnu2 -stack_protector fno_unit_at_a_time libc_cv_output_format libc_cv_has_glob_dat @@ -661,6 +660,9 @@ sysdeps_add_ons sysnames submachine multi_arch +no_stack_protector +stack_protector +libc_cv_ssp base_machine add_on_subdirs add_ons @@ -766,6 +768,7 @@ enable_lock_elision enable_add_ons enable_hidden_plt enable_bind_now +enable_stack_protector enable_static_nss enable_force_install enable_maintainer_mode @@ -1427,6 +1430,9 @@ Optional Features: for add-ons if no parameter given --disable-hidden-plt do not hide internal function calls to avoid PLT --enable-bind-now disable lazy relocations in DSOs + --enable-stack-protector=[yes|no|all|strong] + Use -fstack-protector[-all|-strong] to detect glibc + buffer overflows --enable-static-nss build static NSS modules [default=no] --disable-force-install don't force installation of files from this package, even if they are older than the installed files @@ -3427,6 +3433,18 @@ if test "x$bindnow" = xyes; then fi +# Check whether --enable-stack-protector was given. +if test "${enable_stack_protector+set}" = set; then : + enableval=$enable_stack_protector; enable_stack_protector=$enableval +else + enable_stack_protector=no +fi + +case "$enable_stack_protector" in +all|yes|no|strong) ;; +*) as_fn_error $? "Not a valid argument for --enable-stack-protector: \"$enable_stack_protector\"" "$LINENO" 5;; +esac + # Check whether --enable-static-nss was given. if test "${enable_static_nss+set}" = set; then : enableval=$enable_static_nss; static_nss=$enableval @@ -3912,6 +3930,89 @@ fi test -n "$base_machine" || base_machine=$machine +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for -fstack-protector" >&5 +$as_echo_n "checking for -fstack-protector... " >&6; } +if ${libc_cv_ssp+:} false; then : + $as_echo_n "(cached) " >&6 +else + if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS -Werror -fstack-protector -xc /dev/null -S -o /dev/null' + { { 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_ssp=yes +else + libc_cv_ssp=no +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_ssp" >&5 +$as_echo "$libc_cv_ssp" >&6; } + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for -fstack-protector-strong" >&5 +$as_echo_n "checking for -fstack-protector-strong... " >&6; } +if ${libc_cv_ssp_strong+:} false; then : + $as_echo_n "(cached) " >&6 +else + if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS -Werror -fstack-protector-strong -xc /dev/null -S -o /dev/null' + { { 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_ssp_strong=yes +else + libc_cv_ssp_strong=no +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_ssp_strong" >&5 +$as_echo "$libc_cv_ssp_strong" >&6; } + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for -fstack-protector-all" >&5 +$as_echo_n "checking for -fstack-protector-all... " >&6; } +if ${libc_cv_ssp_all+:} false; then : + $as_echo_n "(cached) " >&6 +else + if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS -Werror -fstack-protector-all -xc /dev/null -S -o /dev/null' + { { 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_ssp_all=yes +else + libc_cv_ssp_all=no +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_ssp_all" >&5 +$as_echo "$libc_cv_ssp_all" >&6; } + +stack_protector= +no_stack_protector= +if test "$libc_cv_ssp" = yes; then + no_stack_protector="-fno-stack-protector -DSTACK_PROTECTOR_LEVEL=0" +fi + +if test "$enable_stack_protector" = yes && test "$libc_cv_ssp" = yes; then + stack_protector="-fstack-protector" + $as_echo "#define STACK_PROTECTOR_LEVEL 1" >>confdefs.h + +elif test "$enable_stack_protector" = all && test "$libc_cv_ssp_all" = yes; then + stack_protector="-fstack-protector-all" + $as_echo "#define STACK_PROTECTOR_LEVEL 2" >>confdefs.h + +elif test "$enable_stack_protector" = strong && test "$libc_cv_ssp_strong" = yes; then + stack_protector="-fstack-protector-strong" + $as_echo "#define STACK_PROTECTOR_LEVEL 3" >>confdefs.h + +fi + + + + # For the multi-arch option we need support in the assembler & linker. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for assembler and linker STT_GNU_IFUNC support" >&5 $as_echo_n "checking for assembler and linker STT_GNU_IFUNC support... " >&6; } @@ -5915,54 +6016,6 @@ else fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for -fstack-protector" >&5 -$as_echo_n "checking for -fstack-protector... " >&6; } -if ${libc_cv_ssp+:} false; then : - $as_echo_n "(cached) " >&6 -else - if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS -Werror -fstack-protector -xc /dev/null -S -o /dev/null' - { { 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_ssp=yes -else - libc_cv_ssp=no -fi - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_ssp" >&5 -$as_echo "$libc_cv_ssp" >&6; } - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for -fstack-protector-strong" >&5 -$as_echo_n "checking for -fstack-protector-strong... " >&6; } -if ${libc_cv_ssp_strong+:} false; then : - $as_echo_n "(cached) " >&6 -else - if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS -Werror -fstack-protector-strong -xc /dev/null -S -o /dev/null' - { { 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_ssp_strong=yes -else - libc_cv_ssp_strong=no -fi - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_ssp_strong" >&5 -$as_echo "$libc_cv_ssp_strong" >&6; } - -stack_protector= -if test "$libc_cv_ssp_strong" = "yes"; then - stack_protector="-fstack-protector-strong" -elif test "$libc_cv_ssp" = "yes"; then - stack_protector="-fstack-protector" -fi - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -mtls-dialect=gnu2" >&5 $as_echo_n "checking for -mtls-dialect=gnu2... " >&6; } if ${libc_cv_mtls_dialect_gnu2+:} false; then : diff --git a/configure.ac b/configure.ac index aa6e2d7e56..c159768984 100644 --- a/configure.ac +++ b/configure.ac @@ -235,6 +235,18 @@ if test "x$bindnow" = xyes; then AC_DEFINE(BIND_NOW) fi +dnl Build glibc with -fstack-protector, -fstack-protector-all, or +dnl -fstack-protector-strong. +AC_ARG_ENABLE([stack-protector], + AC_HELP_STRING([--enable-stack-protector=@<:@yes|no|all|strong@:>@], + [Use -fstack-protector[-all|-strong] to detect glibc buffer overflows]), + [enable_stack_protector=$enableval], + [enable_stack_protector=no]) +case "$enable_stack_protector" in +all|yes|no|strong) ;; +*) AC_MSG_ERROR([Not a valid argument for --enable-stack-protector: \"$enable_stack_protector\"]);; +esac + dnl On some platforms we cannot use dynamic loading. We must provide dnl static NSS modules. AC_ARG_ENABLE([static-nss], @@ -619,6 +631,44 @@ fi test -n "$base_machine" || base_machine=$machine AC_SUBST(base_machine) +AC_CACHE_CHECK(for -fstack-protector, libc_cv_ssp, [dnl +LIBC_TRY_CC_OPTION([$CFLAGS $CPPFLAGS -Werror -fstack-protector], + [libc_cv_ssp=yes], + [libc_cv_ssp=no]) +]) + +AC_CACHE_CHECK(for -fstack-protector-strong, libc_cv_ssp_strong, [dnl +LIBC_TRY_CC_OPTION([$CFLAGS $CPPFLAGS -Werror -fstack-protector-strong], + [libc_cv_ssp_strong=yes], + [libc_cv_ssp_strong=no]) +]) + +AC_CACHE_CHECK(for -fstack-protector-all, libc_cv_ssp_all, [dnl +LIBC_TRY_CC_OPTION([$CFLAGS $CPPFLAGS -Werror -fstack-protector-all], + [libc_cv_ssp_all=yes], + [libc_cv_ssp_all=no]) +]) + +stack_protector= +no_stack_protector= +if test "$libc_cv_ssp" = yes; then + no_stack_protector="-fno-stack-protector -DSTACK_PROTECTOR_LEVEL=0" +fi + +if test "$enable_stack_protector" = yes && test "$libc_cv_ssp" = yes; then + stack_protector="-fstack-protector" + AC_DEFINE(STACK_PROTECTOR_LEVEL, 1) +elif test "$enable_stack_protector" = all && test "$libc_cv_ssp_all" = yes; then + stack_protector="-fstack-protector-all" + AC_DEFINE(STACK_PROTECTOR_LEVEL, 2) +elif test "$enable_stack_protector" = strong && test "$libc_cv_ssp_strong" = yes; then + stack_protector="-fstack-protector-strong" + AC_DEFINE(STACK_PROTECTOR_LEVEL, 3) +fi +AC_SUBST(libc_cv_ssp) +AC_SUBST(stack_protector) +AC_SUBST(no_stack_protector) + # For the multi-arch option we need support in the assembler & linker. AC_CACHE_CHECK([for assembler and linker STT_GNU_IFUNC support], libc_cv_ld_gnu_indirect_function, [dnl @@ -1461,26 +1511,6 @@ else fi AC_SUBST(fno_unit_at_a_time) -AC_CACHE_CHECK(for -fstack-protector, libc_cv_ssp, [dnl -LIBC_TRY_CC_OPTION([$CFLAGS $CPPFLAGS -Werror -fstack-protector], - [libc_cv_ssp=yes], - [libc_cv_ssp=no]) -]) - -AC_CACHE_CHECK(for -fstack-protector-strong, libc_cv_ssp_strong, [dnl -LIBC_TRY_CC_OPTION([$CFLAGS $CPPFLAGS -Werror -fstack-protector-strong], - [libc_cv_ssp_strong=yes], - [libc_cv_ssp_strong=no]) -]) - -stack_protector= -if test "$libc_cv_ssp_strong" = "yes"; then - stack_protector="-fstack-protector-strong" -elif test "$libc_cv_ssp" = "yes"; then - stack_protector="-fstack-protector" -fi -AC_SUBST(stack_protector) - AC_CACHE_CHECK([for -mtls-dialect=gnu2], libc_cv_mtls_dialect_gnu2, [dnl cat > conftest.c < Date: Mon, 26 Dec 2016 10:08:41 +0100 Subject: Do not stack-protect ifunc resolvers [BZ #7065] When dynamically linking, ifunc resolvers are called before TLS is initialized, so they cannot be safely stack-protected. We avoid disabling stack-protection on large numbers of files by using __attribute__ ((__optimize__ ("-fno-stack-protector"))) to turn it off just for the resolvers themselves. (We provide the attribute even when statically linking, because we will later use it elsewhere too.) --- ChangeLog | 25 +++++++++++++++++++++++++ config.h.in | 4 ++++ configure | 2 ++ configure.ac | 1 + elf/ifuncdep2.c | 3 +++ elf/ifuncmain6pie.c | 1 + elf/ifuncmain7.c | 1 + elf/ifuncmod1.c | 3 +++ elf/ifuncmod5.c | 3 +++ include/libc-symbols.h | 12 +++++++++++- sysdeps/generic/ifunc-sel.h | 2 ++ sysdeps/nacl/nacl_interface_query.c | 1 + sysdeps/powerpc/ifunc-sel.h | 2 ++ sysdeps/unix/make-syscalls.sh | 1 + sysdeps/unix/sysv/linux/x86_64/x32/getcpu.c | 1 + sysdeps/x86_64/ifuncmod8.c | 1 + 16 files changed, 62 insertions(+), 1 deletion(-) (limited to 'configure.ac') diff --git a/ChangeLog b/ChangeLog index f17669931b..395a14ba4d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,28 @@ +2016-12-26 Nick Alcock + + [BZ #7065] + * configure.ac (HAVE_CC_NO_STACK_PROTECTOR): Define. + * config.h.in (HAVE_CC_NO_STACK_PROTECTOR): New macro. + * include/libc-symbols.h (inhibit_stack_protector): New macro. + (__ifunc_resolver): Use it. + * elf/ifuncdep2.c (foo1_ifunc, foo2_ifunc, foo3_ifunc): Apply + inhibit_stack_protector. + * elf/ifuncmain6pie.c (foo_ifunc): Likewise. + * elf/ifuncmain7.c (foo_ifunc): Likewise. + * elf/ifuncmod1.c (foo_ifunc, foo_hidden_ifunc) + (foo_protected_ifunc): Likewise. + * elf/ifuncmod5.c (foo_ifunc, foo_hidden_ifunc) + (foo_protected_ifunc): Likewise. + * sysdeps/generic/ifunc-sel.h (ifunc_sel, ifunc_one): Likewise. + * sysdeps/nacl/nacl_interface_query.c + (nacl_interface_query_ifunc): Likewise. + * sysdeps/powerpc/ifunc-sel.h (ifunc_sel, ifunc_one): Likewise. + * sysdeps/unix/sysv/linux/x86_64/x32/getcpu.c (getcpu_ifunc): + Likewise. + * sysdeps/x86_64/ifuncmod8.c (foo_ifunc): Likewise. + * sysdeps/unix/make-syscalls.sh: Apply inhibit_stack_protector to + the generated vDSO syscall resolver. + 2016-12-26 Nick Alcock Florian Weimer diff --git a/config.h.in b/config.h.in index d96ce0f8cf..82f95a6dbd 100644 --- a/config.h.in +++ b/config.h.in @@ -48,6 +48,10 @@ /* Define if compiler accepts -ftree-loop-distribute-patterns. */ #undef HAVE_CC_INHIBIT_LOOP_TO_LIBCALL +/* Define if compiler accepts -fno-stack-protector in an + __attribute__ ((__optimize__)). */ +#undef HAVE_CC_NO_STACK_PROTECTOR + /* The level of stack protection in use for glibc as a whole. May be overridden on a file-by-file basis. */ #ifndef STACK_PROTECTOR_LEVEL diff --git a/configure b/configure index 8c69f09232..b3007953ea 100755 --- a/configure +++ b/configure @@ -3994,6 +3994,8 @@ stack_protector= no_stack_protector= if test "$libc_cv_ssp" = yes; then no_stack_protector="-fno-stack-protector -DSTACK_PROTECTOR_LEVEL=0" + $as_echo "#define HAVE_CC_NO_STACK_PROTECTOR 1" >>confdefs.h + fi if test "$enable_stack_protector" = yes && test "$libc_cv_ssp" = yes; then diff --git a/configure.ac b/configure.ac index c159768984..f5fa1aaefa 100644 --- a/configure.ac +++ b/configure.ac @@ -653,6 +653,7 @@ stack_protector= no_stack_protector= if test "$libc_cv_ssp" = yes; then no_stack_protector="-fno-stack-protector -DSTACK_PROTECTOR_LEVEL=0" + AC_DEFINE(HAVE_CC_NO_STACK_PROTECTOR) fi if test "$enable_stack_protector" = yes && test "$libc_cv_ssp" = yes; then diff --git a/elf/ifuncdep2.c b/elf/ifuncdep2.c index 6e66d318a6..d87d61d5be 100644 --- a/elf/ifuncdep2.c +++ b/elf/ifuncdep2.c @@ -32,6 +32,7 @@ void * foo1_ifunc (void) __asm__ ("foo1"); __asm__(".type foo1, %gnu_indirect_function"); void * +inhibit_stack_protector foo1_ifunc (void) { return ifunc_sel (one, minus_one, zero); @@ -41,6 +42,7 @@ void * foo2_ifunc (void) __asm__ ("foo2"); __asm__(".type foo2, %gnu_indirect_function"); void * +inhibit_stack_protector foo2_ifunc (void) { return ifunc_sel (minus_one, one, zero); @@ -50,6 +52,7 @@ void * foo3_ifunc (void) __asm__ ("foo3"); __asm__(".type foo3, %gnu_indirect_function"); void * +inhibit_stack_protector foo3_ifunc (void) { return ifunc_sel (one, zero, minus_one); diff --git a/elf/ifuncmain6pie.c b/elf/ifuncmain6pie.c index 8478d4c408..04faeb86ef 100644 --- a/elf/ifuncmain6pie.c +++ b/elf/ifuncmain6pie.c @@ -21,6 +21,7 @@ void * foo_ifunc (void) __asm__ ("foo"); __asm__(".type foo, %gnu_indirect_function"); void * +inhibit_stack_protector foo_ifunc (void) { return ifunc_one (one); diff --git a/elf/ifuncmain7.c b/elf/ifuncmain7.c index 617a596d5e..1e8f7ea38e 100644 --- a/elf/ifuncmain7.c +++ b/elf/ifuncmain7.c @@ -20,6 +20,7 @@ __asm__(".type foo, %gnu_indirect_function"); static void * __attribute__ ((used)) +inhibit_stack_protector foo_ifunc (void) { return ifunc_one (one); diff --git a/elf/ifuncmod1.c b/elf/ifuncmod1.c index 0b6138056d..f0bf5fb45f 100644 --- a/elf/ifuncmod1.c +++ b/elf/ifuncmod1.c @@ -36,6 +36,7 @@ void * foo_ifunc (void) __asm__ ("foo"); __asm__(".type foo, %gnu_indirect_function"); void * +inhibit_stack_protector foo_ifunc (void) { return ifunc_sel (one, minus_one, zero); @@ -45,6 +46,7 @@ void * foo_hidden_ifunc (void) __asm__ ("foo_hidden"); __asm__(".type foo_hidden, %gnu_indirect_function"); void * +inhibit_stack_protector foo_hidden_ifunc (void) { return ifunc_sel (minus_one, one, zero); @@ -54,6 +56,7 @@ void * foo_protected_ifunc (void) __asm__ ("foo_protected"); __asm__(".type foo_protected, %gnu_indirect_function"); void * +inhibit_stack_protector foo_protected_ifunc (void) { return ifunc_sel (one, zero, minus_one); diff --git a/elf/ifuncmod5.c b/elf/ifuncmod5.c index 0e65a63691..5a957800e8 100644 --- a/elf/ifuncmod5.c +++ b/elf/ifuncmod5.c @@ -31,6 +31,7 @@ void * foo_ifunc (void) __asm__ ("foo"); __asm__(".type foo, %gnu_indirect_function"); void * +inhibit_stack_protector foo_ifunc (void) { return ifunc_sel (one, minus_one, zero); @@ -40,6 +41,7 @@ void * foo_hidden_ifunc (void) __asm__ ("foo_hidden"); __asm__(".type foo_hidden, %gnu_indirect_function"); void * +inhibit_stack_protector foo_hidden_ifunc (void) { return ifunc_sel (minus_one, one, zero); @@ -49,6 +51,7 @@ void * foo_protected_ifunc (void) __asm__ ("foo_protected"); __asm__(".type foo_protected, %gnu_indirect_function"); void * +inhibit_stack_protector foo_protected_ifunc (void) { return ifunc_sel (one, zero, minus_one); diff --git a/include/libc-symbols.h b/include/libc-symbols.h index 4238d7930b..d981e67343 100644 --- a/include/libc-symbols.h +++ b/include/libc-symbols.h @@ -336,6 +336,16 @@ for linking") #define attribute_relro __attribute__ ((section (".data.rel.ro"))) + +/* Used to disable stack protection in sensitive places, like ifunc + resolvers and early static TLS init. */ +#ifdef HAVE_CC_NO_STACK_PROTECTOR +# define inhibit_stack_protector \ + __attribute__ ((__optimize__ ("-fno-stack-protector"))) +#else +# define inhibit_stack_protector +#endif + /* The following macros are used for PLT bypassing within libc.so (and if needed other libraries similarly). First of all, you need to have the function prototyped somewhere, @@ -737,7 +747,7 @@ for linking") /* Helper / base macros for indirect function symbols. */ #define __ifunc_resolver(type_name, name, expr, arg, init, classifier) \ - classifier void *name##_ifunc (arg) \ + classifier inhibit_stack_protector void *name##_ifunc (arg) \ { \ init (); \ __typeof (type_name) *res = expr; \ diff --git a/sysdeps/generic/ifunc-sel.h b/sysdeps/generic/ifunc-sel.h index 6a27b69c5b..1fff4059cc 100644 --- a/sysdeps/generic/ifunc-sel.h +++ b/sysdeps/generic/ifunc-sel.h @@ -5,6 +5,7 @@ extern int global; static inline void * +inhibit_stack_protector ifunc_sel (int (*f1) (void), int (*f2) (void), int (*f3) (void)) { switch (global) @@ -19,6 +20,7 @@ ifunc_sel (int (*f1) (void), int (*f2) (void), int (*f3) (void)) } static inline void * +inhibit_stack_protector ifunc_one (int (*f1) (void)) { return f1; diff --git a/sysdeps/nacl/nacl_interface_query.c b/sysdeps/nacl/nacl_interface_query.c index adf1dd4c02..dbaa88b037 100644 --- a/sysdeps/nacl/nacl_interface_query.c +++ b/sysdeps/nacl/nacl_interface_query.c @@ -29,6 +29,7 @@ extern TYPE_nacl_irt_query nacl_interface_query_ifunc (void) asm ("nacl_interface_query"); TYPE_nacl_irt_query +inhibit_stack_protector nacl_interface_query_ifunc (void) { return &__nacl_irt_query; diff --git a/sysdeps/powerpc/ifunc-sel.h b/sysdeps/powerpc/ifunc-sel.h index ac589bd3c0..bdb00bf2c6 100644 --- a/sysdeps/powerpc/ifunc-sel.h +++ b/sysdeps/powerpc/ifunc-sel.h @@ -5,6 +5,7 @@ extern int global; static inline void * +inhibit_stack_protector ifunc_sel (int (*f1) (void), int (*f2) (void), int (*f3) (void)) { register void *ret __asm__ ("r3"); @@ -32,6 +33,7 @@ ifunc_sel (int (*f1) (void), int (*f2) (void), int (*f3) (void)) } static inline void * +inhibit_stack_protector ifunc_one (int (*f1) (void)) { register void *ret __asm__ ("r3"); diff --git a/sysdeps/unix/make-syscalls.sh b/sysdeps/unix/make-syscalls.sh index 58d165e015..123553c1d9 100644 --- a/sysdeps/unix/make-syscalls.sh +++ b/sysdeps/unix/make-syscalls.sh @@ -287,6 +287,7 @@ while read file srcfile caller syscall args strong weak; do (echo '#include '; \\ echo 'extern void *${strong}_ifunc (void) __asm ("${strong}");'; \\ echo 'void *'; \\ + echo 'inhibit_stack_protector'; \\ echo '${strong}_ifunc (void)'; \\ echo '{'; \\ echo ' PREPARE_VERSION_KNOWN (symver, ${vdso_symver});'; \\ diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/getcpu.c b/sysdeps/unix/sysv/linux/x86_64/x32/getcpu.c index cbac4b3273..8436f9db93 100644 --- a/sysdeps/unix/sysv/linux/x86_64/x32/getcpu.c +++ b/sysdeps/unix/sysv/linux/x86_64/x32/getcpu.c @@ -21,6 +21,7 @@ void *getcpu_ifunc (void) __asm__ ("__getcpu"); void * +inhibit_stack_protector getcpu_ifunc (void) { PREPARE_VERSION (linux26, "LINUX_2.6", 61765110); diff --git a/sysdeps/x86_64/ifuncmod8.c b/sysdeps/x86_64/ifuncmod8.c index c00436799c..7c065622be 100644 --- a/sysdeps/x86_64/ifuncmod8.c +++ b/sysdeps/x86_64/ifuncmod8.c @@ -28,6 +28,7 @@ foo_impl (float x) } void * +inhibit_stack_protector foo_ifunc (void) { __m128i xmm = _mm_set1_epi32 (-1); -- cgit v1.2.3 From 66a704c43cfec810fea67a6959f2d1c94f4d594f Mon Sep 17 00:00:00 2001 From: Nick Alcock Date: Mon, 26 Dec 2016 10:08:54 +0100 Subject: Work even with compilers which enable -fstack-protector by default [BZ #7065] With all the machinery we just added, we can easily arrange to work even when the compiler passes in -fstack-protector automatically: all the necessary bits of glibc are always compiled with -fno-stack-protector now. So tear out the check in configure, and add appropriate calls to -fno-stack-protector in tests that need them (largely those that use -nostdlib), since we don't yet have a __stack_chk_fail that those tests can rely upon. (GCC often provides one, but we cannot rely on this, especially not when bootstrapping.) When stack protection is disabled, explicitly pass -fno-stack-protector to everything, to stop a compiler hacked to enable it from inserting calls to __stack_chk_fail via the PLT in every object file. --- ChangeLog | 21 ++++++++++++++ aclocal.m4 | 6 ++-- configure | 90 +++++++++++++++++------------------------------------------- configure.ac | 75 ++++++++++++++++---------------------------------- 4 files changed, 73 insertions(+), 119 deletions(-) (limited to 'configure.ac') diff --git a/ChangeLog b/ChangeLog index ae58d91110..5e3e64a3da 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,24 @@ +2016-12-26 Nick Alcock + + [BZ #7065] + * configure.ac: Add check for unsupported stack-protection level. + (libc_cv_predef_stack_protector): Remove. + (no_ssp): New variable. + (STACK_PROTECTOR_LEVEL): Set to zero when --disable-stack-protector. + (stack_protector): Set to -fno-stack-protector similarly. + (libc_cv_ld_gnu_indirect_function): Use no_ssp. + (libc_cv_asm_set_directive): Likewise. + (libc_cv_protected_data): Likewise. + (libc_cv_z_combreloc): Likewise. + (libc_cv_hashstyle): Likewise. + (libc_cv_has_glob_dat): Likewise. + (libc_cv_output_format): Likewise. + (libc_cv_output_format): Likewise. + (libc_cv_ehdr_start): Likewise. + * aclocal.m4 (LIBC_TRY_LINK_STATIC): Likewise. + (LIBC_LINKER_FEATURE): Likewise. + (LIBC_COMPILER_BUILTIN_INLINED): Likewise. + 2016-12-26 Nick Alcock [BZ #7065] diff --git a/aclocal.m4 b/aclocal.m4 index 3d64f7773d..69021558af 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -141,7 +141,7 @@ int _start (void) { return 0; } int __start (void) { return 0; } $1 EOF -AS_IF([AC_TRY_COMMAND([${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS -o conftest +AS_IF([AC_TRY_COMMAND([${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS $no_ssp -o conftest conftest.c -static -nostartfiles -nostdlib 1>&AS_MESSAGE_LOG_FD])], [$2], [$3]) @@ -226,7 +226,7 @@ if test x"$gnu_ld" = x"yes"; then cat > conftest.c <&AS_MESSAGE_LOG_FD]) @@ -268,7 +268,7 @@ libc_compiler_builtin_inlined=no cat > conftest.c <&AS_MESSAGE_LOG_FD]) diff --git a/configure b/configure index b3007953ea..c88f6fe88c 100755 --- a/configure +++ b/configure @@ -4010,11 +4010,25 @@ elif test "$enable_stack_protector" = strong && test "$libc_cv_ssp_strong" = yes stack_protector="-fstack-protector-strong" $as_echo "#define STACK_PROTECTOR_LEVEL 3" >>confdefs.h +else + stack_protector="-fno-stack-protector" + $as_echo "#define STACK_PROTECTOR_LEVEL 0" >>confdefs.h + fi +if test -n "$stack_protector"; then + no_ssp=-fno-stack-protector +else + no_ssp= + + if test "$enable_stack_protector" != no; then + as_fn_error $? "--enable-stack-protector=$enable_stack_protector specified, but specified level of stack protection is not supported by the compiler." "$LINENO" 5 + fi +fi + # For the multi-arch option we need support in the assembler & linker. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for assembler and linker STT_GNU_IFUNC support" >&5 $as_echo_n "checking for assembler and linker STT_GNU_IFUNC support... " >&6; } @@ -4037,7 +4051,7 @@ __start: EOF libc_cv_ld_gnu_indirect_function=no if ${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS \ - -nostartfiles -nostdlib \ + -nostartfiles -nostdlib $no_ssp \ -o conftest conftest.S 1>&5 2>&5; then # Do a link to see if the backend supports IFUNC relocs. $READELF -r conftest 1>&5 @@ -5532,7 +5546,7 @@ extern int glibc_conftest_frobozz; void _start() { glibc_conftest_frobozz = 1; } EOF if ${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS \ - -nostartfiles -nostdlib \ + -nostartfiles -nostdlib $no_ssp \ -o conftest conftest.s conftest1.c 1>&5 2>&5; then libc_cv_asm_set_directive=yes else @@ -5556,7 +5570,7 @@ else int bar __attribute__ ((visibility ("protected"))) = 1; EOF libc_cv_protected_data=no - if { ac_try='${CC-cc} -nostdlib -nostartfiles -fPIC -shared conftest.c -o conftest.so' + if { ac_try='${CC-cc} -nostdlib -nostartfiles $no_ssp -fPIC -shared conftest.c -o conftest.so' { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -5566,7 +5580,7 @@ EOF extern int bar; int main (void) { return bar; } EOF - if { ac_try='${CC-cc} -nostdlib -nostartfiles conftest.c -o conftest conftest.so' + if { ac_try='${CC-cc} -nostdlib -nostartfiles $no_ssp conftest.c -o conftest conftest.so' { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -5651,7 +5665,7 @@ __attribute__ ((constructor)) void ctor (void) { asm (""); } __attribute__ ((destructor)) void dtor (void) { asm (""); } EOF -if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS -o conftest +if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS $no_ssp -o conftest conftest.c -static -nostartfiles -nostdlib 1>&5' { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5 @@ -5764,7 +5778,7 @@ extern int mumble; int foo (void) { return bar (mumble); } EOF if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS - -fPIC -shared -o conftest.so conftest.c + -fPIC -shared $no_ssp -o conftest.so conftest.c -nostdlib -nostartfiles -Wl,-z,combreloc 1>&5' { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5 @@ -5800,7 +5814,7 @@ if test x"$gnu_ld" = x"yes"; then cat > conftest.c <&5' @@ -5854,7 +5868,7 @@ else cat > conftest.c <&5' { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5 @@ -5947,7 +5961,7 @@ int foo (void) { return mumble; } EOF if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS -fPIC -shared -o conftest.so conftest.c - -nostdlib -nostartfiles + -nostdlib -nostartfiles $no_ssp 1>&5' { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5 (eval $ac_try) 2>&5 @@ -5975,7 +5989,7 @@ if ${libc_cv_output_format+:} false; then : $as_echo_n "(cached) " >&6 else if libc_cv_output_format=` -${CC-cc} -nostartfiles -nostdlib -Wl,--print-output-format 2>&5` +${CC-cc} -nostartfiles -nostdlib $no_ssp -Wl,--print-output-format 2>&5` then : else @@ -6453,60 +6467,6 @@ if test $libc_cv_predef_fortify_source = yes; then fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC implicitly enables -fstack-protector" >&5 -$as_echo_n "checking whether $CC implicitly enables -fstack-protector... " >&6; } -if ${libc_cv_predef_stack_protector+:} false; then : - $as_echo_n "(cached) " >&6 -else - -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -extern void foobar (char *); -int -main () -{ -char large_array[2048]; foobar (large_array); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - -libc_undefs=`$NM -u conftest.o | - LC_ALL=C $AWK '$1 == "U" { print $2 | "sort -u"; next } { exit(1) }' \ - 2>&5` || { - as_fn_error $? "confusing output from $NM -u" "$LINENO" 5 -} -echo >&5 "libc_undefs='$libc_undefs'" -# On some architectures, there are architecture-specific undefined -# symbols (resolved by the linker), so filter out unknown symbols. -# This will fail to produce the correct result if the compiler -# defaults to -fstack-protector but this produces an undefined symbol -# other than __stack_chk_fail or __stack_chk_fail_local. However, -# compilers like that have not been encountered in practice. -libc_undefs=`echo "$libc_undefs" | \ - egrep '^(foobar|__stack_chk_fail|__stack_chk_fail_local)$'` -case "$libc_undefs" in -foobar) libc_cv_predef_stack_protector=no ;; -'__stack_chk_fail -foobar'|'__stack_chk_fail_local -foobar') libc_cv_predef_stack_protector=yes ;; -*) as_fn_error $? "unexpected symbols in test: $libc_undefs" "$LINENO" 5 ;; -esac -else - as_fn_error $? "test compilation failed" "$LINENO" 5 -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_predef_stack_protector" >&5 -$as_echo "$libc_cv_predef_stack_protector" >&6; } -libc_extra_cflags= -if test $libc_cv_predef_stack_protector = yes; then - libc_extra_cflags="$libc_extra_cflags -fno-stack-protector" -fi -libc_extra_cppflags= - # Some linkers on some architectures support __ehdr_start but with # bugs. Make sure usage of it does not create relocations in the # output (as the linker should resolve them all for us). @@ -6520,7 +6480,7 @@ old_CFLAGS="$CFLAGS" old_LDFLAGS="$LDFLAGS" old_LIBS="$LIBS" CFLAGS="$CFLAGS -fPIC" -LDFLAGS="$LDFLAGS -nostdlib -nostartfiles -shared" +LDFLAGS="$LDFLAGS -nostdlib -nostartfiles -shared $no_ssp" LIBS= cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ diff --git a/configure.ac b/configure.ac index f5fa1aaefa..2782bfaf08 100644 --- a/configure.ac +++ b/configure.ac @@ -665,11 +665,26 @@ elif test "$enable_stack_protector" = all && test "$libc_cv_ssp_all" = yes; then elif test "$enable_stack_protector" = strong && test "$libc_cv_ssp_strong" = yes; then stack_protector="-fstack-protector-strong" AC_DEFINE(STACK_PROTECTOR_LEVEL, 3) +else + stack_protector="-fno-stack-protector" + AC_DEFINE(STACK_PROTECTOR_LEVEL, 0) fi AC_SUBST(libc_cv_ssp) AC_SUBST(stack_protector) AC_SUBST(no_stack_protector) +if test -n "$stack_protector"; then + dnl Don't run configure tests with stack-protection on, to avoid problems with + dnl bootstrapping. + no_ssp=-fno-stack-protector +else + no_ssp= + + if test "$enable_stack_protector" != no; then + AC_MSG_ERROR([--enable-stack-protector=$enable_stack_protector specified, but specified level of stack protection is not supported by the compiler.]) + fi +fi + # For the multi-arch option we need support in the assembler & linker. AC_CACHE_CHECK([for assembler and linker STT_GNU_IFUNC support], libc_cv_ld_gnu_indirect_function, [dnl @@ -689,7 +704,7 @@ __start: EOF libc_cv_ld_gnu_indirect_function=no if ${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS \ - -nostartfiles -nostdlib \ + -nostartfiles -nostdlib $no_ssp \ -o conftest conftest.S 1>&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD; then # Do a link to see if the backend supports IFUNC relocs. $READELF -r conftest 1>&AS_MESSAGE_LOG_FD @@ -1213,7 +1228,7 @@ extern int glibc_conftest_frobozz; void _start() { glibc_conftest_frobozz = 1; } EOF if ${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS \ - -nostartfiles -nostdlib \ + -nostartfiles -nostdlib $no_ssp \ -o conftest conftest.s conftest1.c 1>&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD; then libc_cv_asm_set_directive=yes else @@ -1230,12 +1245,12 @@ AC_CACHE_CHECK(linker support for protected data symbol, int bar __attribute__ ((visibility ("protected"))) = 1; EOF libc_cv_protected_data=no - if AC_TRY_COMMAND(${CC-cc} -nostdlib -nostartfiles -fPIC -shared conftest.c -o conftest.so); then + if AC_TRY_COMMAND(${CC-cc} -nostdlib -nostartfiles $no_ssp -fPIC -shared conftest.c -o conftest.so); then cat > conftest.c <&AS_MESSAGE_LOG_FD]) then @@ -1395,7 +1410,7 @@ AC_CACHE_CHECK(for --hash-style option, cat > conftest.c <&AS_MESSAGE_LOG_FD]) then @@ -1467,7 +1482,7 @@ int foo (void) { return mumble; } EOF if AC_TRY_COMMAND([${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS -fPIC -shared -o conftest.so conftest.c - -nostdlib -nostartfiles + -nostdlib -nostartfiles $no_ssp 1>&AS_MESSAGE_LOG_FD]) then dnl look for GLOB_DAT relocation. @@ -1484,7 +1499,7 @@ AC_SUBST(libc_cv_has_glob_dat) AC_CACHE_CHECK(linker output format, libc_cv_output_format, [dnl if libc_cv_output_format=` -${CC-cc} -nostartfiles -nostdlib -Wl,--print-output-format 2>&AS_MESSAGE_LOG_FD` +${CC-cc} -nostartfiles -nostdlib $no_ssp -Wl,--print-output-format 2>&AS_MESSAGE_LOG_FD` then : else @@ -1703,48 +1718,6 @@ if test $libc_cv_predef_fortify_source = yes; then fi AC_SUBST(CPPUNDEFS) -dnl Check for silly hacked compilers inserting -fstack-protector. -dnl This breaks badly for the early startup code we compile, since -dnl the compiled code can refer to a magic machine-dependent location -dnl for the canary value before we have sufficient setup for that to -dnl work. It's also questionable to build all of libc with this flag -dnl even when you're doing that for most applications you build, since -dnl libc's code is so heavily-used and performance-sensitive. If we -dnl ever really want to make that work, it should be enabled explicitly -dnl in the libc build, not inherited from implicit compiler settings. -AC_CACHE_CHECK([whether $CC implicitly enables -fstack-protector], - libc_cv_predef_stack_protector, [ -AC_TRY_COMPILE([extern void foobar (char *);], - [char large_array[2048]; foobar (large_array);], [ -libc_undefs=`$NM -u conftest.o | - LC_ALL=C $AWK '$1 == "U" { print $2 | "sort -u"; next } { exit(1) }' \ - 2>&AS_MESSAGE_LOG_FD` || { - AC_MSG_ERROR([confusing output from $NM -u]) -} -echo >&AS_MESSAGE_LOG_FD "libc_undefs='$libc_undefs'" -# On some architectures, there are architecture-specific undefined -# symbols (resolved by the linker), so filter out unknown symbols. -# This will fail to produce the correct result if the compiler -# defaults to -fstack-protector but this produces an undefined symbol -# other than __stack_chk_fail or __stack_chk_fail_local. However, -# compilers like that have not been encountered in practice. -libc_undefs=`echo "$libc_undefs" | \ - egrep '^(foobar|__stack_chk_fail|__stack_chk_fail_local)$'` -case "$libc_undefs" in -foobar) libc_cv_predef_stack_protector=no ;; -'__stack_chk_fail -foobar'|'__stack_chk_fail_local -foobar') libc_cv_predef_stack_protector=yes ;; -*) AC_MSG_ERROR([unexpected symbols in test: $libc_undefs]) ;; -esac], - [AC_MSG_ERROR([test compilation failed])]) -]) -libc_extra_cflags= -if test $libc_cv_predef_stack_protector = yes; then - libc_extra_cflags="$libc_extra_cflags -fno-stack-protector" -fi -libc_extra_cppflags= - # Some linkers on some architectures support __ehdr_start but with # bugs. Make sure usage of it does not create relocations in the # output (as the linker should resolve them all for us). @@ -1754,7 +1727,7 @@ old_CFLAGS="$CFLAGS" old_LDFLAGS="$LDFLAGS" old_LIBS="$LIBS" CFLAGS="$CFLAGS -fPIC" -LDFLAGS="$LDFLAGS -nostdlib -nostartfiles -shared" +LDFLAGS="$LDFLAGS -nostdlib -nostartfiles -shared $no_ssp" LIBS= AC_LINK_IFELSE([AC_LANG_SOURCE([ typedef struct { -- cgit v1.2.3 From 67e58f39412ecd4467034761f3f074283c90f3c8 Mon Sep 17 00:00:00 2001 From: Siddhesh Poyarekar Date: Sat, 31 Dec 2016 23:32:17 +0530 Subject: Add framework for tunables The tunables framework allows us to uniformly manage and expose global variables inside glibc as switches to users. tunables/README has instructions for glibc developers to add new tunables. Tunables support can be enabled by passing the --enable-tunables configure flag to the configure script. This patch only adds a framework and does not pose any limitations on how tunable values are read from the user. It also adds environment variables used in malloc behaviour tweaking to the tunables framework as a PoC of the compatibility interface. * manual/install.texi: Add --enable-tunables option. * INSTALL: Regenerate. * README.tunables: New file. * Makeconfig (CPPFLAGS): Define TOP_NAMESPACE. (before-compile): Generate dl-tunable-list.h early. * config.h.in: Add HAVE_TUNABLES. * config.make.in: Add have-tunables. * configure.ac: Add --enable-tunables option. * configure: Regenerate. * csu/init-first.c (__libc_init_first): Move __libc_init_secure earlier... * csu/init-first.c (LIBC_START_MAIN):... to here. Include dl-tunables.h, libc-internal.h. (LIBC_START_MAIN) [!SHARED]: Initialize tunables for static binaries. * elf/Makefile (dl-routines): Add dl-tunables. * elf/Versions (ld): Add __tunable_set_val to GLIBC_PRIVATE namespace. * elf/dl-support (_dl_nondynamic_init): Unset MALLOC_CHECK_ only when !HAVE_TUNABLES. * elf/rtld.c (process_envvars): Likewise. * elf/dl-sysdep.c [HAVE_TUNABLES]: Include dl-tunables.h (_dl_sysdep_start): Call __tunables_init. * elf/dl-tunable-types.h: New file. * elf/dl-tunables.c: New file. * elf/dl-tunables.h: New file. * elf/dl-tunables.list: New file. * malloc/tst-malloc-usable-static.c: New test case. * malloc/Makefile (tests-static): Add it. * malloc/arena.c [HAVE_TUNABLES]: Include dl-tunables.h. Define TUNABLE_NAMESPACE. (DL_TUNABLE_CALLBACK (set_mallopt_check)): New function. (DL_TUNABLE_CALLBACK_FNDECL): New macro. Use it to define callback functions. (ptmalloc_init): Set tunable values. * scripts/gen-tunables.awk: New file. * sysdeps/mach/hurd/dl-sysdep.c: Include dl-tunables.h. (_dl_sysdep_start): Call __tunables_init. --- ChangeLog | 41 +++++ INSTALL | 5 + Makeconfig | 16 ++ README.tunables | 85 ++++++++++ config.h.in | 3 + config.make.in | 1 + configure | 16 ++ configure.ac | 10 ++ csu/init-first.c | 2 - csu/libc-start.c | 8 + elf/Makefile | 5 + elf/Versions | 3 + elf/dl-support.c | 2 + elf/dl-sysdep.c | 4 + elf/dl-tunable-types.h | 46 ++++++ elf/dl-tunables.c | 320 ++++++++++++++++++++++++++++++++++++++ elf/dl-tunables.h | 88 +++++++++++ elf/dl-tunables.list | 69 ++++++++ elf/rtld.c | 2 + malloc/Makefile | 2 + malloc/arena.c | 54 +++++++ malloc/tst-malloc-usable-static.c | 1 + manual/install.texi | 5 + scripts/gen-tunables.awk | 157 +++++++++++++++++++ sysdeps/mach/hurd/dl-sysdep.c | 4 + 25 files changed, 947 insertions(+), 2 deletions(-) create mode 100644 README.tunables create mode 100644 elf/dl-tunable-types.h create mode 100644 elf/dl-tunables.c create mode 100644 elf/dl-tunables.h create mode 100644 elf/dl-tunables.list create mode 100644 malloc/tst-malloc-usable-static.c create mode 100644 scripts/gen-tunables.awk (limited to 'configure.ac') diff --git a/ChangeLog b/ChangeLog index d219e5432b..85a4ac30df 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,44 @@ +2016-12-31 Siddhesh Poyarekar + + * manual/install.texi: Add --enable-tunables option. + * INSTALL: Regenerate. + * README.tunables: New file. + * Makeconfig (CPPFLAGS): Define TOP_NAMESPACE. + (before-compile): Generate dl-tunable-list.h early. + * config.h.in: Add HAVE_TUNABLES. + * config.make.in: Add have-tunables. + * configure.ac: Add --enable-tunables option. + * configure: Regenerate. + * csu/init-first.c (__libc_init_first): Move + __libc_init_secure earlier... + * csu/init-first.c (LIBC_START_MAIN):... to here. + Include dl-tunables.h, libc-internal.h. + (LIBC_START_MAIN) [!SHARED]: Initialize tunables for static + binaries. + * elf/Makefile (dl-routines): Add dl-tunables. + * elf/Versions (ld): Add __tunable_set_val to GLIBC_PRIVATE + namespace. + * elf/dl-support (_dl_nondynamic_init): Unset MALLOC_CHECK_ + only when !HAVE_TUNABLES. + * elf/rtld.c (process_envvars): Likewise. + * elf/dl-sysdep.c [HAVE_TUNABLES]: Include dl-tunables.h + (_dl_sysdep_start): Call __tunables_init. + * elf/dl-tunable-types.h: New file. + * elf/dl-tunables.c: New file. + * elf/dl-tunables.h: New file. + * elf/dl-tunables.list: New file. + * malloc/tst-malloc-usable-static.c: New test case. + * malloc/Makefile (tests-static): Add it. + * malloc/arena.c [HAVE_TUNABLES]: Include dl-tunables.h. + Define TUNABLE_NAMESPACE. + (DL_TUNABLE_CALLBACK (set_mallopt_check)): New function. + (DL_TUNABLE_CALLBACK_FNDECL): New macro. Use it to define + callback functions. + (ptmalloc_init): Set tunable values. + * scripts/gen-tunables.awk: New file. + * sysdeps/mach/hurd/dl-sysdep.c: Include dl-tunables.h. + (_dl_sysdep_start): Call __tunables_init. + 2016-12-31 Florian Weimer * resolv/resolv.h (RES_BLAST): Deprecate. diff --git a/INSTALL b/INSTALL index 104f36b0bf..25619fc520 100644 --- a/INSTALL +++ b/INSTALL @@ -169,6 +169,11 @@ will be used, and CFLAGS sets optimization options for the compiler. By default for x86_64, the GNU C Library is built with the vector math library. Use this option to disable the vector math library. +'--enable-tunables' + Tunables support allows additional library parameters to be + customized at runtime. This is an experimental feature and affects + startup time and is thus disabled by default. + '--build=BUILD-SYSTEM' '--host=HOST-SYSTEM' These options are for cross-compiling. If you specify both options diff --git a/Makeconfig b/Makeconfig index 0158eaa76e..b173e4cc08 100644 --- a/Makeconfig +++ b/Makeconfig @@ -934,6 +934,11 @@ CPPFLAGS = $(config-extra-cppflags) $(CPPUNDEFS) $(CPPFLAGS-config) \ $(foreach lib,$(libof-$(basename $(@F))) \ $(libof-$( $@.tmp + mv $@.tmp $@ +endif + common-generated += libc-modules.h libc-modules.stmp # The name under which the run-time dynamic linker is installed. diff --git a/README.tunables b/README.tunables new file mode 100644 index 0000000000..df74f3b24b --- /dev/null +++ b/README.tunables @@ -0,0 +1,85 @@ + TUNABLE FRAMEWORK + ================= + +Tunables is a feature in the GNU C Library that allows application authors and +distribution maintainers to alter the runtime library behaviour to match their +workload. + +The tunable framework allows modules within glibc to register variables that +may be tweaked through an environment variable. It aims to enforce a strict +namespace rule to bring consistency to naming of these tunable environment +variables across the project. This document is a guide for glibc developers to +add tunables to the framework. + +ADDING A NEW TUNABLE +-------------------- + +The TOP_NAMESPACE macro is defined by default as 'glibc'. If distributions +intend to add their own tunables, they should do so in a different top +namespace by overriding the TOP_NAMESPACE macro for that tunable. Downstream +implementations are discouraged from using the 'glibc' top namespace for +tunables they don't already have consensus to push upstream. + +There are two steps to adding a tunable: + +1. Add a tunable ID: + +Modules that wish to use the tunables interface must define the +TUNABLE_NAMESPACE macro. Following this, for each tunable you want to +add, make an entry in elf/dl-tunables.list. The format of the file is as +follows: + +TOP_NAMESPACE { + NAMESPACE1 { + TUNABLE1 { + # tunable attributes, one per line + } + # A tunable with default attributes, i.e. string variable. + TUNABLE2 + TUNABLE3 { + # its attributes + } + } + NAMESPACE2 { + ... + } +} + +The list of allowed attributes are: + +- type: Data type. Defaults to STRING. Allowed types are: + INT_32, SIZE_T and STRING. + +- minval: Optional minimum acceptable value. For a string type + this is the minimum length of the value. + +- maxval: Optional maximum acceptable value. For a string type + this is the maximum length of the value. + +- env_alias: An alias environment variable + +- is_secure: Specify whether the tunable should be read for setuid + binaries. True allows the tunable to be read for + setuid binaries while false disables it. Note that + even if this is set as true and the value is read, it + may not be used if it does not validate against the + acceptable values or is not considered safe by the + module. + +2. Call either the TUNABLE_SET_VALUE and pass into it the tunable name and a + pointer to the variable that should be set with the tunable value. + If additional work needs to be done after setting the value, use the + TUNABLE_SET_VALUE_WITH_CALLBACK instead and additionally pass a pointer to + the function that should be called if the tunable value has been set. + +FUTURE WORK +----------- + +The framework currently only allows a one-time initialization of variables +through environment variables and in some cases, modification of variables via +an API call. A future goals for this project include: + +- Setting system-wide and user-wide defaults for tunables through some + mechanism like a configuration file. + +- Allow tweaking of some tunables at runtime diff --git a/config.h.in b/config.h.in index 82f95a6dbd..7bfe923c06 100644 --- a/config.h.in +++ b/config.h.in @@ -256,4 +256,7 @@ /* PowerPC32 uses fctidz for floating point to long long conversions. */ #define HAVE_PPC_FCTIDZ 0 +/* Build glibc with tunables support. */ +#define HAVE_TUNABLES 0 + #endif diff --git a/config.make.in b/config.make.in index 4422025e59..2f8dae213d 100644 --- a/config.make.in +++ b/config.make.in @@ -96,6 +96,7 @@ use-nscd = @use_nscd@ build-hardcoded-path-in-tests= @hardcoded_path_in_tests@ build-pt-chown = @build_pt_chown@ enable-lock-elision = @enable_lock_elision@ +have-tunables = @have_tunables@ # Build tools. CC = @CC@ diff --git a/configure b/configure index c88f6fe88c..d80d738fd1 100755 --- a/configure +++ b/configure @@ -666,6 +666,7 @@ libc_cv_ssp base_machine add_on_subdirs add_ons +have_tunables build_pt_chown build_nscd link_obsolete_rpc @@ -782,6 +783,7 @@ enable_systemtap enable_build_nscd enable_nscd enable_pt_chown +enable_tunables enable_mathvec with_cpu ' @@ -1452,6 +1454,7 @@ Optional Features: --disable-build-nscd disable building and installing the nscd daemon --disable-nscd library functions will not contact the nscd daemon --enable-pt_chown Enable building and installing pt_chown + --enable-tunables Enable tunables support --enable-mathvec Enable building and installing mathvec [default depends on architecture] @@ -3698,6 +3701,19 @@ if test "$build_pt_chown" = yes; then fi +# Check whether --enable-tunables was given. +if test "${enable_tunables+set}" = set; then : + enableval=$enable_tunables; have_tunables=$enableval +else + have_tunables=no +fi + + +if test "$have_tunables" = yes; then + $as_echo "#define HAVE_TUNABLES 1" >>confdefs.h + +fi + # The abi-tags file uses a fairly simplistic model for name recognition that # can't distinguish i486-pc-linux-gnu fully from i486-pc-gnu. So we mutate a # $host_os of `gnu*' here to be `gnu-gnu*' just so that it can tell. diff --git a/configure.ac b/configure.ac index 2782bfaf08..22f5cab200 100644 --- a/configure.ac +++ b/configure.ac @@ -421,6 +421,16 @@ if test "$build_pt_chown" = yes; then AC_DEFINE(HAVE_PT_CHOWN) fi +AC_ARG_ENABLE([tunables], + [AS_HELP_STRING([--enable-tunables], + [Enable tunables support])], + [have_tunables=$enableval], + [have_tunables=no]) +AC_SUBST(have_tunables) +if test "$have_tunables" = yes; then + AC_DEFINE(HAVE_TUNABLES) +fi + # The abi-tags file uses a fairly simplistic model for name recognition that # can't distinguish i486-pc-linux-gnu fully from i486-pc-gnu. So we mutate a # $host_os of `gnu*' here to be `gnu-gnu*' just so that it can tell. diff --git a/csu/init-first.c b/csu/init-first.c index 77c6e1cb9e..465f25b722 100644 --- a/csu/init-first.c +++ b/csu/init-first.c @@ -72,8 +72,6 @@ _init (int argc, char **argv, char **envp) __environ = envp; #ifndef SHARED - __libc_init_secure (); - /* First the initialization which normally would be done by the dynamic linker. */ _dl_non_dynamic_init (); diff --git a/csu/libc-start.c b/csu/libc-start.c index cc59073abe..15db9b4684 100644 --- a/csu/libc-start.c +++ b/csu/libc-start.c @@ -21,6 +21,9 @@ #include #include #include +#include + +#include extern void __libc_init_first (int argc, char **argv, char **envp); @@ -174,6 +177,11 @@ LIBC_START_MAIN (int (*main) (int, char **, char ** MAIN_AUXVEC_DECL), } } + /* Initialize very early so that tunables can use it. */ + __libc_init_secure (); + + __tunables_init (__environ); + /* Perform IREL{,A} relocations. */ apply_irel (); diff --git a/elf/Makefile b/elf/Makefile index 8a2ce02cd5..de28d99224 100644 --- a/elf/Makefile +++ b/elf/Makefile @@ -35,6 +35,11 @@ dl-routines = $(addprefix dl-,load lookup object reloc deps hwcaps \ ifeq (yes,$(use-ldconfig)) dl-routines += dl-cache endif + +ifeq (yes,$(have-tunables)) +dl-routines += dl-tunables +endif + all-dl-routines = $(dl-routines) $(sysdep-dl-routines) # But they are absent from the shared libc, because that code is in ld.so. elide-routines.os = $(all-dl-routines) dl-support enbl-secure dl-origin \ diff --git a/elf/Versions b/elf/Versions index 3d57e36fd2..6abe9db8bd 100644 --- a/elf/Versions +++ b/elf/Versions @@ -70,5 +70,8 @@ ld { # Internal error handling support. Interposed by libc.so. _dl_signal_error; _dl_catch_error; + + # Set value of a tunable. + __tunable_set_val; } } diff --git a/elf/dl-support.c b/elf/dl-support.c index c30194c7b7..d350d6d0d0 100644 --- a/elf/dl-support.c +++ b/elf/dl-support.c @@ -354,8 +354,10 @@ _dl_non_dynamic_init (void) cp = (const char *) __rawmemchr (cp, '\0') + 1; } +#if !HAVE_TUNABLES if (__access ("/etc/suid-debug", F_OK) != 0) __unsetenv ("MALLOC_CHECK_"); +#endif } #ifdef DL_PLATFORM_INIT diff --git a/elf/dl-sysdep.c b/elf/dl-sysdep.c index eaa71556d2..4283767fe0 100644 --- a/elf/dl-sysdep.c +++ b/elf/dl-sysdep.c @@ -44,6 +44,8 @@ #include #include +#include + extern char **_environ attribute_hidden; extern char _end[] attribute_hidden; @@ -219,6 +221,8 @@ _dl_sysdep_start (void **start_argptr, } #endif + __tunables_init (_environ); + #ifdef DL_SYSDEP_INIT DL_SYSDEP_INIT; #endif diff --git a/elf/dl-tunable-types.h b/elf/dl-tunable-types.h new file mode 100644 index 0000000000..d1591b6efb --- /dev/null +++ b/elf/dl-tunable-types.h @@ -0,0 +1,46 @@ +/* Tunable type information. + + Copyright (C) 2016 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 + . */ + +#ifndef _TUNABLE_TYPES_H_ +# define _TUNABLE_TYPES_H_ +#include + +typedef void (*tunable_callback_t) (void *); + +typedef enum +{ + TUNABLE_TYPE_INT_32, + TUNABLE_TYPE_SIZE_T, + TUNABLE_TYPE_STRING +} tunable_type_code_t; + +typedef struct +{ + tunable_type_code_t type_code; + int64_t min; + int64_t max; +} tunable_type_t; + +typedef union +{ + int64_t numval; + const char *strval; +} tunable_val_t; + +#endif diff --git a/elf/dl-tunables.c b/elf/dl-tunables.c new file mode 100644 index 0000000000..472747b3da --- /dev/null +++ b/elf/dl-tunables.c @@ -0,0 +1,320 @@ +/* The tunable framework. See the README.tunables to know how to use the + tunable in a glibc module. + + Copyright (C) 2016 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 + . */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define TUNABLES_INTERNAL 1 +#include "dl-tunables.h" + +/* Compare environment names, bounded by the name hardcoded in glibc. */ +static bool +is_name (const char *orig, const char *envname) +{ + for (;*orig != '\0' && *envname != '\0'; envname++, orig++) + if (*orig != *envname) + break; + + /* The ENVNAME is immediately followed by a value. */ + if (*orig == '\0' && *envname == '=') + return true; + else + return false; +} + +static char ** +get_next_env (char **envp, char **name, size_t *namelen, char **val) +{ + while (envp != NULL && *envp != NULL) + { + char *envline = *envp; + int len = 0; + + while (envline[len] != '\0' && envline[len] != '=') + len++; + + /* Just the name and no value, go to the next one. */ + if (envline[len] == '\0') + continue; + + *name = envline; + *namelen = len; + *val = &envline[len + 1]; + + return ++envp; + } + + return NULL; +} + +static int +tunables_unsetenv (char **ep, const char *name) +{ + while (*ep != NULL) + { + size_t cnt = 0; + + while ((*ep)[cnt] == name[cnt] && name[cnt] != '\0') + ++cnt; + + if (name[cnt] == '\0' && (*ep)[cnt] == '=') + { + /* Found it. Remove this pointer by moving later ones to + the front. */ + char **dp = ep; + + do + dp[0] = dp[1]; + while (*dp++); + /* Continue the loop in case NAME appears again. */ + } + else + ++ep; + } + + return 0; +} + +/* A stripped down strtoul-like implementation for very early use. It does not + set errno if the result is outside bounds because it gets called before + errno may have been set up. */ +static unsigned long int +tunables_strtoul (const char *nptr) +{ + unsigned long int result = 0; + long int sign = 1; + unsigned max_digit; + + while (*nptr == ' ' || *nptr == '\t') + ++nptr; + + if (*nptr == '-') + { + sign = -1; + ++nptr; + } + else if (*nptr == '+') + ++nptr; + + if (*nptr < '0' || *nptr > '9') + return 0UL; + + int base = 10; + max_digit = 9; + if (*nptr == '0') + { + if (nptr[1] == 'x' || nptr[1] == 'X') + { + base = 16; + nptr += 2; + } + else + { + base = 8; + max_digit = 7; + } + } + + while (1) + { + unsigned long int digval; + if (*nptr >= '0' && *nptr <= '0' + max_digit) + digval = *nptr - '0'; + else if (base == 16) + { + if (*nptr >= 'a' && *nptr <= 'f') + digval = *nptr - 'a' + 10; + else if (*nptr >= 'A' && *nptr <= 'F') + digval = *nptr - 'A' + 10; + else + break; + } + else + break; + + if (result > ULONG_MAX / base + || (result == ULONG_MAX / base && digval > ULONG_MAX % base)) + return ULONG_MAX; + result *= base; + result += digval; + ++nptr; + } + + return result * sign; +} + +/* Initialize the internal type if the value validates either using the + explicit constraints of the tunable or with the implicit constraints of its + type. */ +static void +tunable_set_val_if_valid_range (tunable_t *cur, const char *strval, + int64_t default_min, int64_t default_max) +{ + int64_t val = tunables_strtoul (strval); + + int64_t min = cur->type.min; + int64_t max = cur->type.max; + + if (min == max) + { + min = default_min; + max = default_max; + } + + if (val >= min && val <= max) + { + cur->val.numval = val; + cur->strval = strval; + } +} + +/* Validate range of the input value and initialize the tunable CUR if it looks + good. */ +static void +tunable_initialize (tunable_t *cur, const char *strval) +{ + switch (cur->type.type_code) + { + case TUNABLE_TYPE_INT_32: + { + tunable_set_val_if_valid_range (cur, strval, INT32_MIN, INT32_MAX); + break; + } + case TUNABLE_TYPE_SIZE_T: + { + tunable_set_val_if_valid_range (cur, strval, 0, SIZE_MAX); + break; + } + case TUNABLE_TYPE_STRING: + { + cur->val.strval = cur->strval = strval; + break; + } + default: + __builtin_unreachable (); + } +} + +/* Disable a tunable if it is set. */ +static void +disable_tunable (tunable_id_t id, char **envp) +{ + const char *env_alias = tunable_list[id].env_alias; + + if (env_alias != NULL) + tunables_unsetenv (envp, tunable_list[id].env_alias); +} + +/* Disable the glibc.malloc.check tunable in SETUID/SETGID programs unless + the system administrator overrides it by creating the /etc/suid-debug + file. This is a special case where we want to conditionally enable/disable + a tunable even for setuid binaries. We use the special version of access() + to avoid setting ERRNO, which is a TLS variable since TLS has not yet been + set up. */ +static inline void +__always_inline +maybe_disable_malloc_check (void) +{ + if (__libc_enable_secure && __access_noerrno ("/etc/suid-debug", F_OK) != 0) + disable_tunable (TUNABLE_ENUM_NAME(glibc, malloc, check), __environ); +} + +/* Initialize the tunables list from the environment. For now we only use the + ENV_ALIAS to find values. Later we will also use the tunable names to find + values. */ +void +__tunables_init (char **envp) +{ + char *envname = NULL; + char *envval = NULL; + size_t len = 0; + + maybe_disable_malloc_check (); + + while ((envp = get_next_env (envp, &envname, &len, &envval)) != NULL) + { + for (int i = 0; i < sizeof (tunable_list) / sizeof (tunable_t); i++) + { + tunable_t *cur = &tunable_list[i]; + + /* Skip over tunables that have either been set already or should be + skipped. */ + if (cur->strval != NULL || cur->env_alias == NULL + || (__libc_enable_secure && !cur->is_secure)) + continue; + + const char *name = cur->env_alias; + + /* We have a match. Initialize and move on to the next line. */ + if (is_name (name, envname)) + { + tunable_initialize (cur, envval); + break; + } + } + } +} + +/* Set the tunable value. This is called by the module that the tunable exists + in. */ +void +__tunable_set_val (tunable_id_t id, void *valp, tunable_callback_t callback) +{ + tunable_t *cur = &tunable_list[id]; + + /* Don't do anything if our tunable was not set during initialization or if + it failed validation. */ + if (cur->strval == NULL) + return; + + if (valp == NULL) + goto cb; + + switch (cur->type.type_code) + { + case TUNABLE_TYPE_INT_32: + { + *((int32_t *) valp) = (int32_t) cur->val.numval; + break; + } + case TUNABLE_TYPE_SIZE_T: + { + *((size_t *) valp) = (size_t) cur->val.numval; + break; + } + case TUNABLE_TYPE_STRING: + { + *((const char **)valp) = cur->val.strval; + break; + } + default: + __builtin_unreachable (); + } + +cb: + if (callback) + callback (&cur->val); +} diff --git a/elf/dl-tunables.h b/elf/dl-tunables.h new file mode 100644 index 0000000000..a3f5472b45 --- /dev/null +++ b/elf/dl-tunables.h @@ -0,0 +1,88 @@ +/* The tunable framework. See the README to know how to use the tunable in + a glibc module. + + Copyright (C) 2016 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 + . */ + +#ifndef _TUNABLES_H_ +#define _TUNABLES_H_ + +#if !HAVE_TUNABLES +static inline void +__always_inline +__tunables_init (char **unused __attribute_unused) +{ + /* This is optimized out if tunables are not enabled. */ +} +#else + +# include +# include "dl-tunable-types.h" + +/* A tunable. */ +struct _tunable +{ + const char *name; /* Internal name of the tunable. */ + tunable_type_t type; /* Data type of the tunable. */ + tunable_val_t val; /* The value. */ + const char *strval; /* The string containing the value, + points into envp. */ + bool is_secure; /* Whether the tunable must be read + even for setuid binaries. Note that + even if the tunable is read, it may + not get used by the target module if + the value is considered unsafe. */ + /* Compatibility elements. */ + const char *env_alias; /* The compatibility environment + variable name. */ +}; + +typedef struct _tunable tunable_t; + +/* Full name for a tunable is top_ns.tunable_ns.id. */ +# define TUNABLE_NAME_S(top,ns,id) #top "." #ns "." #id + +# define TUNABLE_ENUM_NAME(top,ns,id) TUNABLE_ENUM_NAME1 (top,ns,id) +# define TUNABLE_ENUM_NAME1(top,ns,id) top ## _ ## ns ## _ ## id + +# include "dl-tunable-list.h" + +extern void __tunables_init (char **); +extern void __tunable_set_val (tunable_id_t, void *, tunable_callback_t); + +/* Check if the tunable has been set to a non-default value and if it is, copy + it over into __VAL. */ +# define TUNABLE_SET_VAL(__id,__val) \ +({ \ + __tunable_set_val \ + (TUNABLE_ENUM_NAME (TOP_NAMESPACE, TUNABLE_NAMESPACE, __id), (__val), \ + NULL); \ +}) + +/* Same as TUNABLE_SET_VAL, but also call the callback function __CB. */ +# define TUNABLE_SET_VAL_WITH_CALLBACK(__id,__val,__cb) \ +({ \ + __tunable_set_val \ + (TUNABLE_ENUM_NAME (TOP_NAMESPACE, TUNABLE_NAMESPACE, __id), (__val), \ + DL_TUNABLE_CALLBACK (__cb)); \ +}) + +/* Namespace sanity for callback functions. Use this macro to keep the + namespace of the modules clean. */ +# define DL_TUNABLE_CALLBACK(__name) _dl_tunable_ ## __name +#endif +#endif diff --git a/elf/dl-tunables.list b/elf/dl-tunables.list new file mode 100644 index 0000000000..11504c49e3 --- /dev/null +++ b/elf/dl-tunables.list @@ -0,0 +1,69 @@ +# Copyright (C) 2016 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 +# . + +# Allowed attributes for tunables: +# +# type: Defaults to STRING +# minval: Optional minimum acceptable value +# maxval: Optional maximum acceptable value +# env_alias: An alias environment variable +# is_secure: Specify whether the environment variable should be read for +# setuid binaries. + +glibc { + malloc { + check { + type: INT_32 + minval: 0 + maxval: 3 + env_alias: MALLOC_CHECK_ + is_secure: true + } + top_pad { + type: SIZE_T + env_alias: MALLOC_TOP_PAD_ + } + perturb { + type: INT_32 + minval: 0 + maxval: 0xff + env_alias: MALLOC_PERTURB_ + } + mmap_threshold { + type: SIZE_T + env_alias: MALLOC_MMAP_THRESHOLD_ + } + trim_threshold { + type: SIZE_T + env_alias: MALLOC_TRIM_THRESHOLD_ + } + mmap_max { + type: INT_32 + env_alias: MALLOC_MMAP_MAX_ + } + arena_max { + type: SIZE_T + env_alias: MALLOC_ARENA_MAX + minval: 1 + } + arena_test { + type: SIZE_T + env_alias: MALLOC_ARENA_TEST + minval: 1 + } + } +} diff --git a/elf/rtld.c b/elf/rtld.c index 4ec25d7c30..a60ead693b 100644 --- a/elf/rtld.c +++ b/elf/rtld.c @@ -2510,7 +2510,9 @@ process_envvars (enum mode *modep) if (__access ("/etc/suid-debug", F_OK) != 0) { +#if !HAVE_TUNABLES unsetenv ("MALLOC_CHECK_"); +#endif GLRO(dl_debug_mask) = 0; } diff --git a/malloc/Makefile b/malloc/Makefile index b8efcd68bc..4e4104ec8b 100644 --- a/malloc/Makefile +++ b/malloc/Makefile @@ -37,6 +37,7 @@ tests := mallocbug tst-malloc tst-valloc tst-calloc tst-obstack \ tests-static := \ tst-interpose-static-nothread \ tst-interpose-static-thread \ + tst-malloc-usable-static tests += $(tests-static) test-srcs = tst-mtrace @@ -158,6 +159,7 @@ endif tst-mcheck-ENV = MALLOC_CHECK_=3 tst-malloc-usable-ENV = MALLOC_CHECK_=3 +tst-malloc-usable-static-ENV = $(tst-malloc-usable-ENV) # Uncomment this for test releases. For public releases it is too expensive. #CPPFLAGS-malloc.o += -DMALLOC_DEBUG=1 diff --git a/malloc/arena.c b/malloc/arena.c index eed42471a7..234035f14f 100644 --- a/malloc/arena.c +++ b/malloc/arena.c @@ -19,6 +19,11 @@ #include +#if HAVE_TUNABLES +# define TUNABLE_NAMESPACE malloc +#endif +#include + /* Compile-time constants. */ #define HEAP_MIN_SIZE (32 * 1024) @@ -204,6 +209,34 @@ __malloc_fork_unlock_child (void) __libc_lock_init (list_lock); } +#if HAVE_TUNABLES +static inline int do_set_mallopt_check (int32_t value); +void +DL_TUNABLE_CALLBACK (set_mallopt_check) (void *valp) +{ + int32_t value = *(int32_t *) valp; + do_set_mallopt_check (value); + if (check_action != 0) + __malloc_check_init (); +} + +# define DL_TUNABLE_CALLBACK_FNDECL(__name, __type) \ +static inline int do_ ## __name (__type value); \ +void \ +DL_TUNABLE_CALLBACK (__name) (void *valp) \ +{ \ + __type value = *(__type *) valp; \ + do_ ## __name (value); \ +} + +DL_TUNABLE_CALLBACK_FNDECL (set_mmap_threshold, size_t) +DL_TUNABLE_CALLBACK_FNDECL (set_mmaps_max, int32_t) +DL_TUNABLE_CALLBACK_FNDECL (set_top_pad, size_t) +DL_TUNABLE_CALLBACK_FNDECL (set_perturb_byte, int32_t) +DL_TUNABLE_CALLBACK_FNDECL (set_trim_threshold, size_t) +DL_TUNABLE_CALLBACK_FNDECL (set_arena_max, size_t) +DL_TUNABLE_CALLBACK_FNDECL (set_arena_test, size_t) +#else /* Initialization routine. */ #include extern char **_environ; @@ -238,6 +271,7 @@ next_env_entry (char ***position) return result; } +#endif #ifdef SHARED @@ -272,6 +306,24 @@ ptmalloc_init (void) #endif thread_arena = &main_arena; + +#if HAVE_TUNABLES + /* Ensure initialization/consolidation and do it under a lock so that a + thread attempting to use the arena in parallel waits on us till we + finish. */ + __libc_lock_lock (main_arena.mutex); + malloc_consolidate (&main_arena); + + TUNABLE_SET_VAL_WITH_CALLBACK (check, NULL, set_mallopt_check); + TUNABLE_SET_VAL_WITH_CALLBACK (top_pad, NULL, set_top_pad); + TUNABLE_SET_VAL_WITH_CALLBACK (perturb, NULL, set_perturb_byte); + TUNABLE_SET_VAL_WITH_CALLBACK (mmap_threshold, NULL, set_mmap_threshold); + TUNABLE_SET_VAL_WITH_CALLBACK (trim_threshold, NULL, set_trim_threshold); + TUNABLE_SET_VAL_WITH_CALLBACK (mmap_max, NULL, set_mmaps_max); + TUNABLE_SET_VAL_WITH_CALLBACK (arena_max, NULL, set_arena_max); + TUNABLE_SET_VAL_WITH_CALLBACK (arena_test, NULL, set_arena_test); + __libc_lock_unlock (main_arena.mutex); +#else const char *s = NULL; if (__glibc_likely (_environ != NULL)) { @@ -340,6 +392,8 @@ ptmalloc_init (void) if (check_action != 0) __malloc_check_init (); } +#endif + #if HAVE_MALLOC_INIT_HOOK void (*hook) (void) = atomic_forced_read (__malloc_initialize_hook); if (hook != NULL) diff --git a/malloc/tst-malloc-usable-static.c b/malloc/tst-malloc-usable-static.c new file mode 100644 index 0000000000..8907db01a5 --- /dev/null +++ b/malloc/tst-malloc-usable-static.c @@ -0,0 +1 @@ +#include diff --git a/manual/install.texi b/manual/install.texi index d02e87091f..d41296294e 100644 --- a/manual/install.texi +++ b/manual/install.texi @@ -200,6 +200,11 @@ configure with @option{--disable-werror}. By default for x86_64, @theglibc{} is built with the vector math library. Use this option to disable the vector math library. +@item --enable-tunables +Tunables support allows additional library parameters to be customized at +runtime. This is an experimental feature and affects startup time and is thus +disabled by default. + @item --build=@var{build-system} @itemx --host=@var{host-system} These options are for cross-compiling. If you specify both options and diff --git a/scripts/gen-tunables.awk b/scripts/gen-tunables.awk new file mode 100644 index 0000000000..b65b5a4a33 --- /dev/null +++ b/scripts/gen-tunables.awk @@ -0,0 +1,157 @@ +# Generate dl-tunable-list.h from dl-tunables.list + +BEGIN { + tunable="" + ns="" + top_ns="" +} + +# Skip over blank lines and comments. +/^#/ { + next +} + +/^[ \t]*$/ { + next +} + +# Beginning of either a top namespace, tunable namespace or a tunable, decided +# on the current value of TUNABLE, NS or TOP_NS. +$2 == "{" { + if (top_ns == "") { + top_ns = $1 + } + else if (ns == "") { + ns = $1 + } + else if (tunable == "") { + tunable = $1 + } + else { + printf ("Unexpected occurrence of '{': %s:%d\n", FILENAME, FNR) + exit 1 + } + + next +} + +# End of either a top namespace, tunable namespace or a tunable. +$1 == "}" { + if (tunable != "") { + # Tunables definition ended, now fill in default attributes. + if (!types[top_ns][ns][tunable]) { + types[top_ns][ns][tunable] = "STRING" + } + if (!minvals[top_ns][ns][tunable]) { + minvals[top_ns][ns][tunable] = "0" + } + if (!maxvals[top_ns][ns][tunable]) { + maxvals[top_ns][ns][tunable] = "0" + } + if (!env_alias[top_ns][ns][tunable]) { + env_alias[top_ns][ns][tunable] = "NULL" + } + if (!is_secure[top_ns][ns][tunable]) { + is_secure[top_ns][ns][tunable] = "false" + } + + tunable = "" + } + else if (ns != "") { + ns = "" + } + else if (top_ns != "") { + top_ns = "" + } + else { + printf ("syntax error: extra }: %s:%d\n", FILENAME, FNR) + exit 1 + } + next +} + +# Everything else, which could either be a tunable without any attributes or a +# tunable attribute. +{ + if (ns == "") { + printf("Line %d: Invalid tunable outside a namespace: %s\n", NR, $0) + exit 1 + } + + if (tunable == "") { + # We encountered a tunable without any attributes, so note it with a + # default. + types[top_ns][ns][$1] = "STRING" + next + } + + # Otherwise, we have encountered a tunable attribute. + split($0, arr, ":") + attr = gensub(/^[ \t]+|[ \t]+$/, "", "g", arr[1]) + val = gensub(/^[ \t]+|[ \t]+$/, "", "g", arr[2]) + + if (attr == "type") { + types[top_ns][ns][tunable] = val + } + else if (attr == "minval") { + minvals[top_ns][ns][tunable] = val + } + else if (attr == "maxval") { + maxvals[top_ns][ns][tunable] = val + } + else if (attr == "env_alias") { + env_alias[top_ns][ns][tunable] = sprintf("\"%s\"", val) + } + else if (attr == "is_secure") { + if (val == "true" || val == "false") { + is_secure[top_ns][ns][tunable] = val + } + else { + printf("Line %d: Invalid value (%s) for is_secure: %s, ", NR, val, + $0) + print("Allowed values are 'true' or 'false'") + exit 1 + } + } +} + +END { + if (ns != "") { + print "Unterminated namespace. Is a closing brace missing?" + exit 1 + } + + print "/* AUTOGENERATED by gen-tunables.awk. */" + print "#ifndef _TUNABLES_H_" + print "# error \"Do not include this file directly.\"" + print "# error \"Include tunables.h instead.\"" + print "#endif" + + # Now, the enum names + print "\ntypedef enum" + print "{" + for (t in types) { + for (n in types[t]) { + for (m in types[t][n]) { + printf (" TUNABLE_ENUM_NAME(%s, %s, %s),\n", t, n, m); + } + } + } + print "} tunable_id_t;\n" + + # Finally, the tunable list. + print "\n#ifdef TUNABLES_INTERNAL" + print "static tunable_t tunable_list[] = {" + for (t in types) { + for (n in types[t]) { + for (m in types[t][n]) { + printf (" {TUNABLE_NAME_S(%s, %s, %s)", t, n, m) + printf (", {TUNABLE_TYPE_%s, %s, %s}, {.numval = 0}, NULL, %s, %s},\n", + types[t][n][m], minvals[t][n][m], maxvals[t][n][m], + is_secure[t][n][m], env_alias[t][n][m]); + } + } + } + print "};" + print "#endif" +} diff --git a/sysdeps/mach/hurd/dl-sysdep.c b/sysdeps/mach/hurd/dl-sysdep.c index d730f82280..42bccdab79 100644 --- a/sysdeps/mach/hurd/dl-sysdep.c +++ b/sysdeps/mach/hurd/dl-sysdep.c @@ -44,6 +44,8 @@ #include #include +#include + extern void __mach_init (void); extern int _dl_argc; @@ -143,6 +145,8 @@ _dl_sysdep_start (void **start_argptr, __libc_enable_secure = _dl_hurd_data->flags & EXEC_SECURE; + __tunables_init (_environ); + if (_dl_hurd_data->flags & EXEC_STACK_ARGS && _dl_hurd_data->user_entry == 0) _dl_hurd_data->user_entry = (vm_address_t) ENTRY_POINT; -- cgit v1.2.3 From 6765d5d34d126b26d55e2d73dac4dfec5e6d6241 Mon Sep 17 00:00:00 2001 From: Siddhesh Poyarekar Date: Sat, 31 Dec 2016 23:34:04 +0530 Subject: Enhance --enable-tunables to select tunables frontend at build time At the GNU Tools Cauldron 2016, the state of the current tunables patchset was considered OK with the addition of a way to select the frontend to be used for the tunables. That is, to avoid being locked in to one type of frontend initially, it should be possible to build tunables with a different frontend with something as simple as a configure switch. To that effect, this patch enhances the --enable-tunables option to accept more values than just 'yes' or 'no'. The current frontend (and default when enable-tunables is 'yes') is called 'valstring', to select the frontend where a single environment variable is set to a colon-separated value string. More such frontends can be added in future. * Makeconfig (have-tunables): Check for non-negative instead of positive. * configure.ac: Add 'valstring' as a valid value for --enable-tunables. * configure: Regenerate. * elf/Makefile (have-tunables): Check for non-negative instead of positive. (CPPFLAGS-dl-tunables.c): Define TUNABLES_FRONTEND for dl-tunables.c. * elf/dl-tunables.c (GLIBC_TUNABLES): Define only when TUNABLES_FRONTEND == TUNABLES_FRONTEND_valstring. (tunables_strdup): Likewise. (disable_tunables): Likewise. (parse_tunables): Likewise. (__tunables_init): Process GLIBC_TUNABLES envvar only when. TUNABLES_FRONTEND == TUNABLES_FRONTEND_valstring. * elf/dl-tunables.h (TUNABLES_FRONTEND_valstring): New macro. (TUNABLES_FRONTEND_yes): New macro, define as TUNABLES_FRONTEND_valstring by default. * manual/install.texi: Document new acceptable values for --enable-tunables. * INSTALL: Regenerate. --- ChangeLog | 23 +++++++++++++++++++++++ INSTALL | 18 +++++++++++++++++- Makeconfig | 4 ++-- configure | 3 ++- configure.ac | 2 +- elf/Makefile | 4 +++- elf/dl-tunables.c | 12 +++++++++++- elf/dl-tunables.h | 4 ++++ manual/install.texi | 17 ++++++++++++++++- 9 files changed, 79 insertions(+), 8 deletions(-) (limited to 'configure.ac') diff --git a/ChangeLog b/ChangeLog index 69e527c3ea..eded27fbe3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,28 @@ 2016-12-31 Siddhesh Poyarekar + * Makeconfig (have-tunables): Check for non-negative instead + of positive. + * configure.ac: Add 'valstring' as a valid value for + --enable-tunables. + * configure: Regenerate. + * elf/Makefile (have-tunables): Check for non-negative instead + of positive. + (CPPFLAGS-dl-tunables.c): Define TUNABLES_FRONTEND for + dl-tunables.c. + * elf/dl-tunables.c (GLIBC_TUNABLES): Define only when + TUNABLES_FRONTEND == TUNABLES_FRONTEND_valstring. + (tunables_strdup): Likewise. + (disable_tunables): Likewise. + (parse_tunables): Likewise. + (__tunables_init): Process GLIBC_TUNABLES envvar only when. + TUNABLES_FRONTEND == TUNABLES_FRONTEND_valstring. + * elf/dl-tunables.h (TUNABLES_FRONTEND_valstring): New macro. + (TUNABLES_FRONTEND_yes): New macro, define as + TUNABLES_FRONTEND_valstring by default. + * manual/install.texi: Document new acceptable values for + --enable-tunables. + * INSTALL: Regenerate. + * config.make.in (have-loop-to-function): Define. * elf/Makefile (CFLAGS-dl-tunables.c): Add -fno-tree-loop-distribute-patterns. diff --git a/INSTALL b/INSTALL index 25619fc520..55d52c5f15 100644 --- a/INSTALL +++ b/INSTALL @@ -172,7 +172,23 @@ will be used, and CFLAGS sets optimization options for the compiler. '--enable-tunables' Tunables support allows additional library parameters to be customized at runtime. This is an experimental feature and affects - startup time and is thus disabled by default. + startup time and is thus disabled by default. This option can take + the following values: + + 'no' + This is the default if the option is not passed to configure. + This disables tunables. + + 'yes' + This is the default if the option is passed to configure. + This enables tunables and selects the default frontend + (currently 'valstring'). + + 'valstring' + This enables tunables and selects the 'valstring' frontend for + tunables. This frontend allows users to specify tunables as a + colon-separated list in a single environment variable + 'GLIBC_TUNABLES'. '--build=BUILD-SYSTEM' '--host=HOST-SYSTEM' diff --git a/Makeconfig b/Makeconfig index b173e4cc08..1a2db6da1d 100644 --- a/Makeconfig +++ b/Makeconfig @@ -935,7 +935,7 @@ CPPFLAGS = $(config-extra-cppflags) $(CPPUNDEFS) $(CPPFLAGS-config) \ $(libof-$( Date: Sun, 12 Mar 2017 13:16:18 -0700 Subject: Fix combreloc test with BSD grep The test for "-z combreloc" fails when cross-compiling on a machine that uses BSD grep (e.g. on macos). grep complains about empty subexpression and exits with non-zero status, which is interpreted by configure as "not found". As a result, support for "-z combreloc" (HAVE_Z_COMBRELOC) is not detected, leading to link failure on SPARC. While there, replace fgrep with 'grep -F', as fgrep is non-POSIX. * configure.ac: Avoid empty subexpression in grep. Signed-off-by: Alexey Neyman --- ChangeLog | 5 +++++ configure | 8 ++++---- configure.ac | 10 +++++----- 3 files changed, 14 insertions(+), 9 deletions(-) (limited to 'configure.ac') diff --git a/ChangeLog b/ChangeLog index 03ea36f08e..47faa520be 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2017-03-15 Alexey Neyman + + * configure.ac: Avoid empty subexpression in grep. + * configure: Regenerate. + 2017-03-13 Adhemerval Zanella * posix/test-errno.c (do_test): Initialize setsockopt optlen. diff --git a/configure b/configure index eecd0ace74..5be4ff611f 100755 --- a/configure +++ b/configure @@ -5804,7 +5804,7 @@ if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; } then - if $READELF -S conftest.so | grep '\.rel\(a\|\)\.dyn' > /dev/null; then + if $READELF -S conftest.so | grep -E '.rela?.dyn' > /dev/null; then libc_cv_z_combreloc=yes else libc_cv_z_combreloc=no @@ -6120,7 +6120,7 @@ void zero (void *x) __builtin_memset (x, 0, 1000); } EOF -if { ac_try='${CC-cc} -O3 -S conftest.c -o - | fgrep "memset" > /dev/null' +if { ac_try='${CC-cc} -O3 -S conftest.c -o - | grep -F "memset" > /dev/null' { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -6152,7 +6152,7 @@ char *foo (const char *a, const char *b) return __builtin_strstr (a, b); } EOF -if { ac_try='${CC-cc} -O3 -S conftest.c -o - | fgrep "my_strstr" > /dev/null' +if { ac_try='${CC-cc} -O3 -S conftest.c -o - | grep -F "my_strstr" > /dev/null' { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -6511,7 +6511,7 @@ long ehdr (void) { return __ehdr_start.val; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : - if $READELF -r conftest | fgrep __ehdr_start >/dev/null; then + if $READELF -r conftest | grep -F __ehdr_start >/dev/null; then libc_cv_ehdr_start=broken else libc_cv_ehdr_start=yes diff --git a/configure.ac b/configure.ac index 4a77411b71..4981bf9691 100644 --- a/configure.ac +++ b/configure.ac @@ -1390,8 +1390,8 @@ dnl The following test is a bit weak. We must use a tool which can test dnl cross-platform since the gcc used can be a cross compiler. Without dnl introducing new options this is not easily doable. Instead use a tool dnl which always is cross-platform: readelf. To detect whether -z combreloc -dnl look for a section named .rel.dyn. - if $READELF -S conftest.so | grep '\.rel\(a\|\)\.dyn' > /dev/null; then +dnl look for a section named .rel.dyn or .rela.dyn. + if $READELF -S conftest.so | grep -E '.rela?.dyn' > /dev/null; then libc_cv_z_combreloc=yes else libc_cv_z_combreloc=no @@ -1586,7 +1586,7 @@ void zero (void *x) } EOF dnl -if AC_TRY_COMMAND([${CC-cc} -O3 -S conftest.c -o - | fgrep "memset" > /dev/null]); +if AC_TRY_COMMAND([${CC-cc} -O3 -S conftest.c -o - | grep -F "memset" > /dev/null]); then libc_cv_gcc_builtin_memset=no else @@ -1606,7 +1606,7 @@ char *foo (const char *a, const char *b) } EOF dnl -if AC_TRY_COMMAND([${CC-cc} -O3 -S conftest.c -o - | fgrep "my_strstr" > /dev/null]); +if AC_TRY_COMMAND([${CC-cc} -O3 -S conftest.c -o - | grep -F "my_strstr" > /dev/null]); then libc_cv_gcc_builtin_redirection=yes else @@ -1747,7 +1747,7 @@ typedef struct { extern const Ehdr __ehdr_start __attribute__ ((visibility ("hidden"))); long ehdr (void) { return __ehdr_start.val; } ])], - [if $READELF -r conftest | fgrep __ehdr_start >/dev/null; then + [if $READELF -r conftest | grep -F __ehdr_start >/dev/null; then libc_cv_ehdr_start=broken else libc_cv_ehdr_start=yes -- cgit v1.2.3 From 1e4d83f6fe38613e6f209ff09dfad8e69a6e1629 Mon Sep 17 00:00:00 2001 From: Thorsten Kukuk Date: Tue, 21 Mar 2017 15:14:27 +0100 Subject: Deprecate libnsl by default (only shared library will be build for backward compatibility, no linking possible) and disable building of libnss_compat, libnss_nis and libnss_nisplus, except --enable-obsolete-nsl option is given to configure. * config.h.in: Add LINK_OBSOLETE_NSL. * config.make.in: Add build-obsolete-nsl. * configure.ac: Add obsolete-nsl option. * include/libc-symbols.h: Define libnsl_hidden_nolink_def. * include/rpcsvc/yp.h: Add missing functions as libnsl_hidden_proto. * include/rpcsvc/nislib.h: Likewise. * include/rpcsvc/ypclnt.h: Likewise. * manual/install.texi: Document --enable-obsolete-nsl. * nis/Makefile: Build only libnsl by default (add build-obsolete-nsl). * nis/nis_add.c: Replace libnsl_hidden_def with libnsl_hidden_nolink_def. * nis/nis_addmember.c: Likewise. * nis/nis_call.c: Likewise. * nis/nis_clone_obj.c: Likewise. * nis/nis_defaults.c: Likeise. * nis/nis_domain_of_r.c: Likewise. * nis/nis_error.c: Likewise. * nis/nis_file.c: Likewise. * nis/nis_free.c: Likewise. * nis_local_names.c: Likewise. * nis/nis_lookup.c: Likewise. * nis/nis_modify.c: Likewise. * nis/nis_print.c: Likewise. * nis/nis_remove.c: Likewise. * nis/nis_table.c: Likewise. * nis/nis_util.c: Likewise. * nis/nis_xdr.c: Likewise. * nis/yp_xdr.c: Likewise. * nis/ypclnt.c: Likewise. * nis/ypupdate_xdr.c: Likewise. * nis/nis_checkpoint.c: Add libnsl_hidden_nolink_def to all functions. * nis/nis_clone_dir.c: Likewise. * nis/nis_clone_res.c: Likewise. * nis/nis_creategroup.c: Likewise. * nis/nis_destroygroup.c: Likewise. * nis/nis_domain_of.c: Likewise. * nis/nis_getservlist.c: Likewise. * nis/nis_ismember.c: Likewise. * nis/nis_mkdir.c: Likewise. * nis/nis_ping.c: Likewise. * nis/nis_print_group_entry.c: Likewise. * nis/nis_removemember.c: Likewise. * nis/nis_rmdir.c: Likewise. * nis/nis_server.c: Likewise. * nis/nis_subr.c: Likewise. * nis/nis_verifygroup.c: Likewise. Signed-off-by: Thorsten Kukuk --- ChangeLog | 49 +++++++++++++++++++++++++++++++++++++++++++++ NEWS | 20 ++++++++++++++++++ config.h.in | 4 ++++ config.make.in | 1 + configure | 18 +++++++++++++++++ configure.ac | 11 ++++++++++ include/libc-symbols.h | 6 ++++++ include/rpcsvc/nislib.h | 33 ++++++++++++++++++++++++++++++ include/rpcsvc/yp.h | 4 ++++ include/rpcsvc/ypclnt.h | 9 +++++++++ manual/install.texi | 7 +++++++ nis/Makefile | 17 +++++++++++++--- nis/nis_add.c | 2 +- nis/nis_addmember.c | 1 + nis/nis_call.c | 12 +++++------ nis/nis_checkpoint.c | 1 + nis/nis_clone_dir.c | 1 + nis/nis_clone_obj.c | 2 +- nis/nis_clone_res.c | 1 + nis/nis_creategroup.c | 1 + nis/nis_defaults.c | 6 +++--- nis/nis_destroygroup.c | 1 + nis/nis_domain_of.c | 1 + nis/nis_domain_of_r.c | 2 +- nis/nis_error.c | 7 +++++-- nis/nis_file.c | 5 ++++- nis/nis_free.c | 10 ++++----- nis/nis_getservlist.c | 2 ++ nis/nis_ismember.c | 1 + nis/nis_local_names.c | 8 ++++---- nis/nis_lookup.c | 2 +- nis/nis_mkdir.c | 1 + nis/nis_modify.c | 2 +- nis/nis_ping.c | 1 + nis/nis_print.c | 15 +++++++------- nis/nis_print_group_entry.c | 1 + nis/nis_remove.c | 2 +- nis/nis_removemember.c | 1 + nis/nis_rmdir.c | 1 + nis/nis_server.c | 3 +++ nis/nis_subr.c | 14 +++++++------ nis/nis_table.c | 11 +++++++--- nis/nis_util.c | 2 +- nis/nis_verifygroup.c | 1 + nis/nis_xdr.c | 8 ++++---- nis/yp_xdr.c | 47 ++++++++++++++++++++++++------------------- nis/ypclnt.c | 20 ++++++++++++------ nis/ypupdate_xdr.c | 6 +++--- 48 files changed, 300 insertions(+), 81 deletions(-) (limited to 'configure.ac') diff --git a/ChangeLog b/ChangeLog index eb5b25ae02..f500b833de 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,52 @@ +2017-03-21 Thorsten Kukuk + + * config.h.in: Add LINK_OBSOLETE_NSL. + * config.make.in: Add build-obsolete-nsl. + * configure.ac: Add obsolete-nsl option. + * include/libc-symbols.h: Define libnsl_hidden_nolink_def. + * include/rpcsvc/yp.h: Add missing functions as libnsl_hidden_proto. + * include/rpcsvc/nislib.h: Likewise. + * include/rpcsvc/ypclnt.h: Likewise. + * manual/install.texi: Document --enable-obsolete-nsl. + * nis/Makefile: Build only libnsl by default (add build-obsolete-nsl). + * nis/nis_add.c: Replace libnsl_hidden_def with + libnsl_hidden_nolink_def. + * nis/nis_addmember.c: Likewise. + * nis/nis_call.c: Likewise. + * nis/nis_clone_obj.c: Likewise. + * nis/nis_defaults.c: Likeise. + * nis/nis_domain_of_r.c: Likewise. + * nis/nis_error.c: Likewise. + * nis/nis_file.c: Likewise. + * nis/nis_free.c: Likewise. + * nis_local_names.c: Likewise. + * nis/nis_lookup.c: Likewise. + * nis/nis_modify.c: Likewise. + * nis/nis_print.c: Likewise. + * nis/nis_remove.c: Likewise. + * nis/nis_table.c: Likewise. + * nis/nis_util.c: Likewise. + * nis/nis_xdr.c: Likewise. + * nis/yp_xdr.c: Likewise. + * nis/ypclnt.c: Likewise. + * nis/ypupdate_xdr.c: Likewise. + * nis/nis_checkpoint.c: Add libnsl_hidden_nolink_def to all functions. + * nis/nis_clone_dir.c: Likewise. + * nis/nis_clone_res.c: Likewise. + * nis/nis_creategroup.c: Likewise. + * nis/nis_destroygroup.c: Likewise. + * nis/nis_domain_of.c: Likewise. + * nis/nis_getservlist.c: Likewise. + * nis/nis_ismember.c: Likewise. + * nis/nis_mkdir.c: Likewise. + * nis/nis_ping.c: Likewise. + * nis/nis_print_group_entry.c: Likewise. + * nis/nis_removemember.c: Likewise. + * nis/nis_rmdir.c: Likewise. + * nis/nis_server.c: Likewise. + * nis/nis_subr.c: Likewise. + * nis/nis_verifygroup.c: Likewise. + 2017-03-20 Joseph Myers [BZ #21279] diff --git a/NEWS b/NEWS index 9efe1e5c0e..5162534d2d 100644 --- a/NEWS +++ b/NEWS @@ -17,6 +17,26 @@ Version 2.26 by default. Applications needing features missing from TIRPC should consider the rpcsvc-proto project developed by Thorsten Kukuk (SUSE). +* The NIS(+) name service modules, libnss_nis, libnss_nisplus, and + libnss_compat, are deprecated, and will not be built or installed by + default. Replacement implementations based on TIRPC, which + additionally support IPv6, are available from + . + +* The NIS(+) support library, libnsl, is deprecated. By default, a + compatibility shared library will be built and installed, but not + headers or development libraries. + + Only a few NIS-related programs require this library. + A replacement implementation based on TIRPC is available from + . Like the replacement NIS(+) + name service modules, the replacement supports IPv6, and it can be + coinstalled with the compatibility shared library from glibc. + +* New configure option --enable-obsolete-nsl will cause libnsl's + headers, and the NIS(+) name service modules, to be built and + installed. This option may be removed in a future release. + Security related changes: [Add security related changes here] diff --git a/config.h.in b/config.h.in index fb2cc51c03..4ce845de51 100644 --- a/config.h.in +++ b/config.h.in @@ -172,6 +172,10 @@ to link against. */ #undef LINK_OBSOLETE_RPC +/* Define if obsolete libnsl code should be made available for user-level + code to link against. */ +#undef LINK_OBSOLETE_NSL + /* Define if Systemtap probes should be defined. */ #undef USE_STAP_PROBE diff --git a/config.make.in b/config.make.in index 5836b32a72..d08a462d05 100644 --- a/config.make.in +++ b/config.make.in @@ -92,6 +92,7 @@ sysdeps-add-ons = @sysdeps_add_ons@ cross-compiling = @cross_compiling@ force-install = @force_install@ link-obsolete-rpc = @link_obsolete_rpc@ +build-obsolete-nsl = @build_obsolete_nsl@ build-nscd = @build_nscd@ use-nscd = @use_nscd@ build-hardcoded-path-in-tests= @hardcoded_path_in_tests@ diff --git a/configure b/configure index 5be4ff611f..422482f355 100755 --- a/configure +++ b/configure @@ -669,6 +669,7 @@ add_ons have_tunables build_pt_chown build_nscd +build_obsolete_nsl link_obsolete_rpc libc_cv_static_nss_crypt libc_cv_nss_crypt @@ -779,6 +780,7 @@ enable_werror enable_multi_arch enable_nss_crypt enable_obsolete_rpc +enable_obsolete_nsl enable_systemtap enable_build_nscd enable_nscd @@ -1450,6 +1452,8 @@ Optional Features: --enable-nss-crypt enable libcrypt to use nss --enable-obsolete-rpc build and install the obsolete RPC code for link-time usage + --enable-obsolete-nsl build and install the obsolete libnsl library and + depending NSS modules --enable-systemtap enable systemtap static probe points [default=no] --disable-build-nscd disable building and installing the nscd daemon --disable-nscd library functions will not contact the nscd daemon @@ -3626,6 +3630,20 @@ if test "$link_obsolete_rpc" = yes; then fi +# Check whether --enable-obsolete-nsl was given. +if test "${enable_obsolete_nsl+set}" = set; then : + enableval=$enable_obsolete_nsl; build_obsolete_nsl=$enableval +else + build_obsolete_nsl=no +fi + + + +if test "$build_obsolete_nsl" = yes; then + $as_echo "#define LINK_OBSOLETE_NSL 1" >>confdefs.h + +fi + # Check whether --enable-systemtap was given. if test "${enable_systemtap+set}" = set; then : enableval=$enable_systemtap; systemtap=$enableval diff --git a/configure.ac b/configure.ac index 4981bf9691..7f430425ae 100644 --- a/configure.ac +++ b/configure.ac @@ -374,6 +374,17 @@ if test "$link_obsolete_rpc" = yes; then AC_DEFINE(LINK_OBSOLETE_RPC) fi +AC_ARG_ENABLE([obsolete-nsl], + AC_HELP_STRING([--enable-obsolete-nsl], + [build and install the obsolete libnsl library and depending NSS modules]), + [build_obsolete_nsl=$enableval], + [build_obsolete_nsl=no]) +AC_SUBST(build_obsolete_nsl) + +if test "$build_obsolete_nsl" = yes; then + AC_DEFINE(LINK_OBSOLETE_NSL) +fi + AC_ARG_ENABLE([systemtap], [AS_HELP_STRING([--enable-systemtap], [enable systemtap static probe points @<:@default=no@:>@])], diff --git a/include/libc-symbols.h b/include/libc-symbols.h index 775d8af84e..0783ade0b3 100644 --- a/include/libc-symbols.h +++ b/include/libc-symbols.h @@ -663,6 +663,12 @@ for linking") # define libnsl_hidden_proto(name, attrs...) hidden_proto (name, ##attrs) # define libnsl_hidden_tls_proto(name, attrs...) \ hidden_tls_proto (name, ##attrs) +# ifdef LINK_OBSOLETE_NSL + /* libnsl_hidden_nolink should only get used in libnsl code. */ +# define libnsl_hidden_nolink_def(name, version) libnsl_hidden_def (name) +# else +# define libnsl_hidden_nolink_def(name, version) hidden_nolink (name, libnsl, version) +# endif # define libnsl_hidden_def(name) hidden_def (name) # define libnsl_hidden_weak(name) hidden_weak (name) # define libnsl_hidden_ver(local, name) hidden_ver (local, name) diff --git a/include/rpcsvc/nislib.h b/include/rpcsvc/nislib.h index 05b19877e7..91dab1d171 100644 --- a/include/rpcsvc/nislib.h +++ b/include/rpcsvc/nislib.h @@ -19,6 +19,7 @@ libnsl_hidden_proto (nis_free_directory) libnsl_hidden_proto (nis_free_object) libnsl_hidden_proto (nis_freeresult) libnsl_hidden_proto (readColdStartFile) +libnsl_hidden_proto (writeColdStartFile) libnsl_hidden_proto (nis_print_rights) libnsl_hidden_proto (nis_print_directory) libnsl_hidden_proto (nis_print_group) @@ -43,6 +44,38 @@ libnsl_hidden_proto (__nis_default_owner) libnsl_hidden_proto (__nis_default_group) libnsl_hidden_proto (__nis_default_access) libnsl_hidden_proto (nis_clone_object) +libnsl_hidden_proto (nis_clone_result) +libnsl_hidden_proto (nis_print_group_entry) +libnsl_hidden_proto (nis_verifygroup) +libnsl_hidden_proto (nis_leaf_of) +libnsl_hidden_proto (nis_read_obj) +libnsl_hidden_proto (nis_print_result) +libnsl_hidden_proto (nis_sperror) +libnsl_hidden_proto (nis_add_entry) +libnsl_hidden_proto (nis_mkdir) +libnsl_hidden_proto (nis_getservlist) +libnsl_hidden_proto (nis_stats) +libnsl_hidden_proto (nis_write_obj) +libnsl_hidden_proto (nis_servstate) +libnsl_hidden_proto (nis_freetags) +libnsl_hidden_proto (nis_modify_entry) +libnsl_hidden_proto (nis_remove_entry) +libnsl_hidden_proto (nis_first_entry) +libnsl_hidden_proto (nis_next_entry) +libnsl_hidden_proto (nis_checkpoint) +libnsl_hidden_proto (nis_perror) +libnsl_hidden_proto (nis_lerror) +libnsl_hidden_proto (nis_freeservlist) +libnsl_hidden_proto (nis_ismember) +libnsl_hidden_proto (nis_creategroup) +libnsl_hidden_proto (nis_destroygroup) +libnsl_hidden_proto (nis_name_of) +libnsl_hidden_proto (nis_ping) +libnsl_hidden_proto (nis_rmdir) +libnsl_hidden_proto (nis_addmember) +libnsl_hidden_proto (nis_removemember) +libnsl_hidden_proto (nis_domain_of) +libnsl_hidden_proto (nis_clone_directory) extern const_nis_name __nis_domain_of (const_nis_name) __THROW; diff --git a/include/rpcsvc/yp.h b/include/rpcsvc/yp.h index b6d7c15f62..9078854d40 100644 --- a/include/rpcsvc/yp.h +++ b/include/rpcsvc/yp.h @@ -24,6 +24,10 @@ libnsl_hidden_proto (xdr_ypresp_maplist) libnsl_hidden_proto (xdr_ypresp_order) libnsl_hidden_proto (xdr_ypbind_resp) libnsl_hidden_proto (xdr_ypresp_master) +libnsl_hidden_proto (xdr_ypreq_xfr) +libnsl_hidden_proto (xdr_ypresp_xfr) +libnsl_hidden_proto (xdr_yppushresp_xfr) +libnsl_hidden_proto (xdr_ypbind_setdom) # endif /* !_ISOMAC */ #endif diff --git a/include/rpcsvc/ypclnt.h b/include/rpcsvc/ypclnt.h index 1b4e2f215c..df2a03d9c5 100644 --- a/include/rpcsvc/ypclnt.h +++ b/include/rpcsvc/ypclnt.h @@ -8,6 +8,15 @@ libnsl_hidden_proto (yp_bind) libnsl_hidden_proto (yp_get_default_domain) libnsl_hidden_proto (ypprot_err) libnsl_hidden_proto (yp_master) +libnsl_hidden_proto (yp_update) +libnsl_hidden_proto (yperr_string) +libnsl_hidden_proto (yp_unbind) +libnsl_hidden_proto (yp_order) +libnsl_hidden_proto (yp_first) +libnsl_hidden_proto (yp_next) +libnsl_hidden_proto (yp_match) +libnsl_hidden_proto (yp_all) +libnsl_hidden_proto (__yp_check) # endif /* !_ISOMAC */ #endif diff --git a/manual/install.texi b/manual/install.texi index 3398cfab02..99397c2ee0 100644 --- a/manual/install.texi +++ b/manual/install.texi @@ -226,6 +226,13 @@ This frontend allows users to specify tunables as a colon-separated list in a single environment variable @env{GLIBC_TUNABLES}. @end table +@item --enable-obsolete-nsl +By default, libnsl is only built as shared library for backward +compatibility and the NSS modules libnss_compat, libnss_nis and +libnss_nisplus are not built at all. +Use this option to enable libnsl with all depending NSS modules and +header files. + @item --build=@var{build-system} @itemx --host=@var{host-system} These options are for cross-compiling. If you specify both options and diff --git a/nis/Makefile b/nis/Makefile index d6be9e27fd..6b6f5ee72c 100644 --- a/nis/Makefile +++ b/nis/Makefile @@ -24,9 +24,8 @@ include ../Makeconfig aux := nis_hash -ifeq ($(link-obsolete-rpc),yes) +ifeq ($(build-obsolete-nsl),yes) headers := $(wildcard rpcsvc/*.[hx]) -endif # These are the databases available for the nis (and perhaps later nisplus) # service. This must be a superset of the services in nss. @@ -35,15 +34,21 @@ databases = proto service hosts network grp pwd rpc ethers \ # Specify rules for the nss_* modules. services := nis nisplus compat +endif -extra-libs = libnsl $(services:%=libnss_%) +extra-libs = libnsl +ifeq ($(build-obsolete-nsl),yes) +extra-libs += $(services:%=libnss_%) +endif # These libraries will be built in the `others' pass rather than # the `lib' pass, because they depend on libc.so being built already. extra-libs-others = $(extra-libs) +ifeq ($(build-obsolete-nsl),yes) # The sources are found in the appropriate subdir. subdir-dirs = $(services:%=nss_%) vpath %.c $(subdir-dirs) +endif libnsl-routines = yp_xdr ypclnt ypupdate_xdr \ nis_subr nis_local_names nis_free nis_file \ @@ -57,6 +62,7 @@ libnsl-routines = yp_xdr ypclnt ypupdate_xdr \ nis_findserv nis_callback nis_clone_dir nis_clone_obj\ nis_clone_res nss-default +ifeq ($(build-obsolete-nsl),yes) libnss_compat-routines := $(addprefix compat-,grp pwd spwd initgroups) libnss_compat-inhibit-o = $(filter-out .os,$(object-suffixes)) @@ -67,14 +73,17 @@ libnss_nis-inhibit-o = $(filter-out .os,$(object-suffixes)) libnss_nisplus-routines := $(addprefix nisplus-,$(databases)) nisplus-parser \ nss-nisplus nisplus-initgroups libnss_nisplus-inhibit-o = $(filter-out .os,$(object-suffixes)) +endif include ../Rules +ifeq ($(build-obsolete-nsl),yes) $(objpfx)libnss_compat.so: $(objpfx)libnsl.so$(libnsl.so-version) $(objpfx)libnss_nis.so: $(objpfx)libnsl.so$(libnsl.so-version) \ $(common-objpfx)nss/libnss_files.so $(objpfx)libnss_nisplus.so: $(objpfx)libnsl.so$(libnsl.so-version) +endif libnsl-libc = $(common-objpfx)linkobj/libc.so # Target-specific variable setting to link objects using deprecated @@ -87,5 +96,7 @@ $(services:%=$(objpfx)libnss_%.so) $(objpfx)libnsl.so: \ ifeq ($(build-shared),yes) $(others:%=$(objpfx)%): $(objpfx)libnsl.so$(libnsl.so-version) else +ifeq ($(build-obsolete-nsl),yes) $(others:%=$(objpfx)%): $(objpfx)libnsl.a endif +endif diff --git a/nis/nis_add.c b/nis/nis_add.c index 349db47b0b..3ec49c018a 100644 --- a/nis/nis_add.c +++ b/nis/nis_add.c @@ -71,4 +71,4 @@ nis_add (const_nis_name name, const nis_object *obj2) return res; } -libnsl_hidden_def (nis_add) +libnsl_hidden_nolink_def (nis_add, GLIBC_2_1) diff --git a/nis/nis_addmember.c b/nis/nis_addmember.c index 57494c4ad0..6b0c29530f 100644 --- a/nis/nis_addmember.c +++ b/nis/nis_addmember.c @@ -90,3 +90,4 @@ nis_addmember (const_nis_name member, const_nis_name group) else return NIS_FAIL; } +libnsl_hidden_nolink_def (nis_addmember, GLIBC_2_1) diff --git a/nis/nis_call.c b/nis/nis_call.c index 386333c055..03b15de2bc 100644 --- a/nis/nis_call.c +++ b/nis/nis_call.c @@ -65,7 +65,7 @@ __nisbind_destroy (dir_binding *bind) clnt_destroy (bind->clnt); } } -libnsl_hidden_def (__nisbind_destroy) +libnsl_hidden_nolink_def (__nisbind_destroy, GLIBC_2_1) nis_error __nisbind_next (dir_binding *bind) @@ -107,7 +107,7 @@ __nisbind_next (dir_binding *bind) return NIS_FAIL; } -libnsl_hidden_def (__nisbind_next) +libnsl_hidden_nolink_def (__nisbind_next, GLIBC_2_1) static struct ckey_cache_entry { @@ -246,7 +246,7 @@ __nisbind_connect (dir_binding *dbp) return NIS_SUCCESS; } -libnsl_hidden_def (__nisbind_connect) +libnsl_hidden_nolink_def (__nisbind_connect, GLIBC_2_1) nis_error __nisbind_create (dir_binding *dbp, const nis_server *serv_val, @@ -290,7 +290,7 @@ __nisbind_create (dir_binding *dbp, const nis_server *serv_val, return NIS_SUCCESS; } -libnsl_hidden_def (__nisbind_create) +libnsl_hidden_nolink_def (__nisbind_create, GLIBC_2_1) /* __nisbind_connect (dbp) must be run before calling this function ! So we could use the same binding twice */ @@ -374,7 +374,7 @@ __do_niscall3 (dir_binding *dbp, u_long prog, xdrproc_t xargs, caddr_t req, return retcode; } -libnsl_hidden_def (__do_niscall3) +libnsl_hidden_nolink_def (__do_niscall3, GLIBC_PRIVATE) nis_error @@ -816,7 +816,7 @@ __prepare_niscall (const_nis_name name, directory_obj **dirp, return retcode; } -libnsl_hidden_def (__prepare_niscall) +libnsl_hidden_nolink_def (__prepare_niscall, GLIBC_PRIVATE) nis_error diff --git a/nis/nis_checkpoint.c b/nis/nis_checkpoint.c index a36fec9f86..06656a476e 100644 --- a/nis/nis_checkpoint.c +++ b/nis/nis_checkpoint.c @@ -76,3 +76,4 @@ nis_checkpoint (const_nis_name dirname) return res; } +libnsl_hidden_nolink_def (nis_checkpoint, GLIBC_2_1) diff --git a/nis/nis_clone_dir.c b/nis/nis_clone_dir.c index c3aad5f637..41e2f77210 100644 --- a/nis/nis_clone_dir.c +++ b/nis/nis_clone_dir.c @@ -71,3 +71,4 @@ nis_clone_directory (const directory_obj *src, directory_obj *dest) return res; } +libnsl_hidden_nolink_def(nis_clone_directory, GLIBC_2_1) diff --git a/nis/nis_clone_obj.c b/nis/nis_clone_obj.c index 5181867a45..7299e11f6e 100644 --- a/nis/nis_clone_obj.c +++ b/nis/nis_clone_obj.c @@ -64,4 +64,4 @@ nis_clone_object (const nis_object *src, nis_object *dest) return res; } -libnsl_hidden_def (nis_clone_object) +libnsl_hidden_nolink_def (nis_clone_object, GLIBC_2_1) diff --git a/nis/nis_clone_res.c b/nis/nis_clone_res.c index 9cbf078ede..ca998346f8 100644 --- a/nis/nis_clone_res.c +++ b/nis/nis_clone_res.c @@ -71,3 +71,4 @@ nis_clone_result (const nis_result *src, nis_result *dest) return res; } +libnsl_hidden_nolink_def (nis_clone_result, GLIBC_2_1) diff --git a/nis/nis_creategroup.c b/nis/nis_creategroup.c index 61528e579f..6d5a08dc81 100644 --- a/nis/nis_creategroup.c +++ b/nis/nis_creategroup.c @@ -81,3 +81,4 @@ nis_creategroup (const_nis_name group, unsigned int flags) } return NIS_FAIL; } +libnsl_hidden_nolink_def (nis_creategroup, GLIBC_2_1) diff --git a/nis/nis_defaults.c b/nis/nis_defaults.c index 5ac9fb1482..7e6054d35d 100644 --- a/nis/nis_defaults.c +++ b/nis/nis_defaults.c @@ -375,7 +375,7 @@ __nis_default_owner (char *defaults) return strdup (default_owner ?: nis_local_principal ()); } -libnsl_hidden_def (__nis_default_owner) +libnsl_hidden_nolink_def (__nis_default_owner, GLIBC_2_1) nis_name @@ -402,7 +402,7 @@ __nis_default_group (char *defaults) return strdup (default_group ?: nis_local_group ()); } -libnsl_hidden_def (__nis_default_group) +libnsl_hidden_nolink_def (__nis_default_group, GLIBC_2_1) uint32_t @@ -452,4 +452,4 @@ __nis_default_access (char *param, unsigned int defaults) return result; } -libnsl_hidden_def (__nis_default_access) +libnsl_hidden_nolink_def (__nis_default_access, GLIBC_2_1) diff --git a/nis/nis_destroygroup.c b/nis/nis_destroygroup.c index 3232639e39..662d658693 100644 --- a/nis/nis_destroygroup.c +++ b/nis/nis_destroygroup.c @@ -49,3 +49,4 @@ nis_destroygroup (const_nis_name group) return NIS_FAIL; } +libnsl_hidden_nolink_def (nis_destroygroup, GLIBC_2_1) diff --git a/nis/nis_domain_of.c b/nis/nis_domain_of.c index f58630452c..6e2025cbdc 100644 --- a/nis/nis_domain_of.c +++ b/nis/nis_domain_of.c @@ -25,6 +25,7 @@ nis_domain_of (const_nis_name name) return nis_domain_of_r (name, result, NIS_MAXNAMELEN); } +libnsl_hidden_nolink_def (nis_domain_of, GLIBC_2_1) const_nis_name __nis_domain_of (const_nis_name name) diff --git a/nis/nis_domain_of_r.c b/nis/nis_domain_of_r.c index e81fe45184..57f99a2ced 100644 --- a/nis/nis_domain_of_r.c +++ b/nis/nis_domain_of_r.c @@ -58,4 +58,4 @@ nis_domain_of_r (const_nis_name name, char *buffer, size_t buflen) return memcpy (buffer, cptr, cptr_len + 1); } -libnsl_hidden_def (nis_domain_of_r) +libnsl_hidden_nolink_def (nis_domain_of_r, GLIBC_2_1) diff --git a/nis/nis_error.c b/nis/nis_error.c index 78fd4befdd..e55d784dfb 100644 --- a/nis/nis_error.c +++ b/nis/nis_error.c @@ -59,19 +59,21 @@ nis_sperrno (const nis_error status) else return gettext (msgstr.str + msgidx[status]); } -libnsl_hidden_def (nis_sperrno) +libnsl_hidden_nolink_def (nis_sperrno, GLIBC_2_1) void nis_perror (const nis_error status, const char *label) { fprintf (stderr, "%s: %s\n", label, nis_sperrno (status)); } +libnsl_hidden_nolink_def (nis_perror, GLIBC_2_1) void nis_lerror (const nis_error status, const char *label) { syslog (LOG_ERR, "%s: %s", label, nis_sperrno (status)); } +libnsl_hidden_nolink_def (nis_lerror, GLIBC_2_1) char * nis_sperror_r (const nis_error status, const char *label, @@ -86,7 +88,7 @@ nis_sperror_r (const nis_error status, const char *label, return buffer; } -libnsl_hidden_def (nis_sperror_r) +libnsl_hidden_nolink_def (nis_sperror_r, GLIBC_2_1) char * nis_sperror (const nis_error status, const char *label) @@ -95,3 +97,4 @@ nis_sperror (const nis_error status, const char *label) return nis_sperror_r (status, label, buffer, sizeof (buffer)); } +libnsl_hidden_nolink_def (nis_sperror, GLIBC_2_1) diff --git a/nis/nis_file.c b/nis/nis_file.c index def30b7c9a..c3c6c57f22 100644 --- a/nis/nis_file.c +++ b/nis/nis_file.c @@ -80,13 +80,14 @@ readColdStartFile (void) return read_nis_obj (cold_start_file, (iofct_t) _xdr_directory_obj, (freefct_t) nis_free_directory, sizeof (directory_obj)); } -libnsl_hidden_def (readColdStartFile) +libnsl_hidden_nolink_def (readColdStartFile, GLIBC_2_1) bool_t writeColdStartFile (const directory_obj *obj) { return write_nis_obj (cold_start_file, obj, (iofct_t) _xdr_directory_obj); } +libnsl_hidden_nolink_def (writeColdStartFile, GLIBC_2_1) nis_object * nis_read_obj (const char *name) @@ -94,9 +95,11 @@ nis_read_obj (const char *name) return read_nis_obj (name, (iofct_t) _xdr_nis_object, (freefct_t) nis_free_object, sizeof (nis_object)); } +libnsl_hidden_nolink_def (nis_read_obj, GLIBC_2_1) bool_t nis_write_obj (const char *name, const nis_object *obj) { return write_nis_obj (name, obj, (iofct_t) _xdr_nis_object); } +libnsl_hidden_nolink_def (nis_write_obj, GLIBC_2_1) diff --git a/nis/nis_free.c b/nis/nis_free.c index 108148921a..2b1580e9d5 100644 --- a/nis/nis_free.c +++ b/nis/nis_free.c @@ -28,7 +28,7 @@ __free_fdresult (fd_result *res) free (res); } } -libnsl_hidden_def (__free_fdresult) +libnsl_hidden_nolink_def (__free_fdresult, GLIBC_2_1) void nis_free_request (ib_request *ibreq) @@ -39,7 +39,7 @@ nis_free_request (ib_request *ibreq) free (ibreq); } } -libnsl_hidden_def (nis_free_request) +libnsl_hidden_nolink_def (nis_free_request, GLIBC_2_1) void nis_free_directory (directory_obj *obj) @@ -50,7 +50,7 @@ nis_free_directory (directory_obj *obj) free (obj); } } -libnsl_hidden_def (nis_free_directory) +libnsl_hidden_nolink_def (nis_free_directory, GLIBC_2_1) void nis_free_object (nis_object *obj) @@ -61,7 +61,7 @@ nis_free_object (nis_object *obj) free (obj); } } -libnsl_hidden_def (nis_free_object) +libnsl_hidden_nolink_def (nis_free_object, GLIBC_2_1) void nis_freeresult (nis_result *res) @@ -72,4 +72,4 @@ nis_freeresult (nis_result *res) free (res); } } -libnsl_hidden_def (nis_freeresult) +libnsl_hidden_nolink_def (nis_freeresult, GLIBC_2_1) diff --git a/nis/nis_getservlist.c b/nis/nis_getservlist.c index 29c246cfa5..1f9482c7da 100644 --- a/nis/nis_getservlist.c +++ b/nis/nis_getservlist.c @@ -148,6 +148,7 @@ nis_getservlist (const_nis_name dir) return serv; } +libnsl_hidden_nolink_def (nis_getservlist, GLIBC_2_1) void nis_freeservlist (nis_server **serv) @@ -166,3 +167,4 @@ nis_freeservlist (nis_server **serv) } free (serv); } +libnsl_hidden_nolink_def (nis_freeservlist, GLIBC_2_1) diff --git a/nis/nis_ismember.c b/nis/nis_ismember.c index 1dfdd7fbdf..0006d6f80a 100644 --- a/nis/nis_ismember.c +++ b/nis/nis_ismember.c @@ -146,3 +146,4 @@ nis_ismember (const_nis_name principal, const_nis_name group) else return FALSE; } +libnsl_hidden_nolink_def (nis_ismember, GLIBC_2_1) diff --git a/nis/nis_local_names.c b/nis/nis_local_names.c index c7a184c9ec..090125d7de 100644 --- a/nis/nis_local_names.c +++ b/nis/nis_local_names.c @@ -49,7 +49,7 @@ nis_local_group (void) return __nisgroup; } -libnsl_hidden_def (nis_local_group) +libnsl_hidden_nolink_def (nis_local_group, GLIBC_2_1) nis_name nis_local_directory (void) @@ -75,7 +75,7 @@ nis_local_directory (void) return __nisdomainname; } -libnsl_hidden_def (nis_local_directory) +libnsl_hidden_nolink_def (nis_local_directory, GLIBC_2_1) nis_name nis_local_principal (void) @@ -140,7 +140,7 @@ LOCAL entry for UID %d in directory %s not unique\n"), } return __principal; } -libnsl_hidden_def (nis_local_principal) +libnsl_hidden_nolink_def (nis_local_principal, GLIBC_2_1) nis_name nis_local_host (void) @@ -174,4 +174,4 @@ nis_local_host (void) return __nishostname; } -libnsl_hidden_def (nis_local_host) +libnsl_hidden_nolink_def (nis_local_host, GLIBC_2_1) diff --git a/nis/nis_lookup.c b/nis/nis_lookup.c index 3449ce270c..2b953cff90 100644 --- a/nis/nis_lookup.c +++ b/nis/nis_lookup.c @@ -215,4 +215,4 @@ nis_lookup (const_nis_name name, const unsigned int flags) return res; } -libnsl_hidden_def (nis_lookup) +libnsl_hidden_nolink_def (nis_lookup, GLIBC_2_1) diff --git a/nis/nis_mkdir.c b/nis/nis_mkdir.c index 4cb213380c..bea7d18d0f 100644 --- a/nis/nis_mkdir.c +++ b/nis/nis_mkdir.c @@ -40,3 +40,4 @@ nis_mkdir (const_nis_name dir, const nis_server *server) return res; } +libnsl_hidden_nolink_def (nis_mkdir, GLIBC_2_1) diff --git a/nis/nis_modify.c b/nis/nis_modify.c index b2b139e5da..18d1bd1114 100644 --- a/nis/nis_modify.c +++ b/nis/nis_modify.c @@ -71,4 +71,4 @@ nis_modify (const_nis_name name, const nis_object *obj2) return res; } -libnsl_hidden_def (nis_modify) +libnsl_hidden_nolink_def (nis_modify, GLIBC_2_1) diff --git a/nis/nis_ping.c b/nis/nis_ping.c index 79ed5e4bb1..1924336352 100644 --- a/nis/nis_ping.c +++ b/nis/nis_ping.c @@ -67,3 +67,4 @@ nis_ping (const_nis_name dirname, unsigned int utime, (caddr_t) NULL, 0, NULL); nis_freeresult (res); } +libnsl_hidden_nolink_def (nis_ping, GLIBC_2_1) diff --git a/nis/nis_print.c b/nis/nis_print.c index 591582f568..0ee49020a0 100644 --- a/nis/nis_print.c +++ b/nis/nis_print.c @@ -156,7 +156,7 @@ nis_print_rights (const unsigned int access) } fputs (result, stdout); } -libnsl_hidden_def (nis_print_rights) +libnsl_hidden_nolink_def (nis_print_rights, GLIBC_2_1) void nis_print_directory (const directory_obj *dir) @@ -244,7 +244,7 @@ nis_print_directory (const directory_obj *dir) } } } -libnsl_hidden_def (nis_print_directory) +libnsl_hidden_nolink_def (nis_print_directory, GLIBC_2_1) void nis_print_group (const group_obj *obj) @@ -259,7 +259,7 @@ nis_print_group (const group_obj *obj) for (i = 0; i < obj->gr_members.gr_members_len; i++) printf ("\t%s\n", obj->gr_members.gr_members_val[i]); } -libnsl_hidden_def (nis_print_group) +libnsl_hidden_nolink_def (nis_print_group, GLIBC_2_1) void nis_print_table (const table_obj *obj) @@ -282,7 +282,7 @@ nis_print_table (const table_obj *obj) fputc ('\n', stdout); } } -libnsl_hidden_def (nis_print_table) +libnsl_hidden_nolink_def (nis_print_table, GLIBC_2_1) void nis_print_link (const link_obj *obj) @@ -292,7 +292,7 @@ nis_print_link (const link_obj *obj) printf (_("Linked to : %s\n"), obj->li_name); /* XXX Print the attributes here, if they exists */ } -libnsl_hidden_def (nis_print_link) +libnsl_hidden_nolink_def (nis_print_link, GLIBC_2_1) void nis_print_entry (const entry_obj *obj) @@ -316,7 +316,7 @@ nis_print_entry (const entry_obj *obj) obj->en_cols.en_cols_val[i].ec_value.ec_value_val); } } -libnsl_hidden_def (nis_print_entry) +libnsl_hidden_nolink_def (nis_print_entry, GLIBC_2_1) void nis_print_object (const nis_object * obj) @@ -362,7 +362,7 @@ nis_print_object (const nis_object * obj) break; } } -libnsl_hidden_def (nis_print_object) +libnsl_hidden_nolink_def (nis_print_object, GLIBC_2_1) void nis_print_result (const nis_result *res) @@ -378,3 +378,4 @@ nis_print_result (const nis_result *res) nis_print_object (&res->objects.objects_val[i]); } } +libnsl_hidden_nolink_def (nis_print_result, GLIBC_2_1) diff --git a/nis/nis_print_group_entry.c b/nis/nis_print_group_entry.c index f90f89ae0b..1f2766ee20 100644 --- a/nis/nis_print_group_entry.c +++ b/nis/nis_print_group_entry.c @@ -171,3 +171,4 @@ nis_print_group_entry (const_nis_name group) nis_freeresult (res); } } +libnsl_hidden_nolink_def (nis_print_group_entry, GLIBC_2_1) diff --git a/nis/nis_remove.c b/nis/nis_remove.c index 0cc9841b00..4cfc5c533a 100644 --- a/nis/nis_remove.c +++ b/nis/nis_remove.c @@ -55,4 +55,4 @@ nis_remove (const_nis_name name, const nis_object *obj) return res; } -libnsl_hidden_def (nis_remove) +libnsl_hidden_nolink_def (nis_remove, GLIBC_2_1) diff --git a/nis/nis_removemember.c b/nis/nis_removemember.c index b1e8534162..04a05ca162 100644 --- a/nis/nis_removemember.c +++ b/nis/nis_removemember.c @@ -89,3 +89,4 @@ nis_removemember (const_nis_name member, const_nis_name group) else return NIS_FAIL; } +libnsl_hidden_nolink_def (nis_removemember, GLIBC_2_1) diff --git a/nis/nis_rmdir.c b/nis/nis_rmdir.c index 71fe64379a..a0c738024f 100644 --- a/nis/nis_rmdir.c +++ b/nis/nis_rmdir.c @@ -38,3 +38,4 @@ nis_rmdir (const_nis_name dir, const nis_server *server) return res; } +libnsl_hidden_nolink_def (nis_rmdir, GLIBC_2_1) diff --git a/nis/nis_server.c b/nis/nis_server.c index dd9461c2a7..2fb16ba195 100644 --- a/nis/nis_server.c +++ b/nis/nis_server.c @@ -47,6 +47,7 @@ nis_servstate (const nis_server *serv, const nis_tag *tags, return NIS_SUCCESS; } +libnsl_hidden_nolink_def (nis_servstate, GLIBC_2_1) nis_error nis_stats (const nis_server *serv, const nis_tag *tags, @@ -73,6 +74,7 @@ nis_stats (const nis_server *serv, const nis_tag *tags, return NIS_SUCCESS; } +libnsl_hidden_nolink_def (nis_stats, GLIBC_2_1) void nis_freetags (nis_tag *tags, const int numtags) @@ -83,3 +85,4 @@ nis_freetags (nis_tag *tags, const int numtags) free (tags[i].tag_val); free (tags); } +libnsl_hidden_nolink_def (nis_freetags, GLIBC_2_1) diff --git a/nis/nis_subr.c b/nis/nis_subr.c index 0062953eef..5c31af8840 100644 --- a/nis/nis_subr.c +++ b/nis/nis_subr.c @@ -27,6 +27,7 @@ nis_leaf_of (const_nis_name name) return nis_leaf_of_r (name, result, NIS_MAXNAMELEN); } +libnsl_hidden_nolink_def (nis_leaf_of, GLIBC_2_1) nis_name nis_leaf_of_r (const_nis_name name, char *buffer, size_t buflen) @@ -48,7 +49,7 @@ nis_leaf_of_r (const_nis_name name, char *buffer, size_t buflen) return buffer; } -libnsl_hidden_def (nis_leaf_of_r) +libnsl_hidden_nolink_def (nis_leaf_of_r, GLIBC_2_1) nis_name nis_name_of (const_nis_name name) @@ -57,6 +58,7 @@ nis_name_of (const_nis_name name) return nis_name_of_r (name, result, NIS_MAXNAMELEN); } +libnsl_hidden_nolink_def (nis_name_of, GLIBC_2_1) nis_name nis_name_of_r (const_nis_name name, char *buffer, size_t buflen) @@ -86,7 +88,7 @@ nis_name_of_r (const_nis_name name, char *buffer, size_t buflen) return buffer; } -libnsl_hidden_def (nis_name_of_r) +libnsl_hidden_nolink_def (nis_name_of_r, GLIBC_2_1) static int __always_inline count_dots (const_nis_name str) @@ -288,7 +290,7 @@ nis_getnames (const_nis_name name) return getnames; } -libnsl_hidden_def (nis_getnames) +libnsl_hidden_nolink_def (nis_getnames, GLIBC_2_1) void nis_freenames (nis_name *names) @@ -303,7 +305,7 @@ nis_freenames (nis_name *names) free (names); } -libnsl_hidden_def (nis_freenames) +libnsl_hidden_nolink_def (nis_freenames, GLIBC_2_1) name_pos nis_dir_cmp (const_nis_name n1, const_nis_name n2) @@ -341,11 +343,11 @@ nis_dir_cmp (const_nis_name n1, const_nis_name n2) } } -libnsl_hidden_def (nis_dir_cmp) +libnsl_hidden_nolink_def (nis_dir_cmp, GLIBC_2_1) void nis_destroy_object (nis_object *obj) { nis_free_object (obj); } -libnsl_hidden_def (nis_destroy_object) +libnsl_hidden_nolink_def (nis_destroy_object, GLIBC_2_1) diff --git a/nis/nis_table.c b/nis/nis_table.c index caf3e6af43..bec41f0e88 100644 --- a/nis/nis_table.c +++ b/nis/nis_table.c @@ -127,7 +127,7 @@ __create_ib_request (const_nis_name name, unsigned int flags) return ibreq; } -libnsl_hidden_def (__create_ib_request) +libnsl_hidden_nolink_def (__create_ib_request, GLIBC_PRIVATE) static const struct timeval RPCTIMEOUT = {10, 0}; @@ -200,7 +200,7 @@ __follow_path (char **tablepath, char **tableptr, struct ib_request *ibreq, return NIS_SUCCESS; } -libnsl_hidden_def (__follow_path) +libnsl_hidden_nolink_def (__follow_path, GLIBC_PRIVATE) nis_result * @@ -552,7 +552,7 @@ nis_list (const_nis_name name, unsigned int flags, return res; } -libnsl_hidden_def (nis_list) +libnsl_hidden_nolink_def (nis_list, GLIBC_2_1) nis_result * nis_add_entry (const_nis_name name, const nis_object *obj2, unsigned int flags) @@ -613,6 +613,7 @@ nis_add_entry (const_nis_name name, const nis_object *obj2, unsigned int flags) return res; } +libnsl_hidden_nolink_def (nis_add_entry, GLIBC_2_1) nis_result * nis_modify_entry (const_nis_name name, const nis_object *obj2, @@ -670,6 +671,7 @@ nis_modify_entry (const_nis_name name, const nis_object *obj2, return res; } +libnsl_hidden_nolink_def (nis_modify_entry, GLIBC_2_1) nis_result * nis_remove_entry (const_nis_name name, const nis_object *obj, @@ -718,6 +720,7 @@ nis_remove_entry (const_nis_name name, const nis_object *obj, return res; } +libnsl_hidden_nolink_def (nis_remove_entry, GLIBC_2_1) nis_result * nis_first_entry (const_nis_name name) @@ -755,6 +758,7 @@ nis_first_entry (const_nis_name name) return res; } +libnsl_hidden_nolink_def (nis_first_entry, GLIBC_2_1) nis_result * nis_next_entry (const_nis_name name, const netobj *cookie) @@ -805,3 +809,4 @@ nis_next_entry (const_nis_name name, const netobj *cookie) return res; } +libnsl_hidden_nolink_def (nis_next_entry, GLIBC_2_1) diff --git a/nis/nis_util.c b/nis/nis_util.c index 0ea890b594..681280e803 100644 --- a/nis/nis_util.c +++ b/nis/nis_util.c @@ -45,7 +45,7 @@ __nis_finddirectory (directory_obj *dir, const_nis_name name) return fd_res; } -libnsl_hidden_def (__nis_finddirectory) +libnsl_hidden_nolink_def (__nis_finddirectory, GLIBC_2_1) /* The hash implementation is in a separate file. */ #include "nis_hash.c" diff --git a/nis/nis_verifygroup.c b/nis/nis_verifygroup.c index bb043361b7..294595931f 100644 --- a/nis/nis_verifygroup.c +++ b/nis/nis_verifygroup.c @@ -48,3 +48,4 @@ nis_verifygroup (const_nis_name group) else return NIS_FAIL; } +libnsl_hidden_nolink_def (nis_verifygroup, GLIBC_2_1) diff --git a/nis/nis_xdr.c b/nis/nis_xdr.c index f2c6899ac8..a7b3f8c119 100644 --- a/nis/nis_xdr.c +++ b/nis/nis_xdr.c @@ -320,7 +320,7 @@ _xdr_nis_result (XDR *xdrs, nis_result *objp) } return res; } -libnsl_hidden_def (_xdr_nis_result) +libnsl_hidden_nolink_def (_xdr_nis_result, GLIBC_PRIVATE) bool_t _xdr_ns_request (XDR *xdrs, ns_request *objp) @@ -370,7 +370,7 @@ _xdr_ib_request (XDR *xdrs, ib_request *objp) } return res; } -libnsl_hidden_def (_xdr_ib_request) +libnsl_hidden_nolink_def (_xdr_ib_request, GLIBC_PRIVATE) bool_t _xdr_ping_args (XDR *xdrs, ping_args *objp) @@ -447,7 +447,7 @@ xdr_obj_p (XDR *xdrs, obj_p *objp) return xdr_pointer (xdrs, (char **)objp, sizeof (nis_object), (xdrproc_t)_xdr_nis_object); } -libnsl_hidden_def (xdr_obj_p) +libnsl_hidden_nolink_def (xdr_obj_p, GLIBC_2_1) bool_t xdr_cback_data (XDR *xdrs, cback_data *objp) @@ -456,4 +456,4 @@ xdr_cback_data (XDR *xdrs, cback_data *objp) &objp->entries.entries_len, ~0, sizeof (obj_p), (xdrproc_t) xdr_obj_p); } -libnsl_hidden_def (xdr_cback_data) +libnsl_hidden_nolink_def (xdr_cback_data, GLIBC_2_1) diff --git a/nis/yp_xdr.c b/nis/yp_xdr.c index 34566d19a8..3d8b0bf3a6 100644 --- a/nis/yp_xdr.c +++ b/nis/yp_xdr.c @@ -45,35 +45,35 @@ xdr_ypstat (XDR *xdrs, ypstat *objp) { return xdr_enum (xdrs, (enum_t *) objp); } -libnsl_hidden_def (xdr_ypstat) +libnsl_hidden_nolink_def (xdr_ypstat, GLIBC_2_0) bool_t xdr_ypxfrstat (XDR *xdrs, ypxfrstat *objp) { return xdr_enum (xdrs, (enum_t *) objp); } -libnsl_hidden_def (xdr_ypxfrstat) +libnsl_hidden_nolink_def (xdr_ypxfrstat, GLIBC_2_0) bool_t xdr_domainname (XDR *xdrs, domainname *objp) { return xdr_string (xdrs, objp, XDRMAXNAME); } -libnsl_hidden_def (xdr_domainname) +libnsl_hidden_nolink_def (xdr_domainname, GLIBC_2_0) bool_t xdr_mapname (XDR *xdrs, mapname *objp) { return xdr_string (xdrs, objp, XDRMAXNAME); } -libnsl_hidden_def (xdr_mapname) +libnsl_hidden_nolink_def (xdr_mapname, GLIBC_2_0) bool_t xdr_peername (XDR *xdrs, peername *objp) { return xdr_string (xdrs, objp, XDRMAXNAME); } -libnsl_hidden_def (xdr_peername) +libnsl_hidden_nolink_def (xdr_peername, GLIBC_2_0) bool_t xdr_keydat (XDR *xdrs, keydat *objp) @@ -81,7 +81,7 @@ xdr_keydat (XDR *xdrs, keydat *objp) return xdr_bytes (xdrs, (char **) &objp->keydat_val, (u_int *) &objp->keydat_len, XDRMAXRECORD); } -libnsl_hidden_def (xdr_keydat) +libnsl_hidden_nolink_def (xdr_keydat, GLIBC_2_0) bool_t xdr_valdat (XDR *xdrs, valdat *objp) @@ -89,7 +89,7 @@ xdr_valdat (XDR *xdrs, valdat *objp) return xdr_bytes (xdrs, (char **) &objp->valdat_val, (u_int *) &objp->valdat_len, XDRMAXRECORD); } -libnsl_hidden_def (xdr_valdat) +libnsl_hidden_nolink_def (xdr_valdat, GLIBC_2_0) bool_t xdr_ypmap_parms (XDR *xdrs, ypmap_parms *objp) @@ -102,7 +102,7 @@ xdr_ypmap_parms (XDR *xdrs, ypmap_parms *objp) return FALSE; return xdr_peername (xdrs, &objp->peer); } -libnsl_hidden_def (xdr_ypmap_parms) +libnsl_hidden_nolink_def (xdr_ypmap_parms, GLIBC_2_0) bool_t xdr_ypreq_key (XDR *xdrs, ypreq_key *objp) @@ -113,7 +113,7 @@ xdr_ypreq_key (XDR *xdrs, ypreq_key *objp) return FALSE; return xdr_keydat (xdrs, &objp->key); } -libnsl_hidden_def (xdr_ypreq_key) +libnsl_hidden_nolink_def (xdr_ypreq_key, GLIBC_2_0) bool_t xdr_ypreq_nokey (XDR *xdrs, ypreq_nokey *objp) @@ -122,7 +122,7 @@ xdr_ypreq_nokey (XDR *xdrs, ypreq_nokey *objp) return FALSE; return xdr_mapname (xdrs, &objp->map); } -libnsl_hidden_def (xdr_ypreq_nokey) +libnsl_hidden_nolink_def (xdr_ypreq_nokey, GLIBC_2_0) bool_t xdr_ypreq_xfr (XDR *xdrs, ypreq_xfr *objp) @@ -135,6 +135,7 @@ xdr_ypreq_xfr (XDR *xdrs, ypreq_xfr *objp) return FALSE; return xdr_u_int (xdrs, &objp->port); } +libnsl_hidden_nolink_def (xdr_ypreq_xfr, GLIBC_2_0) bool_t xdr_ypresp_val (XDR *xdrs, ypresp_val *objp) @@ -143,7 +144,7 @@ xdr_ypresp_val (XDR *xdrs, ypresp_val *objp) return FALSE; return xdr_valdat (xdrs, &objp->val); } -libnsl_hidden_def (xdr_ypresp_val) +libnsl_hidden_nolink_def (xdr_ypresp_val, GLIBC_2_0) bool_t xdr_ypresp_key_val (XDR *xdrs, ypresp_key_val *objp) @@ -154,7 +155,7 @@ xdr_ypresp_key_val (XDR *xdrs, ypresp_key_val *objp) return FALSE; return xdr_keydat (xdrs, &objp->key); } -libnsl_hidden_def (xdr_ypresp_key_val) +libnsl_hidden_nolink_def (xdr_ypresp_key_val, GLIBC_2_0) bool_t xdr_ypresp_master (XDR *xdrs, ypresp_master *objp) @@ -163,7 +164,7 @@ xdr_ypresp_master (XDR *xdrs, ypresp_master *objp) return FALSE; return xdr_peername (xdrs, &objp->peer); } -libnsl_hidden_def (xdr_ypresp_master) +libnsl_hidden_nolink_def (xdr_ypresp_master, GLIBC_2_0) bool_t xdr_ypresp_order (XDR *xdrs, ypresp_order *objp) @@ -172,7 +173,7 @@ xdr_ypresp_order (XDR *xdrs, ypresp_order *objp) return FALSE; return xdr_u_int (xdrs, &objp->ordernum); } -libnsl_hidden_def (xdr_ypresp_order) +libnsl_hidden_nolink_def (xdr_ypresp_order, GLIBC_2_0) bool_t xdr_ypresp_all (XDR *xdrs, ypresp_all *objp) @@ -190,7 +191,7 @@ xdr_ypresp_all (XDR *xdrs, ypresp_all *objp) } return TRUE; } -libnsl_hidden_def (xdr_ypresp_all) +libnsl_hidden_nolink_def (xdr_ypresp_all, GLIBC_2_0) bool_t xdr_ypresp_xfr (XDR *xdrs, ypresp_xfr *objp) @@ -199,6 +200,7 @@ xdr_ypresp_xfr (XDR *xdrs, ypresp_xfr *objp) return FALSE; return xdr_ypxfrstat (xdrs, &objp->xfrstat); } +libnsl_hidden_nolink_def (xdr_ypresp_xfr, GLIBC_2_0) bool_t xdr_ypmaplist (XDR *xdrs, ypmaplist *objp) @@ -209,7 +211,7 @@ xdr_ypmaplist (XDR *xdrs, ypmaplist *objp) char **tp = (void *) &objp->next; return xdr_pointer (xdrs, tp, sizeof (ypmaplist), (xdrproc_t) xdr_ypmaplist); } -libnsl_hidden_def (xdr_ypmaplist) +libnsl_hidden_nolink_def (xdr_ypmaplist, GLIBC_2_0) bool_t xdr_ypresp_maplist (XDR *xdrs, ypresp_maplist *objp) @@ -220,14 +222,14 @@ xdr_ypresp_maplist (XDR *xdrs, ypresp_maplist *objp) char **tp = (void *) &objp->maps; return xdr_pointer (xdrs, tp, sizeof (ypmaplist), (xdrproc_t) xdr_ypmaplist); } -libnsl_hidden_def (xdr_ypresp_maplist) +libnsl_hidden_nolink_def (xdr_ypresp_maplist, GLIBC_2_0) bool_t xdr_yppush_status (XDR *xdrs, yppush_status *objp) { return xdr_enum (xdrs, (enum_t *) objp); } -libnsl_hidden_def (xdr_yppush_status) +libnsl_hidden_nolink_def (xdr_yppush_status, GLIBC_2_0) bool_t xdr_yppushresp_xfr (XDR *xdrs, yppushresp_xfr *objp) @@ -236,13 +238,14 @@ xdr_yppushresp_xfr (XDR *xdrs, yppushresp_xfr *objp) return FALSE; return xdr_yppush_status (xdrs, &objp->status); } +libnsl_hidden_nolink_def (xdr_yppushresp_xfr, GLIBC_2_0) bool_t xdr_ypbind_resptype (XDR *xdrs, ypbind_resptype *objp) { return xdr_enum (xdrs, (enum_t *) objp); } -libnsl_hidden_def (xdr_ypbind_resptype) +libnsl_hidden_nolink_def (xdr_ypbind_resptype, GLIBC_2_0) bool_t xdr_ypbind_binding (XDR *xdrs, ypbind_binding *objp) @@ -251,7 +254,7 @@ xdr_ypbind_binding (XDR *xdrs, ypbind_binding *objp) return FALSE; return xdr_opaque (xdrs, objp->ypbind_binding_port, 2); } -libnsl_hidden_def (xdr_ypbind_binding) +libnsl_hidden_nolink_def (xdr_ypbind_binding, GLIBC_2_0) bool_t xdr_ypbind_resp (XDR *xdrs, ypbind_resp *objp) @@ -267,7 +270,7 @@ xdr_ypbind_resp (XDR *xdrs, ypbind_resp *objp) } return FALSE; } -libnsl_hidden_def (xdr_ypbind_resp) +libnsl_hidden_nolink_def (xdr_ypbind_resp, GLIBC_2_0) bool_t xdr_ypbind_setdom (XDR *xdrs, ypbind_setdom *objp) @@ -278,6 +281,7 @@ xdr_ypbind_setdom (XDR *xdrs, ypbind_setdom *objp) return FALSE; return xdr_u_int (xdrs, &objp->ypsetdom_vers); } +libnsl_hidden_nolink_def (xdr_ypbind_setdom, GLIBC_2_0) bool_t xdr_ypall(XDR *xdrs, struct ypall_callback *incallback) @@ -322,3 +326,4 @@ xdr_ypall(XDR *xdrs, struct ypall_callback *incallback) return FALSE; } } +/* XXX libnsl_hidden_nolink_def(xdr_ypall, GLIBC_2_2) */ diff --git a/nis/ypclnt.c b/nis/ypclnt.c index 994a53b989..3c4af2e0cf 100644 --- a/nis/ypclnt.c +++ b/nis/ypclnt.c @@ -226,7 +226,7 @@ yp_bind (const char *indomain) return status; } -libnsl_hidden_def (yp_bind) +libnsl_hidden_nolink_def (yp_bind, GLIBC_2_0) static void yp_unbind_locked (const char *indomain) @@ -266,6 +266,7 @@ yp_unbind (const char *indomain) return; } +libnsl_hidden_nolink_def(yp_unbind, GLIBC_2_0) static int __ypclnt_call (const char *domain, u_long prog, xdrproc_t xargs, @@ -406,7 +407,7 @@ yp_get_default_domain (char **outdomain) return result; } -libnsl_hidden_def (yp_get_default_domain) +libnsl_hidden_nolink_def (yp_get_default_domain, GLIBC_2_0) int __yp_check (char **domain) @@ -424,6 +425,7 @@ __yp_check (char **domain) return 1; return 0; } +libnsl_hidden_nolink_def(__yp_check, GLIBC_2_0) int yp_match (const char *indomain, const char *inmap, const char *inkey, @@ -468,6 +470,7 @@ yp_match (const char *indomain, const char *inmap, const char *inkey, return status; } +libnsl_hidden_nolink_def(yp_match, GLIBC_2_0) int yp_first (const char *indomain, const char *inmap, char **outkey, @@ -522,6 +525,7 @@ yp_first (const char *indomain, const char *inmap, char **outkey, return status; } +libnsl_hidden_nolink_def(yp_first, GLIBC_2_0) int yp_next (const char *indomain, const char *inmap, const char *inkey, @@ -578,6 +582,7 @@ yp_next (const char *indomain, const char *inmap, const char *inkey, return status; } +libnsl_hidden_nolink_def(yp_next, GLIBC_2_0) int yp_master (const char *indomain, const char *inmap, char **outname) @@ -607,7 +612,7 @@ yp_master (const char *indomain, const char *inmap, char **outname) return *outname == NULL ? YPERR_YPERR : YPERR_SUCCESS; } -libnsl_hidden_def (yp_master) +libnsl_hidden_nolink_def (yp_master, GLIBC_2_0) int yp_order (const char *indomain, const char *inmap, unsigned int *outorder) @@ -637,6 +642,7 @@ yp_order (const char *indomain, const char *inmap, unsigned int *outorder) return result; } +libnsl_hidden_nolink_def(yp_order, GLIBC_2_0) struct ypresp_all_data { @@ -780,9 +786,9 @@ yp_all (const char *indomain, const char *inmap, return res; } +libnsl_hidden_nolink_def (yp_all, GLIBC_2_0) int - yp_maplist (const char *indomain, struct ypmaplist **outmaplist) { struct ypresp_maplist resp; @@ -870,6 +876,7 @@ yperr_string (const int error) } return _(str); } +libnsl_hidden_nolink_def(yperr_string, GLIBC_2_0) static const int8_t yp_2_yperr[] = { @@ -893,7 +900,7 @@ ypprot_err (const int code) return YPERR_YPERR; return yp_2_yperr[code - YP_VERS]; } -libnsl_hidden_def (ypprot_err) +libnsl_hidden_nolink_def (ypprot_err, GLIBC_2_0) const char * ypbinderr_string (const int error) @@ -919,7 +926,7 @@ ypbinderr_string (const int error) } return _(str); } -libnsl_hidden_def (ypbinderr_string) +libnsl_hidden_nolink_def (ypbinderr_string, GLIBC_2_0) #define WINDOW 60 @@ -1019,3 +1026,4 @@ again: } return res; } +libnsl_hidden_nolink_def(yp_update, GLIBC_2_0) diff --git a/nis/ypupdate_xdr.c b/nis/ypupdate_xdr.c index 9f6d69f96e..61d8880cab 100644 --- a/nis/ypupdate_xdr.c +++ b/nis/ypupdate_xdr.c @@ -37,7 +37,7 @@ xdr_yp_buf (XDR *xdrs, yp_buf *objp) return xdr_bytes (xdrs, (char **) &objp->yp_buf_val, (u_int *) &objp->yp_buf_len, ~0); } -libnsl_hidden_def (xdr_yp_buf) +libnsl_hidden_nolink_def (xdr_yp_buf, GLIBC_2_0) bool_t xdr_ypupdate_args (XDR *xdrs, ypupdate_args *objp) @@ -48,7 +48,7 @@ xdr_ypupdate_args (XDR *xdrs, ypupdate_args *objp) return FALSE; return xdr_yp_buf (xdrs, &objp->datum); } -libnsl_hidden_def (xdr_ypupdate_args) +libnsl_hidden_nolink_def (xdr_ypupdate_args, GLIBC_2_0) bool_t xdr_ypdelete_args (XDR *xdrs, ypdelete_args *objp) @@ -57,4 +57,4 @@ xdr_ypdelete_args (XDR *xdrs, ypdelete_args *objp) return FALSE; return xdr_yp_buf (xdrs, &objp->key); } -libnsl_hidden_def (xdr_ypdelete_args) +libnsl_hidden_nolink_def (xdr_ypdelete_args, GLIBC_2_0) -- cgit v1.2.3 From a65ea28d1833d3502c5070472e43bda04410e6b5 Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Tue, 13 Jun 2017 09:28:14 -0700 Subject: Make copy of from GCC 7 [BZ #21573] from GCC 7 will include /usr/include/stdlib.h from "#include_next" (instead of stdlib/stdlib.h in the glibc source directory), and this turns up as a make dependency. Also make a copy of to prevent it from including /usr/include/stdlib.h. [BZ #21573] * Makerules [$(c++-bits-std_abs-h) != ""] (before-compile): Add $(common-objpfx)bits/std_abs.h. [$(c++-bits-std_abs-h) != ""] ($(common-objpfx)bits/std_abs.h): New target. * config.make.in (c++-bits-std_abs-h): New. * configure.ac (find_cxx_header): Use "\,$1," with sed. (CXX_BITS_STD_ABS_H): New. (AC_SUBST(CXX_BITS_STD_ABS_H)): Likewise. * configure: Regenerated. --- ChangeLog | 13 +++++++++++++ Makerules | 8 ++++++++ config.make.in | 1 + configure | 5 ++++- configure.ac | 4 +++- 5 files changed, 29 insertions(+), 2 deletions(-) (limited to 'configure.ac') diff --git a/ChangeLog b/ChangeLog index a6978e644d..52ffaf82e1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2017-06-13 H.J. Lu + + [BZ #21573] + * Makerules [$(c++-bits-std_abs-h) != ""] (before-compile): Add + $(common-objpfx)bits/std_abs.h. + [$(c++-bits-std_abs-h) != ""] ($(common-objpfx)bits/std_abs.h): + New target. + * config.make.in (c++-bits-std_abs-h): New. + * configure.ac (find_cxx_header): Use "\,$1," with sed. + (CXX_BITS_STD_ABS_H): New. + (AC_SUBST(CXX_BITS_STD_ABS_H)): Likewise. + * configure: Regenerated. + 2017-06-13 Zack Weinberg * posix/bits/cpu-set.h: Correct indentation of preprocessor diff --git a/Makerules b/Makerules index 7656c492da..f91a4c5d66 100644 --- a/Makerules +++ b/Makerules @@ -134,6 +134,14 @@ $(common-objpfx)cstdlib: $(c++-cstdlib-header) $(common-objpfx)cmath: $(c++-cmath-header) $(INSTALL_DATA) $< $@T $(move-if-change) $@T $@ +ifneq (,$(c++-bits-std_abs-h)) +# Also make a copy of from GCC 7 to prevent it from +# including /usr/include/stdlib.h. +before-compile := $(common-objpfx)bits/std_abs.h $(before-compile) +$(common-objpfx)bits/std_abs.h: $(c++-bits-std_abs-h) + $(INSTALL_DATA) $< $@T + $(move-if-change) $@T $@ +endif endif before-compile := $(common-objpfx)libc-abis.h $(before-compile) diff --git a/config.make.in b/config.make.in index d08a462d05..dadabf9b6a 100644 --- a/config.make.in +++ b/config.make.in @@ -47,6 +47,7 @@ sysincludes = @SYSINCLUDES@ c++-sysincludes = @CXX_SYSINCLUDES@ c++-cstdlib-header = @CXX_CSTDLIB_HEADER@ c++-cmath-header = @CXX_CMATH_HEADER@ +c++-bits-std_abs-h = @CXX_BITS_STD_ABS_H@ all-warnings = @all_warnings@ enable-werror = @enable_werror@ diff --git a/configure b/configure index 422482f355..ceb53949ba 100755 --- a/configure +++ b/configure @@ -634,6 +634,7 @@ BISON INSTALL_INFO PERL BASH_SHELL +CXX_BITS_STD_ABS_H CXX_CMATH_HEADER CXX_CSTDLIB_HEADER CXX_SYSINCLUDES @@ -5336,14 +5337,16 @@ fi # copy of those headers in Makerules. if test -n "$CXX"; then find_cxx_header () { - echo "#include <$1>" | $CXX -M -MP -x c++ - | sed -n "/$1:/{s/:\$//;p}" + echo "#include <$1>" | $CXX -M -MP -x c++ - | sed -n "\,$1:,{s/:\$//;p}" } CXX_CSTDLIB_HEADER="$(find_cxx_header cstdlib)" CXX_CMATH_HEADER="$(find_cxx_header cmath)" + CXX_BITS_STD_ABS_H="$(find_cxx_header bits/std_abs.h)" fi + # Test if LD_LIBRARY_PATH contains the notation for the current directory # since this would lead to problems installing/building glibc. # LD_LIBRARY_PATH contains the current directory if one of the following diff --git a/configure.ac b/configure.ac index 7f430425ae..d74bd4490c 100644 --- a/configure.ac +++ b/configure.ac @@ -1187,13 +1187,15 @@ AC_SUBST(CXX_SYSINCLUDES) # copy of those headers in Makerules. if test -n "$CXX"; then find_cxx_header () { - echo "#include <$1>" | $CXX -M -MP -x c++ - | sed -n "/$1:/{s/:\$//;p}" + echo "#include <$1>" | $CXX -M -MP -x c++ - | sed -n "\,$1:,{s/:\$//;p}" } CXX_CSTDLIB_HEADER="$(find_cxx_header cstdlib)" CXX_CMATH_HEADER="$(find_cxx_header cmath)" + CXX_BITS_STD_ABS_H="$(find_cxx_header bits/std_abs.h)" fi AC_SUBST(CXX_CSTDLIB_HEADER) AC_SUBST(CXX_CMATH_HEADER) +AC_SUBST(CXX_BITS_STD_ABS_H) # Test if LD_LIBRARY_PATH contains the notation for the current directory # since this would lead to problems installing/building glibc. -- cgit v1.2.3 From c2528fef3b05bcffb1ac27c6c09cc3ff24b7f03f Mon Sep 17 00:00:00 2001 From: Florian Weimer Date: Tue, 13 Jun 2017 22:09:59 +0200 Subject: configure: Suppress expected compiler error message --- ChangeLog | 4 ++++ configure | 3 ++- configure.ac | 3 ++- 3 files changed, 8 insertions(+), 2 deletions(-) (limited to 'configure.ac') diff --git a/ChangeLog b/ChangeLog index efc78b5110..c86ab8781c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2017-06-13 Florian Weimer + + * configure.ac (find_cxx_header): Suppress compiler error message. + 2017-06-13 Florian Weimer * malloc/dynarray-skeleton.c: List begin/end as defined functions. diff --git a/configure b/configure index ceb53949ba..4c2922d882 100755 --- a/configure +++ b/configure @@ -5337,7 +5337,8 @@ fi # copy of those headers in Makerules. if test -n "$CXX"; then find_cxx_header () { - echo "#include <$1>" | $CXX -M -MP -x c++ - | sed -n "\,$1:,{s/:\$//;p}" + echo "#include <$1>" | $CXX -M -MP -x c++ - 2>/dev/null \ + | sed -n "\,$1:,{s/:\$//;p}" } CXX_CSTDLIB_HEADER="$(find_cxx_header cstdlib)" CXX_CMATH_HEADER="$(find_cxx_header cmath)" diff --git a/configure.ac b/configure.ac index d74bd4490c..3f486d6df4 100644 --- a/configure.ac +++ b/configure.ac @@ -1187,7 +1187,8 @@ AC_SUBST(CXX_SYSINCLUDES) # copy of those headers in Makerules. if test -n "$CXX"; then find_cxx_header () { - echo "#include <$1>" | $CXX -M -MP -x c++ - | sed -n "\,$1:,{s/:\$//;p}" + echo "#include <$1>" | $CXX -M -MP -x c++ - 2>/dev/null \ + | sed -n "\,$1:,{s/:\$//;p}" } CXX_CSTDLIB_HEADER="$(find_cxx_header cstdlib)" CXX_CMATH_HEADER="$(find_cxx_header cmath)" -- cgit v1.2.3 From 2c0b90ab443abc967cbf75add4f7fde84978cb95 Mon Sep 17 00:00:00 2001 From: Siddhesh Poyarekar Date: Thu, 15 Jun 2017 15:12:54 +0530 Subject: Enable tunables by default All of the major architectures are adopting tunables as a way to add tuning to the library, from hwcap_mask for aarch64 to HLE for s390 and ifunc and cache geometry for x86. Given this adoption and the fact that we don't want additional tuning knobs to be added outside of tunables, it makes sense to enable tunables by default using this trivial patch. Smoke tested on x86 to ensure that tunables code was built without specifying it as a configure flag. I have kept it as --enabled and not changed it to --disable since we want to still keep the option of different kinds of front-ends for tunables. * configure.ac(--enable-tunables): Enable by default. * configure: Regenerate. * NEWS: Mention change. * manual/install.texi (enable-tunables): Adjust documentation. * INSTALL: Regenerate. --- ChangeLog | 8 ++++++++ INSTALL | 18 ++++++++---------- NEWS | 3 +++ configure | 2 +- configure.ac | 2 +- manual/install.texi | 13 ++++++------- 6 files changed, 27 insertions(+), 19 deletions(-) (limited to 'configure.ac') diff --git a/ChangeLog b/ChangeLog index a2d1f5ade1..833f03ea6f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2017-06-15 Siddhesh Poyarekar + + * configure.ac(--enable-tunables): Enable by default. + * configure: Regenerate. + * NEWS: Mention change. + * manual/install.texi (enable-tunables): Adjust documentation. + * INSTALL: Regenerate. + 2017-06-14 Adhemerval Zanella [BZ #18988] diff --git a/INSTALL b/INSTALL index 920c4df0ef..a2f5a40b17 100644 --- a/INSTALL +++ b/INSTALL @@ -177,18 +177,16 @@ will be used, and CFLAGS sets optimization options for the compiler. '--enable-tunables' Tunables support allows additional library parameters to be - customized at runtime. This is an experimental feature and affects - startup time and is thus disabled by default. This option can take - the following values: - - 'no' - This is the default if the option is not passed to configure. - This disables tunables. + customized at runtime. This feature is enabled by default. This + option can take the following values: 'yes' - This is the default if the option is passed to configure. - This enables tunables and selects the default frontend - (currently 'valstring'). + This is the default if no option is passed to configure. This + enables tunables and selects the default frontend (currently + 'valstring'). + + 'no' + This option disables tunables. 'valstring' This enables tunables and selects the 'valstring' frontend for diff --git a/NEWS b/NEWS index 8d35bd6c95..804c1b92e6 100644 --- a/NEWS +++ b/NEWS @@ -95,6 +95,9 @@ Version 2.26 as atomic variables to try to implement Dekker's mutual exclusion algorithm). +* The tunables feature is now enabled by default. This allows users to tweak + behavior of the GNU C Library using the GLIBC_TUNABLES environment variable. + Security related changes: * The DNS stub resolver limits the advertised UDP buffer size to 1200 bytes, diff --git a/configure b/configure index 4c2922d882..8390f2b86e 100755 --- a/configure +++ b/configure @@ -3725,7 +3725,7 @@ fi if test "${enable_tunables+set}" = set; then : enableval=$enable_tunables; have_tunables=$enableval else - have_tunables=no + have_tunables=yes fi diff --git a/configure.ac b/configure.ac index 3f486d6df4..4c0a18edd9 100644 --- a/configure.ac +++ b/configure.ac @@ -436,7 +436,7 @@ AC_ARG_ENABLE([tunables], [AS_HELP_STRING([--enable-tunables], [Enable tunables support. Known values are 'yes', 'no' and 'valstring'])], [have_tunables=$enableval], - [have_tunables=no]) + [have_tunables=yes]) AC_SUBST(have_tunables) if test "$have_tunables" = yes; then AC_DEFINE(HAVE_TUNABLES) diff --git a/manual/install.texi b/manual/install.texi index d39d2daacd..cbc912817a 100644 --- a/manual/install.texi +++ b/manual/install.texi @@ -208,18 +208,17 @@ Use this option to disable the vector math library. @item --enable-tunables Tunables support allows additional library parameters to be customized at -runtime. This is an experimental feature and affects startup time and is thus -disabled by default. This option can take the following values: +runtime. This feature is enabled by default. This option can take the +following values: @table @code -@item no -This is the default if the option is not passed to configure. This disables -tunables. - @item yes -This is the default if the option is passed to configure. This enables tunables +This is the default if no option is passed to configure. This enables tunables and selects the default frontend (currently @samp{valstring}). +@item no +This option disables tunables. + @item valstring This enables tunables and selects the @samp{valstring} frontend for tunables. This frontend allows users to specify tunables as a colon-separated list in a -- cgit v1.2.3 From 4add86749a31f302674599b69d2eea691d69341a Mon Sep 17 00:00:00 2001 From: Joseph Myers Date: Mon, 19 Jun 2017 16:33:00 +0000 Subject: Require GCC 4.9 or later for building glibc. This patch makes configure require GCC 4.9 or later for building glibc, and documents that requirement. Requiring GCC 4.9 or later allows use of _Generic (as in tzcode). It would allow and _Atomic to be used as well if desired, although we need to avoid any libatomic dependencies on any platforms. This patch is explicitly the minimum to implement a new version requirement, with any consequent cleanups of conditional code (not in installed headers or files shared with gnulib etc.) to be done separately. Tested for x86_64. * configure.ac (libc_cv_compiler_ok): Require GCC 4.9 or later. * configure: Regenerated. * manual/install.texi (Tools for Compilation): Document requirement for GCC 4.9 or later. * INSTALL: Regenerated. --- ChangeLog | 8 ++++++++ INSTALL | 4 ++-- NEWS | 4 ++++ configure | 2 +- configure.ac | 2 +- manual/install.texi | 4 ++-- 6 files changed, 18 insertions(+), 6 deletions(-) (limited to 'configure.ac') diff --git a/ChangeLog b/ChangeLog index 3b61f167d2..b3d39a23fd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2017-06-19 Joseph Myers + + * configure.ac (libc_cv_compiler_ok): Require GCC 4.9 or later. + * configure: Regenerated. + * manual/install.texi (Tools for Compilation): Document + requirement for GCC 4.9 or later. + * INSTALL: Regenerated. + 2017-06-19 Florian Weimer [BZ #21624] diff --git a/INSTALL b/INSTALL index a2f5a40b17..71af35b1eb 100644 --- a/INSTALL +++ b/INSTALL @@ -420,9 +420,9 @@ build the GNU C Library: recommend GNU 'make' version 3.79. All earlier versions have severe bugs or lack features. - * GCC 4.7 or newer + * GCC 4.9 or newer - GCC 4.7 or higher is required. In general it is recommended to use + GCC 4.9 or higher is required. In general it is recommended to use the newest version of the compiler that is known to work for building the GNU C Library, as newer compilers usually produce better code. As of release time, GCC 6.3 is the newest compiler diff --git a/NEWS b/NEWS index 9ee22185e8..f81d02f1cb 100644 --- a/NEWS +++ b/NEWS @@ -107,6 +107,10 @@ Version 2.26 PTRACE_DISABLE_TE and PTRACE_TE_ABORT_RAND were added as those are supported by the s390 kernel. +* The minimum GCC version that can be used to build this version of the GNU + C Library is GCC 4.9. Older GCC versions, and non-GNU compilers, can + still be used to compile programs using the GNU C Library. + Security related changes: * The DNS stub resolver limits the advertised UDP buffer size to 1200 bytes, diff --git a/configure b/configure index 8390f2b86e..97a2dadf2d 100755 --- a/configure +++ b/configure @@ -5058,7 +5058,7 @@ int main () { -#if !defined __GNUC__ || __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 7) +#if !defined __GNUC__ || __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 9) #error insufficient compiler #endif ; diff --git a/configure.ac b/configure.ac index 4c0a18edd9..16e97d3930 100644 --- a/configure.ac +++ b/configure.ac @@ -1105,7 +1105,7 @@ AC_CHECK_PROG_VER(AWK, gawk, --version, AC_CACHE_CHECK([if $CC is sufficient to build libc], libc_cv_compiler_ok, [ AC_TRY_COMPILE([], [ -#if !defined __GNUC__ || __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 7) +#if !defined __GNUC__ || __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 9) #error insufficient compiler #endif], [libc_cv_compiler_ok=yes], diff --git a/manual/install.texi b/manual/install.texi index cbc912817a..65174a8b2e 100644 --- a/manual/install.texi +++ b/manual/install.texi @@ -467,9 +467,9 @@ recommend GNU @code{make} version 3.79. All earlier versions have severe bugs or lack features. @item -GCC 4.7 or newer +GCC 4.9 or newer -GCC 4.7 or higher is required. In general it is recommended to use +GCC 4.9 or higher is required. In general it is recommended to use the newest version of the compiler that is known to work for building @theglibc{}, as newer compilers usually produce better code. As of release time, GCC 6.3 is the newest compiler verified to work to build -- cgit v1.2.3 From f300dc7358e785dd92259514f57acd10f695d142 Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Wed, 28 Jun 2017 04:03:57 -0700 Subject: Support building glibc with gold 1.14 or above [BZ #14995] This patch changes configure.ac to allow gold 1.14 or above to be used to configire glibc so that gold glibc bugs can be fixed. Tested with CC="gcc -fuse-ld=gold" CXX="g++ -fuse-ld=gold" on Fedora 25 with gold 1.14 (20170623). Gold 1.14 was first released in binutils 2.28. On x86-64, for "make check", I got Error in `/export/build/gnu/glibc-gold/build-x86_64-linux/elf/constload1': double free or corruption (fasttop): 0x00000000008755f0 *** ======= Backtrace: ========= /export/build/gnu/glibc-gold/build-x86_64-linux/libc.so.6(+0x772fb)[0x7f85225b52fb] /export/build/gnu/glibc-gold/build-x86_64-linux/libc.so.6(+0x7d6c6)[0x7f85225bb6c6] /export/build/gnu/glibc-gold/build-x86_64-linux/libc.so.6(+0x7df0e)[0x7f85225bbf0e] /export/build/gnu/glibc-gold/build-x86_64-linux/dlfcn/libdl.so.2(+0x182d)[0x7f85226e682d] /export/build/gnu/glibc-gold/build-x86_64-linux/dlfcn/libdl.so.2(dlclose+0x1f)[0x7f85226e623f] /export/build/gnu/glibc-gold/build-x86_64-linux/elf/constload2.so(+0x933)[0x7f8522539933] /export/build/gnu/glibc-gold/build-x86_64-linux/elf/ld.so(+0xfd1a)[0x7f85226fbd1a] /export/build/gnu/glibc-gold/build-x86_64-linux/libc.so.6(+0x3c5e0)[0x7f852257a5e0] /export/build/gnu/glibc-gold/build-x86_64-linux/libc.so.6(+0x3c63a)[0x7f852257a63a] /export/build/gnu/glibc-gold/build-x86_64-linux/elf/constload2.so(+0x9aa)[0x7f85225399aa] /export/build/gnu/glibc-gold/build-x86_64-linux/elf/ld.so(+0xf74a)[0x7f85226fb74a] /export/build/gnu/glibc-gold/build-x86_64-linux/elf/ld.so(+0xf85b)[0x7f85226fb85b] /export/build/gnu/glibc-gold/build-x86_64-linux/elf/ld.so(+0x13e98)[0x7f85226ffe98] /export/build/gnu/glibc-gold/build-x86_64-linux/libc.so.6(_dl_catch_error+0x71)[0x7f85226643c1] /export/build/gnu/glibc-gold/build-x86_64-linux/elf/ld.so(+0x13639)[0x7f85226ff639] /export/build/gnu/glibc-gold/build-x86_64-linux/dlfcn/libdl.so.2(+0x1156)[0x7f85226e6156] /export/build/gnu/glibc-gold/build-x86_64-linux/libc.so.6(_dl_catch_error+0x71)[0x7f85226643c1] /export/build/gnu/glibc-gold/build-x86_64-linux/dlfcn/libdl.so.2(+0x1789)[0x7f85226e6789] /export/build/gnu/glibc-gold/build-x86_64-linux/dlfcn/libdl.so.2(dlopen+0x32)[0x7f85226e61e2] /export/build/gnu/glibc-gold/build-x86_64-linux/elf/constload1[0x4009ca] /export/build/gnu/glibc-gold/build-x86_64-linux/libc.so.6(__libc_start_main+0xf1)[0x7f8522565231] /export/build/gnu/glibc-gold/build-x86_64-linux/elf/constload1[0x400a5a] ======= Memory map: ======== 00400000-00401000 r-xp 00000000 08:11 26334965 /export/build/gnu/glibc-gold/build-x86_64-linux/elf/constload1 00401000-00402000 r--p 00000000 08:11 26334965 /export/build/gnu/glibc-gold/build-x86_64-linux/elf/constload1 00402000-00403000 rw-p 00001000 08:11 26334965 /export/build/gnu/glibc-gold/build-x86_64-linux/elf/constload1 00875000-00896000 rw-p 00000000 00:00 0 [heap] 7f851c000000-7f851c021000 rw-p 00000000 00:00 0 7f851c021000-7f8520000000 ---p 00000000 00:00 0 7f85222f3000-7f8522309000 r-xp 00000000 08:02 136658 /usr/lib64/libgcc_s-6.3.1-20170216.so.1 7f8522309000-7f8522508000 ---p 00016000 08:02 136658 /usr/lib64/libgcc_s-6.3.1-20170216.so.1 7f8522508000-7f8522509000 r--p 00015000 08:02 136658 /usr/lib64/libgcc_s-6.3.1-20170216.so.1 7f8522509000-7f852250a000 rw-p 00016000 08:02 136658 /usr/lib64/libgcc_s-6.3.1-20170216.so.1 7f8522539000-7f852253a000 r-xp 00000000 08:11 26334619 /export/build/gnu/glibc-gold/build-x86_64-linux/elf/constload2.so 7f852253a000-7f852253b000 r--p 00000000 08:11 26334619 /export/build/gnu/glibc-gold/build-x86_64-linux/elf/constload2.so 7f852253b000-7f852253c000 rw-p 00001000 08:11 26334619 /export/build/gnu/glibc-gold/build-x86_64-linux/elf/constload2.so 7f852253c000-7f852253e000 rw-p 00000000 00:00 0 7f852253e000-7f85226da000 r-xp 00000000 08:11 26309973 /export/build/gnu/glibc-gold/build-x86_64-linux/libc.so 7f85226da000-7f85226db000 ---p 0019c000 08:11 26309973 /export/build/gnu/glibc-gold/build-x86_64-linux/libc.so 7f85226db000-7f85226de000 r--p 0019c000 08:11 26309973 /export/build/gnu/glibc-gold/build-x86_64-linux/libc.so 7f85226de000-7f85226e1000 rw-p 0019f000 08:11 26309973 /export/build/gnu/glibc-gold/build-x86_64-linux/libc.so 7f85226e1000-7f85226e5000 rw-p 00000000 00:00 0 7f85226e5000-7f85226e8000 r-xp 00000000 08:11 26313777 /export/build/gnu/glibc-gold/build-x86_64-linux/dlfcn/libdl.so 7f85226e8000-7f85226e9000 r--p 00002000 08:11 26313777 /export/build/gnu/glibc-gold/build-x86_64-linux/dlfcn/libdl.so 7f85226e9000-7f85226ea000 rw-p 00003000 08:11 26313777 /export/build/gnu/glibc-gold/build-x86_64-linux/dlfcn/libdl.so 7f85226ea000-7f85226ec000 rw-p 00000000 00:00 0 7f85226ec000-7f8522711000 r-xp 00000000 08:11 26309972 /export/build/gnu/glibc-gold/build-x86_64-linux/elf/ld.so 7f8522711000-7f8522712000 rw-p 00000000 00:00 0 7f8522712000-7f8522713000 r--p 00025000 08:11 26309972 /export/build/gnu/glibc-gold/build-x86_64-linux/elf/ld.so 7f8522713000-7f8522714000 rw-p 00026000 08:11 26309972 /export/build/gnu/glibc-gold/build-x86_64-linux/elf/ld.so 7f8522714000-7f8522715000 rw-p 00000000 00:00 0 7ffc5a2bd000-7ffc5a2df000 rw-p 00000000 00:00 0 [stack] 7ffc5a32c000-7ffc5a32e000 r--p 00000000 00:00 0 [vvar] 7ffc5a32e000-7ffc5a330000 r-xp 00000000 00:00 0 [vdso] ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall] and make[4]: *** [/export/build/gnu/glibc-gold/build-x86_64-linux/elf/vismain] Error 1 This is because gold doesn't support protected data symbols: configure:5672: checking linker support for protected data symbol configure:5682: gcc -fuse-ld=gold -nostdlib -nostartfiles -fno-stack-protector -fPIC -shared conftest.c -o conftest.so configure:5685: $? = 0 configure:5692: gcc -fuse-ld=gold -nostdlib -nostartfiles -fno-stack-protector conftest.c -o conftest conftest.so /usr/local/bin/ld.gold: error: /tmp/ccXWoofs.o: cannot make copy relocation for protected symbol 'bar', defined in conftest.so collect2: error: ld returned 1 exit status make[4]: *** [/export/build/gnu/glibc-gold/build-x86_64-linux/elf/tst-split-dynreloc] Error 1 This is because gold doesn't support INSERT in linker script: https://sourceware.org/bugzilla/show_bug.cgi?id=21676 The total failures are FAIL: dlfcn/bug-dl-leaf FAIL: elf/constload1 FAIL: elf/global FAIL: elf/ifuncmain1 FAIL: elf/ifuncmain1pic FAIL: elf/ifuncmain1pie FAIL: elf/ifuncmain1vis FAIL: elf/ifuncmain1vispic FAIL: elf/ifuncmain1vispie FAIL: elf/ifuncmain3 FAIL: elf/initfirst FAIL: elf/preloadtest FAIL: elf/tst-audit11 FAIL: elf/tst-audit12 FAIL: elf/tst-audit4 FAIL: elf/tst-audit5 FAIL: elf/tst-audit6 FAIL: elf/tst-audit7 FAIL: elf/tst-dlmodcount FAIL: elf/tst-dlmopen1 FAIL: elf/tst-dlmopen3 FAIL: elf/tst-dlopenrpath FAIL: elf/tst-latepthread FAIL: elf/tst-leaks1-mem FAIL: elf/tst-nodelete-dlclose FAIL: elf/unload6 FAIL: nss/test-netdb FAIL: nss/tst-nss-test1 FAIL: posix/tst-getaddrinfo5 [BZ #14995] * configure.ac: Allow gold 1.14 or above to configire glibc * configure: Regenerated. --- ChangeLog | 6 +++++ configure | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- configure.ac | 17 ++++++++++---- 3 files changed, 89 insertions(+), 6 deletions(-) (limited to 'configure.ac') diff --git a/ChangeLog b/ChangeLog index 7bcff3bd62..dc781f94d3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2017-06-28 H.J. Lu + + [BZ #14995] + * configure.ac: Allow gold 1.14 or above to configire glibc + * configure: Regenerated. + 2017-06-28 Joseph Myers [BZ #21457] diff --git a/configure b/configure index 97a2dadf2d..b55fc92c53 100755 --- a/configure +++ b/configure @@ -4662,7 +4662,74 @@ if test $ac_verc_fail = yes; then AS=: critic_missing="$critic_missing as" fi -for ac_prog in $LD + +if test -n "`$LD --version | sed -n 's/^GNU \(gold\).*$/\1/p'`"; then + # Accept gold 1.14 or higher + for ac_prog in $LD +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_LD+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$LD"; then + ac_cv_prog_LD="$LD" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_LD="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +LD=$ac_cv_prog_LD +if test -n "$LD"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LD" >&5 +$as_echo "$LD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$LD" && break +done + +if test -z "$LD"; then + ac_verc_fail=yes +else + # Found it, now check the version. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking version of $LD" >&5 +$as_echo_n "checking version of $LD... " >&6; } + ac_prog_version=`$LD --version 2>&1 | sed -n 's/^.*GNU gold.* \([0-9][0-9]*\.[0-9.]*\).*$/\1/p'` + case $ac_prog_version in + '') ac_prog_version="v. ?.??, bad"; ac_verc_fail=yes;; + 1.1[4-9]*|1.[2-9][0-9]*|1.1[0-9][0-9]*|[2-9].*|[1-9][0-9]*) + ac_prog_version="$ac_prog_version, ok"; ac_verc_fail=no;; + *) ac_prog_version="$ac_prog_version, bad"; ac_verc_fail=yes;; + + esac + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_prog_version" >&5 +$as_echo "$ac_prog_version" >&6; } +fi +if test $ac_verc_fail = yes; then + LD=: critic_missing="$critic_missing GNU gold" +fi + +else + for ac_prog in $LD do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 @@ -4722,9 +4789,10 @@ $as_echo_n "checking version of $LD... " >&6; } $as_echo "$ac_prog_version" >&6; } fi if test $ac_verc_fail = yes; then - LD=: critic_missing="$critic_missing ld" + LD=: critic_missing="$critic_missing GNU ld" fi +fi # These programs are version sensitive. diff --git a/configure.ac b/configure.ac index 16e97d3930..5f62ecb718 100644 --- a/configure.ac +++ b/configure.ac @@ -1076,10 +1076,19 @@ AC_CHECK_PROG_VER(AS, $AS, --version, [GNU assembler.* \([0-9]*\.[0-9.]*\)], [2.1[0-9][0-9]*|2.2[2-9]*|2.[3-9][0-9]*|[3-9].*|[1-9][0-9]*], AS=: critic_missing="$critic_missing as") -AC_CHECK_PROG_VER(LD, $LD, --version, - [GNU ld.* \([0-9][0-9]*\.[0-9.]*\)], - [2.1[0-9][0-9]*|2.2[2-9]*|2.[3-9][0-9]*|[3-9].*|[1-9][0-9]*], - LD=: critic_missing="$critic_missing ld") + +if test -n "`$LD --version | sed -n 's/^GNU \(gold\).*$/\1/p'`"; then + # Accept gold 1.14 or higher + AC_CHECK_PROG_VER(LD, $LD, --version, + [GNU gold.* \([0-9][0-9]*\.[0-9.]*\)], + [1.1[4-9]*|1.[2-9][0-9]*|1.1[0-9][0-9]*|[2-9].*|[1-9][0-9]*], + LD=: critic_missing="$critic_missing GNU gold") +else + AC_CHECK_PROG_VER(LD, $LD, --version, + [GNU ld.* \([0-9][0-9]*\.[0-9.]*\)], + [2.1[0-9][0-9]*|2.2[2-9]*|2.[3-9][0-9]*|[3-9].*|[1-9][0-9]*], + LD=: critic_missing="$critic_missing GNU ld") +fi # These programs are version sensitive. AC_CHECK_TOOL_PREFIX -- cgit v1.2.3 From 073e8fa7739ed453d6854b834f290c263a6cdb9f Mon Sep 17 00:00:00 2001 From: Joseph Myers Date: Wed, 28 Jun 2017 11:31:50 +0000 Subject: Require binutils 2.25 or later to build glibc. This patch implements a requirement of binutils >= 2.25 (up from 2.22) to build glibc. Tests for 2.24 or later on x86_64 and s390 are removed. It was already the case, as indicated by buildbot results, that 2.24 was too old for building tests for 32-bit x86 (produced internal linker errors linking elf/tst-gnu2-tls1mod.so). I don't know if any configure tests for binutils features are obsolete given the increased version requirement. Tested for x86_64. * configure.ac (AS): Require binutils 2.25 or later. (LD): Likewise. * configure: Regenerated. * sysdeps/s390/configure.ac (AS): Remove version check. * sysdeps/s390/configure: Regenerated. * sysdeps/x86_64/configure.ac (AS): Remove version check. * sysdeps/x86_64/configure: Regenerated. * manual/install.texi (Tools for Compilation): Document requirement for binutils 2.25 or later. * INSTALL: Regenerated. --- ChangeLog | 13 +++++++++ INSTALL | 2 +- NEWS | 3 +++ configure | 2 +- configure.ac | 2 +- manual/install.texi | 2 +- sysdeps/s390/configure | 65 --------------------------------------------- sysdeps/s390/configure.ac | 6 ----- sysdeps/x86_64/configure | 64 -------------------------------------------- sysdeps/x86_64/configure.ac | 6 ----- 10 files changed, 20 insertions(+), 145 deletions(-) (limited to 'configure.ac') diff --git a/ChangeLog b/ChangeLog index dc781f94d3..a1558d5bc5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2017-06-28 Joseph Myers + + * configure.ac (AS): Require binutils 2.25 or later. + (LD): Likewise. + * configure: Regenerated. + * sysdeps/s390/configure.ac (AS): Remove version check. + * sysdeps/s390/configure: Regenerated. + * sysdeps/x86_64/configure.ac (AS): Remove version check. + * sysdeps/x86_64/configure: Regenerated. + * manual/install.texi (Tools for Compilation): Document + requirement for binutils 2.25 or later. + * INSTALL: Regenerated. + 2017-06-28 H.J. Lu [BZ #14995] diff --git a/INSTALL b/INSTALL index 4e05e9922b..5c745244a6 100644 --- a/INSTALL +++ b/INSTALL @@ -448,7 +448,7 @@ build the GNU C Library: Check the FAQ for any special compiler issues on particular platforms. - * GNU 'binutils' 2.22 or later + * GNU 'binutils' 2.25 or later You must use GNU 'binutils' (as and ld) to build the GNU C Library. No other assembler or linker has the necessary functionality at the diff --git a/NEWS b/NEWS index 22c43f5977..ba3e77b66a 100644 --- a/NEWS +++ b/NEWS @@ -129,6 +129,9 @@ Version 2.26 C Library is GCC 4.9. Older GCC versions, and non-GNU compilers, can still be used to compile programs using the GNU C Library. +* The minimum GNU Binutils version that can be used to build this version of + the GNU C Library is Binutils 2.25. + * Support is added, on powerpc64le, x86_64, x86 and ia64, for interfaces supporting the _Float128 type from ISO/IEC TS 18661-3:2015. Most of the interfaces are taken from TS 18661-3. The type-generic macros in diff --git a/configure b/configure index b55fc92c53..8e5c5bdde0 100755 --- a/configure +++ b/configure @@ -4780,7 +4780,7 @@ $as_echo_n "checking version of $LD... " >&6; } ac_prog_version=`$LD --version 2>&1 | sed -n 's/^.*GNU ld.* \([0-9][0-9]*\.[0-9.]*\).*$/\1/p'` case $ac_prog_version in '') ac_prog_version="v. ?.??, bad"; ac_verc_fail=yes;; - 2.1[0-9][0-9]*|2.2[2-9]*|2.[3-9][0-9]*|[3-9].*|[1-9][0-9]*) + 2.1[0-9][0-9]*|2.2[5-9]*|2.[3-9][0-9]*|[3-9].*|[1-9][0-9]*) ac_prog_version="$ac_prog_version, ok"; ac_verc_fail=no;; *) ac_prog_version="$ac_prog_version, bad"; ac_verc_fail=yes;; diff --git a/configure.ac b/configure.ac index 5f62ecb718..7e03019c4f 100644 --- a/configure.ac +++ b/configure.ac @@ -1086,7 +1086,7 @@ if test -n "`$LD --version | sed -n 's/^GNU \(gold\).*$/\1/p'`"; then else AC_CHECK_PROG_VER(LD, $LD, --version, [GNU ld.* \([0-9][0-9]*\.[0-9.]*\)], - [2.1[0-9][0-9]*|2.2[2-9]*|2.[3-9][0-9]*|[3-9].*|[1-9][0-9]*], + [2.1[0-9][0-9]*|2.2[5-9]*|2.[3-9][0-9]*|[3-9].*|[1-9][0-9]*], LD=: critic_missing="$critic_missing GNU ld") fi diff --git a/manual/install.texi b/manual/install.texi index ff5661a4fd..03eb2dd93b 100644 --- a/manual/install.texi +++ b/manual/install.texi @@ -493,7 +493,7 @@ You can use whatever compiler you like to compile programs that use Check the FAQ for any special compiler issues on particular platforms. @item -GNU @code{binutils} 2.22 or later +GNU @code{binutils} 2.25 or later You must use GNU @code{binutils} (as and ld) to build @theglibc{}. No other assembler or linker has the necessary functionality at the diff --git a/sysdeps/s390/configure b/sysdeps/s390/configure index 347ac28528..d4a4a3dcf8 100644 --- a/sysdeps/s390/configure +++ b/sysdeps/s390/configure @@ -4,71 +4,6 @@ $as_echo "#define PI_STATIC_AND_HIDDEN 1" >>confdefs.h -for ac_prog in $AS -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_AS+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$AS"; then - ac_cv_prog_AS="$AS" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_AS="$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -AS=$ac_cv_prog_AS -if test -n "$AS"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AS" >&5 -$as_echo "$AS" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$AS" && break -done - -if test -z "$AS"; then - ac_verc_fail=yes -else - # Found it, now check the version. - { $as_echo "$as_me:${as_lineno-$LINENO}: checking version of $AS" >&5 -$as_echo_n "checking version of $AS... " >&6; } - ac_prog_version=`$AS --version 2>&1 | sed -n 's/^.*GNU assembler.* \([0-9]*\.[0-9.]*\).*$/\1/p'` - case $ac_prog_version in - '') ac_prog_version="v. ?.??, bad"; ac_verc_fail=yes;; - 2.2[4-9]*|2.[3-9][0-9]*|[3-9].*|[1-9][0-9]*) - ac_prog_version="$ac_prog_version, ok"; ac_verc_fail=no;; - *) ac_prog_version="$ac_prog_version, bad"; ac_verc_fail=yes;; - - esac - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_prog_version" >&5 -$as_echo "$ac_prog_version" >&6; } -fi -if test $ac_verc_fail = yes; then - critic_missing="$critic_missing The program AS is required in version >= 2.24 for target S390." -fi - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for __builtin_tbegin" >&5 $as_echo_n "checking for __builtin_tbegin... " >&6; } if ${libc_cv_gcc_builtin_tbegin+:} false; then : diff --git a/sysdeps/s390/configure.ac b/sysdeps/s390/configure.ac index 8a782e7c3a..7d0b5ce46f 100644 --- a/sysdeps/s390/configure.ac +++ b/sysdeps/s390/configure.ac @@ -5,12 +5,6 @@ dnl It is always possible to access static and hidden symbols in an dnl position independent way. AC_DEFINE(PI_STATIC_AND_HIDDEN) -dnl Accept as 2.24 or newer. -AC_CHECK_PROG_VER(AS, $AS, --version, - [GNU assembler.* \([0-9]*\.[0-9.]*\)], - [2.2[4-9]*|2.[3-9][0-9]*|[3-9].*|[1-9][0-9]*], critic_missing="$critic_missing The program AS is required in version >= 2.24 for target S390.") - - AC_CACHE_CHECK(for __builtin_tbegin, libc_cv_gcc_builtin_tbegin, [dnl cat > conftest.c <<\EOF #include diff --git a/sysdeps/x86_64/configure b/sysdeps/x86_64/configure index 2d14c344df..efef46b1b7 100644 --- a/sysdeps/x86_64/configure +++ b/sysdeps/x86_64/configure @@ -1,70 +1,6 @@ # This file is generated from configure.ac by Autoconf. DO NOT EDIT! # Local configure fragment for sysdeps/x86_64. -for ac_prog in $AS -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_AS+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$AS"; then - ac_cv_prog_AS="$AS" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_AS="$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -AS=$ac_cv_prog_AS -if test -n "$AS"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AS" >&5 -$as_echo "$AS" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$AS" && break -done - -if test -z "$AS"; then - ac_verc_fail=yes -else - # Found it, now check the version. - { $as_echo "$as_me:${as_lineno-$LINENO}: checking version of $AS" >&5 -$as_echo_n "checking version of $AS... " >&6; } - ac_prog_version=`$AS --version 2>&1 | sed -n 's/^.*GNU assembler.* \([0-9]*\.[0-9.]*\).*$/\1/p'` - case $ac_prog_version in - '') ac_prog_version="v. ?.??, bad"; ac_verc_fail=yes;; - 2.2[4-9]*|2.[3-9][0-9]*|[3-9].*|[1-9][0-9]*) - ac_prog_version="$ac_prog_version, ok"; ac_verc_fail=no;; - *) ac_prog_version="$ac_prog_version, bad"; ac_verc_fail=yes;; - - esac - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_prog_version" >&5 -$as_echo "$ac_prog_version" >&6; } -fi -if test $ac_verc_fail = yes; then - critic_missing="$critic_missing The program AS is required in version >= 2.24 for target x86_64." -fi - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for AVX512DQ support in assembler" >&5 $as_echo_n "checking for AVX512DQ support in assembler... " >&6; } if ${libc_cv_asm_avx512dq+:} false; then : diff --git a/sysdeps/x86_64/configure.ac b/sysdeps/x86_64/configure.ac index 7d8aaafc0c..fa86e953ee 100644 --- a/sysdeps/x86_64/configure.ac +++ b/sysdeps/x86_64/configure.ac @@ -1,12 +1,6 @@ GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory. # Local configure fragment for sysdeps/x86_64. -dnl Accept as 2.24 or newer for AVX512 load and store. -AC_CHECK_PROG_VER(AS, $AS, --version, - [GNU assembler.* \([0-9]*\.[0-9.]*\)], - [2.2[4-9]*|2.[3-9][0-9]*|[3-9].*|[1-9][0-9]*], - critic_missing="$critic_missing The program AS is required in version >= 2.24 for target x86_64.") - dnl Check if asm supports AVX512DQ. AC_CACHE_CHECK(for AVX512DQ support in assembler, libc_cv_asm_avx512dq, [dnl cat > conftest.s <<\EOF -- cgit v1.2.3 From d5c3fafc4307c9b7a4c7d5cb381fcdbfad340bcc Mon Sep 17 00:00:00 2001 From: DJ Delorie Date: Thu, 6 Jul 2017 13:37:30 -0400 Subject: Add per-thread cache to malloc * config.make.in: Enable experimental malloc option. * configure.ac: Likewise. * configure: Regenerate. * manual/install.texi: Document it. * INSTALL: Regenerate. * malloc/Makefile: Likewise. * malloc/malloc.c: Add per-thread cache (tcache). (tcache_put): New. (tcache_get): New. (tcache_thread_freeres): New. (tcache_init): New. (__libc_malloc): Use cached chunks if available. (__libc_free): Initialize tcache if needed. (__libc_realloc): Likewise. (__libc_calloc): Likewise. (_int_malloc): Prefill tcache when appropriate. (_int_free): Likewise. (do_set_tcache_max): New. (do_set_tcache_count): New. (do_set_tcache_unsorted_limit): New. * manual/probes.texi: Document new probes. * malloc/arena.c: Add new tcache tunables. * elf/dl-tunables.list: Likewise. * manual/tunables.texi: Document them. * NEWS: Mention the per-thread cache. --- ChangeLog | 28 +++++ INSTALL | 6 + NEWS | 8 ++ config.make.in | 2 + configure | 13 ++ configure.ac | 7 ++ elf/dl-tunables.list | 12 ++ malloc/Makefile | 5 + malloc/arena.c | 11 ++ malloc/malloc.c | 350 +++++++++++++++++++++++++++++++++++++++++++++++++-- manual/install.texi | 6 + manual/probes.texi | 19 +++ manual/tunables.texi | 32 +++++ 13 files changed, 490 insertions(+), 9 deletions(-) (limited to 'configure.ac') diff --git a/ChangeLog b/ChangeLog index ac598984e3..1c51b3be29 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,31 @@ +2017-07-06 DJ Delorie + + * config.make.in: Enable experimental malloc option. + * configure.ac: Likewise. + * configure: Regenerate. + * manual/install.texi: Document it. + * INSTALL: Regenerate. + * malloc/Makefile: Likewise. + * malloc/malloc.c: Add per-thread cache (tcache). + (tcache_put): New. + (tcache_get): New. + (tcache_thread_freeres): New. + (tcache_init): New. + (__libc_malloc): Use cached chunks if available. + (__libc_free): Initialize tcache if needed. + (__libc_realloc): Likewise. + (__libc_calloc): Likewise. + (_int_malloc): Prefill tcache when appropriate. + (_int_free): Likewise. + (do_set_tcache_max): New. + (do_set_tcache_count): New. + (do_set_tcache_unsorted_limit): New. + * manual/probes.texi: Document new probes. + * malloc/arena.c: Add new tcache tunables. + * elf/dl-tunables.list: Likewise. + * manual/tunables.texi: Document them. + * NEWS: Mention the per-thread cache. + 2017-07-06 Joseph Myers * iconvdata/tst-loading.c (TIMEOUT): Define to 30. diff --git a/INSTALL b/INSTALL index 5c745244a6..0ff87ed603 100644 --- a/INSTALL +++ b/INSTALL @@ -200,6 +200,12 @@ will be used, and CFLAGS sets optimization options for the compiler. libnss_nisplus are not built at all. Use this option to enable libnsl with all depending NSS modules and header files. +'--disable-experimental-malloc' + By default, a per-thread cache is enabled in 'malloc'. While this + cache can be disabled on a per-application basis using tunables + (set glibc.malloc.tcache_count to zero), this option can be used to + remove it from the build completely. + '--build=BUILD-SYSTEM' '--host=HOST-SYSTEM' These options are for cross-compiling. If you specify both options diff --git a/NEWS b/NEWS index 616b3244e7..1266276fcd 100644 --- a/NEWS +++ b/NEWS @@ -9,6 +9,14 @@ Version 2.26 Major new features: +* A per-thread cache has been added to malloc. Access to the cache requires + no locks and therefore significantly accelerates the fast path to allocate + and free small amounts of memory. Refilling an empty cache requires locking + the underlying arena. Performance measurements show significant gains in a + wide variety of user workloads. Workloads were captured using a special + instrumented malloc and analyzed with a malloc simulator. Contributed by + DJ Delorie with the help of Florian Weimer, and Carlos O'Donell. + * Unicode 10.0.0 Support: Character encoding, character type info, and transliteration tables are all updated to Unicode 10.0.0, using generator scripts contributed by Mike FABIAN (Red Hat). diff --git a/config.make.in b/config.make.in index dadabf9b6a..5a4a054612 100644 --- a/config.make.in +++ b/config.make.in @@ -78,6 +78,8 @@ multi-arch = @multi_arch@ mach-interface-list = @mach_interface_list@ +experimental-malloc = @experimental_malloc@ + nss-crypt = @libc_cv_nss_crypt@ static-nss-crypt = @libc_cv_static_nss_crypt@ diff --git a/configure b/configure index 8e5c5bdde0..d8e1c50e11 100755 --- a/configure +++ b/configure @@ -674,6 +674,7 @@ build_obsolete_nsl link_obsolete_rpc libc_cv_static_nss_crypt libc_cv_nss_crypt +experimental_malloc enable_werror all_warnings force_install @@ -779,6 +780,7 @@ enable_kernel enable_all_warnings enable_werror enable_multi_arch +enable_experimental_malloc enable_nss_crypt enable_obsolete_rpc enable_obsolete_nsl @@ -1450,6 +1452,8 @@ Optional Features: --disable-werror do not build with -Werror --enable-multi-arch enable single DSO with optimizations for multiple architectures + --disable-experimental-malloc + disable experimental malloc features --enable-nss-crypt enable libcrypt to use nss --enable-obsolete-rpc build and install the obsolete RPC code for link-time usage @@ -3522,6 +3526,15 @@ else fi +# Check whether --enable-experimental-malloc was given. +if test "${enable_experimental_malloc+set}" = set; then : + enableval=$enable_experimental_malloc; experimental_malloc=$enableval +else + experimental_malloc=yes +fi + + + # Check whether --enable-nss-crypt was given. if test "${enable_nss_crypt+set}" = set; then : enableval=$enable_nss_crypt; nss_crypt=$enableval diff --git a/configure.ac b/configure.ac index 7e03019c4f..77456aa8d9 100644 --- a/configure.ac +++ b/configure.ac @@ -313,6 +313,13 @@ AC_ARG_ENABLE([multi-arch], [multi_arch=$enableval], [multi_arch=default]) +AC_ARG_ENABLE([experimental-malloc], + AC_HELP_STRING([--disable-experimental-malloc], + [disable experimental malloc features]), + [experimental_malloc=$enableval], + [experimental_malloc=yes]) +AC_SUBST(experimental_malloc) + AC_ARG_ENABLE([nss-crypt], AC_HELP_STRING([--enable-nss-crypt], [enable libcrypt to use nss]), diff --git a/elf/dl-tunables.list b/elf/dl-tunables.list index df4f9622b4..c188c6ad52 100644 --- a/elf/dl-tunables.list +++ b/elf/dl-tunables.list @@ -76,6 +76,18 @@ glibc { minval: 1 security_level: SXID_IGNORE } + tcache_max { + type: SIZE_T + security_level: SXID_ERASE + } + tcache_count { + type: SIZE_T + security_level: SXID_ERASE + } + tcache_unsorted_limit { + type: SIZE_T + security_level: SXID_ERASE + } } tune { hwcap_mask { diff --git a/malloc/Makefile b/malloc/Makefile index b50de7cd6c..3fa395b949 100644 --- a/malloc/Makefile +++ b/malloc/Makefile @@ -189,6 +189,11 @@ tst-malloc-usable-static-ENV = $(tst-malloc-usable-ENV) tst-malloc-usable-tunables-ENV = GLIBC_TUNABLES=glibc.malloc.check=3 tst-malloc-usable-static-tunables-ENV = $(tst-malloc-usable-tunables-ENV) +ifeq ($(experimental-malloc),yes) +CPPFLAGS-malloc.c += -DUSE_TCACHE=1 +else +CPPFLAGS-malloc.c += -DUSE_TCACHE=0 +endif # Uncomment this for test releases. For public releases it is too expensive. #CPPFLAGS-malloc.o += -DMALLOC_DEBUG=1 diff --git a/malloc/arena.c b/malloc/arena.c index 660d638c93..dc14fae152 100644 --- a/malloc/arena.c +++ b/malloc/arena.c @@ -236,6 +236,11 @@ TUNABLE_CALLBACK_FNDECL (set_perturb_byte, int32_t) TUNABLE_CALLBACK_FNDECL (set_trim_threshold, size_t) TUNABLE_CALLBACK_FNDECL (set_arena_max, size_t) TUNABLE_CALLBACK_FNDECL (set_arena_test, size_t) +#if USE_TCACHE +TUNABLE_CALLBACK_FNDECL (set_tcache_max, size_t) +TUNABLE_CALLBACK_FNDECL (set_tcache_count, size_t) +TUNABLE_CALLBACK_FNDECL (set_tcache_unsorted_limit, size_t) +#endif #else /* Initialization routine. */ #include @@ -322,6 +327,12 @@ ptmalloc_init (void) TUNABLE_GET (mmap_max, int32_t, TUNABLE_CALLBACK (set_mmaps_max)); TUNABLE_GET (arena_max, size_t, TUNABLE_CALLBACK (set_arena_max)); TUNABLE_GET (arena_test, size_t, TUNABLE_CALLBACK (set_arena_test)); +#if USE_TCACHE + TUNABLE_GET (tcache_max, size_t, TUNABLE_CALLBACK (set_tcache_max)); + TUNABLE_GET (tcache_count, size_t, TUNABLE_CALLBACK (set_tcache_count)); + TUNABLE_GET (tcache_unsorted_limit, size_t, + TUNABLE_CALLBACK (set_tcache_unsorted_limit)); +#endif __libc_lock_unlock (main_arena.mutex); #else const char *s = NULL; diff --git a/malloc/malloc.c b/malloc/malloc.c index aa45626093..2527e25047 100644 --- a/malloc/malloc.c +++ b/malloc/malloc.c @@ -238,6 +238,9 @@ /* For ALIGN_UP et. al. */ #include +/* For DIAG_PUSH/POP_NEEDS_COMMENT et al. */ +#include + #include /* @@ -296,6 +299,30 @@ __malloc_assert (const char *assertion, const char *file, unsigned int line, } #endif +#if USE_TCACHE +/* We want 64 entries. This is an arbitrary limit, which tunables can reduce. */ +# define TCACHE_MAX_BINS 64 +# define MAX_TCACHE_SIZE tidx2usize (TCACHE_MAX_BINS-1) + +/* Only used to pre-fill the tunables. */ +# define tidx2usize(idx) (((size_t) idx) * MALLOC_ALIGNMENT + MINSIZE - SIZE_SZ) + +/* When "x" is from chunksize(). */ +# define csize2tidx(x) (((x) - MINSIZE + MALLOC_ALIGNMENT - 1) / MALLOC_ALIGNMENT) +/* When "x" is a user-provided size. */ +# define usize2tidx(x) csize2tidx (request2size (x)) + +/* With rounding and alignment, the bins are... + idx 0 bytes 0..24 (64-bit) or 0..12 (32-bit) + idx 1 bytes 25..40 or 13..20 + idx 2 bytes 41..56 or 21..28 + etc. */ + +/* This is another arbitrary limit, which tunables can change. Each + tcache bin will hold at most this number of chunks. */ +# define TCACHE_FILL_COUNT 7 +#endif + /* REALLOC_ZERO_BYTES_FREES should be set if a call to @@ -1712,6 +1739,17 @@ struct malloc_par /* First address handed out by MORECORE/sbrk. */ char *sbrk_base; + +#if USE_TCACHE + /* Maximum number of buckets to use. */ + size_t tcache_bins; + size_t tcache_max_bytes; + /* Maximum number of chunks in each bucket. */ + size_t tcache_count; + /* Maximum number of chunks to remove from the unsorted list, which + aren't used to prefill the cache. */ + size_t tcache_unsorted_limit; +#endif }; /* There are several instances of this struct ("arenas") in this @@ -1750,6 +1788,13 @@ static struct malloc_par mp_ = .trim_threshold = DEFAULT_TRIM_THRESHOLD, #define NARENAS_FROM_NCORES(n) ((n) * (sizeof (long) == 4 ? 2 : 8)) .arena_test = NARENAS_FROM_NCORES (1) +#if USE_TCACHE + , + .tcache_count = TCACHE_FILL_COUNT, + .tcache_bins = TCACHE_MAX_BINS, + .tcache_max_bytes = tidx2usize (TCACHE_MAX_BINS-1), + .tcache_unsorted_limit = 0 /* No limit. */ +#endif }; /* Maximum size of memory handled in fastbins. */ @@ -2875,6 +2920,124 @@ mremap_chunk (mchunkptr p, size_t new_size) /*------------------------ Public wrappers. --------------------------------*/ +#if USE_TCACHE + +/* We overlay this structure on the user-data portion of a chunk when + the chunk is stored in the per-thread cache. */ +typedef struct tcache_entry +{ + struct tcache_entry *next; +} tcache_entry; + +/* There is one of these for each thread, which contains the + per-thread cache (hence "tcache_perthread_struct"). Keeping + overall size low is mildly important. Note that COUNTS and ENTRIES + are redundant (we could have just counted the linked list each + time), this is for performance reasons. */ +typedef struct tcache_perthread_struct +{ + char counts[TCACHE_MAX_BINS]; + tcache_entry *entries[TCACHE_MAX_BINS]; +} tcache_perthread_struct; + +static __thread char tcache_shutting_down = 0; +static __thread tcache_perthread_struct *tcache = NULL; + +/* Caller must ensure that we know tc_idx is valid and there's room + for more chunks. */ +static void +tcache_put (mchunkptr chunk, size_t tc_idx) +{ + tcache_entry *e = (tcache_entry *) chunk2mem (chunk); + assert (tc_idx < TCACHE_MAX_BINS); + e->next = tcache->entries[tc_idx]; + tcache->entries[tc_idx] = e; + ++(tcache->counts[tc_idx]); +} + +/* Caller must ensure that we know tc_idx is valid and there's + available chunks to remove. */ +static void * +tcache_get (size_t tc_idx) +{ + tcache_entry *e = tcache->entries[tc_idx]; + assert (tc_idx < TCACHE_MAX_BINS); + assert (tcache->entries[tc_idx] > 0); + tcache->entries[tc_idx] = e->next; + --(tcache->counts[tc_idx]); + return (void *) e; +} + +static void __attribute__ ((section ("__libc_thread_freeres_fn"))) +tcache_thread_freeres (void) +{ + int i; + tcache_perthread_struct *tcache_tmp = tcache; + + if (!tcache) + return; + + tcache = NULL; + + for (i = 0; i < TCACHE_MAX_BINS; ++i) + { + while (tcache_tmp->entries[i]) + { + tcache_entry *e = tcache_tmp->entries[i]; + tcache_tmp->entries[i] = e->next; + __libc_free (e); + } + } + + __libc_free (tcache_tmp); + + tcache_shutting_down = 1; +} +text_set_element (__libc_thread_subfreeres, tcache_thread_freeres); + +static void +tcache_init(void) +{ + mstate ar_ptr; + void *victim = 0; + const size_t bytes = sizeof (tcache_perthread_struct); + + if (tcache_shutting_down) + return; + + arena_get (ar_ptr, bytes); + victim = _int_malloc (ar_ptr, bytes); + if (!victim && ar_ptr != NULL) + { + ar_ptr = arena_get_retry (ar_ptr, bytes); + victim = _int_malloc (ar_ptr, bytes); + } + + + if (ar_ptr != NULL) + __libc_lock_unlock (ar_ptr->mutex); + + /* In a low memory situation, we may not be able to allocate memory + - in which case, we just keep trying later. However, we + typically do this very early, so either there is sufficient + memory, or there isn't enough memory to do non-trivial + allocations anyway. */ + if (victim) + { + tcache = (tcache_perthread_struct *) victim; + memset (tcache, 0, sizeof (tcache_perthread_struct)); + } + +} + +#define MAYBE_INIT_TCACHE() \ + if (__glibc_unlikely (tcache == NULL)) \ + tcache_init(); + +#else +#define MAYBE_INIT_TCACHE() +#endif + void * __libc_malloc (size_t bytes) { @@ -2885,6 +3048,23 @@ __libc_malloc (size_t bytes) = atomic_forced_read (__malloc_hook); if (__builtin_expect (hook != NULL, 0)) return (*hook)(bytes, RETURN_ADDRESS (0)); +#if USE_TCACHE + /* int_free also calls request2size, be careful to not pad twice. */ + size_t tbytes = request2size (bytes); + size_t tc_idx = csize2tidx (tbytes); + + MAYBE_INIT_TCACHE (); + + DIAG_PUSH_NEEDS_COMMENT; + if (tc_idx < mp_.tcache_bins + /*&& tc_idx < TCACHE_MAX_BINS*/ /* to appease gcc */ + && tcache + && tcache->entries[tc_idx] != NULL) + { + return tcache_get (tc_idx); + } + DIAG_POP_NEEDS_COMMENT; +#endif arena_get (ar_ptr, bytes); @@ -2944,6 +3124,8 @@ __libc_free (void *mem) return; } + MAYBE_INIT_TCACHE (); + ar_ptr = arena_for_chunk (p); _int_free (ar_ptr, p, 0); } @@ -2981,7 +3163,10 @@ __libc_realloc (void *oldmem, size_t bytes) if (chunk_is_mmapped (oldp)) ar_ptr = NULL; else - ar_ptr = arena_for_chunk (oldp); + { + MAYBE_INIT_TCACHE (); + ar_ptr = arena_for_chunk (oldp); + } /* Little security check which won't hurt performance: the allocator never wrapps around at the end of the address space. Therefore @@ -3206,6 +3391,8 @@ __libc_calloc (size_t n, size_t elem_size) sz = bytes; + MAYBE_INIT_TCACHE (); + arena_get (av, sz); if (av) { @@ -3336,6 +3523,10 @@ _int_malloc (mstate av, size_t bytes) mchunkptr fwd; /* misc temp for linking */ mchunkptr bck; /* misc temp for linking */ +#if USE_TCACHE + size_t tcache_unsorted_count; /* count of unsorted chunks processed */ +#endif + const char *errstr = NULL; /* @@ -3365,19 +3556,22 @@ _int_malloc (mstate av, size_t bytes) can try it without checking, which saves some time on this fast path. */ +#define REMOVE_FB(fb, victim, pp) \ + do \ + { \ + victim = pp; \ + if (victim == NULL) \ + break; \ + } \ + while ((pp = catomic_compare_and_exchange_val_acq (fb, victim->fd, victim)) \ + != victim); \ + if ((unsigned long) (nb) <= (unsigned long) (get_max_fast ())) { idx = fastbin_index (nb); mfastbinptr *fb = &fastbin (av, idx); mchunkptr pp = *fb; - do - { - victim = pp; - if (victim == NULL) - break; - } - while ((pp = catomic_compare_and_exchange_val_acq (fb, victim->fd, victim)) - != victim); + REMOVE_FB (fb, victim, pp); if (victim != 0) { if (__builtin_expect (fastbin_index (chunksize (victim)) != idx, 0)) @@ -3388,6 +3582,26 @@ _int_malloc (mstate av, size_t bytes) return NULL; } check_remalloced_chunk (av, victim, nb); +#if USE_TCACHE + /* While we're here, if we see other chunks of the same size, + stash them in the tcache. */ + size_t tc_idx = csize2tidx (nb); + if (tcache && tc_idx < mp_.tcache_bins) + { + mchunkptr tc_victim; + + /* While bin not empty and tcache not full, copy chunks over. */ + while (tcache->counts[tc_idx] < mp_.tcache_count + && (pp = *fb) != NULL) + { + REMOVE_FB (fb, tc_victim, pp); + if (tc_victim != 0) + { + tcache_put (tc_victim, tc_idx); + } + } + } +#endif void *p = chunk2mem (victim); alloc_perturb (p, bytes); return p; @@ -3426,6 +3640,32 @@ _int_malloc (mstate av, size_t bytes) if (av != &main_arena) set_non_main_arena (victim); check_malloced_chunk (av, victim, nb); +#if USE_TCACHE + /* While we're here, if we see other chunks of the same size, + stash them in the tcache. */ + size_t tc_idx = csize2tidx (nb); + if (tcache && tc_idx < mp_.tcache_bins) + { + mchunkptr tc_victim; + + /* While bin not empty and tcache not full, copy chunks over. */ + while (tcache->counts[tc_idx] < mp_.tcache_count + && (tc_victim = last (bin)) != bin) + { + if (tc_victim != 0) + { + bck = tc_victim->bk; + set_inuse_bit_at_offset (tc_victim, nb); + if (av != &main_arena) + set_non_main_arena (tc_victim); + bin->bk = bck; + bck->fd = bin; + + tcache_put (tc_victim, tc_idx); + } + } + } +#endif void *p = chunk2mem (victim); alloc_perturb (p, bytes); return p; @@ -3464,6 +3704,16 @@ _int_malloc (mstate av, size_t bytes) otherwise need to expand memory to service a "small" request. */ +#if USE_TCACHE + INTERNAL_SIZE_T tcache_nb = 0; + size_t tc_idx = csize2tidx (nb); + if (tcache && tc_idx < mp_.tcache_bins) + tcache_nb = nb; + int return_cached = 0; + + tcache_unsorted_count = 0; +#endif + for (;; ) { int iters = 0; @@ -3524,10 +3774,26 @@ _int_malloc (mstate av, size_t bytes) set_inuse_bit_at_offset (victim, size); if (av != &main_arena) set_non_main_arena (victim); +#if USE_TCACHE + /* Fill cache first, return to user only if cache fills. + We may return one of these chunks later. */ + if (tcache_nb + && tcache->counts[tc_idx] < mp_.tcache_count) + { + tcache_put (victim, tc_idx); + return_cached = 1; + continue; + } + else + { +#endif check_malloced_chunk (av, victim, nb); void *p = chunk2mem (victim); alloc_perturb (p, bytes); return p; +#if USE_TCACHE + } +#endif } /* place chunk in bin */ @@ -3594,11 +3860,31 @@ _int_malloc (mstate av, size_t bytes) fwd->bk = victim; bck->fd = victim; +#if USE_TCACHE + /* If we've processed as many chunks as we're allowed while + filling the cache, return one of the cached ones. */ + ++tcache_unsorted_count; + if (return_cached + && mp_.tcache_unsorted_limit > 0 + && tcache_unsorted_count > mp_.tcache_unsorted_limit) + { + return tcache_get (tc_idx); + } +#endif + #define MAX_ITERS 10000 if (++iters >= MAX_ITERS) break; } +#if USE_TCACHE + /* If all the small chunks we found ended up cached, return one now. */ + if (return_cached) + { + return tcache_get (tc_idx); + } +#endif + /* If a large request, scan through the chunks of current bin in sorted order to find smallest that fits. Use the skip list for this. @@ -3884,6 +4170,20 @@ _int_free (mstate av, mchunkptr p, int have_lock) check_inuse_chunk(av, p); +#if USE_TCACHE + { + size_t tc_idx = csize2tidx (size); + + if (tcache + && tc_idx < mp_.tcache_bins + && tcache->counts[tc_idx] < mp_.tcache_count) + { + tcache_put (p, tc_idx); + return; + } + } +#endif + /* If eligible, place chunk on a fastbin so it can be found and used quickly in malloc. @@ -4845,6 +5145,38 @@ do_set_arena_max (size_t value) return 1; } +#if USE_TCACHE +static inline int +__always_inline +do_set_tcache_max (size_t value) +{ + if (value >= 0 && value <= MAX_TCACHE_SIZE) + { + LIBC_PROBE (memory_tunable_tcache_max_bytes, 2, value, mp_.tcache_max_bytes); + mp_.tcache_max_bytes = value; + mp_.tcache_bins = csize2tidx (request2size(value)) + 1; + } + return 1; +} + +static inline int +__always_inline +do_set_tcache_count (size_t value) +{ + LIBC_PROBE (memory_tunable_tcache_count, 2, value, mp_.tcache_count); + mp_.tcache_count = value; + return 1; +} + +static inline int +__always_inline +do_set_tcache_unsorted_limit (size_t value) +{ + LIBC_PROBE (memory_tunable_tcache_unsorted_limit, 2, value, mp_.tcache_unsorted_limit); + mp_.tcache_unsorted_limit = value; + return 1; +} +#endif int __libc_mallopt (int param_number, int value) diff --git a/manual/install.texi b/manual/install.texi index 03eb2dd93b..b8deb9ceba 100644 --- a/manual/install.texi +++ b/manual/install.texi @@ -232,6 +232,12 @@ libnss_nisplus are not built at all. Use this option to enable libnsl with all depending NSS modules and header files. +@item --disable-experimental-malloc +By default, a per-thread cache is enabled in @code{malloc}. While +this cache can be disabled on a per-application basis using tunables +(set glibc.malloc.tcache_count to zero), this option can be used to +remove it from the build completely. + @item --build=@var{build-system} @itemx --host=@var{host-system} These options are for cross-compiling. If you specify both options and diff --git a/manual/probes.texi b/manual/probes.texi index eb91c62703..96acaed206 100644 --- a/manual/probes.texi +++ b/manual/probes.texi @@ -231,6 +231,25 @@ dynamic brk/mmap thresholds. Argument @var{$arg1} and @var{$arg2} are the adjusted mmap and trim thresholds, respectively. @end deftp +@deftp Probe memory_tunable_tcache_max_bytes (int @var{$arg1}, int @var{$arg2}) +This probe is triggered when the @code{glibc.malloc.tcache_max} +tunable is set. Argument @var{$arg1} is the requested value, and +@var{$arg2} is the previous value of this tunable. +@end deftp + +@deftp Probe memory_tunable_tcache_count (int @var{$arg1}, int @var{$arg2}) +This probe is triggered when the @code{glibc.malloc.tcache_count} +tunable is set. Argument @var{$arg1} is the requested value, and +@var{$arg2} is the previous value of this tunable. +@end deftp + +@deftp Probe memory_tunable_tcache_unsorted_limit (int @var{$arg1}, int @var{$arg2}) +This probe is triggered when the +@code{glibc.malloc.tcache_unsorted_limit} tunable is set. Argument +@var{$arg1} is the requested value, and @var{$arg2} is the previous +value of this tunable. +@end deftp + @node Mathematical Function Probes @section Mathematical Function Probes diff --git a/manual/tunables.texi b/manual/tunables.texi index 9331b03702..b16d591b90 100644 --- a/manual/tunables.texi +++ b/manual/tunables.texi @@ -193,6 +193,38 @@ systems the limit is twice the number of cores online and on 64-bit systems, it is 8 times the number of cores online. @end deftp +@deftp Tunable glibc.malloc.tcache_max +The maximum size of a request (in bytes) which may be met via the +per-thread cache. The default (and maximum) value is 1032 bytes on +64-bit systems and 516 bytes on 32-bit systems. +@end deftp + +@deftp Tunable glibc.malloc.tcache_count +The maximum number of chunks of each size to cache. The default is 7. +There is no upper limit, other than available system memory. If set +to zero, the per-thread cache is effectively disabled. + +The approximate maximum overhead of the per-thread cache is thus equal +to the number of bins times the chunk count in each bin times the size +of each chunk. With defaults, the approximate maximum overhead of the +per-thread cache is approximately 236 KB on 64-bit systems and 118 KB +on 32-bit systems. +@end deftp + +@deftp Tunable glibc.malloc.tcache_unsorted_limit +When the user requests memory and the request cannot be met via the +per-thread cache, the arenas are used to meet the request. At this +time, additional chunks will be moved from existing arena lists to +pre-fill the corresponding cache. While copies from the fastbins, +smallbins, and regular bins are bounded and predictable due to the bin +sizes, copies from the unsorted bin are not bounded, and incur +additional time penalties as they need to be sorted as they're +scanned. To make scanning the unsorted list more predictable and +bounded, the user may set this tunable to limit the number of chunks +that are scanned from the unsorted list while searching for chunks to +pre-fill the per-thread cache with. The default, or when set to zero, +is no limit. + @node Hardware Capability Tunables @section Hardware Capability Tunables @cindex hardware capability tunables -- cgit v1.2.3 From 19f1a11e7ea2a5082bae9d9a079338c5658ba954 Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Fri, 4 Aug 2017 12:17:15 -0700 Subject: Check linker support for INSERT in linker script Since gold doesn't support INSERT in linker script: https://sourceware.org/bugzilla/show_bug.cgi?id=21676 tst-split-dynreloc fails to link with gold. Check if linker supports INSERT in linker script before using it. * config.make.in (have-insert): New. * configure.ac (libc_cv_insert): New. Set to yes if linker supports INSERT in linker script. (AC_SUBST(libc_cv_insert): New. * configure: Regenerated. * sysdeps/x86_64/Makefile (tests): Add tst-split-dynreloc only if $(have-insert) == yes. --- ChangeLog | 10 ++++++++++ config.make.in | 1 + configure | 33 +++++++++++++++++++++++++++++++++ configure.ac | 21 +++++++++++++++++++++ sysdeps/x86_64/Makefile | 2 ++ 5 files changed, 67 insertions(+) (limited to 'configure.ac') diff --git a/ChangeLog b/ChangeLog index 33caac763c..cc540a148e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2017-08-04 H.J. Lu + + * config.make.in (have-insert): New. + * configure.ac (libc_cv_insert): New. Set to yes if linker + supports INSERT in linker script. + (AC_SUBST(libc_cv_insert): New. + * configure: Regenerated. + * sysdeps/x86_64/Makefile (tests): Add tst-split-dynreloc only + if $(have-insert) == yes. + 2017-08-04 H.J. Lu * elf/Makefile (tests): Add vismain only if diff --git a/config.make.in b/config.make.in index 5a4a054612..7eff1daf6a 100644 --- a/config.make.in +++ b/config.make.in @@ -54,6 +54,7 @@ enable-werror = @enable_werror@ have-z-combreloc = @libc_cv_z_combreloc@ have-z-execstack = @libc_cv_z_execstack@ have-protected-data = @libc_cv_protected_data@ +have-insert = @libc_cv_insert@ have-glob-dat-reloc = @libc_cv_has_glob_dat@ with-fp = @with_fp@ enable-timezone-tools = @enable_timezone_tools@ diff --git a/configure b/configure index d8e1c50e11..e6a54d7841 100755 --- a/configure +++ b/configure @@ -629,6 +629,7 @@ libc_cv_z_execstack libc_cv_z_combreloc ASFLAGS_config libc_cv_cc_with_libunwind +libc_cv_insert libc_cv_protected_data BISON INSTALL_INFO @@ -5716,6 +5717,38 @@ fi $as_echo "$libc_cv_protected_data" >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking linker support for INSERT in linker script" >&5 +$as_echo_n "checking linker support for INSERT in linker script... " >&6; } +if ${libc_cv_insert+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat > conftest.c < conftest.t <&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_insert=yes + fi + rm -f conftest.* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_insert" >&5 +$as_echo "$libc_cv_insert" >&6; } + + { $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 77456aa8d9..2c6308883c 100644 --- a/configure.ac +++ b/configure.ac @@ -1298,6 +1298,27 @@ EOF ]) AC_SUBST(libc_cv_protected_data) +AC_CACHE_CHECK(linker support for INSERT in linker script, + libc_cv_insert, + [cat > conftest.c < conftest.t < conftest.c < Date: Mon, 25 Sep 2017 18:01:23 -0700 Subject: Update configure.ac for binutils 2.25 Commit 073e8fa7739ed453d6854b834f290c263a6cdb9f requires binutils 2.25 or later to build glibc: * configure.ac (AS): Require binutils 2.25 or later. (LD): Likewise. But it only updated LD version check in configure.ac. This patch adds the missing AS version check. * configure.ac (AS): Require binutils 2.25 or later. * configure: Regenerated. --- ChangeLog | 5 +++++ configure | 4 ++-- configure.ac | 4 ++-- 3 files changed, 9 insertions(+), 4 deletions(-) (limited to 'configure.ac') diff --git a/ChangeLog b/ChangeLog index a92b23961d..c2cebf1c91 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2017-09-25 H.J. Lu + + * configure.ac (AS): Require binutils 2.25 or later. + * configure: Regenerated. + 2017-09-25 Paul Pluzhnikov [BZ #22207] diff --git a/configure b/configure index 5cb5210107..067d92d2ba 100755 --- a/configure +++ b/configure @@ -4615,7 +4615,7 @@ $as_echo "$libc_cv_prog_ld_gnu" >&6; } gnu_ld=$libc_cv_prog_ld_gnu -# Accept binutils 2.22 or newer. +# Accept binutils 2.25 or newer. for ac_prog in $AS do # Extract the first word of "$ac_prog", so it can be a program name with args. @@ -4667,7 +4667,7 @@ $as_echo_n "checking version of $AS... " >&6; } ac_prog_version=`$AS --version 2>&1 | sed -n 's/^.*GNU assembler.* \([0-9]*\.[0-9.]*\).*$/\1/p'` case $ac_prog_version in '') ac_prog_version="v. ?.??, bad"; ac_verc_fail=yes;; - 2.1[0-9][0-9]*|2.2[2-9]*|2.[3-9][0-9]*|[3-9].*|[1-9][0-9]*) + 2.1[0-9][0-9]*|2.2[5-9]*|2.[3-9][0-9]*|[3-9].*|[1-9][0-9]*) ac_prog_version="$ac_prog_version, ok"; ac_verc_fail=no;; *) ac_prog_version="$ac_prog_version, bad"; ac_verc_fail=yes;; diff --git a/configure.ac b/configure.ac index 2c6308883c..d412104d8c 100644 --- a/configure.ac +++ b/configure.ac @@ -1078,10 +1078,10 @@ AC_PROG_LN_S LIBC_PROG_BINUTILS -# Accept binutils 2.22 or newer. +# Accept binutils 2.25 or newer. AC_CHECK_PROG_VER(AS, $AS, --version, [GNU assembler.* \([0-9]*\.[0-9.]*\)], - [2.1[0-9][0-9]*|2.2[2-9]*|2.[3-9][0-9]*|[3-9].*|[1-9][0-9]*], + [2.1[0-9][0-9]*|2.2[5-9]*|2.[3-9][0-9]*|[3-9].*|[1-9][0-9]*], AS=: critic_missing="$critic_missing as") if test -n "`$LD --version | sed -n 's/^GNU \(gold\).*$/\1/p'`"; then -- cgit v1.2.3 From 57b4af1955e28c1623c98397b8597847d16bdd8c Mon Sep 17 00:00:00 2001 From: Guido Trentalancia Date: Wed, 4 Oct 2017 15:02:35 +0200 Subject: crypt: Use NSPR header files in addition to NSS header files [BZ #17956] When configuring and building GNU libc using the Mozilla NSS library for cryptography (--enable-nss-crypt option), also include the NSPR header files along with the Mozilla NSS library header files. Finally, when running the check-local-headers test, ignore the Mozilla NSPR library header files (used by the Mozilla NSS library). --- ChangeLog | 11 +++++++++++ configure | 6 +++++- configure.ac | 6 +++++- crypt/Makefile | 8 +++++--- scripts/check-local-headers.sh | 2 +- 5 files changed, 27 insertions(+), 6 deletions(-) (limited to 'configure.ac') diff --git a/ChangeLog b/ChangeLog index da2728a43c..f782b14045 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2017-10-04 Guido Trentalancia + + [BZ #17956] + * configure.ac (--enable-nss-crypt): Use NSPR include directory. + * configure: Regenerate. + * crypt/Makefile (nss-cpp-flags): New variable. + (CPPFLAGS-sha256-crypt.c, CPPFLAGS-sha512-crypt.c) + (CPPFLAGS-md5-crypt.c): Use it. + * scripts/check-local-headers.sh: Ignore nspr header file + directory. + 2017-10-04 Andreas Schwab * nis/Makefile (services): Remove compat. diff --git a/configure b/configure index 067d92d2ba..a7c72eaaa6 100755 --- a/configure +++ b/configure @@ -3549,8 +3549,12 @@ if test x$nss_crypt = xyes; then if test $? -ne 0; then as_fn_error $? "cannot find include directory with nss-config" "$LINENO" 5 fi + nspr_includes=-I$(nspr-config --includedir 2>/dev/null) + if test $? -ne 0; then + as_fn_error $? "cannot find include directory with nspr-config" "$LINENO" 5 + fi old_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS $nss_includes" + CFLAGS="$CFLAGS $nss_includes $nspr_includes" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ diff --git a/configure.ac b/configure.ac index d412104d8c..4b83ae5a09 100644 --- a/configure.ac +++ b/configure.ac @@ -330,8 +330,12 @@ if test x$nss_crypt = xyes; then if test $? -ne 0; then AC_MSG_ERROR([cannot find include directory with nss-config]) fi + nspr_includes=-I$(nspr-config --includedir 2>/dev/null) + if test $? -ne 0; then + AC_MSG_ERROR([cannot find include directory with nspr-config]) + fi old_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS $nss_includes" + CFLAGS="$CFLAGS $nss_includes $nspr_includes" AC_COMPILE_IFELSE([AC_LANG_PROGRAM([typedef int PRBool; #include #include diff --git a/crypt/Makefile b/crypt/Makefile index 0280fba8a7..8bbbf2a121 100644 --- a/crypt/Makefile +++ b/crypt/Makefile @@ -37,9 +37,11 @@ routines += $(libcrypt-routines) endif ifeq ($(nss-crypt),yes) -CPPFLAGS-sha256-crypt.c = -DUSE_NSS -I$(shell nss-config --includedir) -CPPFLAGS-sha512-crypt.c = -DUSE_NSS -I$(shell nss-config --includedir) -CPPFLAGS-md5-crypt.c = -DUSE_NSS -I$(shell nss-config --includedir) +nss-cpp-flags := -DUSE_NSS \ + -I$(shell nss-config --includedir) -I$(shell nspr-config --includedir) +CPPFLAGS-sha256-crypt.c = $(nss-cpp-flags) +CPPFLAGS-sha512-crypt.c = $(nss-cpp-flags) +CPPFLAGS-md5-crypt.c = $(nss-cpp-flags) LDLIBS-crypt.so = -lfreebl3 else libcrypt-routines += md5 sha256 sha512 diff --git a/scripts/check-local-headers.sh b/scripts/check-local-headers.sh index 7859f613b2..4692361686 100755 --- a/scripts/check-local-headers.sh +++ b/scripts/check-local-headers.sh @@ -33,7 +33,7 @@ exec ${AWK} -v includedir="$includedir" ' BEGIN { status = 0 exclude = "^" includedir \ - "/(.*-.*-.*/|.*-.*/|)(asm[-/]|arch|linux/|selinux/|mach/|mach_debug/|device/|hurd/(((hurd|ioctl)_types|paths)\\.h|ioctls\\.defs|ihash\\.h)|cthreads\\.h|gd|nss3/|c\\+\\+/|sys/(capability|sdt(|-config))\\.h|libaudit\\.h)" + "/(.*-.*-.*/|.*-.*/|)(asm[-/]|arch|linux/|selinux/|mach/|mach_debug/|device/|hurd/(((hurd|ioctl)_types|paths)\\.h|ioctls\\.defs|ihash\\.h)|cthreads\\.h|gd|nss3/|nspr/|c\\+\\+/|sys/(capability|sdt(|-config))\\.h|libaudit\\.h)" } /^[^ ]/ && $1 ~ /.*:/ { obj = $1 } { -- cgit v1.2.3 From 644d38570a860f3ed7d478c4ed8965a91e4621a1 Mon Sep 17 00:00:00 2001 From: Joseph Myers Date: Thu, 5 Oct 2017 15:58:13 +0000 Subject: Remove add-ons mechanism. glibc has an add-ons mechanism to allow additional software to be integrated into the glibc build. Such add-ons may be within the glibc source tree, or outside it at a path passed to the --enable-add-ons configure option. localedata and crypt were once add-ons, distributed in separate release tarballs, but long since stopped using that mechanism. Linuxthreads was always an add-on. Ports spent some time as an add-on with separate release tarballs, then was first moved into the glibc source tree, then had its sysdeps files moved into the main sysdeps hierarchy so the add-ons mechanism was no longer used. NPTL spent some time as an add-on in the main glibc tree before stopping using the add-on mechanism. libidn used to have separate release tarballs but no longer does so, but still uses the add-ons mechanism within the glibc source tree. Various other software has supported building with the add-ons mechanism at times in the past, but I don't think any is still widely used. Add-ons involve significant, little-used complexity in the glibc build system, and make it hard to understand what the space of possible glibc configurations is. This patch removes the add-ons mechanism. libidn is now built via the Subdirs mechanism to cause any configuration using sysdeps/unix/inet to build libidn; HAVE_LIBIDN (which effectively means shared libraries are available) is now defined via sysdeps/unix/inet/configure. Various references to add-ons around the source tree are removed (in the case of maint.texi, the example list of sysdeps directories is still very out of date). Externally maintained ports should now put their files in the normal sysdeps directory structure rather than being arranged as add-ons; they probably need to change e.g. elf.h anyway, rather than actually being able to work just as a drop-in subtree. Hurd libpthread should be arranged similarly to NPTL, so some files might go in a hurd-pthreads (or similar) top-level directory in glibc, while sysdeps files should go in the normal sysdeps directory structure (possibly in hurd or hurd-pthreads subdirectories, just as there are nptl subdirectories in the sysdeps tree). Tested for x86_64, and with build-many-glibcs.py. * configure.ac (--enable-add-ons): Remove option. (machine): Do not mention add-ons in comment. (LIBC_PRECONFIGURE): Likewise. (add_ons): Remove variable and sanity checks and logic to locate add-ons. (add_ons_automatic): Remove variable. (configured_add_ons): Likewise. (add_ons_sfx): Likewise. (add_ons_pfx): Likewise. (add_on_subdirs): Likewise. (sysnames_add_ons): Likewise. Remove loop over add-ons and consideration of add-ons in Implies handling. (sysdeps_add_ons): Likewise. * configure: Regenerated. * libidn/configure.ac: Remove. * libidn/configure: Likewise. * sysdeps/unix/inet/configure.ac: New file. * sysdeps/unix/inet/configure: New generated file. * sysdeps/unix/inet/Subdirs: Add libidn. * Makeconfig (sysdeps-srcdirs): Remove variable. (+sysdep_dirs): Do not include $(sysdeps-srcdirs). ($(common-objpfx)config.status): Do not depend on add-on files. ($(common-objpfx)shlib-versions.v.i): Do not mention add-ons in comment. (all-subdirs): Do not include $(add-on-subdirs). * Makefile (dist-prepare): Do not use $(sysdeps-add-ons). * config.make.in (add-ons): Remove variable. (add-on-subdirs): Likewise. (sysdeps-add-ons): Likewise. * manual/Makefile (add-chapters): Remove. ($(objpfx)texis): Do not depend on $(add-chapters). (nonexamples): Do not handle $(add-chapters). (examples): Do not handle $(add-ons). (chapters.% top-menu.%): Do not pass '$(add-chapters)' to libc-texinfo.sh. * manual/install.texi (Installation): Do not mention add-ons. (--enable-add-ons): Do not document configure option. * INSTALL: Regenerated. * manual/libc-texinfo.sh: Do not handle $2 add-ons argument. * manual/maint.texi (Hierarchy Conventions): Do not mention add-ons. * scripts/build-many-glibcs.py (Glibc.build_glibc): Do not use --enable-add-ons. * scripts/gen-sorted.awk: Do not handle Subdirs files from add-ons. * scripts/test-installation.pl: Do not handle glibc-compat add-on. * sysdeps/nptl/Makeconfig: Do not mention add-ons in comment. --- ChangeLog | 50 +++++++ INSTALL | 17 --- Makeconfig | 27 +--- Makefile | 3 +- NEWS | 4 + config.make.in | 3 - configure | 287 ++++------------------------------------- configure.ac | 268 ++++---------------------------------- libidn/configure | 16 --- libidn/configure.ac | 11 -- manual/Makefile | 9 +- manual/install.texi | 16 --- manual/libc-texinfo.sh | 17 +-- manual/maint.texi | 11 +- scripts/build-many-glibcs.py | 1 - scripts/gen-sorted.awk | 34 +---- scripts/test-installation.pl | 3 +- sysdeps/nptl/Makeconfig | 2 +- sysdeps/unix/inet/Subdirs | 1 + sysdeps/unix/inet/configure | 9 ++ sysdeps/unix/inet/configure.ac | 7 + 21 files changed, 142 insertions(+), 654 deletions(-) delete mode 100644 libidn/configure delete mode 100644 libidn/configure.ac create mode 100644 sysdeps/unix/inet/configure create mode 100644 sysdeps/unix/inet/configure.ac (limited to 'configure.ac') diff --git a/ChangeLog b/ChangeLog index b81a3ecd79..fc9637124c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,53 @@ +2017-10-05 Joseph Myers + + * configure.ac (--enable-add-ons): Remove option. + (machine): Do not mention add-ons in comment. + (LIBC_PRECONFIGURE): Likewise. + (add_ons): Remove variable and sanity checks and logic to locate + add-ons. + (add_ons_automatic): Remove variable. + (configured_add_ons): Likewise. + (add_ons_sfx): Likewise. + (add_ons_pfx): Likewise. + (add_on_subdirs): Likewise. + (sysnames_add_ons): Likewise. Remove loop over add-ons and + consideration of add-ons in Implies handling. + (sysdeps_add_ons): Likewise. + * configure: Regenerated. + * libidn/configure.ac: Remove. + * libidn/configure: Likewise. + * sysdeps/unix/inet/configure.ac: New file. + * sysdeps/unix/inet/configure: New generated file. + * sysdeps/unix/inet/Subdirs: Add libidn. + * Makeconfig (sysdeps-srcdirs): Remove variable. + (+sysdep_dirs): Do not include $(sysdeps-srcdirs). + ($(common-objpfx)config.status): Do not depend on add-on files. + ($(common-objpfx)shlib-versions.v.i): Do not mention add-ons in + comment. + (all-subdirs): Do not include $(add-on-subdirs). + * Makefile (dist-prepare): Do not use $(sysdeps-add-ons). + * config.make.in (add-ons): Remove variable. + (add-on-subdirs): Likewise. + (sysdeps-add-ons): Likewise. + * manual/Makefile (add-chapters): Remove. + ($(objpfx)texis): Do not depend on $(add-chapters). + (nonexamples): Do not handle $(add-chapters). + (examples): Do not handle $(add-ons). + (chapters.% top-menu.%): Do not pass '$(add-chapters)' to + libc-texinfo.sh. + * manual/install.texi (Installation): Do not mention add-ons. + (--enable-add-ons): Do not document configure option. + * INSTALL: Regenerated. + * manual/libc-texinfo.sh: Do not handle $2 add-ons argument. + * manual/maint.texi (Hierarchy Conventions): Do not mention + add-ons. + * scripts/build-many-glibcs.py (Glibc.build_glibc): Do not use + --enable-add-ons. + * scripts/gen-sorted.awk: Do not handle Subdirs files from + add-ons. + * scripts/test-installation.pl: Do not handle glibc-compat add-on. + * sysdeps/nptl/Makeconfig: Do not mention add-ons in comment. + 2017-10-05 Andreas Schwab [BZ #15142] diff --git a/INSTALL b/INSTALL index 4d9024c667..bc972b2ffa 100644 --- a/INSTALL +++ b/INSTALL @@ -5,11 +5,6 @@ Before you do anything else, you should read the FAQ at . It answers common questions and describes problems you may experience with compilation and installation. - Features can be added to the GNU C Library via "add-on" bundles. -These are separate tar files, which you unpack into the top level of the -source tree. Then you give 'configure' the '--enable-add-ons' option to -activate them, and they will be compiled into the library. - You will need recent versions of several GNU tools: definitely GCC and GNU Make, and possibly others. *Note Tools for Compilation::, below. @@ -69,18 +64,6 @@ will be used, and CFLAGS sets optimization options for the compiler. this option if you want to compile the GNU C Library with a newer set of kernel headers than the ones found in '/usr/include'. -'--enable-add-ons[=LIST]' - Specify add-on packages to include in the build. If this option is - specified with no list, it enables all the add-on packages it finds - in the main source directory; this is the default behavior. You - may specify an explicit list of add-ons to use in LIST, separated - by spaces or commas (if you use spaces, remember to quote them from - the shell). Each add-on in LIST can be an absolute directory name - or can be a directory name relative to the main source directory, - or relative to the build directory (that is, the current working - directory). For example, - '--enable-add-ons=nptl,../glibc-libidn-VERSION'. - '--enable-kernel=VERSION' This option is currently only useful on GNU/Linux systems. The VERSION parameter should have the form X.Y.Z and describes the diff --git a/Makeconfig b/Makeconfig index 0ceff92a3d..5ff6f2e29a 100644 --- a/Makeconfig +++ b/Makeconfig @@ -59,15 +59,7 @@ stack-align-test-flags = # `configure' writes a definition of `config-sysdirs' in `config.make'. sysdirs := $(foreach D,$(config-sysdirs),$(firstword $(filter /%,$D) $(..)$D)) -# Add-ons that contribute sysdeps trees get added to the include list -# after sysdeps/generic. This makes #include work right -# to find specific add-on files without assuming the add-on directory name. -# It also means that headers can go into an add-on's base directory -# instead of the add-on needing a sysdeps/generic of its own. -sysdeps-srcdirs := $(foreach add-on,$(sysdeps-add-ons),\ - $(firstword $(filter /%,$(add-on)) \ - $(..)$(add-on))) -+sysdep_dirs = $(sysdirs) $(sysdeps-srcdirs) ++sysdep_dirs = $(sysdirs) ifdef objdir +sysdep_dirs := $(objdir) $(+sysdep_dirs) endif @@ -81,8 +73,8 @@ $(common-objpfx)config.make: $(common-objpfx)config.status \ $(..)config.make.in $(..)config.h.in cd $(&2; \ echo Run \`configure\' to configure it before building. >&2; \ @@ -1077,8 +1062,6 @@ endif ifeq ($(sysd-sorted-done),t) -include $(common-objpfx)soversions.mk ifndef avoid-generated -# This lets add-ons give more-specific matches that override defaults -# in the top-level file. $(common-objpfx)shlib-versions.v.i: \ $(wildcard $(+sysdep_dirs:=/shlib-versions) \ $(subdir-srcdirs:=/shlib-versions)) \ @@ -1186,7 +1169,7 @@ all-subdirs = csu assert ctype locale intl catgets math setjmp signal \ grp pwd posix io termios resource misc socket sysvipc gmon \ gnulib iconv iconvdata wctype manual shadow gshadow po argp \ crypt localedata timezone rt conform debug mathvec support \ - $(add-on-subdirs) dlfcn elf + dlfcn elf ifndef avoid-generated # sysd-sorted itself will contain rules making the sysd-sorted target diff --git a/Makefile b/Makefile index 3e0ae6f43b..869fe70475 100644 --- a/Makefile +++ b/Makefile @@ -351,8 +351,7 @@ files-for-dist := README INSTALL configure ChangeLog NEWS # Regenerate stuff, then error if these things are not committed yet. dist-prepare: $(files-for-dist) - conf=`find sysdeps $(addsuffix /sysdeps,$(sysdeps-add-ons)) \ - -name configure`; \ + conf=`find sysdeps -name configure`; \ $(MAKE) $$conf && \ git diff --stat HEAD -- $^ $$conf \ | $(AWK) '{ print; rc=1 } END { exit rc }' diff --git a/NEWS b/NEWS index a034cd8476..464d1ce9b3 100644 --- a/NEWS +++ b/NEWS @@ -50,6 +50,10 @@ Deprecated and removed features, and other changes affecting compatibility: platforms where it was previously the same, this changes the C++ name mangling for interfaces involving this type. +* The add-ons mechanism for building additional packages at the same time as + glibc has been removed. The --enable-add-ons configure option is now + ignored. + Changes to build and runtime requirements: [Add changes to build and runtime requirements here] diff --git a/config.make.in b/config.make.in index ea7a42cc19..fd2dbc91d1 100644 --- a/config.make.in +++ b/config.make.in @@ -90,9 +90,6 @@ build-pic-default= @libc_cv_pic_default@ build-pie-default= @libc_cv_pie_default@ build-profile = @profile@ build-static-nss = @static_nss@ -add-ons = @add_ons@ -add-on-subdirs = @add_on_subdirs@ -sysdeps-add-ons = @sysdeps_add_ons@ cross-compiling = @cross_compiling@ force-install = @force_install@ link-obsolete-rpc = @link_obsolete_rpc@ diff --git a/configure b/configure index a7c72eaaa6..c2c9c72d5a 100755 --- a/configure +++ b/configure @@ -659,7 +659,6 @@ LN_S INSTALL_DATA INSTALL_SCRIPT INSTALL_PROGRAM -sysdeps_add_ons sysnames submachine multi_arch @@ -667,8 +666,6 @@ no_stack_protector stack_protector libc_cv_ssp base_machine -add_on_subdirs -add_ons have_tunables build_pt_chown build_nscd @@ -771,7 +768,6 @@ enable_timezone_tools enable_hardcoded_path_in_tests enable_stackguard_randomization enable_lock_elision -enable_add_ons enable_hidden_plt enable_bind_now enable_stack_protector @@ -806,8 +802,7 @@ CPP CXX CXXFLAGS CCC' -ac_subdirs_all=' -' +ac_subdirs_all='' # Initialize some variables set by options. ac_init_help= @@ -1434,9 +1429,6 @@ Optional Features: number at program start --enable-lock-elision=yes/no Enable lock elision for pthread mutexes by default - --enable-add-ons[=DIRS...] - configure and build add-ons in DIR1,DIR2,... search - for add-ons if no parameter given --disable-hidden-plt do not hide internal function calls to avoid PLT --enable-bind-now disable lazy relocations in DSOs --enable-stack-protector=[yes|no|all|strong] @@ -3415,14 +3407,6 @@ if test "$enable_lock_elision" = yes ; then fi -# Check whether --enable-add-ons was given. -if test "${enable_add_ons+set}" = set; then : - enableval=$enable_add_ons; -else - enable_add_ons=yes -fi - - # Check whether --enable-hidden-plt was given. if test "${enable_hidden_plt+set}" = set; then : enableval=$enable_hidden_plt; hidden=$enableval @@ -3785,7 +3769,7 @@ config_os="`echo $config_os | sed 's/^unknown-//'`" # Some configurations imply other options. elf=yes -# The configure fragment of an add-on port can modify these to supplement +# The configure fragment of a port can modify these to supplement # or override the table in the case statement below. No fragment should # ever change the config_* variables, however. machine=$config_machine @@ -3823,143 +3807,6 @@ $as_echo_n "checking for sysdeps preconfigure fragments... " >&6; } $as_echo "" >&6; } fi -subdirs="$subdirs " - - -case "$enable_add_ons" in -''|no) add_ons= ;; -yes|'*') - add_ons=`cd $srcdir && ls -d 2> /dev/null */configure */sysdeps | - sed 's@/[^/]*$@@' | sort | uniq` - add_ons_automatic=yes - ;; -*) add_ons=`echo "$enable_add_ons" | sed 's/,/ /g'` - add_ons_automatic=no ;; -esac - -configured_add_ons= -add_ons_sfx= -add_ons_pfx= -if test x"$add_ons" != x; then - for f in $add_ons; do - # Some sanity checks - case "$f" in - crypt) - as_fn_error $? " -*** It seems that you're using an old \`crypt' add-on. crypt is now -*** part of glibc and using the old add-on will not work with this -*** release. Start again with fresh sources and without the old -*** \`crypt' add-on." "$LINENO" 5 - ;; - localedata) - as_fn_error $? " -*** It seems that you're using an old \`localedata' add-on. localedata -*** is now part of glibc and using the old add-on will not work with -*** this release. Start again with fresh sources and without the old -*** \`localedata' add-on." "$LINENO" 5 - ;; - esac - done - - # Now source each add-on's configure fragment. - # The fragments can use $srcdir/$libc_add_on to find themselves, - # and test $add_ons_automatic to see if they were explicitly requested. - # A fragment can clear (or even change) $libc_add_on to affect - # whether it goes into the list to be actually used in the build. - use_add_ons= - for libc_add_on in $add_ons; do - # Test whether such a directory really exists. - # It can be absolute, or relative to $srcdir, or relative to the build dir. - case "$libc_add_on" in - /*) - libc_add_on_srcdir=$libc_add_on - ;; - *) - test -d "$srcdir/$libc_add_on" || { - if test -d "$libc_add_on"; then - libc_add_on="`pwd`/$libc_add_on" - else - as_fn_error $? "add-on directory \"$libc_add_on\" does not exist" "$LINENO" 5 - fi - } - libc_add_on_srcdir=$srcdir/$libc_add_on - ;; - esac - - libc_add_on_frag=$libc_add_on_srcdir/configure - libc_add_on_canonical= - libc_add_on_config_subdirs= - if test -r "$libc_add_on_frag"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: running configure fragment for add-on $libc_add_on" >&5 -$as_echo "$as_me: running configure fragment for add-on $libc_add_on" >&6;} - libc_add_on_canonical=unknown - libc_add_on_subdirs= - . "$libc_add_on_frag" - test -z "$libc_add_on" || { - configured_add_ons="$configured_add_ons $libc_add_on" - if test "x$libc_add_on_canonical" = xunknown; then - as_fn_error $? "fragment must set \$libc_add_on_canonical" "$LINENO" 5 - fi - for d in $libc_add_on_subdirs; do - case "$libc_add_on" in - /*) subdir_srcdir="$libc_add_on" ;; - *) subdir_srcdir="\$(..)$libc_add_on" ;; - esac - case "$d" in - .) - d="${libc_add_on_canonical:-$libc_add_on}" - ;; - /*) - subdir_srcdir="$d" - ;; - *) - subdir_srcdir="$subdir_srcdir/$d" - ;; - esac - d=`echo "$d" | sed 's@/*$@@;s@^.*/@@'` - add_on_subdirs="$add_on_subdirs $d" - test "$subdir_srcdir" = "\$(..)$d" || config_vars="$config_vars -$d-srcdir = $subdir_srcdir" - done - for d in $libc_add_on_config_subdirs; do - case "$d" in - /*) as_fn_error $? "fragment uses absolute path in \$libc_add_on_config_subdirs" "$LINENO" 5 ;; - esac - if test ! -d "$libc_add_on_srcdir/$d"; then - as_fn_error $? "fragment wants to configure missing directory $d" "$LINENO" 5 - fi - case "$libc_add_on" in - /*) as_fn_error $? "relative path required for add-on using \$libc_add_on_config_subdirs" "$LINENO" 5 ;; - esac - subdirs="$subdirs $libc_add_on/$d" - done - } - fi - if test -n "$libc_add_on"; then - if frags=`ls -d $libc_add_on_srcdir/sysdeps/*/preconfigure 2> /dev/null` -then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking add-on $libc_add_on for preconfigure fragments" >&5 -$as_echo_n "checking add-on $libc_add_on for preconfigure fragments... " >&6; } - for frag in $frags; do - name=`echo "$frag" | sed 's@/[^/]*$@@;s@^.*/@@'` - echo $ECHO_N "$name $ECHO_C" >&6 - . "$frag" - done - { $as_echo "$as_me:${as_lineno-$LINENO}: result: " >&5 -$as_echo "" >&6; } -fi - use_add_ons="$use_add_ons $libc_add_on" - add_ons_pfx="$add_ons_pfx $libc_add_on/" - test -z "$libc_add_on_canonical" || - add_ons_sfx="$add_ons_sfx /$libc_add_on_canonical" - fi - done - # Use echo to strip excess whitespace. - add_ons="`echo $use_add_ons`" -fi - - - ### ### By using the undocumented --enable-hacker-mode option for configure @@ -4231,7 +4078,6 @@ done # Find what sysdep directories exist. -sysnames_add_ons= sysnames= for b in $base ''; do for m0 in $mach ''; do @@ -4240,34 +4086,21 @@ for b in $base ''; do for o in /$ostry ''; do test "$o" = / && continue for m in $mach ''; do - for d in $add_ons_pfx ''; do - for a in $add_ons_sfx ''; do - try_suffix="$m0$b$v$o$m" - if test -n "$try_suffix"; then - try_srcdir="${srcdir}/" - case "$d" in - /*) try_srcdir= ;; - esac - try="${d}sysdeps$try_suffix$a" - test -n "$enable_debug_configure" && - echo "$0 DEBUG: try $try" >&2 - if test -d "$try_srcdir$try"; then - sysnames="$sysnames $try" - { test -n "$o" || test -n "$b"; } && os_used=t - { test -n "$m" || test -n "$m0"; } && machine_used=t - case x${m0:-$m} in - x*/$submachine) submachine_used=t ;; - esac - if test -n "$d"; then - case "$sysnames_add_ons" in - *" $d "*) ;; - *|'') sysnames_add_ons="$sysnames_add_ons $d" ;; - esac - fi - fi - fi - done - done + try_suffix="$m0$b$v$o$m" + if test -n "$try_suffix"; then + try_srcdir="${srcdir}/" + try="sysdeps$try_suffix" + test -n "$enable_debug_configure" && + echo "$0 DEBUG: try $try" >&2 + if test -d "$try_srcdir$try"; then + sysnames="$sysnames $try" + { test -n "$o" || test -n "$b"; } && os_used=t + { test -n "$m" || test -n "$m0"; } && machine_used=t + case x${m0:-$m} in + x*/$submachine) submachine_used=t ;; + esac + fi + fi done done done @@ -4276,7 +4109,7 @@ done # If the assembler supports gnu_indirect_function symbol type and the # architecture supports multi-arch, we enable multi-arch by default. -case $sysnames_add_ons$sysnames in +case $sysnames in *"$multi_arch_d"*) ;; *) @@ -4339,24 +4172,15 @@ while test $# -gt 0; do eval "${implies_type}=\"\$${implies_type} \$name_base/\$x\"" found=yes fi - for d in $add_ons_pfx ''; do - try="${d}sysdeps/$x" - case $d in - /*) try_srcdir= ;; - *) try_srcdir=$srcdir/ ;; - esac - test -n "$enable_debug_configure" && - echo "DEBUG: $name $implies_file $x try($d) {$try_srcdir}$try" >&2 - if test $try != $xsrcdir$name_base/$x && test -d $try_srcdir$try; - then - eval "${implies_type}=\"\$${implies_type} \$try\"" - found=yes - case "$sysnames_add_ons" in - *" $d "*) ;; - *|'') sysnames_add_ons="$sysnames_add_ons $d" ;; - esac - fi - done + try="sysdeps/$x" + try_srcdir=$srcdir/ + test -n "$enable_debug_configure" && + echo "DEBUG: $name $implies_file $x try() {$try_srcdir}$try" >&2 + if test $try != $xsrcdir$name_base/$x && test -d $try_srcdir$try; + then + eval "${implies_type}=\"\$${implies_type} \$try\"" + found=yes + fi if test $found = no; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $name/$implies_file specifies nonexistent $x" >&5 $as_echo "$as_me: WARNING: $name/$implies_file specifies nonexistent $x" >&2;} @@ -4394,63 +4218,6 @@ sysnames="$names $default_sysnames" { $as_echo "$as_me:${as_lineno-$LINENO}: result: $default_sysnames" >&5 $as_echo "$default_sysnames" >&6; } -# Collect the list of add-ons that supply partial sysdeps trees. -sysdeps_add_ons= -for add_on in $add_ons; do - case "$add_on" in - /*) xsrcdir= ;; - *) xsrcdir="$srcdir/" ;; - esac - - test -d "$xsrcdir$add_on/sysdeps" || { - case "$configured_add_ons " in - *" $add_on "*) ;; - *|'') - as_fn_error $? "add-on $add_on has no configure fragment or sysdeps tree" "$LINENO" 5 - ;; - esac - continue - } - - sysdeps_add_ons="$sysdeps_add_ons $add_on" - case "$sysnames_add_ons" in - *" $add_on/ "*) ;; - *|'') - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: add-on $add_on contributed no sysdeps directories" >&5 -$as_echo "$as_me: WARNING: add-on $add_on contributed no sysdeps directories" >&2;} - continue ;; - esac - - found=no - for d in $sysnames; do - case "$d" in - $add_on/sysdeps/*) ;; - *) continue ;; - esac - (cd "$xsrcdir$d" && for f in *[!~]; do - case "$f" in - sys|bits) - for ff in $f/*.h; do - test -d "$ff" || { test -e "$ff" && exit 88; } - done - ;; - *) - test -d "$f" || { test -e "$f" && exit 88; } - ;; - esac - done) - if test $? -eq 88; then - found=yes - break - fi - done - if test $found = no; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: add-on $add_on contributed no useful sysdeps directories" >&5 -$as_echo "$as_me: WARNING: add-on $add_on contributed no useful sysdeps directories" >&2;} - fi -done - - ### Locate tools. diff --git a/configure.ac b/configure.ac index 4b83ae5a09..195e81acfd 100644 --- a/configure.ac +++ b/configure.ac @@ -209,13 +209,6 @@ if test "$enable_lock_elision" = yes ; then AC_DEFINE(ENABLE_LOCK_ELISION) fi -dnl Generic infrastructure for drop-in additions to libc. -AC_ARG_ENABLE([add-ons], - AC_HELP_STRING([--enable-add-ons@<:@=DIRS...@:>@], - [configure and build add-ons in DIR1,DIR2,... - search for add-ons if no parameter given]), - , [enable_add_ons=yes]) - AC_ARG_ENABLE([hidden-plt], AC_HELP_STRING([--disable-hidden-plt], [do not hide internal function calls to avoid PLT]), @@ -483,7 +476,7 @@ config_os="`echo $config_os | sed 's/^unknown-//'`" # Some configurations imply other options. elf=yes -# The configure fragment of an add-on port can modify these to supplement +# The configure fragment of a port can modify these to supplement # or override the table in the case statement below. No fragment should # ever change the config_* variables, however. machine=$config_machine @@ -506,138 +499,9 @@ AC_ARG_WITH([cpu], # check below. libc_config_ok=no -dnl Let sysdeps/*/preconfigure act here, like they can in add-ons. +dnl Let sysdeps/*/preconfigure act here. LIBC_PRECONFIGURE([$srcdir], [for sysdeps]) -dnl Having this here, though empty, makes sure that if add-ons' fragments -dnl do AC_CONFIG_SUBDIRS([some-dir]), which just sets $subdirs, then -dnl our AC_OUTPUT will actually use it. -AC_CONFIG_SUBDIRS() - -case "$enable_add_ons" in -''|no) add_ons= ;; -yes|'*') - add_ons=`cd $srcdir && ls -d 2> /dev/null */configure */sysdeps | - sed 's@/[[^/]]*$@@' | sort | uniq` - add_ons_automatic=yes - ;; -*) add_ons=`echo "$enable_add_ons" | sed 's/,/ /g'` - add_ons_automatic=no ;; -esac - -configured_add_ons= -add_ons_sfx= -add_ons_pfx= -if test x"$add_ons" != x; then - for f in $add_ons; do - # Some sanity checks - case "$f" in - crypt) - AC_MSG_ERROR([ -*** It seems that you're using an old \`crypt' add-on. crypt is now -*** part of glibc and using the old add-on will not work with this -*** release. Start again with fresh sources and without the old -*** \`crypt' add-on.]) - ;; - localedata) - AC_MSG_ERROR([ -*** It seems that you're using an old \`localedata' add-on. localedata -*** is now part of glibc and using the old add-on will not work with -*** this release. Start again with fresh sources and without the old -*** \`localedata' add-on.]) - ;; - esac - done - - # Now source each add-on's configure fragment. - # The fragments can use $srcdir/$libc_add_on to find themselves, - # and test $add_ons_automatic to see if they were explicitly requested. - # A fragment can clear (or even change) $libc_add_on to affect - # whether it goes into the list to be actually used in the build. - use_add_ons= - for libc_add_on in $add_ons; do - # Test whether such a directory really exists. - # It can be absolute, or relative to $srcdir, or relative to the build dir. - case "$libc_add_on" in - /*) - libc_add_on_srcdir=$libc_add_on - ;; - *) - test -d "$srcdir/$libc_add_on" || { - if test -d "$libc_add_on"; then - libc_add_on="`pwd`/$libc_add_on" - else - AC_MSG_ERROR(add-on directory \"$libc_add_on\" does not exist) - fi - } - libc_add_on_srcdir=$srcdir/$libc_add_on - ;; - esac - - libc_add_on_frag=$libc_add_on_srcdir/configure - libc_add_on_canonical= - libc_add_on_config_subdirs= - if test -r "$libc_add_on_frag"; then - AC_MSG_NOTICE(running configure fragment for add-on $libc_add_on) - libc_add_on_canonical=unknown - libc_add_on_subdirs= - . "$libc_add_on_frag" - test -z "$libc_add_on" || { - configured_add_ons="$configured_add_ons $libc_add_on" - if test "x$libc_add_on_canonical" = xunknown; then - AC_MSG_ERROR(fragment must set \$libc_add_on_canonical) - fi - for d in $libc_add_on_subdirs; do - case "$libc_add_on" in - /*) subdir_srcdir="$libc_add_on" ;; - *) subdir_srcdir="\$(..)$libc_add_on" ;; - esac - case "$d" in - .) - d="${libc_add_on_canonical:-$libc_add_on}" - ;; - /*) - subdir_srcdir="$d" - ;; - *) - subdir_srcdir="$subdir_srcdir/$d" - ;; - esac - d=`echo "$d" | sed 's@/*$@@;s@^.*/@@'` - add_on_subdirs="$add_on_subdirs $d" - test "$subdir_srcdir" = "\$(..)$d" || config_vars="$config_vars -$d-srcdir = $subdir_srcdir" - done - for d in $libc_add_on_config_subdirs; do - case "$d" in - /*) AC_MSG_ERROR(dnl -fragment uses absolute path in \$libc_add_on_config_subdirs) ;; - esac - if test ! -d "$libc_add_on_srcdir/$d"; then - AC_MSG_ERROR(fragment wants to configure missing directory $d) - fi - case "$libc_add_on" in - /*) AC_MSG_ERROR(dnl -relative path required for add-on using \$libc_add_on_config_subdirs) ;; - esac - subdirs="$subdirs $libc_add_on/$d" - done - } - fi - if test -n "$libc_add_on"; then - LIBC_PRECONFIGURE([$libc_add_on_srcdir], [add-on $libc_add_on for]) - use_add_ons="$use_add_ons $libc_add_on" - add_ons_pfx="$add_ons_pfx $libc_add_on/" - test -z "$libc_add_on_canonical" || - add_ons_sfx="$add_ons_sfx /$libc_add_on_canonical" - fi - done - # Use echo to strip excess whitespace. - add_ons="`echo $use_add_ons`" -fi -AC_SUBST(add_ons) -AC_SUBST(add_on_subdirs) - ### ### By using the undocumented --enable-hacker-mode option for configure @@ -853,7 +717,6 @@ dnl We are done with glob and regexp uses of [ and ]; return to autoconf. changequote([,])dnl # Find what sysdep directories exist. -sysnames_add_ons= sysnames= for b in $base ''; do for m0 in $mach ''; do @@ -862,34 +725,21 @@ for b in $base ''; do for o in /$ostry ''; do test "$o" = / && continue for m in $mach ''; do - for d in $add_ons_pfx ''; do - for a in $add_ons_sfx ''; do - try_suffix="$m0$b$v$o$m" - if test -n "$try_suffix"; then - try_srcdir="${srcdir}/" - case "$d" in - /*) try_srcdir= ;; - esac - try="${d}sysdeps$try_suffix$a" - test -n "$enable_debug_configure" && - echo "$0 [DEBUG]: try $try" >&2 - if test -d "$try_srcdir$try"; then - sysnames="$sysnames $try" - { test -n "$o" || test -n "$b"; } && os_used=t - { test -n "$m" || test -n "$m0"; } && machine_used=t - case x${m0:-$m} in - x*/$submachine) submachine_used=t ;; - esac - if test -n "$d"; then - case "$sysnames_add_ons" in - *" $d "*) ;; - *|'') sysnames_add_ons="$sysnames_add_ons $d" ;; - esac - fi - fi - fi - done - done + try_suffix="$m0$b$v$o$m" + if test -n "$try_suffix"; then + try_srcdir="${srcdir}/" + try="sysdeps$try_suffix" + test -n "$enable_debug_configure" && + echo "$0 [DEBUG]: try $try" >&2 + if test -d "$try_srcdir$try"; then + sysnames="$sysnames $try" + { test -n "$o" || test -n "$b"; } && os_used=t + { test -n "$m" || test -n "$m0"; } && machine_used=t + case x${m0:-$m} in + x*/$submachine) submachine_used=t ;; + esac + fi + fi done done done @@ -898,7 +748,7 @@ done # If the assembler supports gnu_indirect_function symbol type and the # architecture supports multi-arch, we enable multi-arch by default. -case $sysnames_add_ons$sysnames in +case $sysnames in *"$multi_arch_d"*) ;; *) @@ -960,24 +810,15 @@ while test $# -gt 0; do eval "${implies_type}=\"\$${implies_type} \$name_base/\$x\"" found=yes fi - for d in $add_ons_pfx ''; do - try="${d}sysdeps/$x" - case $d in - /*) try_srcdir= ;; - *) try_srcdir=$srcdir/ ;; - esac - test -n "$enable_debug_configure" && - echo "[DEBUG]: $name $implies_file $x try($d) {$try_srcdir}$try" >&2 - if test $try != $xsrcdir$name_base/$x && test -d $try_srcdir$try; - then - eval "${implies_type}=\"\$${implies_type} \$try\"" - found=yes - case "$sysnames_add_ons" in - *" $d "*) ;; - *|'') sysnames_add_ons="$sysnames_add_ons $d" ;; - esac - fi - done + try="sysdeps/$x" + try_srcdir=$srcdir/ + test -n "$enable_debug_configure" && + echo "[DEBUG]: $name $implies_file $x try() {$try_srcdir}$try" >&2 + if test $try != $xsrcdir$name_base/$x && test -d $try_srcdir$try; + then + eval "${implies_type}=\"\$${implies_type} \$try\"" + found=yes + fi if test $found = no; then AC_MSG_WARN($name/$implies_file specifies nonexistent $x) fi @@ -1015,61 +856,6 @@ AC_SUBST(sysnames) # The other names were emitted during the scan. AC_MSG_RESULT($default_sysnames) -# Collect the list of add-ons that supply partial sysdeps trees. -sysdeps_add_ons= -for add_on in $add_ons; do - case "$add_on" in - /*) xsrcdir= ;; - *) xsrcdir="$srcdir/" ;; - esac - - test -d "$xsrcdir$add_on/sysdeps" || { - case "$configured_add_ons " in - *" $add_on "*) ;; - *|'') - AC_MSG_ERROR(add-on $add_on has no configure fragment or sysdeps tree) - ;; - esac - continue - } - - sysdeps_add_ons="$sysdeps_add_ons $add_on" - case "$sysnames_add_ons" in - *" $add_on/ "*) ;; - *|'') - AC_MSG_WARN(add-on $add_on contributed no sysdeps directories) - continue ;; - esac - - found=no - for d in $sysnames; do - case "$d" in - $add_on/sysdeps/*) ;; - *) continue ;; - esac - (cd "$xsrcdir$d" && for f in *[[!~]]; do - case "$f" in - sys|bits) - for ff in $f/*.h; do - test -d "$ff" || { test -e "$ff" && exit 88; } - done - ;; - *) - test -d "$f" || { test -e "$f" && exit 88; } - ;; - esac - done) - if test $? -eq 88; then - found=yes - break - fi - done - if test $found = no; then - AC_MSG_WARN(add-on $add_on contributed no useful sysdeps directories) - fi -done -AC_SUBST(sysdeps_add_ons) - ### Locate tools. diff --git a/libidn/configure b/libidn/configure deleted file mode 100644 index 8195663d96..0000000000 --- a/libidn/configure +++ /dev/null @@ -1,16 +0,0 @@ -# This file is generated from configure.ac by Autoconf. DO NOT EDIT! - -libc_add_on_canonical= - -if test "$shared" = yes; then : - - libc_add_on_subdirs=. - - # Get this defined in config.h for main source code to test. - $as_echo "#define HAVE_LIBIDN 1" >>confdefs.h - - -else - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: libidn add-on ignored with --disable-shared" >&5 -$as_echo "$as_me: WARNING: libidn add-on ignored with --disable-shared" >&2;} -fi diff --git a/libidn/configure.ac b/libidn/configure.ac deleted file mode 100644 index 16740ffb92..0000000000 --- a/libidn/configure.ac +++ /dev/null @@ -1,11 +0,0 @@ -dnl glibc configure fragment for libidn add-on -GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory. - -libc_add_on_canonical= - -AS_IF([test "$shared" = yes], [ - libc_add_on_subdirs=. - - # Get this defined in config.h for main source code to test. - AC_DEFINE([HAVE_LIBIDN]) -], [AC_MSG_WARN([libidn add-on ignored with --disable-shared])]) diff --git a/manual/Makefile b/manual/Makefile index 4ed63a8ef3..3b4c7c934a 100644 --- a/manual/Makefile +++ b/manual/Makefile @@ -40,20 +40,18 @@ chapters = $(addsuffix .texi, \ resource setjmp signal startup process ipc job \ nss users sysinfo conf crypt debug threads \ probes tunables) -add-chapters = $(wildcard $(foreach d, $(add-ons), ../$d/$d.texi)) appendices = lang.texi header.texi install.texi maint.texi platform.texi \ contrib.texi licenses = freemanuals.texi lgpl-2.1.texi fdl-1.3.texi -include $(objpfx)texis -$(objpfx)texis: texis.awk $(chapters) $(add-chapters) $(appendices) $(licenses) +$(objpfx)texis: texis.awk $(chapters) $(appendices) $(licenses) $(make-target-directory) $(AWK) -f $^ > $@.T mv -f $@.T $@ -nonexamples = $(filter-out $(add-chapters) %.c.texi, $(texis)) -examples = $(filter-out $(foreach d, $(add-ons), ../$d/%.c.texi), \ - $(filter %.c.texi, $(texis))) +nonexamples = $(filter-out %.c.texi, $(texis)) +examples = $(filter %.c.texi, $(texis)) # Generated files directly included from libc.texinfo. libc-texi-generated = chapters.texi top-menu.texi dir-add.texi \ @@ -69,7 +67,6 @@ texis-path := $(filter-out $(libc-texi-generated) summary.texi $(examples), \ chapters.% top-menu.%: libc-texinfo.sh $(texis-path) Makefile AWK=$(AWK) $(SHELL) $< $(objpfx) \ '$(chapters)' \ - '$(add-chapters)' \ '$(appendices) $(licenses)' diff --git a/manual/install.texi b/manual/install.texi index 35948b1bbb..96b988e829 100644 --- a/manual/install.texi +++ b/manual/install.texi @@ -13,11 +13,6 @@ Before you do anything else, you should read the FAQ at questions and describes problems you may experience with compilation and installation. -Features can be added to @theglibc{} via @dfn{add-on} bundles. These are -separate tar files, which you unpack into the top level of the source -tree. Then you give @code{configure} the @samp{--enable-add-ons} option -to activate them, and they will be compiled into the library. - You will need recent versions of several GNU tools: definitely GCC and GNU Make, and possibly others. @xref{Tools for Compilation}, below. @@ -95,17 +90,6 @@ occasionally happen in this case. You can also use this option if you want to compile @theglibc{} with a newer set of kernel headers than the ones found in @file{/usr/include}. -@item --enable-add-ons[=@var{list}] -Specify add-on packages to include in the build. If this option is -specified with no list, it enables all the add-on packages it finds in -the main source directory; this is the default behavior. You may -specify an explicit list of add-ons to use in @var{list}, separated by -spaces or commas (if you use spaces, remember to quote them from the -shell). Each add-on in @var{list} can be an absolute directory name -or can be a directory name relative to the main source directory, or -relative to the build directory (that is, the current working directory). -For example, @samp{--enable-add-ons=nptl,../glibc-libidn-@var{version}}. - @item --enable-kernel=@var{version} This option is currently only useful on @gnulinuxsystems{}. The @var{version} parameter should have the form X.Y.Z and describes the diff --git a/manual/libc-texinfo.sh b/manual/libc-texinfo.sh index 4d0a52213b..aea27f9e94 100644 --- a/manual/libc-texinfo.sh +++ b/manual/libc-texinfo.sh @@ -31,26 +31,11 @@ collect_nodes () { $AWK -f tsort.awk | sed 's/_/ /g' } -# Emit "@set ADD-ON" for each add-on contributing a manual chapter. -for addon in $2; do - addon=`basename $addon .texi` - echo >&3 "@set $addon" -done - collect_nodes $1 | build_menu -if [ -n "$2" ]; then - - { echo; echo 'Add-ons'; echo; } >&4 - - egrep '^(@c )?@node.*Top' `echo $2 /dev/null | tr ' ' '\n' | sort` | - cut -d, -f1 | sed 's/@c //;s/@node //' | build_menu - -fi - { echo; echo 'Appendices'; echo; } >&4 -collect_nodes $3 | build_menu +collect_nodes $2 | build_menu exec 3>&- 4>&- 5>&- diff --git a/manual/maint.texi b/manual/maint.texi index 473ab162f0..fce06bfa88 100644 --- a/manual/maint.texi +++ b/manual/maint.texi @@ -381,19 +381,10 @@ identical @file{irix6.2} and @file{irix6.3} directories, by removing trailing suffixes starting with a period. As an example, here is the complete list of directories that would be -tried for the configuration @w{@samp{i686-linux-gnu}} (with the -@file{crypt} and @file{linuxthreads} add-on): +tried for the configuration @w{@samp{i686-linux-gnu}}: @smallexample sysdeps/i386/elf -crypt/sysdeps/unix -linuxthreads/sysdeps/unix/sysv/linux -linuxthreads/sysdeps/pthread -linuxthreads/sysdeps/unix/sysv -linuxthreads/sysdeps/unix -linuxthreads/sysdeps/i386/i686 -linuxthreads/sysdeps/i386 -linuxthreads/sysdeps/pthread/no-cmpxchg sysdeps/unix/sysv/linux/i386 sysdeps/unix/sysv/linux sysdeps/gnu diff --git a/scripts/build-many-glibcs.py b/scripts/build-many-glibcs.py index 8ce1c6f7f9..a6c01f9cc4 100755 --- a/scripts/build-many-glibcs.py +++ b/scripts/build-many-glibcs.py @@ -1342,7 +1342,6 @@ class Glibc(object): cmdlist.create_copy_dir(srcdir, srcdir_copy) cfg_cmd = [os.path.join(srcdir_copy, 'configure'), '--prefix=/usr', - '--enable-add-ons', '--enable-profile', '--build=%s' % self.ctx.build_triplet, '--host=%s' % self.triplet, diff --git a/scripts/gen-sorted.awk b/scripts/gen-sorted.awk index 922eafcc2d..ecbed9ef43 100755 --- a/scripts/gen-sorted.awk +++ b/scripts/gen-sorted.awk @@ -46,36 +46,10 @@ type == "Subdirs" && NF == 2 && $1 == "inhibit" { type == "Subdirs" && thisdir { all[cnt++] = thisdir; - if (FILENAME ~ (srcpfx ? /^\.\.\/sysdeps\// : /^sysdeps\//) \ - || system("test -d " srcpfx thisdir) == 0) { - # This Subdirs file is in the main source tree, - # or this subdirectory exists in the main source tree. - this_srcdir = srcpfx thisdir - } - else { - # The Subdirs file comes from an add-on that should have the subdirectory. - dir = FILENAME; - do - sub(/\/[^/]+$/, "", dir); - while (dir !~ /\/sysdeps$/); - sub(/\/sysdeps$/, "", dir); - if (system("test -d " dir "/" thisdir) == 0) - dir = dir "/" thisdir; - else { - sub(/\/[^/]+$/, "", dir); - if (system("test -d " dir "/" thisdir) == 0) - dir = dir "/" thisdir; - else { - print FILENAME ":" FNR ":", "cannot find", thisdir > "/dev/stderr"; - exit 2 - } - } - file = dir "/Depend"; - if (srcpfx) - sub(/^\.\.\//, "", dir); - if (dir !~ /^\/.*$/) - dir = "$(..)" dir; - print thisdir "-srcdir", ":=", dir; + this_srcdir = srcpfx thisdir + if (system("test -d " this_srcdir) != 0) { + print FILENAME ":" FNR ":", "cannot find", this_srcdir > "/dev/stderr"; + exit 2 } file = this_srcdir "/Depend"; if (system("test -f " file) == 0) { diff --git a/scripts/test-installation.pl b/scripts/test-installation.pl index c5b9fdefd2..45c666b0a2 100755 --- a/scripts/test-installation.pl +++ b/scripts/test-installation.pl @@ -116,14 +116,13 @@ while () { # Filter out some libraries we don't want to link: # - nss_ldap since it's not yet available # - libdb1 since it conflicts with libdb - # - libnss1_* from glibc-compat add-on # - libthread_db since it contains unresolved references # - it's just a test NSS module # - We don't provide the libgcc so we don't test it # - libmvec if it wasn't built next if ($build_mathvec == 0 && $name eq "mvec"); if ($name ne "nss_ldap" && $name ne "db1" - && !($name =~/^nss1_/) && $name ne "thread_db" + && $name ne "thread_db" && $name ne "nss_test1" && $name ne "libgcc_s") { $link_libs .= " -l$name"; $versions{$name} = $version; diff --git a/sysdeps/nptl/Makeconfig b/sysdeps/nptl/Makeconfig index d31b77680f..3516d51df3 100644 --- a/sysdeps/nptl/Makeconfig +++ b/sysdeps/nptl/Makeconfig @@ -16,7 +16,7 @@ # License along with the GNU C Library; if not, see # . -# Makeconfig fragment for NPTL add-on. +# Makeconfig fragment for NPTL. # This gets included at the end of the main glibc Makeconfig. have-thread-library = yes diff --git a/sysdeps/unix/inet/Subdirs b/sysdeps/unix/inet/Subdirs index 0a02dd4447..1223e43a37 100644 --- a/sysdeps/unix/inet/Subdirs +++ b/sysdeps/unix/inet/Subdirs @@ -6,3 +6,4 @@ nis nscd nss streams +libidn diff --git a/sysdeps/unix/inet/configure b/sysdeps/unix/inet/configure new file mode 100644 index 0000000000..fd0afad16d --- /dev/null +++ b/sysdeps/unix/inet/configure @@ -0,0 +1,9 @@ +# This file is generated from configure.ac by Autoconf. DO NOT EDIT! + +if test "$shared" = yes; then : + + # Get this defined in config.h for main source code to test. + $as_echo "#define HAVE_LIBIDN 1" >>confdefs.h + + +fi diff --git a/sysdeps/unix/inet/configure.ac b/sysdeps/unix/inet/configure.ac new file mode 100644 index 0000000000..e9b3443733 --- /dev/null +++ b/sysdeps/unix/inet/configure.ac @@ -0,0 +1,7 @@ +dnl glibc configure fragment for sysdeps/unix/inet. +GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory. + +AS_IF([test "$shared" = yes], [ + # Get this defined in config.h for main source code to test. + AC_DEFINE([HAVE_LIBIDN]) +]) -- cgit v1.2.3 From 8f6f5362727dc93360fe37e6d4e964f386b7b8e7 Mon Sep 17 00:00:00 2001 From: Adhemerval Zanella Date: Tue, 10 Oct 2017 11:12:50 -0300 Subject: Avoid build multiarch if compiler warns about mismatched alias GCC 8 emits an warning for alias for functions with incompatible types and it is used extensivelly for ifunc resolvers implementations in C (for instance on weak_alias with the internal symbol name to the external one or with the libc_hidden_def to set ifunc for internal usage). This breaks the build when the ifunc resolver is not defined using gcc attribute extensions (HAVE_GCC_IFUNC being 0). Although for all currently architectures that have multiarch support this compiler options is enabled for default, there is still the option where the user might try build glibc with a compiler without support for such extension. In this case this patch just disable the multiarch folder in sysdeps selections. GCC 7 and before still builds IFUNCs regardless of compiler support (although for the lack of attribute support debug information would be optimal). Checked with a build on multiarch support architectures (aarch64, arm, sparc, s390, powerpc, x86_64, i386) with multiarch enable and disable and with GCC 7 and GCC 8. * configure.ac (libc_cv_gcc_incompatbile_alias): New define: indicates whether compiler emits an warning for alias for functions with incompatible types. --- ChangeLog | 4 ++++ configure | 45 ++++++++++++++++++++++++++++++++++++++++++--- configure.ac | 37 ++++++++++++++++++++++++++++++++++--- 3 files changed, 80 insertions(+), 6 deletions(-) (limited to 'configure.ac') diff --git a/ChangeLog b/ChangeLog index 66a500b78c..aa7e9a96c5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2017-10-20 Adhemerval Zanella + * configure.ac (libc_cv_gcc_incompatbile_alias): New define: + indicates whether compiler emits an warning for alias for + functions with incompatible types. + [BZ #22273] * sysdeps/unix/sysv/linux/spawni.c (__spawnix): Handle the case where the auxiliary process is terminated by a signal before calling _exit diff --git a/configure b/configure index c2c9c72d5a..6010977c58 100755 --- a/configure +++ b/configure @@ -3996,6 +3996,32 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_gcc_indirect_function" >&5 $as_echo "$libc_cv_gcc_indirect_function" >&6; } +# Check if gcc warns about alias for function with incompatible types. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if compiler warns about alias for function with incompatible types" >&5 +$as_echo_n "checking if compiler warns about alias for function with incompatible types... " >&6; } +if ${libc_cv_gcc_incompatible_alias+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat > conftest.c <&5 2>&5 ; then + libc_cv_gcc_incompatible_alias=no +fi +rm -f conftest* +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_gcc_incompatible_alias" >&5 +$as_echo "$libc_cv_gcc_incompatible_alias" >&6; } + if test x"$libc_cv_ld_gnu_indirect_function" != xyes; then if test x"$multi_arch" = xyes; then as_fn_error $? "--enable-multi-arch support requires assembler and linker support" "$LINENO" 5 @@ -4003,12 +4029,25 @@ if test x"$libc_cv_ld_gnu_indirect_function" != xyes; then multi_arch=no fi fi -if test x"$libc_cv_gcc_indirect_function" != xyes && - test x"$multi_arch" = xyes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: --enable-multi-arch support recommends a gcc with gnu-indirect-function support. +if test x"$libc_cv_gcc_indirect_function" != xyes; then + # GCC 8+ emits a warning for alias with incompatible types and it might + # fail to build ifunc resolvers aliases to either weak or internal + # symbols. Disables multiarch build in this case. + if test x"$libc_cv_gcc_incompatible_alias" == xyes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: gcc emits a warning for alias between functions of incompatible types" >&5 +$as_echo "$as_me: WARNING: gcc emits a warning for alias between functions of incompatible types" >&2;} + if test x"$multi_arch" = xyes; then + as_fn_error $? "--enable-multi-arch support requires a gcc with gnu-indirect-function support" "$LINENO" 5 + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Multi-arch is disabled." >&5 +$as_echo "$as_me: WARNING: Multi-arch is disabled." >&2;} + multi_arch=no + elif test x"$multi_arch" = xyes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: --enable-multi-arch support recommends a gcc with gnu-indirect-function support. Please use a gcc which supports it by default or configure gcc with --enable-gnu-indirect-function" >&5 $as_echo "$as_me: WARNING: --enable-multi-arch support recommends a gcc with gnu-indirect-function support. Please use a gcc which supports it by default or configure gcc with --enable-gnu-indirect-function" >&2;} + fi fi multi_arch_d= if test x"$multi_arch" != xno; then diff --git a/configure.ac b/configure.ac index 195e81acfd..148f7d1682 100644 --- a/configure.ac +++ b/configure.ac @@ -634,6 +634,26 @@ if ${CC-cc} -c conftest.c -o conftest.o 1>&AS_MESSAGE_LOG_FD \ fi rm -f conftest*]) +# Check if gcc warns about alias for function with incompatible types. +AC_CACHE_CHECK([if compiler warns about alias for function with incompatible types], + libc_cv_gcc_incompatible_alias, [dnl +cat > conftest.c <&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD ; then + libc_cv_gcc_incompatible_alias=no +fi +rm -f conftest*]) + if test x"$libc_cv_ld_gnu_indirect_function" != xyes; then if test x"$multi_arch" = xyes; then AC_MSG_ERROR([--enable-multi-arch support requires assembler and linker support]) @@ -641,10 +661,21 @@ if test x"$libc_cv_ld_gnu_indirect_function" != xyes; then multi_arch=no fi fi -if test x"$libc_cv_gcc_indirect_function" != xyes && - test x"$multi_arch" = xyes; then - AC_MSG_WARN([--enable-multi-arch support recommends a gcc with gnu-indirect-function support. +if test x"$libc_cv_gcc_indirect_function" != xyes; then + # GCC 8+ emits a warning for alias with incompatible types and it might + # fail to build ifunc resolvers aliases to either weak or internal + # symbols. Disables multiarch build in this case. + if test x"$libc_cv_gcc_incompatible_alias" == xyes; then + AC_MSG_WARN([gcc emits a warning for alias between functions of incompatible types]) + if test x"$multi_arch" = xyes; then + AC_MSG_ERROR([--enable-multi-arch support requires a gcc with gnu-indirect-function support]) + fi + AC_MSG_WARN([Multi-arch is disabled.]) + multi_arch=no + elif test x"$multi_arch" = xyes; then + AC_MSG_WARN([--enable-multi-arch support recommends a gcc with gnu-indirect-function support. Please use a gcc which supports it by default or configure gcc with --enable-gnu-indirect-function]) + fi fi multi_arch_d= if test x"$multi_arch" != xno; then -- cgit v1.2.3 From abcb584d0eae7270b35e1b3fed1f9661e26b8be0 Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Mon, 6 Nov 2017 08:29:48 -0800 Subject: Use newly built crt*.o files to build shared objects [BZ #22362] When multi-lib GCC is used to build glibc, the search order of GCC driver for crt*.o is -B*/`gcc -print-multi-directory`, the installed diretory, -B*/. This patch adds multi-lib support to csu/Makefile so that -B/glibc-build-directory/csu/ will pick up the newly built crt*.o. Tested on x86-64 for i686 and x32. [BZ #22362] * Makerules (make-link-multidir): New. * config.make.in (multidir): New. * configure.ac (libc_cv_multidir): New. AC_SUBST. * configure: Regenerated. * csu/Makefile [$(multidir) != .](multilib-extra-objs): New. [$(multidir) != .](extra-objs): Add $(multilib-extra-objs). [$(multidir) != .]($(addprefix $(objpfx)$(multidir)/, $(install-lib))): New target. --- ChangeLog | 12 ++++++++++++ Makerules | 9 +++++++++ config.make.in | 1 + configure | 6 ++++++ configure.ac | 5 +++++ csu/Makefile | 10 ++++++++++ 6 files changed, 43 insertions(+) (limited to 'configure.ac') diff --git a/ChangeLog b/ChangeLog index acd573cfc3..57c99d6562 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2017-11-06 H.J. Lu + + [BZ #22362] + * Makerules (make-link-multidir): New. + * config.make.in (multidir): New. + * configure.ac (libc_cv_multidir): New. AC_SUBST. + * configure: Regenerated. + * csu/Makefile [$(multidir) != .](multilib-extra-objs): New. + [$(multidir) != .](extra-objs): Add $(multilib-extra-objs). + [$(multidir) != .]($(addprefix $(objpfx)$(multidir)/, $(install-lib))): + New target. + 2017-11-06 Joseph Myers [BZ #22402] diff --git a/Makerules b/Makerules index bbfbefe33f..522de25cfd 100644 --- a/Makerules +++ b/Makerules @@ -1079,6 +1079,11 @@ rm -f $@.new $(SHELL) $(..)scripts/rellns-sh $< $@.new mv -f $@.new $@ endef +define make-link-multidir +$(patsubst %/,cd %,$(objpfx)); \ + $(LN_S) . $(multidir) 2> /dev/null; \ + test -L $(multidir) +endef else # If we have no symbolic links don't bother with rellns-sh. define make-link @@ -1086,6 +1091,10 @@ rm -f $@.new $(LN_S) $< $@.new mv -f $@.new $@ endef +define make-link-multidir +$(make-target-directory) +ln -f $(objpfx)/$(@F) $@ +endef endif ifeq (yes,$(build-shared)) diff --git a/config.make.in b/config.make.in index fd2dbc91d1..bd84a5747d 100644 --- a/config.make.in +++ b/config.make.in @@ -21,6 +21,7 @@ includedir = @includedir@ datarootdir = @datarootdir@ localstatedir = @libc_cv_localstatedir@ localedir = @localedir@ +multidir= @libc_cv_multidir@ # Should we use and build ldconfig? use-ldconfig = @use_ldconfig@ diff --git a/configure b/configure index 6010977c58..c8697d9b1a 100755 --- a/configure +++ b/configure @@ -594,6 +594,7 @@ mach_interface_list DEFINES static_nss profile +libc_cv_multidir libc_cv_pie_default libc_cv_pic_default shared @@ -6698,6 +6699,11 @@ fi $as_echo "$libc_cv_pie_default" >&6; } +# Set the `multidir' variable by grabbing the variable from the compiler. +# We do it once and save the result in a generated makefile. +libc_cv_multidir=`${CC-cc} $CFLAGS $CPPFLAGS -print-multi-directory` + + diff --git a/configure.ac b/configure.ac index 148f7d1682..9f25c9fa0f 100644 --- a/configure.ac +++ b/configure.ac @@ -1783,6 +1783,11 @@ fi rm -f conftest.*]) AC_SUBST(libc_cv_pie_default) +# Set the `multidir' variable by grabbing the variable from the compiler. +# We do it once and save the result in a generated makefile. +libc_cv_multidir=`${CC-cc} $CFLAGS $CPPFLAGS -print-multi-directory` +AC_SUBST(libc_cv_multidir) + AC_SUBST(profile) AC_SUBST(static_nss) diff --git a/csu/Makefile b/csu/Makefile index fd668a5d00..e42a32b3eb 100644 --- a/csu/Makefile +++ b/csu/Makefile @@ -77,6 +77,11 @@ crtstuff = crti crtn install-lib += $(crtstuff:=.o) extra-objs += $(crtstuff:=.o) +ifneq ($(multidir),.) +multilib-extra-objs = $(addprefix $(multidir)/, $(install-lib)) +extra-objs += $(multilib-extra-objs) +endif + extra-objs += abi-note.o init.o asm-CPPFLAGS += -I$(objpfx). @@ -147,3 +152,8 @@ $(objpfx)abi-tag.h: $(..)abi-tags done if test -r $@.new; then mv -f $@.new $@; \ else echo >&2 'This configuration not matched in $<'; exit 1; fi + +ifneq ($(multidir),.) +$(addprefix $(objpfx)$(multidir)/, $(install-lib)): $(addprefix $(objpfx), $(install-lib)) + $(make-link-multidir) +endif -- cgit v1.2.3 From a306c790a835894c22d076a04a9924d3daeb9462 Mon Sep 17 00:00:00 2001 From: Siddhesh Poyarekar Date: Thu, 16 Nov 2017 11:49:26 +0530 Subject: Prefer https for Sourceware links Update all sourceware links to https. The website redirects everything to https anyway so let the web server do a bit less work. The only reference that remains unchanged is the one in the old ChangeLog, since it didn't seem worth changing it. * NEWS: Update sourceware link to https. * configure.ac: Likewise. * crypt/md5test-giant.c: Likewise. * dlfcn/bug-atexit1.c: Likewise. * dlfcn/bug-atexit2.c: Likewise. * localedata/README: Likewise. * malloc/tst-mallocfork.c: Likewise. * manual/install.texi: Likewise. * nptl/tst-pthread-getattr.c: Likewise. * stdio-common/tst-fgets.c: Likewise. * stdio-common/tst-fwrite.c: Likewise. * sunrpc/Makefile: Likewise. * sysdeps/arm/armv7/multiarch/memcpy_impl.S: Likewise. * wcsmbs/tst-mbrtowc2.c: Likewise. * configure: Regenerate. * INSTALL: Regenerate. --- ChangeLog | 19 +++++++++++++++++++ INSTALL | 4 ++-- NEWS | 2 +- configure | 14 +++++++------- configure.ac | 6 +++--- crypt/md5test-giant.c | 2 +- dlfcn/bug-atexit1.c | 2 +- dlfcn/bug-atexit2.c | 2 +- localedata/README | 2 +- malloc/tst-mallocfork.c | 2 +- manual/install.texi | 4 ++-- nptl/tst-pthread-getattr.c | 4 ++-- stdio-common/tst-fgets.c | 2 +- stdio-common/tst-fwrite.c | 2 +- sunrpc/Makefile | 2 +- sysdeps/arm/armv7/multiarch/memcpy_impl.S | 2 +- wcsmbs/tst-mbrtowc2.c | 3 ++- 17 files changed, 47 insertions(+), 27 deletions(-) (limited to 'configure.ac') diff --git a/ChangeLog b/ChangeLog index d7d81aceb7..c5a5c9c502 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,22 @@ +2017-11-16 Siddhesh Poyarekar + + * INSTALL: Update sourceware link to https. + * NEWS: Likewise. + * configure: Likewise. + * configure.ac: Likewise. + * crypt/md5test-giant.c: Likewise. + * dlfcn/bug-atexit1.c: Likewise. + * dlfcn/bug-atexit2.c: Likewise. + * localedata/README: Likewise. + * malloc/tst-mallocfork.c: Likewise. + * manual/install.texi: Likewise. + * nptl/tst-pthread-getattr.c: Likewise. + * stdio-common/tst-fgets.c: Likewise. + * stdio-common/tst-fwrite.c: Likewise. + * sunrpc/Makefile: Likewise. + * sysdeps/arm/armv7/multiarch/memcpy_impl.S: Likewise. + * wcsmbs/tst-mbrtowc2.c: Likewise. + 2017-11-15 Martin Sebor * misc/sys/cdefs.h (__attribute_nonstring__): New macro. diff --git a/INSTALL b/INSTALL index bc972b2ffa..35e82fbca9 100644 --- a/INSTALL +++ b/INSTALL @@ -2,7 +2,7 @@ Installing the GNU C Library **************************** Before you do anything else, you should read the FAQ at -. It answers common questions and +. It answers common questions and describes problems you may experience with compilation and installation. You will need recent versions of several GNU tools: definitely GCC @@ -541,7 +541,7 @@ remain unfixed for all eternity, if not longer. It is a good idea to verify that the problem has not already been reported. Bugs are documented in two places: The file 'BUGS' describes a number of well known bugs and the central GNU C Library bug tracking -system has a WWW interface at . The +system has a WWW interface at . The WWW interface gives you access to open and closed reports. A closed report normally includes a patch or a hint on solving the problem. diff --git a/NEWS b/NEWS index 520db40982..1c5da21327 100644 --- a/NEWS +++ b/NEWS @@ -2,7 +2,7 @@ GNU C Library NEWS -- history of user-visible changes. Copyright (C) 1992-2017 Free Software Foundation, Inc. See the end for copying conditions. -Please send GNU C library bug reports via +Please send GNU C library bug reports via using `glibc' in the "product" field. Version 2.27 diff --git a/configure b/configure index c8697d9b1a..d9d9243238 100755 --- a/configure +++ b/configure @@ -2,7 +2,7 @@ # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.69 for GNU C Library (see version.h). # -# Report bugs to . +# Report bugs to . # # # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. @@ -266,7 +266,7 @@ fi $as_echo "$0: be upgraded to zsh 4.3.4 or later." else $as_echo "$0: Please tell bug-autoconf@gnu.org and -$0: http://sourceware.org/bugzilla/ about your system, +$0: https://sourceware.org/bugzilla/ about your system, $0: including any error possibly output before this $0: message. Then install a modern shell, or manually run $0: the script under such a shell if you do have one." @@ -581,7 +581,7 @@ PACKAGE_NAME='GNU C Library' PACKAGE_TARNAME='glibc' PACKAGE_VERSION='(see version.h)' PACKAGE_STRING='GNU C Library (see version.h)' -PACKAGE_BUGREPORT='http://sourceware.org/bugzilla/' +PACKAGE_BUGREPORT='https://sourceware.org/bugzilla/' PACKAGE_URL='http://www.gnu.org/software/glibc/' ac_unique_file="include/features.h" @@ -1494,7 +1494,7 @@ Some influential environment variables: Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. -Report bugs to . +Report bugs to . GNU C Library home page: . General help using GNU software: . _ACEOF @@ -2188,12 +2188,12 @@ _ACEOF # We require GCC, and by default use its preprocessor. Override AC_PROG_CPP # here to work around the Autoconf issue discussed in -# . +# . # AC_PROG_CPP # We require GCC. Override _AC_PROG_CC_C89 here to work around the Autoconf # issue discussed in -# . +# . @@ -7286,7 +7286,7 @@ $config_headers Configuration commands: $config_commands -Report bugs to . +Report bugs to . GNU C Library home page: . General help using GNU software: ." diff --git a/configure.ac b/configure.ac index 9f25c9fa0f..8ebc490a55 100644 --- a/configure.ac +++ b/configure.ac @@ -1,6 +1,6 @@ dnl Process this file with autoconf to produce a configure script. dnl Note we do not use AC_PREREQ here! See aclocal.m4 for what we use instead. -AC_INIT([GNU C Library], [(see version.h)], [http://sourceware.org/bugzilla/], [glibc]) +AC_INIT([GNU C Library], [(see version.h)], [https://sourceware.org/bugzilla/], [glibc]) AC_CONFIG_SRCDIR([include/features.h]) AC_CONFIG_HEADERS([config.h]) AC_CONFIG_AUX_DIR([scripts]) @@ -19,7 +19,7 @@ AC_DEFUN([_AC_INCLUDES_DEFAULT_REQUIREMENTS], # We require GCC, and by default use its preprocessor. Override AC_PROG_CPP # here to work around the Autoconf issue discussed in -# . +# . AC_DEFUN([AC_PROG_CPP], [AC_REQUIRE([AC_PROG_CC])dnl AC_ARG_VAR([CPP], [C preprocessor])dnl @@ -36,7 +36,7 @@ AC_SUBST(CPP)dnl # We require GCC. Override _AC_PROG_CC_C89 here to work around the Autoconf # issue discussed in -# . +# . AC_DEFUN([_AC_PROG_CC_C89], [[$1]]) dnl This is here so we can set $subdirs directly based on configure fragments. diff --git a/crypt/md5test-giant.c b/crypt/md5test-giant.c index 4655a74db8..a7634eeb35 100644 --- a/crypt/md5test-giant.c +++ b/crypt/md5test-giant.c @@ -1,4 +1,4 @@ -/* Testcase for http://sourceware.org/bugzilla/show_bug.cgi?id=14090. +/* Testcase for https://sourceware.org/bugzilla/show_bug.cgi?id=14090. Copyright (C) 2012-2017 Free Software Foundation, Inc. This file is part of the GNU C Library. diff --git a/dlfcn/bug-atexit1.c b/dlfcn/bug-atexit1.c index e2d1d2f776..fdfb6bc0b7 100644 --- a/dlfcn/bug-atexit1.c +++ b/dlfcn/bug-atexit1.c @@ -1,5 +1,5 @@ /* Derived from a test case in - http://sourceware.org/bugzilla/show_bug.cgi?id=1158. */ + https://sourceware.org/bugzilla/show_bug.cgi?id=1158. */ #include #include #include diff --git a/dlfcn/bug-atexit2.c b/dlfcn/bug-atexit2.c index 15e9f7aa01..279804dcf2 100644 --- a/dlfcn/bug-atexit2.c +++ b/dlfcn/bug-atexit2.c @@ -1,5 +1,5 @@ /* Derived from a test case in - http://sourceware.org/bugzilla/show_bug.cgi?id=1158. */ + https://sourceware.org/bugzilla/show_bug.cgi?id=1158. */ #include #include #include diff --git a/localedata/README b/localedata/README index 3e828986c1..e844719180 100644 --- a/localedata/README +++ b/localedata/README @@ -42,7 +42,7 @@ especially in the section describing the `setlocale' function. All problems should be reported using - http://sourceware.org/bugzilla/ + https://sourceware.org/bugzilla/ One more note: the `POSIX' locale definition is not meant to be used diff --git a/malloc/tst-mallocfork.c b/malloc/tst-mallocfork.c index f90ce94887..4ff6ec09f4 100644 --- a/malloc/tst-mallocfork.c +++ b/malloc/tst-mallocfork.c @@ -1,5 +1,5 @@ /* Derived from the test case in - http://sourceware.org/bugzilla/show_bug.cgi?id=838. */ + https://sourceware.org/bugzilla/show_bug.cgi?id=838. */ #include #include #include diff --git a/manual/install.texi b/manual/install.texi index 96b988e829..f1fa28c937 100644 --- a/manual/install.texi +++ b/manual/install.texi @@ -9,7 +9,7 @@ @appendix Installing @theglibc{} Before you do anything else, you should read the FAQ at -@url{http://sourceware.org/glibc/wiki/FAQ}. It answers common +@url{https://sourceware.org/glibc/wiki/FAQ}. It answers common questions and describes problems you may experience with compilation and installation. @@ -613,7 +613,7 @@ reported. Bugs are documented in two places: The file @file{BUGS} describes a number of well known bugs and the central @glibcadj{} bug tracking system has a WWW interface at -@url{http://sourceware.org/bugzilla/}. The WWW +@url{https://sourceware.org/bugzilla/}. The WWW interface gives you access to open and closed reports. A closed report normally includes a patch or a hint on solving the problem. diff --git a/nptl/tst-pthread-getattr.c b/nptl/tst-pthread-getattr.c index 86719f97ab..27c60c84de 100644 --- a/nptl/tst-pthread-getattr.c +++ b/nptl/tst-pthread-getattr.c @@ -35,8 +35,8 @@ results in a test case failure. To avoid these problems, we cap the stack size to one less than 8M. See the following mailing list threads for more information about this problem: - - . */ + + . */ #define MAX_STACK_SIZE (8192 * 1024 - 1) static size_t pagesize; diff --git a/stdio-common/tst-fgets.c b/stdio-common/tst-fgets.c index 0aa9030e3a..912b7068eb 100644 --- a/stdio-common/tst-fgets.c +++ b/stdio-common/tst-fgets.c @@ -1,5 +1,5 @@ /* Derived from the test case in - http://sourceware.org/bugzilla/show_bug.cgi?id=713. */ + https://sourceware.org/bugzilla/show_bug.cgi?id=713. */ #include static int diff --git a/stdio-common/tst-fwrite.c b/stdio-common/tst-fwrite.c index 2986c8932a..1db10d0f6a 100644 --- a/stdio-common/tst-fwrite.c +++ b/stdio-common/tst-fwrite.c @@ -1,5 +1,5 @@ /* Derived from the test case in - http://sourceware.org/bugzilla/show_bug.cgi?id=1078. */ + https://sourceware.org/bugzilla/show_bug.cgi?id=1078. */ #include #include #include diff --git a/sunrpc/Makefile b/sunrpc/Makefile index 125d538208..f1b8323e93 100644 --- a/sunrpc/Makefile +++ b/sunrpc/Makefile @@ -173,7 +173,7 @@ cross-rpcgen-objs := $(addprefix $(objpfx)cross-,$(rpcgen-objs)) # When generic makefile support for build system programs is # available, it should replace this code. See -# . +# . $(cross-rpcgen-objs): $(objpfx)cross-%.o: %.c $(before-compile) $(BUILD_CC) $($(basename $( #include #include -- cgit v1.2.3 From 1faaf7035cabda101e1d6653bff7a539f201db91 Mon Sep 17 00:00:00 2001 From: Juro Bystricky Date: Thu, 30 Nov 2017 21:21:15 +0000 Subject: plural.c: improve reproducibility There is a subtle non-determinism when building glibc. This depends on whether the glibc is built using the distibuted file intl/plural.c or built using the generated file intl/plural.c. These two files (intl/plural.c generated vs. distributed) are slightly different, hence we may end up with slightly different libraries. Originally, having "bison" installed was optional. So if "bison" was not present, we always built libraries with the distributed plural.c. If bison was installed, we *** may have *** replaced the distributed file plural.c with a new plural.c generated from plural.y. if the timestamps triggered this rule: plural.c plural.y $(BISON) $(BISONFLAGS) $@ $^ Given that timestamps are not preserved in GIT repositories, the above rule is not reliable without explicitly touching plural.c or plural.y. In other words, the rule may or may not have fired. In summary: there are two distinct sources of non-determinism: 1. Having "bison" installed or not 2. Having "bison" installed but timestamps poorly defined. This patch fixes this by requiring "bison" being installed and by always generating intl/plural.c from intl/plural.y. (This is achieved by simply removing checked-in intl/plural.c) [BZ #22432] * configure.ac (BISON): Require to be present. * configure: Regenerated. * intl/Makefile (generated): Add plural.c. [$(BISON) != no]: Make code unconditional. (plural.c): Change rule to $(objpfx)plural.c. ($(objpfx)plural.o): Depend on $(objpfx)plural.c. * intl/plural.c: Remove. * manual/install.texi (Tools for Compilation): Document bison as required. * INSTALL: Regenerated. --- ChangeLog | 14 + INSTALL | 10 +- NEWS | 3 +- configure | 128 ++-- configure.ac | 7 +- intl/Makefile | 9 +- intl/plural.c | 2011 --------------------------------------------------- manual/install.texi | 14 +- 8 files changed, 98 insertions(+), 2098 deletions(-) delete mode 100644 intl/plural.c (limited to 'configure.ac') diff --git a/ChangeLog b/ChangeLog index 8c042b8be6..4380b73a03 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2017-11-30 Juro Bystricky + + [BZ #22432] + * configure.ac (BISON): Require to be present. + * configure: Regenerated. + * intl/Makefile (generated): Add plural.c. + [$(BISON) != no]: Make code unconditional. + (plural.c): Change rule to $(objpfx)plural.c. + ($(objpfx)plural.o): Depend on $(objpfx)plural.c. + * intl/plural.c: Remove. + * manual/install.texi (Tools for Compilation): Document bison as + required. + * INSTALL: Regenerated. + 2017-11-30 Joseph Myers * sysdeps/m68k/m680x0/fpu/s_llrint.c: Include diff --git a/INSTALL b/INSTALL index ac8db74a0f..d1a34c2a90 100644 --- a/INSTALL +++ b/INSTALL @@ -462,6 +462,11 @@ build the GNU C Library: version 4.1.3 is the newest verified to work to build the GNU C Library. + * GNU 'bison' 2.7 or later + + 'bison' is used to generate the 'yacc' parser code in the 'intl' + subdirectory. + * Perl 5 Perl is not required, but it is used if present to test the @@ -481,11 +486,6 @@ and if you change any of the message translation files you will need * GNU 'gettext' 0.10.36 or later -If you wish to regenerate the 'yacc' parser code in the 'intl' -subdirectory you will need - - * GNU 'bison' 2.7 or later - You may also need these packages if you upgrade your source tree using patches, although we try to avoid this. diff --git a/NEWS b/NEWS index f3fdf9aec5..48af4acaea 100644 --- a/NEWS +++ b/NEWS @@ -79,7 +79,8 @@ Deprecated and removed features, and other changes affecting compatibility: Changes to build and runtime requirements: - [Add changes to build and runtime requirements here] +* bison version 2.7 or later is required to generate code in the 'intl' + subdirectory. Security related changes: diff --git a/configure b/configure index d9d9243238..caba102846 100755 --- a/configure +++ b/configure @@ -632,7 +632,6 @@ ASFLAGS_config libc_cv_cc_with_libunwind libc_cv_insert libc_cv_protected_data -BISON INSTALL_INFO PERL BASH_SHELL @@ -645,6 +644,7 @@ PYTHON PYTHON_PROG AUTOCONF NM +BISON AWK SED MAKEINFO @@ -4940,6 +4940,69 @@ if test $ac_verc_fail = yes; then critic_missing="$critic_missing gawk" fi +for ac_prog in bison +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_BISON+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$BISON"; then + ac_cv_prog_BISON="$BISON" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_BISON="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +BISON=$ac_cv_prog_BISON +if test -n "$BISON"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $BISON" >&5 +$as_echo "$BISON" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$BISON" && break +done + +if test -z "$BISON"; then + ac_verc_fail=yes +else + # Found it, now check the version. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking version of $BISON" >&5 +$as_echo_n "checking version of $BISON... " >&6; } + ac_prog_version=`$BISON --version 2>&1 | sed -n 's/^.*bison (GNU Bison) \([0-9]*\.[0-9.]*\).*$/\1/p'` + case $ac_prog_version in + '') ac_prog_version="v. ?.??, bad"; ac_verc_fail=yes;; + 2.7*|[3-9].*|[1-9][0-9]*) + ac_prog_version="$ac_prog_version, ok"; ac_verc_fail=no;; + *) ac_prog_version="$ac_prog_version, bad"; ac_verc_fail=yes;; + + esac + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_prog_version" >&5 +$as_echo "$ac_prog_version" >&6; } +fi +if test $ac_verc_fail = yes; then + critic_missing="$critic_missing bison" +fi + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC is sufficient to build libc" >&5 $as_echo_n "checking if $CC is sufficient to build libc... " >&6; } @@ -5399,69 +5462,6 @@ $as_echo "no" >&6; } fi -for ac_prog in bison -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_BISON+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$BISON"; then - ac_cv_prog_BISON="$BISON" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_BISON="$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -BISON=$ac_cv_prog_BISON -if test -n "$BISON"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $BISON" >&5 -$as_echo "$BISON" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$BISON" && break -done - -if test -z "$BISON"; then - ac_verc_fail=yes -else - # Found it, now check the version. - { $as_echo "$as_me:${as_lineno-$LINENO}: checking version of $BISON" >&5 -$as_echo_n "checking version of $BISON... " >&6; } - ac_prog_version=`$BISON --version 2>&1 | sed -n 's/^.*bison (GNU Bison) \([0-9]*\.[0-9.]*\).*$/\1/p'` - case $ac_prog_version in - '') ac_prog_version="v. ?.??, bad"; ac_verc_fail=yes;; - 2.7*|[3-9].*|[1-9][0-9]*) - ac_prog_version="$ac_prog_version, ok"; ac_verc_fail=no;; - *) ac_prog_version="$ac_prog_version, bad"; ac_verc_fail=yes;; - - esac - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_prog_version" >&5 -$as_echo "$ac_prog_version" >&6; } -fi -if test $ac_verc_fail = yes; then - BISON=no -fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for .set assembler directive" >&5 $as_echo_n "checking for .set assembler directive... " >&6; } diff --git a/configure.ac b/configure.ac index 8ebc490a55..9707ae4d8e 100644 --- a/configure.ac +++ b/configure.ac @@ -939,6 +939,9 @@ AC_CHECK_PROG_VER(SED, sed, --version, AC_CHECK_PROG_VER(AWK, gawk, --version, [GNU Awk[^0-9]*\([0-9][0-9.]*\)], [3.1.[2-9]*|3.[2-9]*|[4-9]*], critic_missing="$critic_missing gawk") +AC_CHECK_PROG_VER(BISON, bison, --version, + [bison (GNU Bison) \([0-9]*\.[0-9.]*\)], + [2.7*|[3-9].*|[1-9][0-9]*], critic_missing="$critic_missing bison") AC_CACHE_CHECK([if $CC is sufficient to build libc], libc_cv_compiler_ok, [ AC_TRY_COMPILE([], [ @@ -1070,10 +1073,6 @@ if test "$PERL" != no && fi AC_PATH_PROG(INSTALL_INFO, install-info, no, $PATH:/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin) -AC_CHECK_PROG_VER(BISON, bison, --version, - [bison (GNU Bison) \([0-9]*\.[0-9.]*\)], - [2.7*|[3-9].*|[1-9][0-9]*], - BISON=no) AC_CACHE_CHECK(for .set assembler directive, libc_cv_asm_set_directive, [dnl cat > conftest.s <. */ - -/* As a special exception, you may create a larger work that contains - part or all of the Bison parser skeleton and distribute that work - under terms of your choice, so long as that work isn't itself a - parser generator using the skeleton or a modified version thereof - as a parser skeleton. Alternatively, if you modify or redistribute - the parser skeleton itself, you may (at your option) remove this - special exception, which will cause the skeleton and the resulting - Bison output files to be licensed under the GNU General Public - License without this special exception. - - This special exception was added by the Free Software Foundation in - version 2.2 of Bison. */ - -/* C LALR(1) parser skeleton written by Richard Stallman, by - simplifying the original so-called "semantic" parser. */ - -/* All symbols defined below should begin with yy or YY, to avoid - infringing on user name space. This should be done even for local - variables, as they might otherwise be expanded by user macros. - There are some unavoidable exceptions within include files to - define necessary library symbols; they are noted "INFRINGES ON - USER NAME SPACE" below. */ - -/* Identify Bison output. */ -#define YYBISON 1 - -/* Bison version. */ -#define YYBISON_VERSION "2.7" - -/* Skeleton name. */ -#define YYSKELETON_NAME "yacc.c" - -/* Pure parsers. */ -#define YYPURE 2 - -/* Push parsers. */ -#define YYPUSH 0 - -/* Pull parsers. */ -#define YYPULL 1 - - -/* Substitute the variable and function names. */ -#define yyparse __gettextparse -#define yylex __gettextlex -#define yyerror __gettexterror -#define yylval __gettextlval -#define yychar __gettextchar -#define yydebug __gettextdebug -#define yynerrs __gettextnerrs - -/* Copy the first part of user declarations. */ -/* Line 371 of yacc.c */ -#line 1 "plural.y" - -/* Expression parsing for plural form selection. - Copyright (C) 2000-2017 Free Software Foundation, Inc. - Written by Ulrich Drepper , 2000. - - This program 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. - - This program 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 this program. If not, see . */ - -/* For bison < 2.0, the bison generated parser uses alloca. AIX 3 forces us - to put this declaration at the beginning of the file. The declaration in - bison's skeleton file comes too late. This must come before - because may include arbitrary system headers. - This can go away once the AM_INTL_SUBDIR macro requires bison >= 2.0. */ -#if defined _AIX && !defined __GNUC__ - #pragma alloca -#endif - -#ifdef HAVE_CONFIG_H -# include -#endif - -#include -#include -#include -#include "plural-exp.h" - -/* The main function generated by the parser is called __gettextparse, - but we want it to be called PLURAL_PARSE. */ -#ifndef _LIBC -# define __gettextparse PLURAL_PARSE -#endif - - -/* Line 371 of yacc.c */ -#line 119 "plural.c" - -# ifndef YY_NULL -# if defined __cplusplus && 201103L <= __cplusplus -# define YY_NULL nullptr -# else -# define YY_NULL 0 -# endif -# endif - -/* Enabling verbose error messages. */ -#ifdef YYERROR_VERBOSE -# undef YYERROR_VERBOSE -# define YYERROR_VERBOSE 1 -#else -# define YYERROR_VERBOSE 0 -#endif - - -/* Enabling traces. */ -#ifndef YYDEBUG -# define YYDEBUG 0 -#endif -#if YYDEBUG -extern int __gettextdebug; -#endif - -/* Tokens. */ -#ifndef YYTOKENTYPE -# define YYTOKENTYPE - /* Put the tokens into the symbol table, so that GDB and other debuggers - know about them. */ - enum yytokentype { - EQUOP2 = 258, - CMPOP2 = 259, - ADDOP2 = 260, - MULOP2 = 261, - NUMBER = 262 - }; -#endif -/* Tokens. */ -#define EQUOP2 258 -#define CMPOP2 259 -#define ADDOP2 260 -#define MULOP2 261 -#define NUMBER 262 - - - -#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED -typedef union YYSTYPE -{ -/* Line 387 of yacc.c */ -#line 49 "plural.y" - - unsigned long int num; - enum expression_operator op; - struct expression *exp; - - -/* Line 387 of yacc.c */ -#line 180 "plural.c" -} YYSTYPE; -# define YYSTYPE_IS_TRIVIAL 1 -# define yystype YYSTYPE /* obsolescent; will be withdrawn */ -# define YYSTYPE_IS_DECLARED 1 -#endif - - -#ifdef YYPARSE_PARAM -#if defined __STDC__ || defined __cplusplus -int __gettextparse (void *YYPARSE_PARAM); -#else -int __gettextparse (); -#endif -#else /* ! YYPARSE_PARAM */ -#if defined __STDC__ || defined __cplusplus -int __gettextparse (struct parse_args *arg); -#else -int __gettextparse (); -#endif -#endif /* ! YYPARSE_PARAM */ - - - -/* Copy the second part of user declarations. */ -/* Line 390 of yacc.c */ -#line 55 "plural.y" - -/* Prototypes for local functions. */ -static int yylex (YYSTYPE *lval, struct parse_args *arg); -static void yyerror (struct parse_args *arg, const char *str); - -/* Allocation of expressions. */ - -static struct expression * -new_exp (int nargs, enum expression_operator op, - struct expression * const *args) -{ - int i; - struct expression *newp; - - /* If any of the argument could not be malloc'ed, just return NULL. */ - for (i = nargs - 1; i >= 0; i--) - if (args[i] == NULL) - goto fail; - - /* Allocate a new expression. */ - newp = (struct expression *) malloc (sizeof (*newp)); - if (newp != NULL) - { - newp->nargs = nargs; - newp->operation = op; - for (i = nargs - 1; i >= 0; i--) - newp->val.args[i] = args[i]; - return newp; - } - - fail: - for (i = nargs - 1; i >= 0; i--) - FREE_EXPRESSION (args[i]); - - return NULL; -} - -static inline struct expression * -new_exp_0 (enum expression_operator op) -{ - return new_exp (0, op, NULL); -} - -static inline struct expression * -new_exp_1 (enum expression_operator op, struct expression *right) -{ - struct expression *args[1]; - - args[0] = right; - return new_exp (1, op, args); -} - -static struct expression * -new_exp_2 (enum expression_operator op, struct expression *left, - struct expression *right) -{ - struct expression *args[2]; - - args[0] = left; - args[1] = right; - return new_exp (2, op, args); -} - -static inline struct expression * -new_exp_3 (enum expression_operator op, struct expression *bexp, - struct expression *tbranch, struct expression *fbranch) -{ - struct expression *args[3]; - - args[0] = bexp; - args[1] = tbranch; - args[2] = fbranch; - return new_exp (3, op, args); -} - - -/* Line 390 of yacc.c */ -#line 284 "plural.c" - -#ifdef short -# undef short -#endif - -#ifdef YYTYPE_UINT8 -typedef YYTYPE_UINT8 yytype_uint8; -#else -typedef unsigned char yytype_uint8; -#endif - -#ifdef YYTYPE_INT8 -typedef YYTYPE_INT8 yytype_int8; -#elif (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -typedef signed char yytype_int8; -#else -typedef short int yytype_int8; -#endif - -#ifdef YYTYPE_UINT16 -typedef YYTYPE_UINT16 yytype_uint16; -#else -typedef unsigned short int yytype_uint16; -#endif - -#ifdef YYTYPE_INT16 -typedef YYTYPE_INT16 yytype_int16; -#else -typedef short int yytype_int16; -#endif - -#ifndef YYSIZE_T -# ifdef __SIZE_TYPE__ -# define YYSIZE_T __SIZE_TYPE__ -# elif defined size_t -# define YYSIZE_T size_t -# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -# include /* INFRINGES ON USER NAME SPACE */ -# define YYSIZE_T size_t -# else -# define YYSIZE_T unsigned int -# endif -#endif - -#define YYSIZE_MAXIMUM ((YYSIZE_T) -1) - -#ifndef YY_ -# if defined YYENABLE_NLS && YYENABLE_NLS -# if ENABLE_NLS -# include /* INFRINGES ON USER NAME SPACE */ -# define YY_(Msgid) dgettext ("bison-runtime", Msgid) -# endif -# endif -# ifndef YY_ -# define YY_(Msgid) Msgid -# endif -#endif - -/* Suppress unused-variable warnings by "using" E. */ -#if ! defined lint || defined __GNUC__ -# define YYUSE(E) ((void) (E)) -#else -# define YYUSE(E) /* empty */ -#endif - -/* Identity function, used to suppress warnings about constant conditions. */ -#ifndef lint -# define YYID(N) (N) -#else -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static int -YYID (int yyi) -#else -static int -YYID (yyi) - int yyi; -#endif -{ - return yyi; -} -#endif - -#if ! defined yyoverflow || YYERROR_VERBOSE - -/* The parser invokes alloca or malloc; define the necessary symbols. */ - -# ifdef YYSTACK_USE_ALLOCA -# if YYSTACK_USE_ALLOCA -# ifdef __GNUC__ -# define YYSTACK_ALLOC __builtin_alloca -# elif defined __BUILTIN_VA_ARG_INCR -# include /* INFRINGES ON USER NAME SPACE */ -# elif defined _AIX -# define YYSTACK_ALLOC __alloca -# elif defined _MSC_VER -# include /* INFRINGES ON USER NAME SPACE */ -# define alloca _alloca -# else -# define YYSTACK_ALLOC alloca -# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -# include /* INFRINGES ON USER NAME SPACE */ - /* Use EXIT_SUCCESS as a witness for stdlib.h. */ -# ifndef EXIT_SUCCESS -# define EXIT_SUCCESS 0 -# endif -# endif -# endif -# endif -# endif - -# ifdef YYSTACK_ALLOC - /* Pacify GCC's `empty if-body' warning. */ -# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0)) -# ifndef YYSTACK_ALLOC_MAXIMUM - /* The OS might guarantee only one guard page at the bottom of the stack, - and a page size can be as small as 4096 bytes. So we cannot safely - invoke alloca (N) if N exceeds 4096. Use a slightly smaller number - to allow for a few compiler-allocated temporary stack slots. */ -# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ -# endif -# else -# define YYSTACK_ALLOC YYMALLOC -# define YYSTACK_FREE YYFREE -# ifndef YYSTACK_ALLOC_MAXIMUM -# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM -# endif -# if (defined __cplusplus && ! defined EXIT_SUCCESS \ - && ! ((defined YYMALLOC || defined malloc) \ - && (defined YYFREE || defined free))) -# include /* INFRINGES ON USER NAME SPACE */ -# ifndef EXIT_SUCCESS -# define EXIT_SUCCESS 0 -# endif -# endif -# ifndef YYMALLOC -# define YYMALLOC malloc -# if ! defined malloc && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ -# endif -# endif -# ifndef YYFREE -# define YYFREE free -# if ! defined free && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -void free (void *); /* INFRINGES ON USER NAME SPACE */ -# endif -# endif -# endif -#endif /* ! defined yyoverflow || YYERROR_VERBOSE */ - - -#if (! defined yyoverflow \ - && (! defined __cplusplus \ - || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) - -/* A type that is properly aligned for any stack member. */ -union yyalloc -{ - yytype_int16 yyss_alloc; - YYSTYPE yyvs_alloc; -}; - -/* The size of the maximum gap between one aligned stack and the next. */ -# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) - -/* The size of an array large to enough to hold all stacks, each with - N elements. */ -# define YYSTACK_BYTES(N) \ - ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \ - + YYSTACK_GAP_MAXIMUM) - -# define YYCOPY_NEEDED 1 - -/* Relocate STACK from its old location to the new one. The - local variables YYSIZE and YYSTACKSIZE give the old and new number of - elements in the stack, and YYPTR gives the new location of the - stack. Advance YYPTR to a properly aligned location for the next - stack. */ -# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ - do \ - { \ - YYSIZE_T yynewbytes; \ - YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ - Stack = &yyptr->Stack_alloc; \ - yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ - yyptr += yynewbytes / sizeof (*yyptr); \ - } \ - while (YYID (0)) - -#endif - -#if defined YYCOPY_NEEDED && YYCOPY_NEEDED -/* Copy COUNT objects from SRC to DST. The source and destination do - not overlap. */ -# ifndef YYCOPY -# if defined __GNUC__ && 1 < __GNUC__ -# define YYCOPY(Dst, Src, Count) \ - __builtin_memcpy (Dst, Src, (Count) * sizeof (*(Src))) -# else -# define YYCOPY(Dst, Src, Count) \ - do \ - { \ - YYSIZE_T yyi; \ - for (yyi = 0; yyi < (Count); yyi++) \ - (Dst)[yyi] = (Src)[yyi]; \ - } \ - while (YYID (0)) -# endif -# endif -#endif /* !YYCOPY_NEEDED */ - -/* YYFINAL -- State number of the termination state. */ -#define YYFINAL 9 -/* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 54 - -/* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 16 -/* YYNNTS -- Number of nonterminals. */ -#define YYNNTS 3 -/* YYNRULES -- Number of rules. */ -#define YYNRULES 13 -/* YYNRULES -- Number of states. */ -#define YYNSTATES 27 - -/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ -#define YYUNDEFTOK 2 -#define YYMAXUTOK 262 - -#define YYTRANSLATE(YYX) \ - ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) - -/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ -static const yytype_uint8 yytranslate[] = -{ - 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 10, 2, 2, 2, 2, 5, 2, - 14, 15, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 12, 2, - 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 13, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 1, 2, 6, 7, - 8, 9, 11 -}; - -#if YYDEBUG -/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in - YYRHS. */ -static const yytype_uint8 yyprhs[] = -{ - 0, 0, 3, 5, 11, 15, 19, 23, 27, 31, - 35, 38, 40, 42 -}; - -/* YYRHS -- A `-1'-separated list of the rules' RHS. */ -static const yytype_int8 yyrhs[] = -{ - 17, 0, -1, 18, -1, 18, 3, 18, 12, 18, - -1, 18, 4, 18, -1, 18, 5, 18, -1, 18, - 6, 18, -1, 18, 7, 18, -1, 18, 8, 18, - -1, 18, 9, 18, -1, 10, 18, -1, 13, -1, - 11, -1, 14, 18, 15, -1 -}; - -/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ -static const yytype_uint8 yyrline[] = -{ - 0, 152, 152, 160, 164, 168, 172, 176, 180, 184, - 188, 192, 196, 201 -}; -#endif - -#if YYDEBUG || YYERROR_VERBOSE || 0 -/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. - First, the terminals, then, starting at YYNTOKENS, nonterminals. */ -static const char *const yytname[] = -{ - "$end", "error", "$undefined", "'?'", "'|'", "'&'", "EQUOP2", "CMPOP2", - "ADDOP2", "MULOP2", "'!'", "NUMBER", "':'", "'n'", "'('", "')'", - "$accept", "start", "exp", YY_NULL -}; -#endif - -# ifdef YYPRINT -/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to - token YYLEX-NUM. */ -static const yytype_uint16 yytoknum[] = -{ - 0, 256, 257, 63, 124, 38, 258, 259, 260, 261, - 33, 262, 58, 110, 40, 41 -}; -# endif - -/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ -static const yytype_uint8 yyr1[] = -{ - 0, 16, 17, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18 -}; - -/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ -static const yytype_uint8 yyr2[] = -{ - 0, 2, 1, 5, 3, 3, 3, 3, 3, 3, - 2, 1, 1, 3 -}; - -/* YYDEFACT[STATE-NAME] -- Default reduction number in state STATE-NUM. - Performed when YYTABLE doesn't specify something else to do. Zero - means the default is an error. */ -static const yytype_uint8 yydefact[] = -{ - 0, 0, 12, 11, 0, 0, 2, 10, 0, 1, - 0, 0, 0, 0, 0, 0, 0, 13, 0, 4, - 5, 6, 7, 8, 9, 0, 3 -}; - -/* YYDEFGOTO[NTERM-NUM]. */ -static const yytype_int8 yydefgoto[] = -{ - -1, 5, 6 -}; - -/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing - STATE-NUM. */ -#define YYPACT_NINF -10 -static const yytype_int8 yypact[] = -{ - -9, -9, -10, -10, -9, 8, 36, -10, 13, -10, - -9, -9, -9, -9, -9, -9, -9, -10, 26, 41, - 45, 18, -2, 14, -10, -9, 36 -}; - -/* YYPGOTO[NTERM-NUM]. */ -static const yytype_int8 yypgoto[] = -{ - -10, -10, -1 -}; - -/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If - positive, shift that token. If negative, reduce the rule which - number is the opposite. If YYTABLE_NINF, syntax error. */ -#define YYTABLE_NINF -1 -static const yytype_uint8 yytable[] = -{ - 7, 1, 2, 8, 3, 4, 15, 16, 9, 18, - 19, 20, 21, 22, 23, 24, 10, 11, 12, 13, - 14, 15, 16, 16, 26, 14, 15, 16, 17, 10, - 11, 12, 13, 14, 15, 16, 0, 0, 25, 10, - 11, 12, 13, 14, 15, 16, 12, 13, 14, 15, - 16, 13, 14, 15, 16 -}; - -#define yypact_value_is_default(Yystate) \ - (!!((Yystate) == (-10))) - -#define yytable_value_is_error(Yytable_value) \ - YYID (0) - -static const yytype_int8 yycheck[] = -{ - 1, 10, 11, 4, 13, 14, 8, 9, 0, 10, - 11, 12, 13, 14, 15, 16, 3, 4, 5, 6, - 7, 8, 9, 9, 25, 7, 8, 9, 15, 3, - 4, 5, 6, 7, 8, 9, -1, -1, 12, 3, - 4, 5, 6, 7, 8, 9, 5, 6, 7, 8, - 9, 6, 7, 8, 9 -}; - -/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing - symbol of state STATE-NUM. */ -static const yytype_uint8 yystos[] = -{ - 0, 10, 11, 13, 14, 17, 18, 18, 18, 0, - 3, 4, 5, 6, 7, 8, 9, 15, 18, 18, - 18, 18, 18, 18, 18, 12, 18 -}; - -#define yyerrok (yyerrstatus = 0) -#define yyclearin (yychar = YYEMPTY) -#define YYEMPTY (-2) -#define YYEOF 0 - -#define YYACCEPT goto yyacceptlab -#define YYABORT goto yyabortlab -#define YYERROR goto yyerrorlab - - -/* Like YYERROR except do call yyerror. This remains here temporarily - to ease the transition to the new meaning of YYERROR, for GCC. - Once GCC version 2 has supplanted version 1, this can go. However, - YYFAIL appears to be in use. Nevertheless, it is formally deprecated - in Bison 2.4.2's NEWS entry, where a plan to phase it out is - discussed. */ - -#define YYFAIL goto yyerrlab -#if defined YYFAIL - /* This is here to suppress warnings from the GCC cpp's - -Wunused-macros. Normally we don't worry about that warning, but - some users do, and we want to make it easy for users to remove - YYFAIL uses, which will produce warnings from Bison 2.5. */ -#endif - -#define YYRECOVERING() (!!yyerrstatus) - -#define YYBACKUP(Token, Value) \ -do \ - if (yychar == YYEMPTY) \ - { \ - yychar = (Token); \ - yylval = (Value); \ - YYPOPSTACK (yylen); \ - yystate = *yyssp; \ - goto yybackup; \ - } \ - else \ - { \ - yyerror (arg, YY_("syntax error: cannot back up")); \ - YYERROR; \ - } \ -while (YYID (0)) - -/* Error token number */ -#define YYTERROR 1 -#define YYERRCODE 256 - - -/* This macro is provided for backward compatibility. */ -#ifndef YY_LOCATION_PRINT -# define YY_LOCATION_PRINT(File, Loc) ((void) 0) -#endif - - -/* YYLEX -- calling `yylex' with the right arguments. */ -#ifdef YYLEX_PARAM -# define YYLEX yylex (&yylval, YYLEX_PARAM) -#else -# define YYLEX yylex (&yylval, arg) -#endif - -/* Enable debugging if requested. */ -#if YYDEBUG - -# ifndef YYFPRINTF -# include /* INFRINGES ON USER NAME SPACE */ -# define YYFPRINTF fprintf -# endif - -# define YYDPRINTF(Args) \ -do { \ - if (yydebug) \ - YYFPRINTF Args; \ -} while (YYID (0)) - -# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ -do { \ - if (yydebug) \ - { \ - YYFPRINTF (stderr, "%s ", Title); \ - yy_symbol_print (stderr, \ - Type, Value, arg); \ - YYFPRINTF (stderr, "\n"); \ - } \ -} while (YYID (0)) - - -/*--------------------------------. -| Print this symbol on YYOUTPUT. | -`--------------------------------*/ - -/*ARGSUSED*/ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static void -yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, struct parse_args *arg) -#else -static void -yy_symbol_value_print (yyoutput, yytype, yyvaluep, arg) - FILE *yyoutput; - int yytype; - YYSTYPE const * const yyvaluep; - struct parse_args *arg; -#endif -{ - FILE *yyo = yyoutput; - YYUSE (yyo); - if (!yyvaluep) - return; - YYUSE (arg); -# ifdef YYPRINT - if (yytype < YYNTOKENS) - YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); -# else - YYUSE (yyoutput); -# endif - switch (yytype) - { - default: - break; - } -} - - -/*--------------------------------. -| Print this symbol on YYOUTPUT. | -`--------------------------------*/ - -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static void -yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, struct parse_args *arg) -#else -static void -yy_symbol_print (yyoutput, yytype, yyvaluep, arg) - FILE *yyoutput; - int yytype; - YYSTYPE const * const yyvaluep; - struct parse_args *arg; -#endif -{ - if (yytype < YYNTOKENS) - YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); - else - YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); - - yy_symbol_value_print (yyoutput, yytype, yyvaluep, arg); - YYFPRINTF (yyoutput, ")"); -} - -/*------------------------------------------------------------------. -| yy_stack_print -- Print the state stack from its BOTTOM up to its | -| TOP (included). | -`------------------------------------------------------------------*/ - -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static void -yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop) -#else -static void -yy_stack_print (yybottom, yytop) - yytype_int16 *yybottom; - yytype_int16 *yytop; -#endif -{ - YYFPRINTF (stderr, "Stack now"); - for (; yybottom <= yytop; yybottom++) - { - int yybot = *yybottom; - YYFPRINTF (stderr, " %d", yybot); - } - YYFPRINTF (stderr, "\n"); -} - -# define YY_STACK_PRINT(Bottom, Top) \ -do { \ - if (yydebug) \ - yy_stack_print ((Bottom), (Top)); \ -} while (YYID (0)) - - -/*------------------------------------------------. -| Report that the YYRULE is going to be reduced. | -`------------------------------------------------*/ - -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static void -yy_reduce_print (YYSTYPE *yyvsp, int yyrule, struct parse_args *arg) -#else -static void -yy_reduce_print (yyvsp, yyrule, arg) - YYSTYPE *yyvsp; - int yyrule; - struct parse_args *arg; -#endif -{ - int yynrhs = yyr2[yyrule]; - int yyi; - unsigned long int yylno = yyrline[yyrule]; - YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", - yyrule - 1, yylno); - /* The symbols being reduced. */ - for (yyi = 0; yyi < yynrhs; yyi++) - { - YYFPRINTF (stderr, " $%d = ", yyi + 1); - yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], - &(yyvsp[(yyi + 1) - (yynrhs)]) - , arg); - YYFPRINTF (stderr, "\n"); - } -} - -# define YY_REDUCE_PRINT(Rule) \ -do { \ - if (yydebug) \ - yy_reduce_print (yyvsp, Rule, arg); \ -} while (YYID (0)) - -/* Nonzero means print parse trace. It is left uninitialized so that - multiple parsers can coexist. */ -int yydebug; -#else /* !YYDEBUG */ -# define YYDPRINTF(Args) -# define YY_SYMBOL_PRINT(Title, Type, Value, Location) -# define YY_STACK_PRINT(Bottom, Top) -# define YY_REDUCE_PRINT(Rule) -#endif /* !YYDEBUG */ - - -/* YYINITDEPTH -- initial size of the parser's stacks. */ -#ifndef YYINITDEPTH -# define YYINITDEPTH 200 -#endif - -/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only - if the built-in stack extension method is used). - - Do not make this value too large; the results are undefined if - YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) - evaluated with infinite-precision integer arithmetic. */ - -#ifndef YYMAXDEPTH -# define YYMAXDEPTH 10000 -#endif - - -#if YYERROR_VERBOSE - -# ifndef yystrlen -# if defined __GLIBC__ && defined _STRING_H -# define yystrlen strlen -# else -/* Return the length of YYSTR. */ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static YYSIZE_T -yystrlen (const char *yystr) -#else -static YYSIZE_T -yystrlen (yystr) - const char *yystr; -#endif -{ - YYSIZE_T yylen; - for (yylen = 0; yystr[yylen]; yylen++) - continue; - return yylen; -} -# endif -# endif - -# ifndef yystpcpy -# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE -# define yystpcpy stpcpy -# else -/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in - YYDEST. */ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static char * -yystpcpy (char *yydest, const char *yysrc) -#else -static char * -yystpcpy (yydest, yysrc) - char *yydest; - const char *yysrc; -#endif -{ - char *yyd = yydest; - const char *yys = yysrc; - - while ((*yyd++ = *yys++) != '\0') - continue; - - return yyd - 1; -} -# endif -# endif - -# ifndef yytnamerr -/* Copy to YYRES the contents of YYSTR after stripping away unnecessary - quotes and backslashes, so that it's suitable for yyerror. The - heuristic is that double-quoting is unnecessary unless the string - contains an apostrophe, a comma, or backslash (other than - backslash-backslash). YYSTR is taken from yytname. If YYRES is - null, do not copy; instead, return the length of what the result - would have been. */ -static YYSIZE_T -yytnamerr (char *yyres, const char *yystr) -{ - if (*yystr == '"') - { - YYSIZE_T yyn = 0; - char const *yyp = yystr; - - for (;;) - switch (*++yyp) - { - case '\'': - case ',': - goto do_not_strip_quotes; - - case '\\': - if (*++yyp != '\\') - goto do_not_strip_quotes; - /* Fall through. */ - default: - if (yyres) - yyres[yyn] = *yyp; - yyn++; - break; - - case '"': - if (yyres) - yyres[yyn] = '\0'; - return yyn; - } - do_not_strip_quotes: ; - } - - if (! yyres) - return yystrlen (yystr); - - return yystpcpy (yyres, yystr) - yyres; -} -# endif - -/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message - about the unexpected token YYTOKEN for the state stack whose top is - YYSSP. - - Return 0 if *YYMSG was successfully written. Return 1 if *YYMSG is - not large enough to hold the message. In that case, also set - *YYMSG_ALLOC to the required number of bytes. Return 2 if the - required number of bytes is too large to store. */ -static int -yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, - yytype_int16 *yyssp, int yytoken) -{ - YYSIZE_T yysize0 = yytnamerr (YY_NULL, yytname[yytoken]); - YYSIZE_T yysize = yysize0; - enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; - /* Internationalized format string. */ - const char *yyformat = YY_NULL; - /* Arguments of yyformat. */ - char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; - /* Number of reported tokens (one for the "unexpected", one per - "expected"). */ - int yycount = 0; - - /* There are many possibilities here to consider: - - Assume YYFAIL is not used. It's too flawed to consider. See - - for details. YYERROR is fine as it does not invoke this - function. - - If this state is a consistent state with a default action, then - the only way this function was invoked is if the default action - is an error action. In that case, don't check for expected - tokens because there are none. - - The only way there can be no lookahead present (in yychar) is if - this state is a consistent state with a default action. Thus, - detecting the absence of a lookahead is sufficient to determine - that there is no unexpected or expected token to report. In that - case, just report a simple "syntax error". - - Don't assume there isn't a lookahead just because this state is a - consistent state with a default action. There might have been a - previous inconsistent state, consistent state with a non-default - action, or user semantic action that manipulated yychar. - - Of course, the expected token list depends on states to have - correct lookahead information, and it depends on the parser not - to perform extra reductions after fetching a lookahead from the - scanner and before detecting a syntax error. Thus, state merging - (from LALR or IELR) and default reductions corrupt the expected - token list. However, the list is correct for canonical LR with - one exception: it will still contain any token that will not be - accepted due to an error action in a later state. - */ - if (yytoken != YYEMPTY) - { - int yyn = yypact[*yyssp]; - yyarg[yycount++] = yytname[yytoken]; - if (!yypact_value_is_default (yyn)) - { - /* Start YYX at -YYN if negative to avoid negative indexes in - YYCHECK. In other words, skip the first -YYN actions for - this state because they are default actions. */ - int yyxbegin = yyn < 0 ? -yyn : 0; - /* Stay within bounds of both yycheck and yytname. */ - int yychecklim = YYLAST - yyn + 1; - int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; - int yyx; - - for (yyx = yyxbegin; yyx < yyxend; ++yyx) - if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR - && !yytable_value_is_error (yytable[yyx + yyn])) - { - if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) - { - yycount = 1; - yysize = yysize0; - break; - } - yyarg[yycount++] = yytname[yyx]; - { - YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULL, yytname[yyx]); - if (! (yysize <= yysize1 - && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) - return 2; - yysize = yysize1; - } - } - } - } - - switch (yycount) - { -# define YYCASE_(N, S) \ - case N: \ - yyformat = S; \ - break - YYCASE_(0, YY_("syntax error")); - YYCASE_(1, YY_("syntax error, unexpected %s")); - YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s")); - YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s")); - YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s")); - YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s")); -# undef YYCASE_ - } - - { - YYSIZE_T yysize1 = yysize + yystrlen (yyformat); - if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) - return 2; - yysize = yysize1; - } - - if (*yymsg_alloc < yysize) - { - *yymsg_alloc = 2 * yysize; - if (! (yysize <= *yymsg_alloc - && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM)) - *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM; - return 1; - } - - /* Avoid sprintf, as that infringes on the user's name space. - Don't have undefined behavior even if the translation - produced a string with the wrong number of "%s"s. */ - { - char *yyp = *yymsg; - int yyi = 0; - while ((*yyp = *yyformat) != '\0') - if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount) - { - yyp += yytnamerr (yyp, yyarg[yyi++]); - yyformat += 2; - } - else - { - yyp++; - yyformat++; - } - } - return 0; -} -#endif /* YYERROR_VERBOSE */ - -/*-----------------------------------------------. -| Release the memory associated to this symbol. | -`-----------------------------------------------*/ - -/*ARGSUSED*/ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static void -yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, struct parse_args *arg) -#else -static void -yydestruct (yymsg, yytype, yyvaluep, arg) - const char *yymsg; - int yytype; - YYSTYPE *yyvaluep; - struct parse_args *arg; -#endif -{ - YYUSE (yyvaluep); - YYUSE (arg); - - if (!yymsg) - yymsg = "Deleting"; - YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); - - switch (yytype) - { - - default: - break; - } -} - - - - -/*----------. -| yyparse. | -`----------*/ - -#ifdef YYPARSE_PARAM -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -int -yyparse (void *YYPARSE_PARAM) -#else -int -yyparse (YYPARSE_PARAM) - void *YYPARSE_PARAM; -#endif -#else /* ! YYPARSE_PARAM */ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -int -yyparse (struct parse_args *arg) -#else -int -yyparse (arg) - struct parse_args *arg; -#endif -#endif -{ -/* The lookahead symbol. */ -int yychar; - - -#if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__ -/* Suppress an incorrect diagnostic about yylval being uninitialized. */ -# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ - _Pragma ("GCC diagnostic push") \ - _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")\ - _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") -# define YY_IGNORE_MAYBE_UNINITIALIZED_END \ - _Pragma ("GCC diagnostic pop") -#else -/* Default value used for initialization, for pacifying older GCCs - or non-GCC compilers. */ -static YYSTYPE yyval_default; -# define YY_INITIAL_VALUE(Value) = Value -#endif -#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN -# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN -# define YY_IGNORE_MAYBE_UNINITIALIZED_END -#endif -#ifndef YY_INITIAL_VALUE -# define YY_INITIAL_VALUE(Value) /* Nothing. */ -#endif - -/* The semantic value of the lookahead symbol. */ -YYSTYPE yylval YY_INITIAL_VALUE(yyval_default); - - /* Number of syntax errors so far. */ - int yynerrs; - - int yystate; - /* Number of tokens to shift before error messages enabled. */ - int yyerrstatus; - - /* The stacks and their tools: - `yyss': related to states. - `yyvs': related to semantic values. - - Refer to the stacks through separate pointers, to allow yyoverflow - to reallocate them elsewhere. */ - - /* The state stack. */ - yytype_int16 yyssa[YYINITDEPTH]; - yytype_int16 *yyss; - yytype_int16 *yyssp; - - /* The semantic value stack. */ - YYSTYPE yyvsa[YYINITDEPTH]; - YYSTYPE *yyvs; - YYSTYPE *yyvsp; - - YYSIZE_T yystacksize; - - int yyn; - int yyresult; - /* Lookahead token as an internal (translated) token number. */ - int yytoken = 0; - /* The variables used to return semantic value and location from the - action routines. */ - YYSTYPE yyval; - -#if YYERROR_VERBOSE - /* Buffer for error messages, and its allocated size. */ - char yymsgbuf[128]; - char *yymsg = yymsgbuf; - YYSIZE_T yymsg_alloc = sizeof yymsgbuf; -#endif - -#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) - - /* The number of symbols on the RHS of the reduced rule. - Keep to zero when no symbol should be popped. */ - int yylen = 0; - - yyssp = yyss = yyssa; - yyvsp = yyvs = yyvsa; - yystacksize = YYINITDEPTH; - - YYDPRINTF ((stderr, "Starting parse\n")); - - yystate = 0; - yyerrstatus = 0; - yynerrs = 0; - yychar = YYEMPTY; /* Cause a token to be read. */ - goto yysetstate; - -/*------------------------------------------------------------. -| yynewstate -- Push a new state, which is found in yystate. | -`------------------------------------------------------------*/ - yynewstate: - /* In all cases, when you get here, the value and location stacks - have just been pushed. So pushing a state here evens the stacks. */ - yyssp++; - - yysetstate: - *yyssp = yystate; - - if (yyss + yystacksize - 1 <= yyssp) - { - /* Get the current used size of the three stacks, in elements. */ - YYSIZE_T yysize = yyssp - yyss + 1; - -#ifdef yyoverflow - { - /* Give user a chance to reallocate the stack. Use copies of - these so that the &'s don't force the real ones into - memory. */ - YYSTYPE *yyvs1 = yyvs; - yytype_int16 *yyss1 = yyss; - - /* Each stack pointer address is followed by the size of the - data in use in that stack, in bytes. This used to be a - conditional around just the two extra args, but that might - be undefined if yyoverflow is a macro. */ - yyoverflow (YY_("memory exhausted"), - &yyss1, yysize * sizeof (*yyssp), - &yyvs1, yysize * sizeof (*yyvsp), - &yystacksize); - - yyss = yyss1; - yyvs = yyvs1; - } -#else /* no yyoverflow */ -# ifndef YYSTACK_RELOCATE - goto yyexhaustedlab; -# else - /* Extend the stack our own way. */ - if (YYMAXDEPTH <= yystacksize) - goto yyexhaustedlab; - yystacksize *= 2; - if (YYMAXDEPTH < yystacksize) - yystacksize = YYMAXDEPTH; - - { - yytype_int16 *yyss1 = yyss; - union yyalloc *yyptr = - (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); - if (! yyptr) - goto yyexhaustedlab; - YYSTACK_RELOCATE (yyss_alloc, yyss); - YYSTACK_RELOCATE (yyvs_alloc, yyvs); -# undef YYSTACK_RELOCATE - if (yyss1 != yyssa) - YYSTACK_FREE (yyss1); - } -# endif -#endif /* no yyoverflow */ - - yyssp = yyss + yysize - 1; - yyvsp = yyvs + yysize - 1; - - YYDPRINTF ((stderr, "Stack size increased to %lu\n", - (unsigned long int) yystacksize)); - - if (yyss + yystacksize - 1 <= yyssp) - YYABORT; - } - - YYDPRINTF ((stderr, "Entering state %d\n", yystate)); - - if (yystate == YYFINAL) - YYACCEPT; - - goto yybackup; - -/*-----------. -| yybackup. | -`-----------*/ -yybackup: - - /* Do appropriate processing given the current state. Read a - lookahead token if we need one and don't already have one. */ - - /* First try to decide what to do without reference to lookahead token. */ - yyn = yypact[yystate]; - if (yypact_value_is_default (yyn)) - goto yydefault; - - /* Not known => get a lookahead token if don't already have one. */ - - /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ - if (yychar == YYEMPTY) - { - YYDPRINTF ((stderr, "Reading a token: ")); - yychar = YYLEX; - } - - if (yychar <= YYEOF) - { - yychar = yytoken = YYEOF; - YYDPRINTF ((stderr, "Now at end of input.\n")); - } - else - { - yytoken = YYTRANSLATE (yychar); - YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); - } - - /* If the proper action on seeing token YYTOKEN is to reduce or to - detect an error, take that action. */ - yyn += yytoken; - if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) - goto yydefault; - yyn = yytable[yyn]; - if (yyn <= 0) - { - if (yytable_value_is_error (yyn)) - goto yyerrlab; - yyn = -yyn; - goto yyreduce; - } - - /* Count tokens shifted since error; after three, turn off error - status. */ - if (yyerrstatus) - yyerrstatus--; - - /* Shift the lookahead token. */ - YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); - - /* Discard the shifted token. */ - yychar = YYEMPTY; - - yystate = yyn; - YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN - *++yyvsp = yylval; - YY_IGNORE_MAYBE_UNINITIALIZED_END - - goto yynewstate; - - -/*-----------------------------------------------------------. -| yydefault -- do the default action for the current state. | -`-----------------------------------------------------------*/ -yydefault: - yyn = yydefact[yystate]; - if (yyn == 0) - goto yyerrlab; - goto yyreduce; - - -/*-----------------------------. -| yyreduce -- Do a reduction. | -`-----------------------------*/ -yyreduce: - /* yyn is the number of a rule to reduce with. */ - yylen = yyr2[yyn]; - - /* If YYLEN is nonzero, implement the default value of the action: - `$$ = $1'. - - Otherwise, the following line sets YYVAL to garbage. - This behavior is undocumented and Bison - users should not rely upon it. Assigning to YYVAL - unconditionally makes the parser a bit smaller, and it avoids a - GCC warning that YYVAL may be used uninitialized. */ - yyval = yyvsp[1-yylen]; - - - YY_REDUCE_PRINT (yyn); - switch (yyn) - { - case 2: -/* Line 1792 of yacc.c */ -#line 153 "plural.y" - { - if ((yyvsp[(1) - (1)].exp) == NULL) - YYABORT; - arg->res = (yyvsp[(1) - (1)].exp); - } - break; - - case 3: -/* Line 1792 of yacc.c */ -#line 161 "plural.y" - { - (yyval.exp) = new_exp_3 (qmop, (yyvsp[(1) - (5)].exp), (yyvsp[(3) - (5)].exp), (yyvsp[(5) - (5)].exp)); - } - break; - - case 4: -/* Line 1792 of yacc.c */ -#line 165 "plural.y" - { - (yyval.exp) = new_exp_2 (lor, (yyvsp[(1) - (3)].exp), (yyvsp[(3) - (3)].exp)); - } - break; - - case 5: -/* Line 1792 of yacc.c */ -#line 169 "plural.y" - { - (yyval.exp) = new_exp_2 (land, (yyvsp[(1) - (3)].exp), (yyvsp[(3) - (3)].exp)); - } - break; - - case 6: -/* Line 1792 of yacc.c */ -#line 173 "plural.y" - { - (yyval.exp) = new_exp_2 ((yyvsp[(2) - (3)].op), (yyvsp[(1) - (3)].exp), (yyvsp[(3) - (3)].exp)); - } - break; - - case 7: -/* Line 1792 of yacc.c */ -#line 177 "plural.y" - { - (yyval.exp) = new_exp_2 ((yyvsp[(2) - (3)].op), (yyvsp[(1) - (3)].exp), (yyvsp[(3) - (3)].exp)); - } - break; - - case 8: -/* Line 1792 of yacc.c */ -#line 181 "plural.y" - { - (yyval.exp) = new_exp_2 ((yyvsp[(2) - (3)].op), (yyvsp[(1) - (3)].exp), (yyvsp[(3) - (3)].exp)); - } - break; - - case 9: -/* Line 1792 of yacc.c */ -#line 185 "plural.y" - { - (yyval.exp) = new_exp_2 ((yyvsp[(2) - (3)].op), (yyvsp[(1) - (3)].exp), (yyvsp[(3) - (3)].exp)); - } - break; - - case 10: -/* Line 1792 of yacc.c */ -#line 189 "plural.y" - { - (yyval.exp) = new_exp_1 (lnot, (yyvsp[(2) - (2)].exp)); - } - break; - - case 11: -/* Line 1792 of yacc.c */ -#line 193 "plural.y" - { - (yyval.exp) = new_exp_0 (var); - } - break; - - case 12: -/* Line 1792 of yacc.c */ -#line 197 "plural.y" - { - if (((yyval.exp) = new_exp_0 (num)) != NULL) - (yyval.exp)->val.num = (yyvsp[(1) - (1)].num); - } - break; - - case 13: -/* Line 1792 of yacc.c */ -#line 202 "plural.y" - { - (yyval.exp) = (yyvsp[(2) - (3)].exp); - } - break; - - -/* Line 1792 of yacc.c */ -#line 1604 "plural.c" - default: break; - } - /* User semantic actions sometimes alter yychar, and that requires - that yytoken be updated with the new translation. We take the - approach of translating immediately before every use of yytoken. - One alternative is translating here after every semantic action, - but that translation would be missed if the semantic action invokes - YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or - if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an - incorrect destructor might then be invoked immediately. In the - case of YYERROR or YYBACKUP, subsequent parser actions might lead - to an incorrect destructor call or verbose syntax error message - before the lookahead is translated. */ - YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); - - YYPOPSTACK (yylen); - yylen = 0; - YY_STACK_PRINT (yyss, yyssp); - - *++yyvsp = yyval; - - /* Now `shift' the result of the reduction. Determine what state - that goes to, based on the state we popped back to and the rule - number reduced by. */ - - yyn = yyr1[yyn]; - - yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; - if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) - yystate = yytable[yystate]; - else - yystate = yydefgoto[yyn - YYNTOKENS]; - - goto yynewstate; - - -/*------------------------------------. -| yyerrlab -- here on detecting error | -`------------------------------------*/ -yyerrlab: - /* Make sure we have latest lookahead translation. See comments at - user semantic actions for why this is necessary. */ - yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar); - - /* If not already recovering from an error, report this error. */ - if (!yyerrstatus) - { - ++yynerrs; -#if ! YYERROR_VERBOSE - yyerror (arg, YY_("syntax error")); -#else -# define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \ - yyssp, yytoken) - { - char const *yymsgp = YY_("syntax error"); - int yysyntax_error_status; - yysyntax_error_status = YYSYNTAX_ERROR; - if (yysyntax_error_status == 0) - yymsgp = yymsg; - else if (yysyntax_error_status == 1) - { - if (yymsg != yymsgbuf) - YYSTACK_FREE (yymsg); - yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc); - if (!yymsg) - { - yymsg = yymsgbuf; - yymsg_alloc = sizeof yymsgbuf; - yysyntax_error_status = 2; - } - else - { - yysyntax_error_status = YYSYNTAX_ERROR; - yymsgp = yymsg; - } - } - yyerror (arg, yymsgp); - if (yysyntax_error_status == 2) - goto yyexhaustedlab; - } -# undef YYSYNTAX_ERROR -#endif - } - - - - if (yyerrstatus == 3) - { - /* If just tried and failed to reuse lookahead token after an - error, discard it. */ - - if (yychar <= YYEOF) - { - /* Return failure if at end of input. */ - if (yychar == YYEOF) - YYABORT; - } - else - { - yydestruct ("Error: discarding", - yytoken, &yylval, arg); - yychar = YYEMPTY; - } - } - - /* Else will try to reuse lookahead token after shifting the error - token. */ - goto yyerrlab1; - - -/*---------------------------------------------------. -| yyerrorlab -- error raised explicitly by YYERROR. | -`---------------------------------------------------*/ -yyerrorlab: - - /* Pacify compilers like GCC when the user code never invokes - YYERROR and the label yyerrorlab therefore never appears in user - code. */ - if (/*CONSTCOND*/ 0) - goto yyerrorlab; - - /* Do not reclaim the symbols of the rule which action triggered - this YYERROR. */ - YYPOPSTACK (yylen); - yylen = 0; - YY_STACK_PRINT (yyss, yyssp); - yystate = *yyssp; - goto yyerrlab1; - - -/*-------------------------------------------------------------. -| yyerrlab1 -- common code for both syntax error and YYERROR. | -`-------------------------------------------------------------*/ -yyerrlab1: - yyerrstatus = 3; /* Each real token shifted decrements this. */ - - for (;;) - { - yyn = yypact[yystate]; - if (!yypact_value_is_default (yyn)) - { - yyn += YYTERROR; - if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) - { - yyn = yytable[yyn]; - if (0 < yyn) - break; - } - } - - /* Pop the current state because it cannot handle the error token. */ - if (yyssp == yyss) - YYABORT; - - - yydestruct ("Error: popping", - yystos[yystate], yyvsp, arg); - YYPOPSTACK (1); - yystate = *yyssp; - YY_STACK_PRINT (yyss, yyssp); - } - - YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN - *++yyvsp = yylval; - YY_IGNORE_MAYBE_UNINITIALIZED_END - - - /* Shift the error token. */ - YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); - - yystate = yyn; - goto yynewstate; - - -/*-------------------------------------. -| yyacceptlab -- YYACCEPT comes here. | -`-------------------------------------*/ -yyacceptlab: - yyresult = 0; - goto yyreturn; - -/*-----------------------------------. -| yyabortlab -- YYABORT comes here. | -`-----------------------------------*/ -yyabortlab: - yyresult = 1; - goto yyreturn; - -#if !defined yyoverflow || YYERROR_VERBOSE -/*-------------------------------------------------. -| yyexhaustedlab -- memory exhaustion comes here. | -`-------------------------------------------------*/ -yyexhaustedlab: - yyerror (arg, YY_("memory exhausted")); - yyresult = 2; - /* Fall through. */ -#endif - -yyreturn: - if (yychar != YYEMPTY) - { - /* Make sure we have latest lookahead translation. See comments at - user semantic actions for why this is necessary. */ - yytoken = YYTRANSLATE (yychar); - yydestruct ("Cleanup: discarding lookahead", - yytoken, &yylval, arg); - } - /* Do not reclaim the symbols of the rule which action triggered - this YYABORT or YYACCEPT. */ - YYPOPSTACK (yylen); - YY_STACK_PRINT (yyss, yyssp); - while (yyssp != yyss) - { - yydestruct ("Cleanup: popping", - yystos[*yyssp], yyvsp, arg); - YYPOPSTACK (1); - } -#ifndef yyoverflow - if (yyss != yyssa) - YYSTACK_FREE (yyss); -#endif -#if YYERROR_VERBOSE - if (yymsg != yymsgbuf) - YYSTACK_FREE (yymsg); -#endif - /* Make sure YYID is used. */ - return YYID (yyresult); -} - - -/* Line 2055 of yacc.c */ -#line 207 "plural.y" - - -void -FREE_EXPRESSION (struct expression *exp) -{ - if (exp == NULL) - return; - - /* Handle the recursive case. */ - switch (exp->nargs) - { - case 3: - FREE_EXPRESSION (exp->val.args[2]); - /* FALLTHROUGH */ - case 2: - FREE_EXPRESSION (exp->val.args[1]); - /* FALLTHROUGH */ - case 1: - FREE_EXPRESSION (exp->val.args[0]); - /* FALLTHROUGH */ - default: - break; - } - - free (exp); -} - - -static int -yylex (YYSTYPE *lval, struct parse_args *arg) -{ - const char *exp = arg->cp; - int result; - - while (1) - { - if (exp[0] == '\0') - { - arg->cp = exp; - return YYEOF; - } - - if (exp[0] != ' ' && exp[0] != '\t') - break; - - ++exp; - } - - result = *exp++; - switch (result) - { - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - { - unsigned long int n = result - '0'; - while (exp[0] >= '0' && exp[0] <= '9') - { - n *= 10; - n += exp[0] - '0'; - ++exp; - } - lval->num = n; - result = NUMBER; - } - break; - - case '=': - if (exp[0] == '=') - { - ++exp; - lval->op = equal; - result = EQUOP2; - } - else - result = YYERRCODE; - break; - - case '!': - if (exp[0] == '=') - { - ++exp; - lval->op = not_equal; - result = EQUOP2; - } - break; - - case '&': - case '|': - if (exp[0] == result) - ++exp; - else - result = YYERRCODE; - break; - - case '<': - if (exp[0] == '=') - { - ++exp; - lval->op = less_or_equal; - } - else - lval->op = less_than; - result = CMPOP2; - break; - - case '>': - if (exp[0] == '=') - { - ++exp; - lval->op = greater_or_equal; - } - else - lval->op = greater_than; - result = CMPOP2; - break; - - case '*': - lval->op = mult; - result = MULOP2; - break; - - case '/': - lval->op = divide; - result = MULOP2; - break; - - case '%': - lval->op = module; - result = MULOP2; - break; - - case '+': - lval->op = plus; - result = ADDOP2; - break; - - case '-': - lval->op = minus; - result = ADDOP2; - break; - - case 'n': - case '?': - case ':': - case '(': - case ')': - /* Nothing, just return the character. */ - break; - - case ';': - case '\n': - case '\0': - /* Be safe and let the user call this function again. */ - --exp; - result = YYEOF; - break; - - default: - result = YYERRCODE; -#if YYDEBUG != 0 - --exp; -#endif - break; - } - - arg->cp = exp; - - return result; -} - - -static void -yyerror (struct parse_args *arg, const char *str) -{ - /* Do nothing. We don't print error messages here. */ -} diff --git a/manual/install.texi b/manual/install.texi index f1fa28c937..ea559e4e72 100644 --- a/manual/install.texi +++ b/manual/install.texi @@ -509,6 +509,12 @@ function, which was introduced in version 3.1.2 of @code{gawk}. As of release time, @code{gawk} version 4.1.3 is the newest verified to work to build @theglibc{}. +@item +GNU @code{bison} 2.7 or later + +@code{bison} is used to generate the @code{yacc} parser code in the @file{intl} +subdirectory. + @item Perl 5 @@ -540,14 +546,6 @@ and if you change any of the message translation files you will need GNU @code{gettext} 0.10.36 or later @end itemize -@noindent -If you wish to regenerate the @code{yacc} parser code in the @file{intl} -subdirectory you will need - -@itemize @bullet -@item -GNU @code{bison} 2.7 or later -@end itemize @noindent You may also need these packages if you upgrade your source tree using -- cgit v1.2.3 From 07ed18d26a342741cb25a4739158c65ed9dd4d09 Mon Sep 17 00:00:00 2001 From: Rogerio Alves Date: Tue, 5 Dec 2017 14:24:14 -0200 Subject: Add elision tunables This patch adds several new tunables to control the behavior of elision on supported platforms[1]. Since elision now depends on tunables, we should always *compile* with elision enabled, and leave the code disabled, but available for runtime selection. This gives us *much* better compile-time testing of the existing code to avoid bit-rot[2]. Tested on ppc, ppc64, ppc64le, s390x and x86_64. [1] This part of the patch was initially proposed by Paul Murphy but was "staled" because the framework have changed since the patch was originally proposed: https://patchwork.sourceware.org/patch/10342/ [2] This part of the patch was inititally proposed as a RFC by Carlos O'Donnell. Make sense to me integrate this on the patch: https://sourceware.org/ml/libc-alpha/2017-05/msg00335.html * elf/dl-tunables.list: Add elision parameters. * manual/tunables.texi: Add entries about elision tunable. * sysdeps/unix/sysv/linux/powerpc/elision-conf.c: Add callback functions to dynamically enable/disable elision. Add multiple callbacks functions to set elision parameters. Deleted __libc_enable_secure check. * sysdeps/unix/sysv/linux/s390/elision-conf.c: Likewise. * sysdeps/unix/sysv/linux/x86/elision-conf.c: Likewise. * configure: Regenerated. * configure.ac: Option enable_lock_elision was deleted. * config.h.in: ENABLE_LOCK_ELISION flag was deleted. * config.make.in: Remove references to enable_lock_elision. * manual/install.texi: Elision configure option was removed. * INSTALL: Regenerated to remove enable_lock_elision. * nptl/Makefile: Disable elision so it can verify error case for destroying a mutex. * sysdeps/powerpc/nptl/elide.h: Cleanup ENABLE_LOCK_ELISION check. Deleted macros for the case when ENABLE_LOCK_ELISION was not defined. * sysdeps/s390/configure: Regenerated. * sysdeps/s390/configure.ac: Remove references to enable_lock_elision.. * nptl/tst-mutex8.c: Deleted all #ifndef ENABLE_LOCK_ELISION from the test. * sysdeps/powerpc/powerpc32/sysdep.h: Deleted all ENABLE_LOCK_ELISION checks. * sysdeps/powerpc/powerpc64/sysdep.h: Likewise. * sysdeps/powerpc/sysdep.h: Likewise. * sysdeps/s390/nptl/bits/pthreadtypes-arch.h: Likewise. * sysdeps/unix/sysv/linux/powerpc/force-elision.h: Likewise. * sysdeps/unix/sysv/linux/s390/elision-conf.h: Likewise. * sysdeps/unix/sysv/linux/s390/force-elision.h: Likewise. * sysdeps/unix/sysv/linux/s390/lowlevellock.h: Likewise. * sysdeps/unix/sysv/linux/s390/Makefile: Remove references to enable-lock-elision. Reviewed-by: Tulio Magno Quites Machado Filho --- ChangeLog | 39 +++++++++++++ INSTALL | 3 - config.h.in | 3 - config.make.in | 1 - configure | 17 ------ configure.ac | 10 ---- elf/dl-tunables.list | 34 +++++++++++ manual/install.texi | 3 - manual/tunables.texi | 69 +++++++++++++++++++++++ nptl/Makefile | 4 ++ nptl/tst-mutex8.c | 12 +--- sysdeps/powerpc/nptl/elide.h | 9 --- sysdeps/powerpc/powerpc32/sysdep.h | 2 +- sysdeps/powerpc/powerpc64/sysdep.h | 2 +- sysdeps/powerpc/sysdep.h | 4 +- sysdeps/s390/configure | 2 +- sysdeps/s390/configure.ac | 2 +- sysdeps/s390/nptl/bits/pthreadtypes-arch.h | 4 -- sysdeps/unix/sysv/linux/powerpc/elision-conf.c | 75 +++++++++++++++++++++++-- sysdeps/unix/sysv/linux/powerpc/force-elision.h | 2 - sysdeps/unix/sysv/linux/s390/Makefile | 2 - sysdeps/unix/sysv/linux/s390/elision-conf.c | 72 ++++++++++++++++++++++-- sysdeps/unix/sysv/linux/s390/elision-conf.h | 2 - sysdeps/unix/sysv/linux/s390/force-elision.h | 2 - sysdeps/unix/sysv/linux/s390/lowlevellock.h | 2 - sysdeps/unix/sysv/linux/x86/elision-conf.c | 74 +++++++++++++++++++++--- 26 files changed, 357 insertions(+), 94 deletions(-) (limited to 'configure.ac') diff --git a/ChangeLog b/ChangeLog index c2a78bbf40..98ae6ac712 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,42 @@ +2017-12-05 Rogerio A. Cardoso , + Paul E. Murphy , + Carlos O'Donnell + + * elf/dl-tunables.list: Add elision parameters. + * manual/tunables.texi: Add entries about elision tunable. + * sysdeps/unix/sysv/linux/powerpc/elision-conf.c: + Add callback functions to dynamically enable/disable elision. + Add multiple callbacks functions to set elision parameters. + Deleted __libc_enable_secure check. + * sysdeps/unix/sysv/linux/s390/elision-conf.c: Likewise. + * sysdeps/unix/sysv/linux/x86/elision-conf.c: Likewise. + * configure: Regenerated. + * configure.ac: Option enable_lock_elision was deleted. + * config.h.in: ENABLE_LOCK_ELISION flag was deleted. + * config.make.in: Remove references to enable_lock_elision. + * manual/install.texi: Elision configure option was removed. + * INSTALL: Regenerated to remove enable_lock_elision. + * nptl/Makefile: + Disable elision so it can verify error case for destroying a mutex. + * sysdeps/powerpc/nptl/elide.h: + Cleanup ENABLE_LOCK_ELISION check. + Deleted macros for the case when ENABLE_LOCK_ELISION was not defined. + * sysdeps/s390/configure: Regenerated. + * sysdeps/s390/configure.ac: Remove references to enable_lock_elision.. + * nptl/tst-mutex8.c: + Deleted all #ifndef ENABLE_LOCK_ELISION from the test. + * sysdeps/powerpc/powerpc32/sysdep.h: + Deleted all ENABLE_LOCK_ELISION checks. + * sysdeps/powerpc/powerpc64/sysdep.h: Likewise. + * sysdeps/powerpc/sysdep.h: Likewise. + * sysdeps/s390/nptl/bits/pthreadtypes-arch.h: Likewise. + * sysdeps/unix/sysv/linux/powerpc/force-elision.h: Likewise. + * sysdeps/unix/sysv/linux/s390/elision-conf.h: Likewise. + * sysdeps/unix/sysv/linux/s390/force-elision.h: Likewise. + * sysdeps/unix/sysv/linux/s390/lowlevellock.h: Likewise. + * sysdeps/unix/sysv/linux/s390/Makefile: Remove references to + enable-lock-elision. + 2017-12-05 Joseph Myers * stdlib/strtod.c: Include . diff --git a/INSTALL b/INSTALL index d1a34c2a90..e59c11dabd 100644 --- a/INSTALL +++ b/INSTALL @@ -116,9 +116,6 @@ will be used, and CFLAGS sets optimization options for the compiler. formats may change over time. Consult the 'timezone' subdirectory for more details. -'--enable-lock-elision=yes' - Enable lock elision for pthread mutexes by default. - '--enable-stack-protector' '--enable-stack-protector=strong' '--enable-stack-protector=all' diff --git a/config.h.in b/config.h.in index 8d76dadca2..3c91d597ff 100644 --- a/config.h.in +++ b/config.h.in @@ -131,9 +131,6 @@ /* Define if __stack_chk_guard canary should be randomized at program startup. */ #undef ENABLE_STACKGUARD_RANDOMIZE -/* Define if lock elision should be enabled by default. */ -#undef ENABLE_LOCK_ELISION - /* Package description. */ #undef PKGVERSION diff --git a/config.make.in b/config.make.in index bd84a5747d..9da77d1efa 100644 --- a/config.make.in +++ b/config.make.in @@ -99,7 +99,6 @@ build-nscd = @build_nscd@ use-nscd = @use_nscd@ build-hardcoded-path-in-tests= @hardcoded_path_in_tests@ build-pt-chown = @build_pt_chown@ -enable-lock-elision = @enable_lock_elision@ have-tunables = @have_tunables@ # Build tools. diff --git a/configure b/configure index caba102846..dd8b8c95e6 100755 --- a/configure +++ b/configure @@ -679,7 +679,6 @@ enable_werror all_warnings force_install bindnow -enable_lock_elision hardcoded_path_in_tests enable_timezone_tools use_default_link @@ -768,7 +767,6 @@ enable_profile enable_timezone_tools enable_hardcoded_path_in_tests enable_stackguard_randomization -enable_lock_elision enable_hidden_plt enable_bind_now enable_stack_protector @@ -1428,8 +1426,6 @@ Optional Features: --enable-stackguard-randomization initialize __stack_chk_guard canary with a random number at program start - --enable-lock-elision=yes/no - Enable lock elision for pthread mutexes by default --disable-hidden-plt do not hide internal function calls to avoid PLT --enable-bind-now disable lazy relocations in DSOs --enable-stack-protector=[yes|no|all|strong] @@ -3395,19 +3391,6 @@ if test "$enable_stackguard_randomize" = yes; then fi -# Check whether --enable-lock-elision was given. -if test "${enable_lock_elision+set}" = set; then : - enableval=$enable_lock_elision; enable_lock_elision=$enableval -else - enable_lock_elision=no -fi - - -if test "$enable_lock_elision" = yes ; then - $as_echo "#define ENABLE_LOCK_ELISION 1" >>confdefs.h - -fi - # Check whether --enable-hidden-plt was given. if test "${enable_hidden_plt+set}" = set; then : enableval=$enable_hidden_plt; hidden=$enableval diff --git a/configure.ac b/configure.ac index 9707ae4d8e..f85a50da53 100644 --- a/configure.ac +++ b/configure.ac @@ -199,16 +199,6 @@ if test "$enable_stackguard_randomize" = yes; then AC_DEFINE(ENABLE_STACKGUARD_RANDOMIZE) fi -AC_ARG_ENABLE([lock-elision], - AC_HELP_STRING([--enable-lock-elision[=yes/no]], - [Enable lock elision for pthread mutexes by default]), - [enable_lock_elision=$enableval], - [enable_lock_elision=no]) -AC_SUBST(enable_lock_elision) -if test "$enable_lock_elision" = yes ; then - AC_DEFINE(ENABLE_LOCK_ELISION) -fi - AC_ARG_ENABLE([hidden-plt], AC_HELP_STRING([--disable-hidden-plt], [do not hide internal function calls to avoid PLT]), diff --git a/elf/dl-tunables.list b/elf/dl-tunables.list index c188c6ad52..ec0fe20787 100644 --- a/elf/dl-tunables.list +++ b/elf/dl-tunables.list @@ -96,4 +96,38 @@ glibc { default: HWCAP_IMPORTANT } } + + elision { + enable { + type: INT_32 + minval: 0 + maxval: 1 + security_level: SXID_ERASE + } + skip_lock_busy { + type: INT_32 + default: 3 + security_level: SXID_ERASE + } + skip_lock_internal_abort { + type: INT_32 + default: 3 + security_level: SXID_ERASE + } + skip_lock_after_retries { + type: INT_32 + default: 3 + security_level: SXID_ERASE + } + tries { + type: INT_32 + default: 3 + security_level: SXID_ERASE + } + skip_trylock_internal_abort { + type: INT_32 + default: 3 + security_level: SXID_ERASE + } + } } diff --git a/manual/install.texi b/manual/install.texi index ea559e4e72..a3cb09dafc 100644 --- a/manual/install.texi +++ b/manual/install.texi @@ -145,9 +145,6 @@ Note that you need to make sure the external tools are kept in sync with the versions that @theglibc{} expects as the data formats may change over time. Consult the @file{timezone} subdirectory for more details. -@item --enable-lock-elision=yes -Enable lock elision for pthread mutexes by default. - @item --enable-stack-protector @itemx --enable-stack-protector=strong @itemx --enable-stack-protector=all diff --git a/manual/tunables.texi b/manual/tunables.texi index f503daef56..e851b95c59 100644 --- a/manual/tunables.texi +++ b/manual/tunables.texi @@ -31,6 +31,7 @@ their own namespace. @menu * Tunable names:: The structure of a tunable name * Memory Allocation Tunables:: Tunables in the memory allocation subsystem +* Elision Tunables:: Tunables in elision subsystem * Hardware Capability Tunables:: Tunables that modify the hardware capabilities seen by @theglibc{} @end menu @@ -212,6 +213,74 @@ pre-fill the per-thread cache with. The default, or when set to zero, is no limit. @end deftp +@node Elision Tunables +@section Elision Tunables +@cindex elision tunables +@cindex tunables, elision + +@deftp {Tunable namespace} glibc.elision +Contended locks are usually slow and can lead to performance and scalability +issues in multithread code. Lock elision will use memory transactions to under +certain conditions, to elide locks and improve performance. +Elision behavior can be modified by setting the following tunables in +the @code{elision} namespace: +@end deftp + +@deftp Tunable glibc.elision.enable +The @code{glibc.elision.enable} tunable enables lock elision if the feature is +supported by the hardware. If elision is not supported by the hardware this +tunable has no effect. + +Elision tunables are supported for 64-bit Intel, IBM POWER, and z System +architectures. +@end deftp + +@deftp Tunable glibc.elision.skip_lock_busy +The @code{glibc.elision.skip_lock_busy} tunable sets how many times to use a +non-transactional lock after a transactional failure has occurred because the +lock is already acquired. Expressed in number of lock acquisition attempts. + +The default value of this tunable is @samp{3}. +@end deftp + +@deftp Tunable glibc.elision.skip_lock_internal_abort +The @code{glibc.elision.skip_lock_internal_abort} tunable sets how many times +the thread should avoid using elision if a transaction aborted for any reason +other than a different thread's memory accesses. Expressed in number of lock +acquisition attempts. + +The default value of this tunable is @samp{3}. +@end deftp + +@deftp Tunable glibc.elision.skip_lock_after_retries +The @code{glibc.elision.skip_lock_after_retries} tunable sets how many times +to try to elide a lock with transactions, that only failed due to a different +thread's memory accesses, before falling back to regular lock. +Expressed in number of lock elision attempts. + +This tunable is supported only on IBM POWER, and z System architectures. + +The default value of this tunable is @samp{3}. +@end deftp + +@deftp Tunable glibc.elision.tries +The @code{glibc.elision.tries} sets how many times to retry elision if there is +chance for the transaction to finish execution e.g., it wasn't +aborted due to the lock being already acquired. If elision is not supported +by the hardware this tunable is set to @samp{0} to avoid retries. + +The default value of this tunable is @samp{3}. +@end deftp + +@deftp Tunable glibc.elision.skip_trylock_internal_abort +The @code{glibc.elision.skip_trylock_internal_abort} tunable sets how many +times the thread should avoid trying the lock if a transaction aborted due to +reasons other than a different thread's memory accesses. Expressed in number +of try lock attempts. + +The default value of this tunable is @samp{3}. +@end deftp + @node Hardware Capability Tunables @section Hardware Capability Tunables @cindex hardware capability tunables diff --git a/nptl/Makefile b/nptl/Makefile index b0215e12d7..11e6ecd88b 100644 --- a/nptl/Makefile +++ b/nptl/Makefile @@ -714,6 +714,10 @@ endif $(objpfx)tst-compat-forwarder: $(objpfx)tst-compat-forwarder-mod.so +# Disable elision for tst-mutex8 so it can verify error case for +# destroying a mutex. +tst-mutex8-ENV = GLIBC_TUNABLES=glibc.elision.enable=0 + # The tests here better do not run in parallel ifneq ($(filter %tests,$(MAKECMDGOALS)),) .NOTPARALLEL: diff --git a/nptl/tst-mutex8.c b/nptl/tst-mutex8.c index 1d288d243c..ef59db55de 100644 --- a/nptl/tst-mutex8.c +++ b/nptl/tst-mutex8.c @@ -127,9 +127,8 @@ check_type (const char *mas, pthread_mutexattr_t *ma) return 1; } - /* Elided mutexes don't fail destroy. If elision is not explicitly disabled - we don't know, so can also not check this. */ -#ifndef ENABLE_LOCK_ELISION + /* Elided mutexes don't fail destroy, but this test is run with + elision disabled so we can test them. */ e = pthread_mutex_destroy (m); if (e == 0) { @@ -142,7 +141,6 @@ check_type (const char *mas, pthread_mutexattr_t *ma) mas); return 1; } -#endif if (pthread_mutex_unlock (m) != 0) { @@ -157,7 +155,6 @@ check_type (const char *mas, pthread_mutexattr_t *ma) } /* Elided mutexes don't fail destroy. */ -#ifndef ENABLE_LOCK_ELISION e = pthread_mutex_destroy (m); if (e == 0) { @@ -171,7 +168,6 @@ mutex_destroy of self-trylocked mutex did not return EBUSY %s\n", mas); return 1; } -#endif if (pthread_mutex_unlock (m) != 0) { @@ -207,7 +203,6 @@ mutex_destroy of self-trylocked mutex did not return EBUSY %s\n", } /* Elided mutexes don't fail destroy. */ -#ifndef ENABLE_LOCK_ELISION e = pthread_mutex_destroy (m); if (e == 0) { @@ -220,7 +215,6 @@ mutex_destroy of self-trylocked mutex did not return EBUSY %s\n", mutex_destroy of condvar-used mutex did not return EBUSY for %s\n", mas); return 1; } -#endif done = true; if (pthread_cond_signal (&c) != 0) @@ -280,7 +274,6 @@ mutex_destroy of condvar-used mutex did not return EBUSY for %s\n", mas); } /* Elided mutexes don't fail destroy. */ -#ifndef ENABLE_LOCK_ELISION e = pthread_mutex_destroy (m); if (e == 0) { @@ -295,7 +288,6 @@ mutex_destroy of condvar-used mutex did not return EBUSY for %s\n", mas); mas); return 1; } -#endif if (pthread_cancel (th) != 0) { diff --git a/sysdeps/powerpc/nptl/elide.h b/sysdeps/powerpc/nptl/elide.h index 1c42814b71..06986ccbce 100644 --- a/sysdeps/powerpc/nptl/elide.h +++ b/sysdeps/powerpc/nptl/elide.h @@ -19,7 +19,6 @@ #ifndef ELIDE_PPC_H # define ELIDE_PPC_H -#ifdef ENABLE_LOCK_ELISION # include # include @@ -114,12 +113,4 @@ __elide_unlock (int is_lock_free) # define ELIDE_UNLOCK(is_lock_free) \ __elide_unlock (is_lock_free) -# else - -# define ELIDE_LOCK(adapt_count, is_lock_free) 0 -# define ELIDE_TRYLOCK(adapt_count, is_lock_free, write) 0 -# define ELIDE_UNLOCK(is_lock_free) 0 - -#endif /* ENABLE_LOCK_ELISION */ - #endif diff --git a/sysdeps/powerpc/powerpc32/sysdep.h b/sysdeps/powerpc/powerpc32/sysdep.h index 965ea43c94..1d2ff732ee 100644 --- a/sysdeps/powerpc/powerpc32/sysdep.h +++ b/sysdeps/powerpc/powerpc32/sysdep.h @@ -90,7 +90,7 @@ GOT_LABEL: ; \ cfi_endproc; \ ASM_SIZE_DIRECTIVE(name) -#if ! IS_IN(rtld) && defined (ENABLE_LOCK_ELISION) +#if ! IS_IN(rtld) # define ABORT_TRANSACTION \ cmpwi 2,0; \ beq 1f; \ diff --git a/sysdeps/powerpc/powerpc64/sysdep.h b/sysdeps/powerpc/powerpc64/sysdep.h index ab5f395cfd..bff184e374 100644 --- a/sysdeps/powerpc/powerpc64/sysdep.h +++ b/sysdeps/powerpc/powerpc64/sysdep.h @@ -263,7 +263,7 @@ LT_LABELSUFFIX(name,_name_end): ; \ TRACEBACK_MASK(name,mask); \ END_2(name) -#if !IS_IN(rtld) && defined (ENABLE_LOCK_ELISION) +#if !IS_IN(rtld) # define ABORT_TRANSACTION \ cmpdi 13,0; \ beq 1f; \ diff --git a/sysdeps/powerpc/sysdep.h b/sysdeps/powerpc/sysdep.h index f07b959eee..d1a9bd9b55 100644 --- a/sysdeps/powerpc/sysdep.h +++ b/sysdeps/powerpc/sysdep.h @@ -21,10 +21,8 @@ */ #define _SYSDEPS_SYSDEP_H 1 #include -#ifdef ENABLE_LOCK_ELISION #include #include -#endif #define PPC_FEATURE_970 (PPC_FEATURE_POWER4 + PPC_FEATURE_HAS_ALTIVEC) @@ -176,7 +174,7 @@ we abort transaction just before syscalls. [1] Documentation/powerpc/transactional_memory.txt [Syscalls] */ -#if !IS_IN(rtld) && defined (ENABLE_LOCK_ELISION) +#if !IS_IN(rtld) # define ABORT_TRANSACTION \ ({ \ if (THREAD_GET_TM_CAPABLE ()) \ diff --git a/sysdeps/s390/configure b/sysdeps/s390/configure index d4a4a3dcf8..74b415f2ab 100644 --- a/sysdeps/s390/configure +++ b/sysdeps/s390/configure @@ -35,7 +35,7 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_gcc_builtin_tbegin" >&5 $as_echo "$libc_cv_gcc_builtin_tbegin" >&6; } -if test "$enable_lock_elision" = yes && test "$libc_cv_gcc_builtin_tbegin" = no ; then +if test "$libc_cv_gcc_builtin_tbegin" = no ; then critic_missing="$critic_missing The used GCC has no support for __builtin_tbegin, which is needed for lock-elision on target S390." fi diff --git a/sysdeps/s390/configure.ac b/sysdeps/s390/configure.ac index 7d0b5ce46f..1cdb021282 100644 --- a/sysdeps/s390/configure.ac +++ b/sysdeps/s390/configure.ac @@ -26,7 +26,7 @@ else fi rm -f conftest* ]) -if test "$enable_lock_elision" = yes && test "$libc_cv_gcc_builtin_tbegin" = no ; then +if test "$libc_cv_gcc_builtin_tbegin" = no ; then critic_missing="$critic_missing The used GCC has no support for __builtin_tbegin, which is needed for lock-elision on target S390." fi diff --git a/sysdeps/s390/nptl/bits/pthreadtypes-arch.h b/sysdeps/s390/nptl/bits/pthreadtypes-arch.h index 1ae277367d..fd15931974 100644 --- a/sysdeps/s390/nptl/bits/pthreadtypes-arch.h +++ b/sysdeps/s390/nptl/bits/pthreadtypes-arch.h @@ -40,11 +40,7 @@ /* Definitions for internal mutex struct. */ #define __PTHREAD_COMPAT_PADDING_MID #define __PTHREAD_COMPAT_PADDING_END -#ifdef ENABLE_LOCK_ELISION #define __PTHREAD_MUTEX_LOCK_ELISION 1 -#else -#define __PTHREAD_MUTEX_LOCK_ELISION 0 -#endif #define __PTHREAD_MUTEX_NUSERS_AFTER_KIND (__WORDSIZE != 64) #define __PTHREAD_MUTEX_USE_UNION (__WORDSIZE != 64) diff --git a/sysdeps/unix/sysv/linux/powerpc/elision-conf.c b/sysdeps/unix/sysv/linux/powerpc/elision-conf.c index f631f0a035..06361e6b2f 100644 --- a/sysdeps/unix/sysv/linux/powerpc/elision-conf.c +++ b/sysdeps/unix/sysv/linux/powerpc/elision-conf.c @@ -22,6 +22,11 @@ #include #include +#if HAVE_TUNABLES +# define TUNABLE_NAMESPACE elision +#endif +#include + /* Reasonable initial tuning values, may be revised in the future. This is a conservative initial value. */ @@ -50,7 +55,52 @@ struct elision_config __elision_aconf = DEFAULT locks should be automatically use elision in pthread_mutex_lock(). Disabled for suid programs. Only used when elision is available. */ -int __pthread_force_elision attribute_hidden; +int __pthread_force_elision attribute_hidden = 0; + +#if HAVE_TUNABLES +static inline void +__always_inline +do_set_elision_enable (int32_t elision_enable) +{ + /* Enable elision if it's avaliable in hardware. It's not necessary to check + if __libc_enable_secure isn't enabled since elision_enable will be set + according to the default, which is disabled. */ + if (elision_enable == 1) + __pthread_force_elision = (GLRO (dl_hwcap2) + & PPC_FEATURE2_HAS_HTM) ? 1 : 0; +} + +/* The pthread->elision_enable tunable is 0 or 1 indicating that elision + should be disabled or enabled respectively. The feature will only be used + if it's supported by the hardware. */ + +void +TUNABLE_CALLBACK (set_elision_enable) (tunable_val_t *valp) +{ + int32_t elision_enable = (int32_t) valp->numval; + do_set_elision_enable (elision_enable); +} + +#define TUNABLE_CALLBACK_FNDECL(__name, __type) \ +static inline void \ +__always_inline \ +do_set_elision_ ## __name (__type value) \ +{ \ + __elision_aconf.__name = value; \ +} \ +void \ +TUNABLE_CALLBACK (set_elision_ ## __name) (tunable_val_t *valp) \ +{ \ + __type value = (__type) (valp)->numval; \ + do_set_elision_ ## __name (value); \ +} + +TUNABLE_CALLBACK_FNDECL (skip_lock_busy, int32_t); +TUNABLE_CALLBACK_FNDECL (skip_lock_internal_abort, int32_t); +TUNABLE_CALLBACK_FNDECL (skip_lock_out_of_tbegin_retries, int32_t); +TUNABLE_CALLBACK_FNDECL (try_tbegin, int32_t); +TUNABLE_CALLBACK_FNDECL (skip_trylock_internal_abort, int32_t); +#endif /* Initialize elision. */ @@ -59,13 +109,26 @@ elision_init (int argc __attribute__ ((unused)), char **argv __attribute__ ((unused)), char **environ) { -#ifdef ENABLE_LOCK_ELISION - int elision_available = (GLRO (dl_hwcap2) & PPC_FEATURE2_HAS_HTM) ? 1 : 0; - __pthread_force_elision = __libc_enable_secure ? 0 : elision_available; +#if HAVE_TUNABLES + /* Elision depends on tunables and must be explicitly turned on by setting + the appropriate tunable on a supported platform. */ + + TUNABLE_GET (enable, int32_t, + TUNABLE_CALLBACK (set_elision_enable)); + TUNABLE_GET (skip_lock_busy, int32_t, + TUNABLE_CALLBACK (set_elision_skip_lock_busy)); + TUNABLE_GET (skip_lock_internal_abort, int32_t, + TUNABLE_CALLBACK (set_elision_skip_lock_internal_abort)); + TUNABLE_GET (skip_lock_after_retries, int32_t, + TUNABLE_CALLBACK (set_elision_skip_lock_out_of_tbegin_retries)); + TUNABLE_GET (tries, int32_t, + TUNABLE_CALLBACK (set_elision_try_tbegin)); + TUNABLE_GET (skip_trylock_internal_abort, int32_t, + TUNABLE_CALLBACK (set_elision_skip_trylock_internal_abort)); #endif + if (!__pthread_force_elision) - /* Disable elision on rwlocks. */ - __elision_aconf.try_tbegin = 0; + __elision_aconf.try_tbegin = 0; /* Disable elision on rwlocks. */ } #ifdef SHARED diff --git a/sysdeps/unix/sysv/linux/powerpc/force-elision.h b/sysdeps/unix/sysv/linux/powerpc/force-elision.h index 318f7915c7..d1feeeb01e 100644 --- a/sysdeps/unix/sysv/linux/powerpc/force-elision.h +++ b/sysdeps/unix/sysv/linux/powerpc/force-elision.h @@ -16,7 +16,6 @@ License along with the GNU C Library; if not, see . */ -#ifdef ENABLE_LOCK_ELISION /* Automatically enable elision for existing user lock kinds. */ #define FORCE_ELISION(m, s) \ if (__pthread_force_elision \ @@ -25,4 +24,3 @@ mutex->__data.__kind |= PTHREAD_MUTEX_ELISION_NP; \ s; \ } -#endif diff --git a/sysdeps/unix/sysv/linux/s390/Makefile b/sysdeps/unix/sysv/linux/s390/Makefile index c5f544d139..77f38523b5 100644 --- a/sysdeps/unix/sysv/linux/s390/Makefile +++ b/sysdeps/unix/sysv/linux/s390/Makefile @@ -16,7 +16,6 @@ sysdep_routines += dl-vdso endif ifeq ($(subdir),nptl) -ifeq ($(enable-lock-elision),yes) libpthread-sysdep_routines += elision-lock elision-unlock elision-timed \ elision-trylock @@ -26,7 +25,6 @@ CFLAGS-elision-timed.c = $(elision-CFLAGS) CFLAGS-elision-trylock.c = $(elision-CFLAGS) CFLAGS-elision-unlock.c = $(elision-CFLAGS) endif -endif ifeq ($(subdir),misc) tests += tst-ptrace-singleblock diff --git a/sysdeps/unix/sysv/linux/s390/elision-conf.c b/sysdeps/unix/sysv/linux/s390/elision-conf.c index cc0fdef2aa..ab334cb79b 100644 --- a/sysdeps/unix/sysv/linux/s390/elision-conf.c +++ b/sysdeps/unix/sysv/linux/s390/elision-conf.c @@ -22,6 +22,11 @@ #include #include +#if HAVE_TUNABLES +# define TUNABLE_NAMESPACE elision +#endif +#include + /* Reasonable initial tuning values, may be revised in the future. This is a conservative initial value. */ @@ -53,6 +58,50 @@ struct elision_config __elision_aconf = int __pthread_force_elision attribute_hidden = 0; +#if HAVE_TUNABLES +static inline void +__always_inline +do_set_elision_enable (int32_t elision_enable) +{ + /* Enable elision if it's avaliable in hardware. It's not necessary to check + if __libc_enable_secure isn't enabled since elision_enable will be set + according to the default, which is disabled. */ + if (elision_enable == 1) + __pthread_force_elision = (GLRO (dl_hwcap) & HWCAP_S390_TE) ? 1 : 0; +} + +/* The pthread->elision_enable tunable is 0 or 1 indicating that elision + should be disabled or enabled respectively. The feature will only be used + if it's supported by the hardware. */ + +void +TUNABLE_CALLBACK (set_elision_enable) (tunable_val_t *valp) +{ + int32_t elision_enable = (int32_t) valp->numval; + do_set_elision_enable (elision_enable); +} + +#define TUNABLE_CALLBACK_FNDECL(__name, __type) \ +static inline void \ +__always_inline \ +do_set_elision_ ## __name (__type value) \ +{ \ + __elision_aconf.__name = value; \ +} \ +void \ +TUNABLE_CALLBACK (set_elision_ ## __name) (tunable_val_t *valp) \ +{ \ + __type value = (__type) (valp)->numval; \ + do_set_elision_ ## __name (value); \ +} + +TUNABLE_CALLBACK_FNDECL (skip_lock_busy, int32_t); +TUNABLE_CALLBACK_FNDECL (skip_lock_internal_abort, int32_t); +TUNABLE_CALLBACK_FNDECL (skip_lock_out_of_tbegin_retries, int32_t); +TUNABLE_CALLBACK_FNDECL (try_tbegin, int32_t); +TUNABLE_CALLBACK_FNDECL (skip_trylock_internal_abort, int32_t); +#endif + /* Initialize elison. */ static void @@ -60,11 +109,26 @@ elision_init (int argc __attribute__ ((unused)), char **argv __attribute__ ((unused)), char **environ) { - /* Set when the CPU and the kernel supports transactional execution. - When false elision is never attempted. */ - int elision_available = (GLRO (dl_hwcap) & HWCAP_S390_TE) ? 1 : 0; +#if HAVE_TUNABLES + /* Elision depends on tunables and must be explicitly turned on by setting + the appropriate tunable on a supported platform. */ + + TUNABLE_GET (enable, int32_t, + TUNABLE_CALLBACK (set_elision_enable)); + TUNABLE_GET (skip_lock_busy, int32_t, + TUNABLE_CALLBACK (set_elision_skip_lock_busy)); + TUNABLE_GET (skip_lock_internal_abort, int32_t, + TUNABLE_CALLBACK (set_elision_skip_lock_internal_abort)); + TUNABLE_GET (skip_lock_after_retries, int32_t, + TUNABLE_CALLBACK (set_elision_skip_lock_out_of_tbegin_retries)); + TUNABLE_GET (tries, int32_t, + TUNABLE_CALLBACK (set_elision_try_tbegin)); + TUNABLE_GET (skip_trylock_internal_abort, int32_t, + TUNABLE_CALLBACK (set_elision_skip_trylock_internal_abort)); +#endif - __pthread_force_elision = __libc_enable_secure ? 0 : elision_available; + if (!__pthread_force_elision) + __elision_aconf.try_tbegin = 0; /* Disable elision on rwlocks. */ } #ifdef SHARED diff --git a/sysdeps/unix/sysv/linux/s390/elision-conf.h b/sysdeps/unix/sysv/linux/s390/elision-conf.h index 3143f3b114..32f0ed3b8c 100644 --- a/sysdeps/unix/sysv/linux/s390/elision-conf.h +++ b/sysdeps/unix/sysv/linux/s390/elision-conf.h @@ -15,7 +15,6 @@ You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; if not, see . */ -#ifdef ENABLE_LOCK_ELISION #ifndef _ELISION_CONF_H #define _ELISION_CONF_H 1 @@ -41,4 +40,3 @@ extern int __pthread_force_elision attribute_hidden; #define HAVE_ELISION 1 #endif -#endif diff --git a/sysdeps/unix/sysv/linux/s390/force-elision.h b/sysdeps/unix/sysv/linux/s390/force-elision.h index 3ae3bcd566..8e1e33e1c5 100644 --- a/sysdeps/unix/sysv/linux/s390/force-elision.h +++ b/sysdeps/unix/sysv/linux/s390/force-elision.h @@ -16,7 +16,6 @@ License along with the GNU C Library; if not, see . */ -#ifdef ENABLE_LOCK_ELISION /* Automatically enable elision for existing user lock kinds. */ #define FORCE_ELISION(m, s) \ if (__pthread_force_elision \ @@ -25,4 +24,3 @@ mutex->__data.__kind |= PTHREAD_MUTEX_ELISION_NP; \ s; \ } -#endif diff --git a/sysdeps/unix/sysv/linux/s390/lowlevellock.h b/sysdeps/unix/sysv/linux/s390/lowlevellock.h index 604137f7f2..48f87a85f5 100644 --- a/sysdeps/unix/sysv/linux/s390/lowlevellock.h +++ b/sysdeps/unix/sysv/linux/s390/lowlevellock.h @@ -22,7 +22,6 @@ #include /* Transactional lock elision definitions. */ -# ifdef ENABLE_LOCK_ELISION extern int __lll_timedlock_elision (int *futex, short *adapt_count, const struct timespec *timeout, int private) attribute_hidden; @@ -45,6 +44,5 @@ extern int __lll_trylock_elision(int *futex, short *adapt_count) __lll_unlock_elision (&(futex), &(adapt_count), private) # define lll_trylock_elision(futex, adapt_count) \ __lll_trylock_elision(&(futex), &(adapt_count)) -# endif /* ENABLE_LOCK_ELISION */ #endif /* lowlevellock.h */ diff --git a/sysdeps/unix/sysv/linux/x86/elision-conf.c b/sysdeps/unix/sysv/linux/x86/elision-conf.c index 673b0005a7..7e9fbf9382 100644 --- a/sysdeps/unix/sysv/linux/x86/elision-conf.c +++ b/sysdeps/unix/sysv/linux/x86/elision-conf.c @@ -22,6 +22,11 @@ #include #include +#if HAVE_TUNABLES +# define TUNABLE_NAMESPACE elision +#endif +#include + /* Reasonable initial tuning values, may be revised in the future. This is a conservative initial value. */ @@ -48,21 +53,76 @@ struct elision_config __elision_aconf = pthread_mutex_lock(). Disabled for suid programs. Only used when elision is available. */ -int __pthread_force_elision attribute_hidden; +int __pthread_force_elision attribute_hidden = 0; + +#if HAVE_TUNABLES +static inline void +__always_inline +do_set_elision_enable (int32_t elision_enable) +{ + /* Enable elision if it's avaliable in hardware. It's not necessary to check + if __libc_enable_secure isn't enabled since elision_enable will be set + according to the default, which is disabled. */ + if (elision_enable == 1) + __pthread_force_elision = HAS_CPU_FEATURE (RTM) ? 1 : 0; +} + +/* The pthread->elision_enable tunable is 0 or 1 indicating that elision + should be disabled or enabled respectively. The feature will only be used + if it's supported by the hardware. */ -/* Initialize elison. */ +void +TUNABLE_CALLBACK (set_elision_enable) (tunable_val_t *valp) +{ + int32_t elision_enable = (int32_t) valp->numval; + do_set_elision_enable (elision_enable); +} + +#define TUNABLE_CALLBACK_FNDECL(__name, __type) \ +static inline void \ +__always_inline \ +do_set_elision_ ## __name (__type value) \ +{ \ + __elision_aconf.__name = value; \ +} \ +void \ +TUNABLE_CALLBACK (set_elision_ ## __name) (tunable_val_t *valp) \ +{ \ + __type value = (__type) (valp)->numval; \ + do_set_elision_ ## __name (value); \ +} + +TUNABLE_CALLBACK_FNDECL (skip_lock_busy, int32_t); +TUNABLE_CALLBACK_FNDECL (skip_lock_internal_abort, int32_t); +TUNABLE_CALLBACK_FNDECL (retry_try_xbegin, int32_t); +TUNABLE_CALLBACK_FNDECL (skip_trylock_internal_abort, int32_t); +#endif + +/* Initialize elision. */ static void elision_init (int argc __attribute__ ((unused)), char **argv __attribute__ ((unused)), char **environ) { - int elision_available = HAS_CPU_FEATURE (RTM); -#ifdef ENABLE_LOCK_ELISION - __pthread_force_elision = __libc_enable_secure ? 0 : elision_available; +#if HAVE_TUNABLES + /* Elision depends on tunables and must be explicitly turned on by setting + the appropriate tunable on a supported platform. */ + + TUNABLE_GET (enable, int32_t, + TUNABLE_CALLBACK (set_elision_enable)); + TUNABLE_GET (skip_lock_busy, int32_t, + TUNABLE_CALLBACK (set_elision_skip_lock_busy)); + TUNABLE_GET (skip_lock_internal_abort, int32_t, + TUNABLE_CALLBACK (set_elision_skip_lock_internal_abort)); + TUNABLE_GET (tries, int32_t, + TUNABLE_CALLBACK (set_elision_retry_try_xbegin)); + TUNABLE_GET (skip_trylock_internal_abort, int32_t, + TUNABLE_CALLBACK (set_elision_skip_trylock_internal_abort)); #endif - if (!elision_available) - __elision_aconf.retry_try_xbegin = 0; /* Disable elision on rwlocks */ + + if (!__pthread_force_elision) + __elision_aconf.retry_try_xbegin = 0; /* Disable elision on rwlocks. */ } #ifdef SHARED -- cgit v1.2.3 From 8df5d34720dd71e934545bade879e04697830757 Mon Sep 17 00:00:00 2001 From: Joseph Myers Date: Tue, 12 Dec 2017 13:56:47 +0000 Subject: Remove --with-fp / --without-fp. There is a configure option --without-fp that specifies that nofpu sysdeps directories should be used instead of fpu directories. For most glibc configurations, this option is of no use: either there is no valid nofpu variant of that configuration, or there are no fpu or nofpu sysdeps directories for that processor and so the option does nothing. For a few configurations, if you are using a soft-float compiler this option is required, and failing to use it generally results in compilation errors from inline asm using unavailable floating-point instructions. We're moving away from --with-cpu to configuring glibc based on how the compiler generates code, and it is natural to do so for --without-fp as well; in most cases the soft-float and hard-float ABIs are incompatible so you have no hope of building a working glibc with an inappropriately configured compiler or libgcc. This patch eliminates --without-fp, replacing it entirely by automatic configuration based on the compiler. Configurations for which this is relevant (coldfire / mips / powerpc32 / sh) define a variable with_fp_cond in their preconfigure fragments (under the same conditions under which those fragments do anything); this is a preprocessor conditional which the toplevel configure script then uses in a test to determine which sysdeps directories to use. The config.make with-fp variable remains. It's used only by powerpc (sysdeps/powerpc/powerpc32/Makefile) to add -mhard-float to various flags variables. For powerpc, -mcpu= options can imply use of soft-float. That could be an issue if you want to build for e.g. 476fp, but are using --with-cpu=476 because there isn't a 476fp sysdeps directory. If in future we eliminate --with-cpu and replace it entirely by testing the compiler, it would be natural at that point to eliminate that code as well (as the user should then just use a compiler defaulting to 476fp and the 476 sysdeps directory would be used automatically). Tested for x86_64, and tested with build-many-glibcs.py that installed shared libraries are unchanged by this patch. * configure.ac (--with-fp): Remove configure option. (with_fp_cond): New variable. (libc_cv_with_fp): New configure test. Use this variable instead of with_fp. * configure: Regenerated. * config.make.in (with-fp): Use @libc_cv_with_fp@. * manual/install.texi (Configuring and compiling): Remove --without-fp. * INSTALL: Regenerated. * sysdeps/m68k/preconfigure (with_fp_cond): Define for ColdFire. * sysdeps/mips/preconfigure (with_fp_cond): Define. * sysdeps/powerpc/preconfigure (with_fp_cond): Define for 32-bit. * sysdeps/sh/preconfigure (with_fp_cond): Define. * scripts/build-many-glibcs.py (Context.add_all_configs): Do not use --without-fp to configure glibc. --- ChangeLog | 18 ++++++++++++++++ INSTALL | 4 ---- NEWS | 5 +++++ config.make.in | 2 +- configure | 44 +++++++++++++++++++++++++++----------- configure.ac | 31 +++++++++++++++++++++------ manual/install.texi | 4 ---- scripts/build-many-glibcs.py | 51 +++++++++++++++----------------------------- sysdeps/m68k/preconfigure | 6 +++++- sysdeps/mips/preconfigure | 2 ++ sysdeps/powerpc/preconfigure | 1 + sysdeps/sh/preconfigure | 10 +++++++-- 12 files changed, 112 insertions(+), 66 deletions(-) (limited to 'configure.ac') diff --git a/ChangeLog b/ChangeLog index 90e47f7877..7a54848d30 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,21 @@ +2017-12-12 Joseph Myers + + * configure.ac (--with-fp): Remove configure option. + (with_fp_cond): New variable. + (libc_cv_with_fp): New configure test. Use this variable instead + of with_fp. + * configure: Regenerated. + * config.make.in (with-fp): Use @libc_cv_with_fp@. + * manual/install.texi (Configuring and compiling): Remove + --without-fp. + * INSTALL: Regenerated. + * sysdeps/m68k/preconfigure (with_fp_cond): Define for ColdFire. + * sysdeps/mips/preconfigure (with_fp_cond): Define. + * sysdeps/powerpc/preconfigure (with_fp_cond): Define for 32-bit. + * sysdeps/sh/preconfigure (with_fp_cond): Define. + * scripts/build-many-glibcs.py (Context.add_all_configs): Do not + use --without-fp to configure glibc. + 2017-12-12 Rical Jasan * manual/locale.texi (nl_langinfo): Fix a typo. diff --git a/INSTALL b/INSTALL index e59c11dabd..80306de35c 100644 --- a/INSTALL +++ b/INSTALL @@ -81,10 +81,6 @@ will be used, and CFLAGS sets optimization options for the compiler. library will still be usable, but functionality may be lost--for example, you can't build a shared libc with old binutils. -'--without-fp' - Use this option if your computer lacks hardware floating-point - support and your operating system does not emulate an FPU. - '--disable-shared' Don't build shared libraries even if it is possible. Not all systems support shared libraries; you need ELF support and diff --git a/NEWS b/NEWS index 25a2116cdd..c6d859ca75 100644 --- a/NEWS +++ b/NEWS @@ -76,6 +76,11 @@ Deprecated and removed features, and other changes affecting compatibility: glibc has been removed. The --enable-add-ons configure option is now ignored. +* The --without-fp configure option is now ignored. Whether hardware + floating-point instructions are used is now configured based on whether + the compiler used at configure time (without any options implied by a + --with-cpu= configure option) uses such instructions. + * The res_hnok, res_dnok, res_mailok and res_ownok functions now check that the specified string can be parsed as a domain name. diff --git a/config.make.in b/config.make.in index 9da77d1efa..04513dbb74 100644 --- a/config.make.in +++ b/config.make.in @@ -57,7 +57,7 @@ have-z-execstack = @libc_cv_z_execstack@ have-protected-data = @libc_cv_protected_data@ have-insert = @libc_cv_insert@ have-glob-dat-reloc = @libc_cv_has_glob_dat@ -with-fp = @with_fp@ +with-fp = @libc_cv_with_fp@ enable-timezone-tools = @enable_timezone_tools@ unwind-find-fde = @libc_cv_gcc_unwind_find_fde@ have-fpie = @libc_cv_fpie@ diff --git a/configure b/configure index dd8b8c95e6..4a85706862 100755 --- a/configure +++ b/configure @@ -666,6 +666,7 @@ multi_arch no_stack_protector stack_protector libc_cv_ssp +libc_cv_with_fp base_machine have_tunables build_pt_chown @@ -683,7 +684,6 @@ hardcoded_path_in_tests enable_timezone_tools use_default_link sysheaders -with_fp ac_ct_CXX CXXFLAGS CXX @@ -756,7 +756,6 @@ with_bugurl with_gd with_gd_include with_gd_lib -with_fp with_binutils with_selinux with_headers @@ -1467,7 +1466,6 @@ Optional Packages: --with-gd=DIR find libgd include dir and library with prefix DIR --with-gd-include=DIR find libgd include files in DIR --with-gd-lib=DIR find libgd library files in DIR - --with-fp if using floating-point hardware [default=yes] --with-binutils=PATH specify location of binutils (as and ld) --with-selinux if building with SELinux support --with-headers=PATH location of system headers to use (for example @@ -3294,15 +3292,6 @@ libgd-LDFLAGS = $libgd_ldflags" fi -# Check whether --with-fp was given. -if test "${with_fp+set}" = set; then : - withval=$with_fp; with_fp=$withval -else - with_fp=yes -fi - - - # Check whether --with-binutils was given. if test "${with_binutils+set}" = set; then : withval=$with_binutils; path_binutils=$withval @@ -3778,6 +3767,11 @@ fi # check below. libc_config_ok=no +# A preconfigure script for a system that may or may not use fpu +# sysdeps directories sets this to a preprocessor conditional for +# whether to use such directories. +with_fp_cond=1 + if frags=`ls -d $srcdir/sysdeps/*/preconfigure 2> /dev/null` then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sysdeps preconfigure fragments" >&5 @@ -3816,6 +3810,30 @@ fi test -n "$base_machine" || base_machine=$machine +# Determine whether to use fpu or nofpu sysdeps directories. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for use of fpu sysdeps directories" >&5 +$as_echo_n "checking for use of fpu sysdeps directories... " >&6; } +if ${libc_cv_with_fp+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat > conftest.c <&5 2>&5 ; then + libc_cv_with_fp=yes +fi +rm -f conftest* +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_with_fp" >&5 +$as_echo "$libc_cv_with_fp" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -fstack-protector" >&5 $as_echo_n "checking for -fstack-protector... " >&6; } if ${libc_cv_ssp+:} false; then : @@ -4085,7 +4103,7 @@ tail=$machine${submachine:+/$submachine} while m=`echo $tail | sed 's@^\(.*\)/\([^/]*\)$@& \1@'`; test -n "$m"; do set $m # Prepend the machine's FPU directory unless --without-fp. - if test "$with_fp" = yes; then + if test "$libc_cv_with_fp" = yes; then maybe_fpu=/fpu else maybe_fpu=/nofpu diff --git a/configure.ac b/configure.ac index f85a50da53..edf662715b 100644 --- a/configure.ac +++ b/configure.ac @@ -127,12 +127,6 @@ libgd-LDFLAGS = $libgd_ldflags" fi dnl Arguments to specify presence of other packages/features. -AC_ARG_WITH([fp], - AC_HELP_STRING([--with-fp], - [if using floating-point hardware @<:@default=yes@:>@]), - [with_fp=$withval], - [with_fp=yes]) -AC_SUBST(with_fp) AC_ARG_WITH([binutils], AC_HELP_STRING([--with-binutils=PATH], [specify location of binutils (as and ld)]), @@ -489,6 +483,11 @@ AC_ARG_WITH([cpu], # check below. libc_config_ok=no +# A preconfigure script for a system that may or may not use fpu +# sysdeps directories sets this to a preprocessor conditional for +# whether to use such directories. +with_fp_cond=1 + dnl Let sysdeps/*/preconfigure act here. LIBC_PRECONFIGURE([$srcdir], [for sysdeps]) @@ -517,6 +516,24 @@ fi test -n "$base_machine" || base_machine=$machine AC_SUBST(base_machine) +# Determine whether to use fpu or nofpu sysdeps directories. +AC_CACHE_CHECK([for use of fpu sysdeps directories], + libc_cv_with_fp, [dnl +cat > conftest.c <&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD ; then + libc_cv_with_fp=yes +fi +rm -f conftest*]) +AC_SUBST(libc_cv_with_fp) + AC_CACHE_CHECK(for -fstack-protector, libc_cv_ssp, [dnl LIBC_TRY_CC_OPTION([$CFLAGS $CPPFLAGS -Werror -fstack-protector], [libc_cv_ssp=yes], @@ -720,7 +737,7 @@ tail=$machine${submachine:+/$submachine} while m=`echo $tail | sed 's@^\(.*\)/\([^/]*\)$@& \1@'`; test -n "$m"; do set $m # Prepend the machine's FPU directory unless --without-fp. - if test "$with_fp" = yes; then + if test "$libc_cv_with_fp" = yes; then maybe_fpu=/fpu else maybe_fpu=/nofpu diff --git a/manual/install.texi b/manual/install.texi index a3cb09dafc..e81f1c50c3 100644 --- a/manual/install.texi +++ b/manual/install.texi @@ -106,10 +106,6 @@ problem and suppress these constructs, so that the library will still be usable, but functionality may be lost---for example, you can't build a shared libc with old binutils. -@item --without-fp -Use this option if your computer lacks hardware floating-point support -and your operating system does not emulate an FPU. - @c disable static doesn't work currently @c @item --disable-static @c Don't build static libraries. Static libraries aren't that useful these diff --git a/scripts/build-many-glibcs.py b/scripts/build-many-glibcs.py index 59972a0602..599e12e355 100755 --- a/scripts/build-many-glibcs.py +++ b/scripts/build-many-glibcs.py @@ -216,15 +216,12 @@ class Context(object): os_name='linux-gnu', variant='soft', gcc_cfg=['--with-mips-plt', '--with-float=soft'], - glibcs=[{'variant': 'n32-soft', - 'cfg': ['--without-fp']}, + glibcs=[{'variant': 'n32-soft'}, {'variant': 'soft', 'arch': 'mips', - 'ccopts': '-mabi=32', - 'cfg': ['--without-fp']}, + 'ccopts': '-mabi=32'}, {'variant': 'n64-soft', - 'ccopts': '-mabi=64', - 'cfg': ['--without-fp']}]) + 'ccopts': '-mabi=64'}]) self.add_config(arch='mips64', os_name='linux-gnu', variant='nan2008', @@ -244,15 +241,12 @@ class Context(object): '--with-arch-64=mips64r2', '--with-arch-32=mips32r2', '--with-float=soft'], - glibcs=[{'variant': 'n32-nan2008-soft', - 'cfg': ['--without-fp']}, + glibcs=[{'variant': 'n32-nan2008-soft'}, {'variant': 'nan2008-soft', 'arch': 'mips', - 'ccopts': '-mabi=32', - 'cfg': ['--without-fp']}, + 'ccopts': '-mabi=32'}, {'variant': 'n64-nan2008-soft', - 'ccopts': '-mabi=64', - 'cfg': ['--without-fp']}]) + 'ccopts': '-mabi=64'}]) self.add_config(arch='mips64el', os_name='linux-gnu', gcc_cfg=['--with-mips-plt'], @@ -265,15 +259,12 @@ class Context(object): os_name='linux-gnu', variant='soft', gcc_cfg=['--with-mips-plt', '--with-float=soft'], - glibcs=[{'variant': 'n32-soft', - 'cfg': ['--without-fp']}, + glibcs=[{'variant': 'n32-soft'}, {'variant': 'soft', 'arch': 'mipsel', - 'ccopts': '-mabi=32', - 'cfg': ['--without-fp']}, + 'ccopts': '-mabi=32'}, {'variant': 'n64-soft', - 'ccopts': '-mabi=64', - 'cfg': ['--without-fp']}]) + 'ccopts': '-mabi=64'}]) self.add_config(arch='mips64el', os_name='linux-gnu', variant='nan2008', @@ -293,15 +284,12 @@ class Context(object): '--with-arch-64=mips64r2', '--with-arch-32=mips32r2', '--with-float=soft'], - glibcs=[{'variant': 'n32-nan2008-soft', - 'cfg': ['--without-fp']}, + glibcs=[{'variant': 'n32-nan2008-soft'}, {'variant': 'nan2008-soft', 'arch': 'mipsel', - 'ccopts': '-mabi=32', - 'cfg': ['--without-fp']}, + 'ccopts': '-mabi=32'}, {'variant': 'n64-nan2008-soft', - 'ccopts': '-mabi=64', - 'cfg': ['--without-fp']}]) + 'ccopts': '-mabi=64'}]) self.add_config(arch='nios2', os_name='linux-gnu') self.add_config(arch='powerpc', @@ -314,8 +302,7 @@ class Context(object): os_name='linux-gnu', variant='soft', gcc_cfg=['--disable-multilib', '--with-float=soft', - '--enable-secureplt'], - glibcs=[{'variant': 'soft', 'cfg': ['--without-fp']}]) + '--enable-secureplt']) self.add_config(arch='powerpc64', os_name='linux-gnu', gcc_cfg=['--disable-multilib', '--enable-secureplt']) @@ -325,13 +312,11 @@ class Context(object): self.add_config(arch='powerpc', os_name='linux-gnuspe', gcc_cfg=['--disable-multilib', '--enable-secureplt', - '--enable-e500-double'], - glibcs=[{'cfg': ['--without-fp']}]) + '--enable-e500-double']) self.add_config(arch='powerpc', os_name='linux-gnuspe', variant='e500v1', - gcc_cfg=['--disable-multilib', '--enable-secureplt'], - glibcs=[{'variant': 'e500v1', 'cfg': ['--without-fp']}]) + gcc_cfg=['--disable-multilib', '--enable-secureplt']) self.add_config(arch='s390x', os_name='linux-gnu', glibcs=[{}, @@ -347,13 +332,11 @@ class Context(object): self.add_config(arch='sh4', os_name='linux-gnu', variant='soft', - gcc_cfg=['--without-fp'], - glibcs=[{'variant': 'soft', 'cfg': ['--without-fp']}]) + gcc_cfg=['--without-fp']) self.add_config(arch='sh4eb', os_name='linux-gnu', variant='soft', - gcc_cfg=['--without-fp'], - glibcs=[{'variant': 'soft', 'cfg': ['--without-fp']}]) + gcc_cfg=['--without-fp']) self.add_config(arch='sparc64', os_name='linux-gnu', glibcs=[{}, diff --git a/sysdeps/m68k/preconfigure b/sysdeps/m68k/preconfigure index 94fc1aabc2..1028dac080 100644 --- a/sysdeps/m68k/preconfigure +++ b/sysdeps/m68k/preconfigure @@ -13,5 +13,9 @@ m68k) variant=`(echo "#ifdef __mcoldfire__" echo >&2 "Cannot determine m68k processor variant" exit 1 fi - base_machine=m68k machine=m68k/$variant ;; + base_machine=m68k machine=m68k/$variant + if test "$variant" = "coldfire"; then + with_fp_cond="defined __mcffpu__" + fi + ;; esac diff --git a/sysdeps/mips/preconfigure b/sysdeps/mips/preconfigure index c118592b27..48fc32ed5b 100644 --- a/sysdeps/mips/preconfigure +++ b/sysdeps/mips/preconfigure @@ -25,5 +25,7 @@ mips*) if test "$abiflag" != "_ABIO32" -a "$mips16flag" = "1"; then as_fn_error $? "MIPS16 is only supported with the o32 ABI." "$LINENO" 5 fi + + with_fp_cond="defined __mips_hard_float" ;; esac diff --git a/sysdeps/powerpc/preconfigure b/sysdeps/powerpc/preconfigure index 7de2eafd52..0030bfd0c0 100644 --- a/sysdeps/powerpc/preconfigure +++ b/sysdeps/powerpc/preconfigure @@ -16,5 +16,6 @@ powerpc*) base_machine=powerpc machine=powerpc/powerpc32 fi rm -f conftest.i + with_fp_cond="!defined __NO_FPRS__" ;; esac diff --git a/sysdeps/sh/preconfigure b/sysdeps/sh/preconfigure index c1f6537797..16e29273df 100644 --- a/sysdeps/sh/preconfigure +++ b/sysdeps/sh/preconfigure @@ -1,6 +1,12 @@ # preconfigure fragment for sh. case "$machine" in -sh3*) base_machine=sh machine=sh/sh3 ;; -sh4*) base_machine=sh machine=sh/sh4 ;; +sh3*) base_machine=sh + machine=sh/sh3 + with_fp_cond="defined __SH_FPU_ANY__" + ;; +sh4*) base_machine=sh + machine=sh/sh4 + with_fp_cond="defined __SH_FPU_ANY__" + ;; esac -- cgit v1.2.3 From 9d7a3741c9e59eba87fb3ca6b9f979befce07826 Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Fri, 15 Dec 2017 16:59:33 -0800 Subject: Add --enable-static-pie configure option to build static PIE [BZ #19574] Static PIE extends address space layout randomization to static executables. It provides additional security hardening benefits at the cost of some memory and performance. Dynamic linker, ld.so, is a standalone program which can be loaded at any address. This patch adds a configure option, --enable-static-pie, to embed the part of ld.so in static executable to create static position independent executable (static PIE). A static PIE is similar to static executable, but can be loaded at any address without help from a dynamic linker. When --enable-static-pie is used to configure glibc, libc.a is built as PIE and all static executables, including tests, are built as static PIE. The resulting libc.a can be used together with GCC 8 or above to build static PIE with the compiler option, -static-pie. But GCC 8 isn't required to build glibc with --enable-static-pie. Only GCC with PIE support is needed. When an older GCC is used to build glibc with --enable-static-pie, proper input files are passed to linker to create static executables as static PIE, together with "-z text" to prevent dynamic relocations in read-only segments, which are not allowed in static PIE. The following changes are made for static PIE: 1. Add a new function, _dl_relocate_static_pie, to: a. Get the run-time load address. b. Read the dynamic section. c. Perform dynamic relocations. Dynamic linker also performs these steps. But static PIE doesn't load any shared objects. 2. Call _dl_relocate_static_pie at entrance of LIBC_START_MAIN in libc.a. crt1.o, which is used to create dynamic and non-PIE static executables, is updated to include a dummy _dl_relocate_static_pie. rcrt1.o is added to create static PIE, which will link in the real _dl_relocate_static_pie. grcrt1.o is also added to create static PIE with -pg. GCC 8 has been updated to support rcrt1.o and grcrt1.o for static PIE. Static PIE can work on all architectures which support PIE, provided: 1. Target must support accessing of local functions without dynamic relocations, which is needed in start.S to call __libc_start_main with function addresses of __libc_csu_init, __libc_csu_fini and main. All functions in static PIE are local functions. If PIE start.S can't reach main () defined in a shared object, the code sequence: pass address of local_main to __libc_start_main ... local_main: tail call to main via PLT can be used. 2. start.S is updated to check PIC instead SHARED for PIC code path and avoid dynamic relocation, when PIC is defined and SHARED isn't defined, to support static PIE. 3. All assembly codes are updated check PIC instead SHARED for PIC code path to avoid dynamic relocations in read-only sections. 4. All assembly codes are updated check SHARED instead PIC for static symbol name. 5. elf_machine_load_address in dl-machine.h are updated to support static PIE. 6. __brk works without TLS nor dynamic relocations in read-only section so that it can be used by __libc_setup_tls to initializes TLS in static PIE. NB: When glibc is built with GCC defaulted to PIE, libc.a is compiled with -fPIE, regardless if --enable-static-pie is used to configure glibc. When glibc is configured with --enable-static-pie, libc.a is compiled with -fPIE, regardless whether GCC defaults to PIE or not. The same libc.a can be used to build both static executable and static PIE. There is no need for separate PIE copy of libc.a. On x86-64, the normal static sln: text data bss dec hex filename 625425 8284 5456 639165 9c0bd elf/sln the static PIE sln: text data bss dec hex filename 657626 20636 5392 683654 a6e86 elf/sln The code size is increased by 5% and the binary size is increased by 7%. Linker requirements to build glibc with --enable-static-pie: 1. Linker supports --no-dynamic-linker to remove PT_INTERP segment from static PIE. 2. Linker can create working static PIE. The x86-64 linker needs the fix for https://sourceware.org/bugzilla/show_bug.cgi?id=21782 The i386 linker needs to be able to convert "movl main@GOT(%ebx), %eax" to "leal main@GOTOFF(%ebx), %eax" if main is defined locally. Binutils 2.29 or above are OK for i686 and x86-64. But linker status for other targets need to be verified. 3. Linker should resolve undefined weak symbols to 0 in static PIE: https://sourceware.org/bugzilla/show_bug.cgi?id=22269 4. Many ELF backend linkers incorrectly check bfd_link_pic for TLS relocations, which should check bfd_link_executable instead: https://sourceware.org/bugzilla/show_bug.cgi?id=22263 Tested on aarch64, i686 and x86-64. Using GCC 7 and binutils master branch, build-many-glibcs.py with --enable-static-pie with all patches for static PIE applied have the following build successes: PASS: glibcs-aarch64_be-linux-gnu build PASS: glibcs-aarch64-linux-gnu build PASS: glibcs-armeb-linux-gnueabi-be8 build PASS: glibcs-armeb-linux-gnueabi build PASS: glibcs-armeb-linux-gnueabihf-be8 build PASS: glibcs-armeb-linux-gnueabihf build PASS: glibcs-arm-linux-gnueabi build PASS: glibcs-arm-linux-gnueabihf build PASS: glibcs-arm-linux-gnueabihf-v7a build PASS: glibcs-arm-linux-gnueabihf-v7a-disable-multi-arch build PASS: glibcs-m68k-linux-gnu build PASS: glibcs-microblazeel-linux-gnu build PASS: glibcs-microblaze-linux-gnu build PASS: glibcs-mips64el-linux-gnu-n32 build PASS: glibcs-mips64el-linux-gnu-n32-nan2008 build PASS: glibcs-mips64el-linux-gnu-n32-nan2008-soft build PASS: glibcs-mips64el-linux-gnu-n32-soft build PASS: glibcs-mips64el-linux-gnu-n64 build PASS: glibcs-mips64el-linux-gnu-n64-nan2008 build PASS: glibcs-mips64el-linux-gnu-n64-nan2008-soft build PASS: glibcs-mips64el-linux-gnu-n64-soft build PASS: glibcs-mips64-linux-gnu-n32 build PASS: glibcs-mips64-linux-gnu-n32-nan2008 build PASS: glibcs-mips64-linux-gnu-n32-nan2008-soft build PASS: glibcs-mips64-linux-gnu-n32-soft build PASS: glibcs-mips64-linux-gnu-n64 build PASS: glibcs-mips64-linux-gnu-n64-nan2008 build PASS: glibcs-mips64-linux-gnu-n64-nan2008-soft build PASS: glibcs-mips64-linux-gnu-n64-soft build PASS: glibcs-mipsel-linux-gnu build PASS: glibcs-mipsel-linux-gnu-nan2008 build PASS: glibcs-mipsel-linux-gnu-nan2008-soft build PASS: glibcs-mipsel-linux-gnu-soft build PASS: glibcs-mips-linux-gnu build PASS: glibcs-mips-linux-gnu-nan2008 build PASS: glibcs-mips-linux-gnu-nan2008-soft build PASS: glibcs-mips-linux-gnu-soft build PASS: glibcs-nios2-linux-gnu build PASS: glibcs-powerpc64le-linux-gnu build PASS: glibcs-powerpc64-linux-gnu build PASS: glibcs-tilegxbe-linux-gnu-32 build PASS: glibcs-tilegxbe-linux-gnu build PASS: glibcs-tilegx-linux-gnu-32 build PASS: glibcs-tilegx-linux-gnu build PASS: glibcs-tilepro-linux-gnu build and the following build failures: FAIL: glibcs-alpha-linux-gnu build elf/sln is failed to link due to: assertion fail bfd/elf64-alpha.c:4125 This is caused by linker bug and/or non-PIC code in PIE libc.a. FAIL: glibcs-hppa-linux-gnu build elf/sln is failed to link due to: collect2: fatal error: ld terminated with signal 11 [Segmentation fault] https://sourceware.org/bugzilla/show_bug.cgi?id=22537 FAIL: glibcs-ia64-linux-gnu build elf/sln is failed to link due to: collect2: fatal error: ld terminated with signal 11 [Segmentation fault] FAIL: glibcs-powerpc-linux-gnu build FAIL: glibcs-powerpc-linux-gnu-soft build FAIL: glibcs-powerpc-linux-gnuspe build FAIL: glibcs-powerpc-linux-gnuspe-e500v1 build elf/sln is failed to link due to: ld: read-only segment has dynamic relocations. This is caused by linker bug and/or non-PIC code in PIE libc.a. See: https://sourceware.org/bugzilla/show_bug.cgi?id=22264 FAIL: glibcs-powerpc-linux-gnu-power4 build elf/sln is failed to link due to: findlocale.c:96:(.text+0x22c): @local call to ifunc memchr This is caused by linker bug and/or non-PIC code in PIE libc.a. FAIL: glibcs-s390-linux-gnu build elf/sln is failed to link due to: collect2: fatal error: ld terminated with signal 11 [Segmentation fault], core dumped assertion fail bfd/elflink.c:14299 This is caused by linker bug and/or non-PIC code in PIE libc.a. FAIL: glibcs-sh3eb-linux-gnu build FAIL: glibcs-sh3-linux-gnu build FAIL: glibcs-sh4eb-linux-gnu build FAIL: glibcs-sh4eb-linux-gnu-soft build FAIL: glibcs-sh4-linux-gnu build FAIL: glibcs-sh4-linux-gnu-soft build elf/sln is failed to link due to: ld: read-only segment has dynamic relocations. This is caused by linker bug and/or non-PIC code in PIE libc.a. See: https://sourceware.org/bugzilla/show_bug.cgi?id=22263 Also TLS code sequence in SH assembly syscalls in glibc doesn't match TLS code sequence expected by ld: https://sourceware.org/bugzilla/show_bug.cgi?id=22270 FAIL: glibcs-sparc64-linux-gnu build FAIL: glibcs-sparcv9-linux-gnu build FAIL: glibcs-tilegxbe-linux-gnu build FAIL: glibcs-tilegxbe-linux-gnu-32 build FAIL: glibcs-tilegx-linux-gnu build FAIL: glibcs-tilegx-linux-gnu-32 build FAIL: glibcs-tilepro-linux-gnu build elf/sln is failed to link due to: ld: read-only segment has dynamic relocations. This is caused by linker bug and/or non-PIC code in PIE libc.a. See: https://sourceware.org/bugzilla/show_bug.cgi?id=22263 [BZ #19574] * INSTALL: Regenerated. * Makeconfig (real-static-start-installed-name): New. (pic-default): Updated for --enable-static-pie. (pie-default): New for --enable-static-pie. (default-pie-ldflag): Likewise. (+link-static-before-libc): Replace $(DEFAULT-LDFLAGS-$(@F)) with $(if $($(@F)-no-pie),$(no-pie-ldflag),$(default-pie-ldflag)). Replace $(static-start-installed-name) with $(real-static-start-installed-name). (+prectorT): Updated for --enable-static-pie. (+postctorT): Likewise. (CFLAGS-.o): Add $(pie-default). (CFLAGS-.op): Likewise. * NEWS: Mention --enable-static-pie. * config.h.in (ENABLE_STATIC_PIE): New. * configure.ac (--enable-static-pie): New configure option. (have-no-dynamic-linker): New LIBC_CONFIG_VAR. (have-static-pie): Likewise. Enable static PIE if linker supports --no-dynamic-linker. (ENABLE_STATIC_PIE): New AC_DEFINE. (enable-static-pie): New LIBC_CONFIG_VAR. * configure: Regenerated. * csu/Makefile (omit-deps): Add r$(start-installed-name) and gr$(start-installed-name) for --enable-static-pie. (extra-objs): Likewise. (install-lib): Likewise. (extra-objs): Add static-reloc.o and static-reloc.os ($(objpfx)$(start-installed-name)): Also depend on $(objpfx)static-reloc.o. ($(objpfx)r$(start-installed-name)): New. ($(objpfx)g$(start-installed-name)): Also depend on $(objpfx)static-reloc.os. ($(objpfx)gr$(start-installed-name)): New. * csu/libc-start.c (LIBC_START_MAIN): Call _dl_relocate_static_pie in libc.a. * csu/libc-tls.c (__libc_setup_tls): Add main_map->l_addr to initimage. * csu/static-reloc.c: New file. * elf/Makefile (routines): Add dl-reloc-static-pie. (elide-routines.os): Likewise. (DEFAULT-LDFLAGS-tst-tls1-static-non-pie): Removed. (tst-tls1-static-non-pie-no-pie): New. * elf/dl-reloc-static-pie.c: New file. * elf/dl-support.c (_dl_get_dl_main_map): New function. * elf/dynamic-link.h (ELF_DURING_STARTUP): Also check STATIC_PIE_BOOTSTRAP. * elf/get-dynamic-info.h (elf_get_dynamic_info): Likewise. * gmon/Makefile (tests): Add tst-gmon-static-pie. (tests-static): Likewise. (DEFAULT-LDFLAGS-tst-gmon-static): Removed. (tst-gmon-static-no-pie): New. (CFLAGS-tst-gmon-static-pie.c): Likewise. (CRT-tst-gmon-static-pie): Likewise. (tst-gmon-static-pie-ENV): Likewise. (tests-special): Likewise. ($(objpfx)tst-gmon-static-pie.out): Likewise. (clean-tst-gmon-static-pie-data): Likewise. ($(objpfx)tst-gmon-static-pie-gprof.out): Likewise. * gmon/tst-gmon-static-pie.c: New file. * manual/install.texi: Document --enable-static-pie. * sysdeps/generic/ldsodefs.h (_dl_relocate_static_pie): New. (_dl_get_dl_main_map): Likewise. * sysdeps/i386/configure.ac: Check if linker supports static PIE. * sysdeps/x86_64/configure.ac: Likewise. * sysdeps/i386/configure: Regenerated. * sysdeps/x86_64/configure: Likewise. * sysdeps/mips/Makefile (ASFLAGS-.o): Add $(pie-default). (ASFLAGS-.op): Likewise. --- ChangeLog | 72 +++++++++++++++++++++++++++++++++++++++++ INSTALL | 9 ++++++ Makeconfig | 38 +++++++++++++++++++--- NEWS | 9 ++++++ config.h.in | 3 ++ configure | 79 +++++++++++++++++++++++++++++++++++++++++++++ configure.ac | 29 +++++++++++++++++ csu/Makefile | 24 ++++++++++++-- csu/libc-start.c | 2 ++ csu/libc-tls.c | 6 ++-- csu/static-reloc.c | 26 +++++++++++++++ elf/Makefile | 7 ++-- elf/dl-reloc-static-pie.c | 52 +++++++++++++++++++++++++++++ elf/dl-support.c | 11 +++++++ elf/dynamic-link.h | 2 +- elf/get-dynamic-info.h | 6 ++-- gmon/Makefile | 25 +++++++++++++- gmon/tst-gmon-static-pie.c | 1 + manual/install.texi | 9 ++++++ sysdeps/generic/ldsodefs.h | 11 +++++++ sysdeps/i386/configure | 33 +++++++++++++++++++ sysdeps/i386/configure.ac | 23 +++++++++++++ sysdeps/mips/Makefile | 3 ++ sysdeps/x86_64/configure | 33 +++++++++++++++++++ sysdeps/x86_64/configure.ac | 25 ++++++++++++++ 25 files changed, 521 insertions(+), 17 deletions(-) create mode 100644 csu/static-reloc.c create mode 100644 elf/dl-reloc-static-pie.c create mode 100644 gmon/tst-gmon-static-pie.c (limited to 'configure.ac') diff --git a/ChangeLog b/ChangeLog index 852043e521..e9f203fd37 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,75 @@ +2017-12-15 H.J. Lu + + [BZ #19574] + * INSTALL: Regenerated. + * Makeconfig (real-static-start-installed-name): New. + (pic-default): Updated for --enable-static-pie. + (pie-default): New for --enable-static-pie. + (default-pie-ldflag): Likewise. + (+link-static-before-libc): Replace $(DEFAULT-LDFLAGS-$(@F)) + with $(if $($(@F)-no-pie),$(no-pie-ldflag),$(default-pie-ldflag)). + Replace $(static-start-installed-name) with + $(real-static-start-installed-name). + (+prectorT): Updated for --enable-static-pie. + (+postctorT): Likewise. + (CFLAGS-.o): Add $(pie-default). + (CFLAGS-.op): Likewise. + * NEWS: Mention --enable-static-pie. + * config.h.in (ENABLE_STATIC_PIE): New. + * configure.ac (--enable-static-pie): New configure option. + (have-no-dynamic-linker): New LIBC_CONFIG_VAR. + (have-static-pie): Likewise. + Enable static PIE if linker supports --no-dynamic-linker. + (ENABLE_STATIC_PIE): New AC_DEFINE. + (enable-static-pie): New LIBC_CONFIG_VAR. + * configure: Regenerated. + * csu/Makefile (omit-deps): Add r$(start-installed-name) and + gr$(start-installed-name) for --enable-static-pie. + (extra-objs): Likewise. + (install-lib): Likewise. + (extra-objs): Add static-reloc.o and static-reloc.os + ($(objpfx)$(start-installed-name)): Also depend on + $(objpfx)static-reloc.o. + ($(objpfx)r$(start-installed-name)): New. + ($(objpfx)g$(start-installed-name)): Also depend on + $(objpfx)static-reloc.os. + ($(objpfx)gr$(start-installed-name)): New. + * csu/libc-start.c (LIBC_START_MAIN): Call _dl_relocate_static_pie + in libc.a. + * csu/libc-tls.c (__libc_setup_tls): Add main_map->l_addr to + initimage. + * csu/static-reloc.c: New file. + * elf/Makefile (routines): Add dl-reloc-static-pie. + (elide-routines.os): Likewise. + (DEFAULT-LDFLAGS-tst-tls1-static-non-pie): Removed. + (tst-tls1-static-non-pie-no-pie): New. + * elf/dl-reloc-static-pie.c: New file. + * elf/dl-support.c (_dl_get_dl_main_map): New function. + * elf/dynamic-link.h (ELF_DURING_STARTUP): Also check + STATIC_PIE_BOOTSTRAP. + * elf/get-dynamic-info.h (elf_get_dynamic_info): Likewise. + * gmon/Makefile (tests): Add tst-gmon-static-pie. + (tests-static): Likewise. + (DEFAULT-LDFLAGS-tst-gmon-static): Removed. + (tst-gmon-static-no-pie): New. + (CFLAGS-tst-gmon-static-pie.c): Likewise. + (CRT-tst-gmon-static-pie): Likewise. + (tst-gmon-static-pie-ENV): Likewise. + (tests-special): Likewise. + ($(objpfx)tst-gmon-static-pie.out): Likewise. + (clean-tst-gmon-static-pie-data): Likewise. + ($(objpfx)tst-gmon-static-pie-gprof.out): Likewise. + * gmon/tst-gmon-static-pie.c: New file. + * manual/install.texi: Document --enable-static-pie. + * sysdeps/generic/ldsodefs.h (_dl_relocate_static_pie): New. + (_dl_get_dl_main_map): Likewise. + * sysdeps/i386/configure.ac: Check if linker supports static PIE. + * sysdeps/x86_64/configure.ac: Likewise. + * sysdeps/i386/configure: Regenerated. + * sysdeps/x86_64/configure: Likewise. + * sysdeps/mips/Makefile (ASFLAGS-.o): Add $(pie-default). + (ASFLAGS-.op): Likewise. + 2017-12-15 Joseph Myers * io/Makefile (tst-open-tmpfile-ARGS): New variable. diff --git a/INSTALL b/INSTALL index 80306de35c..9a1404bd3c 100644 --- a/INSTALL +++ b/INSTALL @@ -86,6 +86,15 @@ will be used, and CFLAGS sets optimization options for the compiler. systems support shared libraries; you need ELF support and (currently) the GNU linker. +'--enable-static-pie' + Enable static position independent executable (static PIE) support. + Static PIE is similar to static executable, but can be loaded at + any address without help from a dynamic linker. All static + programs as well as static tests are built as static PIE, except + for those marked with no-pie. The resulting glibc can be used with + the GCC option, -static-pie, which is available with GCC 8 or + above, to create static PIE. + '--disable-profile' Don't build libraries with profiling information. You may want to use this option if you don't plan to do profiling. diff --git a/Makeconfig b/Makeconfig index 1346109ac0..99cc136bfa 100644 --- a/Makeconfig +++ b/Makeconfig @@ -352,6 +352,14 @@ ifndef static-start-installed-name static-start-installed-name = $(start-installed-name) endif +ifeq (yes,$(enable-static-pie)) +# Link with rcrt1.o, instead of crt1.o, to call _dl_relocate_static_pie +# to relocate static PIE. +real-static-start-installed-name = r$(static-start-installed-name) +else +real-static-start-installed-name = $(static-start-installed-name) +endif + ifeq (yesyes,$(build-shared)$(have-z-combreloc)) combreloc-LDFLAGS = -Wl,-z,combreloc LDFLAGS.so += $(combreloc-LDFLAGS) @@ -371,6 +379,20 @@ LDFLAGS.so += $(hashstyle-LDFLAGS) LDFLAGS-rtld += $(hashstyle-LDFLAGS) endif +ifeq (yes,$(enable-static-pie)) +pic-default = -DPIC +# Compile libc.a and libc_p.a with -fPIE/-fpie for static PIE. +pie-default = $(pie-ccflag) +ifeq (yes,$(have-static-pie)) +default-pie-ldflag = -static-pie +else +# Static PIE can't have dynamic relocations in read-only segments since +# static PIE is mapped into memory by kernel. --eh-frame-hdr is needed +# for PIE to support exception. +default-pie-ldflag = -Wl,-pie,--no-dynamic-linker,--eh-frame-hdr,-z,text +endif +endif + # If lazy relocations are disabled, add the -z now flag. Use # LDFLAGS-lib.so instead of LDFLAGS.so, to avoid adding the flag to # test modules. @@ -420,9 +442,9 @@ endif # Command for statically linking programs with the C library. ifndef +link-static +link-static-before-libc = $(CC) -nostdlib -nostartfiles -static -o $@ \ - $(DEFAULT-LDFLAGS-$(@F)) \ + $(if $($(@F)-no-pie),$(no-pie-ldflag),$(default-pie-ldflag)) \ $(sysdep-LDFLAGS) $(LDFLAGS) $(LDFLAGS-$(@F)) \ - $(firstword $(CRT-$(@F)) $(csu-objpfx)$(static-start-installed-name)) \ + $(firstword $(CRT-$(@F)) $(csu-objpfx)$(real-static-start-installed-name)) \ $(+preinit) $(+prectorT) \ $(filter-out $(addprefix $(csu-objpfx),start.o \ $(start-installed-name))\ @@ -637,8 +659,14 @@ endif +prectorS = `$(CC) $(sysdep-LDFLAGS) --print-file-name=crtbeginS.o` +postctorS = `$(CC) $(sysdep-LDFLAGS) --print-file-name=crtendS.o` # Variants of the two previous definitions for statically linking programs. +ifeq (yes,$(enable-static-pie)) +# Static PIE must use PIE variants. ++prectorT = $(+prectorS) ++postctorT = $(+postctorS) +else +prectorT = `$(CC) $(sysdep-LDFLAGS) --print-file-name=crtbeginT.o` +postctorT = `$(CC) $(sysdep-LDFLAGS) --print-file-name=crtend.o` +endif csu-objpfx = $(common-objpfx)csu/ elf-objpfx = $(common-objpfx)elf/ @@ -959,7 +987,8 @@ libtypes = $(foreach o,$(object-suffixes-for-libc),$(libtype$o)) all-object-suffixes := .o .os .oS object-suffixes := CPPFLAGS-.o = $(pic-default) -CFLAGS-.o = $(filter %frame-pointer,$(+cflags)) +# libc.a must be compiled with -fPIE/-fpie for static PIE. +CFLAGS-.o = $(filter %frame-pointer,$(+cflags)) $(pie-default) libtype.o := lib%.a object-suffixes += .o ifeq (yes,$(build-shared)) @@ -984,7 +1013,8 @@ ifeq (yes,$(build-profile)) all-object-suffixes += .op object-suffixes += .op CPPFLAGS-.op = -DPROF $(pic-default) -CFLAGS-.op = -pg +# libc_p.a must be compiled with -fPIE/-fpie for static PIE. +CFLAGS-.op = -pg $(pie-default) libtype.op = lib%_p.a endif diff --git a/NEWS b/NEWS index c5607c855f..61fed654d8 100644 --- a/NEWS +++ b/NEWS @@ -9,6 +9,15 @@ Version 2.27 Major new features: +* The GNU C Library can now be compiled with support for building static + PIE executables (See --enable-static-pie in INSTALL). These static PIE + exectuables are like static executables but can be loaded at any address + and provide additional security hardening benefits at the cost of some + memory and performance. When the library is built with --enable-static-pie + the resulting libc.a is usable with GCC 8 and above to create static PIE + executables using the GCC option '-static-pie'. This feature is currently + supported on i386, x86_64 and x32. + * Optimized x86-64 asin, atan2, exp, expf, log, pow, atan, sin, cosf, sinf and tan with FMA, contributed by Arjan van de Ven and H.J. Lu from Intel. diff --git a/config.h.in b/config.h.in index 3c91d597ff..d928e7dd86 100644 --- a/config.h.in +++ b/config.h.in @@ -238,6 +238,9 @@ /* Build glibc with tunables support. */ #define HAVE_TUNABLES 0 +/* Define if static PIE is enabled. */ +#define ENABLE_STATIC_PIE 0 + /* Some compiler options may now allow to use ebp in __asm__ (used mainly in i386 6 argument syscall issue). */ #define CAN_USE_REGISTER_ASM_EBP 0 diff --git a/configure b/configure index 4a85706862..9da9fb2736 100755 --- a/configure +++ b/configure @@ -763,6 +763,7 @@ with_default_link enable_sanity_checks enable_shared enable_profile +enable_static_pie enable_timezone_tools enable_hardcoded_path_in_tests enable_stackguard_randomization @@ -1417,6 +1418,8 @@ Optional Features: in special situations) [default=yes] --enable-shared build shared library [default=yes if GNU ld] --enable-profile build profiled library [default=no] + --enable-static-pie enable static PIE support and use it in the + testsuite [default=no] --disable-timezone-tools do not install timezone tools [default=install] --enable-hardcoded-path-in-tests @@ -3350,6 +3353,13 @@ else profile=no fi +# Check whether --enable-static-pie was given. +if test "${enable_static_pie+set}" = set; then : + enableval=$enable_static_pie; static_pie=$enableval +else + static_pie=no +fi + # Check whether --enable-timezone-tools was given. if test "${enable_timezone_tools+set}" = set; then : enableval=$enable_timezone_tools; enable_timezone_tools=$enableval @@ -5806,6 +5816,62 @@ fi $as_echo "$libc_linker_feature" >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for linker that supports --no-dynamic-linker" >&5 +$as_echo_n "checking for linker that supports --no-dynamic-linker... " >&6; } +libc_linker_feature=no +if test x"$gnu_ld" = x"yes"; then + libc_linker_check=`$LD -v --help 2>/dev/null | grep "\--no-dynamic-linker"` + if test -n "$libc_linker_check"; then + cat > conftest.c <&5 + (eval $ac_try) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; } + then + libc_linker_feature=yes + fi + rm -f conftest* + fi +fi +if test $libc_linker_feature = yes; then + libc_cv_no_dynamic_linker=yes +else + libc_cv_no_dynamic_linker=no +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_linker_feature" >&5 +$as_echo "$libc_linker_feature" >&6; } +config_vars="$config_vars +have-no-dynamic-linker = $libc_cv_no_dynamic_linker" + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for -static-pie" >&5 +$as_echo_n "checking for -static-pie... " >&6; } +if ${libc_cv_static_pie+:} false; then : + $as_echo_n "(cached) " >&6 +else + if { ac_try='${CC-cc} -static-pie -xc /dev/null -S -o /dev/null' + { { 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_static_pie=yes +else + libc_cv_static_pie=no +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_static_pie" >&5 +$as_echo "$libc_cv_static_pie" >&6; } +config_vars="$config_vars +have-static-pie = $libc_cv_static_pie" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -fpie" >&5 $as_echo_n "checking for -fpie... " >&6; } if ${libc_cv_fpie+:} false; then : @@ -6705,6 +6771,19 @@ $as_echo "$libc_cv_pie_default" >&6; } libc_cv_multidir=`${CC-cc} $CFLAGS $CPPFLAGS -print-multi-directory` +if test "$static_pie" = yes; then + # The linker must support --no-dynamic-linker. + if test "$libc_cv_no_dynamic_linker" != yes; then + as_fn_error $? "linker support for --no-dynamic-linker needed" "$LINENO" 5 + fi + # Default to PIE. + libc_cv_pie_default=yes + $as_echo "#define ENABLE_STATIC_PIE 1" >>confdefs.h + +fi +config_vars="$config_vars +enable-static-pie = $static_pie" + diff --git a/configure.ac b/configure.ac index edf662715b..8e4006f0a9 100644 --- a/configure.ac +++ b/configure.ac @@ -170,6 +170,11 @@ AC_ARG_ENABLE([profile], [build profiled library @<:@default=no@:>@]), [profile=$enableval], [profile=no]) +AC_ARG_ENABLE([static-pie], + AC_HELP_STRING([--enable-static-pie], + [enable static PIE support and use it in the testsuite @<:@default=no@:>@]), + [static_pie=$enableval], + [static_pie=no]) AC_ARG_ENABLE([timezone-tools], AC_HELP_STRING([--disable-timezone-tools], [do not install timezone tools @<:@default=install@:>@]), @@ -1287,6 +1292,19 @@ LIBC_LINKER_FEATURE([-z execstack], [-Wl,-z,execstack], [libc_cv_z_execstack=yes], [libc_cv_z_execstack=no]) AC_SUBST(libc_cv_z_execstack) +LIBC_LINKER_FEATURE([--no-dynamic-linker], + [-Wl,--no-dynamic-linker], + [libc_cv_no_dynamic_linker=yes], + [libc_cv_no_dynamic_linker=no]) +LIBC_CONFIG_VAR([have-no-dynamic-linker], [$libc_cv_no_dynamic_linker]) + +AC_CACHE_CHECK(for -static-pie, libc_cv_static_pie, [dnl +LIBC_TRY_CC_OPTION([-static-pie], + [libc_cv_static_pie=yes], + [libc_cv_static_pie=no]) +]) +LIBC_CONFIG_VAR([have-static-pie], [$libc_cv_static_pie]) + AC_CACHE_CHECK(for -fpie, libc_cv_fpie, [dnl LIBC_TRY_CC_OPTION([-fpie], [libc_cv_fpie=yes], [libc_cv_fpie=no]) ]) @@ -1794,6 +1812,17 @@ AC_SUBST(libc_cv_pie_default) libc_cv_multidir=`${CC-cc} $CFLAGS $CPPFLAGS -print-multi-directory` AC_SUBST(libc_cv_multidir) +if test "$static_pie" = yes; then + # The linker must support --no-dynamic-linker. + if test "$libc_cv_no_dynamic_linker" != yes; then + AC_MSG_ERROR([linker support for --no-dynamic-linker needed]) + fi + # Default to PIE. + libc_cv_pie_default=yes + AC_DEFINE(ENABLE_STATIC_PIE) +fi +LIBC_CONFIG_VAR([enable-static-pie], [$static_pie]) + AC_SUBST(profile) AC_SUBST(static_nss) diff --git a/csu/Makefile b/csu/Makefile index e42a32b3eb..86b95a9759 100644 --- a/csu/Makefile +++ b/csu/Makefile @@ -37,7 +37,9 @@ extra-objs = start.o \ S$(start-installed-name) omit-deps = $(patsubst %.o,%,$(start-installed-name) g$(start-installed-name) \ b$(start-installed-name) $(csu-dummies) \ - S$(start-installed-name)) + S$(start-installed-name) \ + r$(start-installed-name) \ + gr$(start-installed-name)) install-lib = $(start-installed-name) g$(start-installed-name) $(csu-dummies) # No tests are allowed in the csu/ subdirectory because the startup @@ -60,10 +62,17 @@ extra-objs += gmon-start.o endif ifneq ($(start-installed-name),$(static-start-installed-name)) +# FIXME: Only Hurd defines static-start-installed-name. Hurd needs to +# provide special rules to support static PIE. extra-objs += $(static-start-installed-name) g$(static-start-installed-name) omit-deps += $(patsubst %.o,%,$(static-start-installed-name) \ g$(static-start-installed-name)) install-lib += $(static-start-installed-name) g$(static-start-installed-name) +else +ifeq (yes,$(enable-static-pie)) +extra-objs += r$(start-installed-name) gr$(start-installed-name) +install-lib += r$(start-installed-name) gr$(start-installed-name) +endif endif before-compile += $(objpfx)abi-tag.h @@ -82,7 +91,10 @@ multilib-extra-objs = $(addprefix $(multidir)/, $(install-lib)) extra-objs += $(multilib-extra-objs) endif -extra-objs += abi-note.o init.o +extra-objs += abi-note.o init.o static-reloc.o +ifeq (yes,$(build-shared)) +extra-objs += static-reloc.os +endif asm-CPPFLAGS += -I$(objpfx). # Enable unwinding so backtrace unwinds to __libc_start_main @@ -101,6 +113,9 @@ ifndef start-installed-name-rule # We link the ELF startfile along with a SHT_NOTE section indicating # the kernel ABI the binaries linked with this library will require. $(objpfx)$(start-installed-name): $(objpfx)start.o $(objpfx)abi-note.o \ + $(objpfx)init.o $(objpfx)static-reloc.o + $(link-relocatable) +$(objpfx)r$(start-installed-name): $(objpfx)start.o $(objpfx)abi-note.o \ $(objpfx)init.o $(link-relocatable) $(objpfx)S$(start-installed-name): $(objpfx)start.os $(objpfx)abi-note.o \ @@ -113,7 +128,10 @@ endif # to turn on profiling code at startup. ifeq (yes,$(build-shared)) $(objpfx)g$(start-installed-name): \ - $(objpfx)g%: $(objpfx)S% $(objpfx)gmon-start.os + $(objpfx)g%: $(objpfx)S% $(objpfx)gmon-start.os $(objpfx)static-reloc.os + $(link-relocatable) +$(objpfx)gr$(start-installed-name): \ + $(objpfx)gr%: $(objpfx)r% $(objpfx)gmon-start.o $(link-relocatable) ifneq ($(start-installed-name),$(static-start-installed-name)) $(objpfx)g$(static-start-installed-name): \ diff --git a/csu/libc-start.c b/csu/libc-start.c index 24c63be02f..34dd125260 100644 --- a/csu/libc-start.c +++ b/csu/libc-start.c @@ -141,6 +141,8 @@ LIBC_START_MAIN (int (*main) (int, char **, char ** MAIN_AUXVEC_DECL), __libc_multiple_libcs = &_dl_starting_up && !_dl_starting_up; #ifndef SHARED + _dl_relocate_static_pie (); + char **ev = &argv[argc + 1]; __environ = ev; diff --git a/csu/libc-tls.c b/csu/libc-tls.c index 00138eb43a..1f8ddaf543 100644 --- a/csu/libc-tls.c +++ b/csu/libc-tls.c @@ -114,6 +114,8 @@ __libc_setup_tls (void) size_t tcb_offset; const ElfW(Phdr) *phdr; + struct link_map *main_map = GL(dl_ns)[LM_ID_BASE]._ns_loaded; + /* Look through the TLS segment if there is any. */ if (_dl_phdr != NULL) for (phdr = _dl_phdr; phdr < &_dl_phdr[_dl_phnum]; ++phdr) @@ -122,7 +124,7 @@ __libc_setup_tls (void) /* Remember the values we need. */ memsz = phdr->p_memsz; filesz = phdr->p_filesz; - initimage = (void *) phdr->p_vaddr; + initimage = (void *) phdr->p_vaddr + main_map->l_addr; align = phdr->p_align; if (phdr->p_align > max_align) max_align = phdr->p_align; @@ -163,8 +165,6 @@ __libc_setup_tls (void) _dl_static_dtv[0].counter = (sizeof (_dl_static_dtv) / sizeof (_dl_static_dtv[0])) - 2; // _dl_static_dtv[1].counter = 0; would be needed if not already done - struct link_map *main_map = GL(dl_ns)[LM_ID_BASE]._ns_loaded; - /* Initialize the TLS block. */ #if TLS_TCB_AT_TP _dl_static_dtv[2].pointer.val = ((char *) tlsblock + tcb_offset diff --git a/csu/static-reloc.c b/csu/static-reloc.c new file mode 100644 index 0000000000..37be72c8ea --- /dev/null +++ b/csu/static-reloc.c @@ -0,0 +1,26 @@ +/* Special startup support for non-PIE static executables. + Copyright (C) 2017 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 + . */ + +#if ENABLE_STATIC_PIE +#include + +void +_dl_relocate_static_pie (void) +{ +} +#endif diff --git a/elf/Makefile b/elf/Makefile index 8563555079..47c3d23ed8 100644 --- a/elf/Makefile +++ b/elf/Makefile @@ -24,7 +24,8 @@ include ../Makeconfig 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-origin dl-libc dl-sym dl-sysdep dl-error \ + dl-reloc-static-pie # The core dynamic linking functions are in libc for the static and # profiled libraries. @@ -52,7 +53,7 @@ endif all-dl-routines = $(dl-routines) $(sysdep-dl-routines) # But they are absent from the shared libc, because that code is in ld.so. elide-routines.os = $(all-dl-routines) dl-support enbl-secure dl-origin \ - dl-sysdep dl-exception + dl-sysdep dl-exception dl-reloc-static-pie shared-only-routines += dl-caller # ld.so uses those routines, plus some special stuff for being the program @@ -153,7 +154,7 @@ tests-static-internal := tst-tls1-static tst-tls2-static \ tst-tls1-static-non-pie CRT-tst-tls1-static-non-pie := $(csu-objpfx)crt1.o -DEFAULT-LDFLAGS-tst-tls1-static-non-pie = $(no-pie-ldflag) +tst-tls1-static-non-pie-no-pie = yes tests := tst-tls9 tst-leaks1 \ tst-array1 tst-array2 tst-array3 tst-array4 tst-array5 \ diff --git a/elf/dl-reloc-static-pie.c b/elf/dl-reloc-static-pie.c new file mode 100644 index 0000000000..6e43aea76a --- /dev/null +++ b/elf/dl-reloc-static-pie.c @@ -0,0 +1,52 @@ +/* Support for relocating static PIE. + Copyright (C) 2017 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 + . */ + +#if ENABLE_STATIC_PIE +#include +#include +#include "dynamic-link.h" + +/* Relocate static executable with PIE. */ + +void +_dl_relocate_static_pie (void) +{ + struct link_map *main_map = _dl_get_dl_main_map (); + +# define STATIC_PIE_BOOTSTRAP +# define BOOTSTRAP_MAP (main_map) +# define RESOLVE_MAP(sym, version, flags) BOOTSTRAP_MAP +# include "dynamic-link.h" + + /* Figure out the run-time load address of static PIE. */ + main_map->l_addr = elf_machine_load_address (); + + /* Read our own dynamic section and fill in the info array. */ + main_map->l_ld = ((void *) main_map->l_addr + elf_machine_dynamic ()); + elf_get_dynamic_info (main_map, NULL); + +# ifdef ELF_MACHINE_BEFORE_RTLD_RELOC + ELF_MACHINE_BEFORE_RTLD_RELOC (main_map->l_info); +# endif + + /* Relocate ourselves so we can do normal function calls and + data access using the global offset table. */ + ELF_DYNAMIC_RELOCATE (main_map, 0, 0, 0); + main_map->l_relocated = 1; +} +#endif diff --git a/elf/dl-support.c b/elf/dl-support.c index 235d3a7f46..b9fc1a66fe 100644 --- a/elf/dl-support.c +++ b/elf/dl-support.c @@ -385,3 +385,14 @@ _dl_non_dynamic_init (void) #ifdef DL_SYSINFO_IMPLEMENTATION DL_SYSINFO_IMPLEMENTATION #endif + +#if ENABLE_STATIC_PIE +/* Since relocation to hidden _dl_main_map causes relocation overflow on + aarch64, a function is used to get the address of _dl_main_map. */ + +struct link_map * +_dl_get_dl_main_map (void) +{ + return &_dl_main_map; +} +#endif diff --git a/elf/dynamic-link.h b/elf/dynamic-link.h index ebea7567cd..6278649711 100644 --- a/elf/dynamic-link.h +++ b/elf/dynamic-link.h @@ -94,7 +94,7 @@ elf_machine_lazy_rel (struct link_map *map, #ifdef RESOLVE_MAP -# ifdef RTLD_BOOTSTRAP +# if defined RTLD_BOOTSTRAP || defined STATIC_PIE_BOOTSTRAP # define ELF_DURING_STARTUP (1) # else # define ELF_DURING_STARTUP (0) diff --git a/elf/get-dynamic-info.h b/elf/get-dynamic-info.h index 7525c3a5b2..eb26d23649 100644 --- a/elf/get-dynamic-info.h +++ b/elf/get-dynamic-info.h @@ -38,7 +38,7 @@ elf_get_dynamic_info (struct link_map *l, ElfW(Dyn) *temp) typedef Elf64_Xword d_tag_utype; #endif -#ifndef RTLD_BOOTSTRAP +#if !defined RTLD_BOOTSTRAP && !defined STATIC_PIE_BOOTSTRAP if (dyn == NULL) return; #endif @@ -139,9 +139,11 @@ elf_get_dynamic_info (struct link_map *l, ElfW(Dyn) *temp) /* Only the bind now flags are allowed. */ assert (info[VERSYMIDX (DT_FLAGS_1)] == NULL || (info[VERSYMIDX (DT_FLAGS_1)]->d_un.d_val & ~DF_1_NOW) == 0); + /* Flags must not be set for ld.so. */ assert (info[DT_FLAGS] == NULL || (info[DT_FLAGS]->d_un.d_val & ~DF_BIND_NOW) == 0); - /* Flags must not be set for ld.so. */ +#endif +#if defined RTLD_BOOTSTRAP || defined STATIC_PIE_BOOTSTRAP assert (info[DT_RUNPATH] == NULL); assert (info[DT_RPATH] == NULL); #else diff --git a/gmon/Makefile b/gmon/Makefile index 89ab3fc7da..29e746723e 100644 --- a/gmon/Makefile +++ b/gmon/Makefile @@ -39,6 +39,10 @@ tests-static += tst-gmon-static ifeq (yesyes,$(have-fpie)$(build-shared)) tests += tst-gmon-pie tests-pie += tst-gmon-pie +ifeq (yes,$(enable-static-pie)) +tests += tst-gmon-static-pie +tests-static += tst-gmon-static-pie +endif endif # The mcount code won't work without a frame pointer. @@ -54,7 +58,7 @@ endif CFLAGS-tst-gmon-static.c := $(PIE-ccflag) -fno-omit-frame-pointer -pg CRT-tst-gmon-static := $(csu-objpfx)gcrt1.o -DEFAULT-LDFLAGS-tst-gmon-static = $(no-pie-ldflag) +tst-gmon-static-no-pie = yes tst-gmon-static-ENV := GMON_OUT_PREFIX=$(objpfx)tst-gmon-static.data ifeq ($(run-built-tests),yes) tests-special += $(objpfx)tst-gmon-static-gprof.out @@ -67,6 +71,15 @@ ifeq ($(run-built-tests),yes) tests-special += $(objpfx)tst-gmon-pie-gprof.out endif +ifeq (yes,$(enable-static-pie)) +CFLAGS-tst-gmon-static-pie.c := $(PIE-ccflag) -fno-omit-frame-pointer -pg +CRT-tst-gmon-static-pie := $(csu-objpfx)grcrt1.o +tst-gmon-static-pie-ENV := GMON_OUT_PREFIX=$(objpfx)tst-gmon-static-pie.data +ifeq ($(run-built-tests),yes) +tests-special += $(objpfx)tst-gmon-static-pie-gprof.out +endif +endif + include ../Rules @@ -111,3 +124,13 @@ clean-tst-gmon-pie-data: $(objpfx)tst-gmon-pie-gprof.out: tst-gmon-gprof.sh $(objpfx)tst-gmon-pie.out $(SHELL) $< $(GPROF) $(objpfx)tst-gmon-pie $(objpfx)tst-gmon-pie.data.* > $@; \ $(evaluate-test) + +$(objpfx)tst-gmon-static-pie.out: clean-tst-gmon-static-pie-data +clean-tst-gmon-static-pie-data: + rm -f $(objpfx)tst-gmon-static-pie.data.* + +$(objpfx)tst-gmon-static-pie-gprof.out: tst-gmon-static-gprof.sh \ + $(objpfx)tst-gmon-static-pie.out + $(SHELL) $< $(GPROF) $(objpfx)tst-gmon-static-pie \ + $(objpfx)tst-gmon-static-pie.data.* > $@; \ + $(evaluate-test) diff --git a/gmon/tst-gmon-static-pie.c b/gmon/tst-gmon-static-pie.c new file mode 100644 index 0000000000..1eef2583b6 --- /dev/null +++ b/gmon/tst-gmon-static-pie.c @@ -0,0 +1 @@ +#include "tst-gmon.c" diff --git a/manual/install.texi b/manual/install.texi index e81f1c50c3..fb956b5d6a 100644 --- a/manual/install.texi +++ b/manual/install.texi @@ -116,6 +116,15 @@ Don't build shared libraries even if it is possible. Not all systems support shared libraries; you need ELF support and (currently) the GNU linker. +@item --enable-static-pie +Enable static position independent executable (static PIE) support. +Static PIE is similar to static executable, but can be loaded at any +address without help from a dynamic linker. All static programs as +well as static tests are built as static PIE, except for those marked +with no-pie. The resulting glibc can be used with the GCC option, +-static-pie, which is available with GCC 8 or above, to create static +PIE. + @item --disable-profile Don't build libraries with profiling information. You may want to use this option if you don't plan to do profiling. diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h index 7a65dc641c..196513851f 100644 --- a/sysdeps/generic/ldsodefs.h +++ b/sysdeps/generic/ldsodefs.h @@ -1051,6 +1051,17 @@ extern void _dl_determine_tlsoffset (void) attribute_hidden; stack protector, among other things). */ void __libc_setup_tls (void); +# if ENABLE_STATIC_PIE +/* Relocate static executable with PIE. */ +extern void _dl_relocate_static_pie (void) attribute_hidden; + +/* Get a pointer to _dl_main_map. */ +extern struct link_map * _dl_get_dl_main_map (void) + __attribute__ ((visibility ("hidden"))); +# else +# define _dl_relocate_static_pie() +# endif + /* Initialization of libpthread for statically linked applications. If libpthread is not linked in, this is an empty function. */ void __pthread_initialize_minimal (void) weak_function; diff --git a/sysdeps/i386/configure b/sysdeps/i386/configure index 4cf968d8bc..90c63caf35 100644 --- a/sysdeps/i386/configure +++ b/sysdeps/i386/configure @@ -50,6 +50,39 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_compiler_builtin_inlined" >&5 $as_echo "$libc_compiler_builtin_inlined" >&6; } +if test "$static_pie" = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for linker static PIE support" >&5 +$as_echo_n "checking for linker static PIE support... " >&6; } +if ${libc_cv_ld_static_pie+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat > conftest.s <<\EOF + .text + .global _start +_start: + movl _start@GOT(%ebx), %eax +EOF + libc_cv_pie_option="-Wl,-pie" + libc_cv_ld_static_pie=no + if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS -nostartfiles -nostdlib $no_ssp $libc_cv_pie_option -o conftest conftest.s 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 + if $READELF -r conftest | grep 'There are no relocations in this file.' > /dev/null; then + libc_cv_ld_static_pie=yes + fi + fi +rm -f conftest* +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_ld_static_pie" >&5 +$as_echo "$libc_cv_ld_static_pie" >&6; } + if test "$libc_cv_ld_static_pie" != yes; then + as_fn_error $? "linker support for static PIE needed" "$LINENO" 5 + fi +fi + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Intel MPX support" >&5 $as_echo_n "checking for Intel MPX support... " >&6; } if ${libc_cv_asm_mpx+:} false; then : diff --git a/sysdeps/i386/configure.ac b/sysdeps/i386/configure.ac index b598b120bc..6d2068d2b3 100644 --- a/sysdeps/i386/configure.ac +++ b/sysdeps/i386/configure.ac @@ -30,6 +30,29 @@ LIBC_COMPILER_BUILTIN_INLINED( *** Please use host i786, i686, i586, or i486. *** For example: /source/glibc/configure CFLAGS='-O2 -march=i686' ...])]) +dnl Check if linker can convert "movl main@GOT(%ebx), %eax" to +dnl "leal main@GOTOFF(%ebx), %eax" for static PIE. +if test "$static_pie" = yes; then + AC_CACHE_CHECK(for linker static PIE support, libc_cv_ld_static_pie, [dnl +cat > conftest.s <<\EOF + .text + .global _start +_start: + movl _start@GOT(%ebx), %eax +EOF + libc_cv_pie_option="-Wl,-pie" + libc_cv_ld_static_pie=no + if AC_TRY_COMMAND(${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS -nostartfiles -nostdlib $no_ssp $libc_cv_pie_option -o conftest conftest.s 1>&AS_MESSAGE_LOG_FD); then + if $READELF -r conftest | grep 'There are no relocations in this file.' > /dev/null; then + libc_cv_ld_static_pie=yes + fi + fi +rm -f conftest*]) + if test "$libc_cv_ld_static_pie" != yes; then + AC_MSG_ERROR([linker support for static PIE needed]) + fi +fi + dnl Check whether asm supports Intel MPX AC_CACHE_CHECK(for Intel MPX support, libc_cv_asm_mpx, [dnl cat > conftest.s <<\EOF diff --git a/sysdeps/mips/Makefile b/sysdeps/mips/Makefile index fd891ddf09..7ac6fa5031 100644 --- a/sysdeps/mips/Makefile +++ b/sysdeps/mips/Makefile @@ -23,6 +23,9 @@ CPPFLAGS-crtn.S += $(pic-ccflag) endif ASFLAGS-.os += $(pic-ccflag) +# libc.a and libc_p.a must be compiled with -fPIE/-fpie for static PIE. +ASFLAGS-.o += $(pie-default) +ASFLAGS-.op += $(pie-default) ifeq ($(subdir),elf) ifneq ($(o32-fpabi),) diff --git a/sysdeps/x86_64/configure b/sysdeps/x86_64/configure index efef46b1b7..8674d14569 100644 --- a/sysdeps/x86_64/configure +++ b/sysdeps/x86_64/configure @@ -85,6 +85,39 @@ if test x"$build_mathvec" = xnotset; then build_mathvec=yes fi +if test "$static_pie" = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for linker static PIE support" >&5 +$as_echo_n "checking for linker static PIE support... " >&6; } +if ${libc_cv_ld_static_pie+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat > conftest.s <<\EOF + .text + .global _start + .weak foo +_start: + leaq foo(%rip), %rax +EOF + libc_cv_pie_option="-Wl,-pie" + if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS -nostartfiles -nostdlib $no_ssp $libc_cv_pie_option -o conftest conftest.s 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_ld_static_pie=yes + else + libc_cv_ld_static_pie=no + fi +rm -f conftest* +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_ld_static_pie" >&5 +$as_echo "$libc_cv_ld_static_pie" >&6; } + if test "$libc_cv_ld_static_pie" != yes; then + as_fn_error $? "linker support for static PIE needed" "$LINENO" 5 + fi +fi + $as_echo "#define PI_STATIC_AND_HIDDEN 1" >>confdefs.h diff --git a/sysdeps/x86_64/configure.ac b/sysdeps/x86_64/configure.ac index fa86e953ee..b7d2c0124f 100644 --- a/sysdeps/x86_64/configure.ac +++ b/sysdeps/x86_64/configure.ac @@ -44,6 +44,31 @@ if test x"$build_mathvec" = xnotset; then build_mathvec=yes fi +dnl Check if linker supports static PIE with the fix for +dnl +dnl https://sourceware.org/bugzilla/show_bug.cgi?id=21782 +dnl +if test "$static_pie" = yes; then + AC_CACHE_CHECK(for linker static PIE support, libc_cv_ld_static_pie, [dnl +cat > conftest.s <<\EOF + .text + .global _start + .weak foo +_start: + leaq foo(%rip), %rax +EOF + libc_cv_pie_option="-Wl,-pie" + if AC_TRY_COMMAND(${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS -nostartfiles -nostdlib $no_ssp $libc_cv_pie_option -o conftest conftest.s 1>&AS_MESSAGE_LOG_FD); then + libc_cv_ld_static_pie=yes + else + libc_cv_ld_static_pie=no + fi +rm -f conftest*]) + if test "$libc_cv_ld_static_pie" != yes; then + AC_MSG_ERROR([linker support for static PIE needed]) + fi +fi + dnl It is always possible to access static and hidden symbols in an dnl position independent way. AC_DEFINE(PI_STATIC_AND_HIDDEN) -- cgit v1.2.3 From 00c714df398b63934540d95ce3792596f7a94a6c Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Mon, 18 Dec 2017 12:24:26 -0800 Subject: Pass -no-pie to GCC only if GCC defaults to PIE [BZ #22614] After --enable-static-pie is added to configure, libc_cv_pie_default is set to yes when either --enable-static-pie is used to configure glibc or GCC defaults to PIE. We should set no-pie-ldflag to -no-pie, which is supported on GCC 6 and later, only if GCC defaults to PIE, not when --enable-static-pie is used to configure glibc. Tested on x32 with --enable-static-pie using GCC 5 and without --enable-static-pie using GCC 7. [BZ #22614] * Makeconfig (no-pie-ldflag): Set to -no-pie only if $(cc-pie-default) == yes. * config.make.in (cc-pie-default): New. * configure.ac (libc_cv_pie_default): Renamed to ... (libc_cv_cc_pie_default): This. (libc_cv_pie_default): Set to $libc_cv_cc_pie_default. * configure: Regenerated. --- ChangeLog | 11 +++++++++++ Makeconfig | 4 +++- config.make.in | 1 + configure | 13 ++++++++----- configure.ac | 8 +++++--- 5 files changed, 28 insertions(+), 9 deletions(-) (limited to 'configure.ac') diff --git a/ChangeLog b/ChangeLog index a46375fd56..e7d5d4b110 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2017-12-18 H.J. Lu + + [BZ #22614] + * Makeconfig (no-pie-ldflag): Set to -no-pie only if + $(cc-pie-default) == yes. + * config.make.in (cc-pie-default): New. + * configure.ac (libc_cv_pie_default): Renamed to ... + (libc_cv_cc_pie_default): This. + (libc_cv_pie_default): Set to $libc_cv_cc_pie_default. + * configure: Regenerated. + 2017-12-18 Florian Weimer [BZ #20204] diff --git a/Makeconfig b/Makeconfig index 99cc136bfa..80c498e33b 100644 --- a/Makeconfig +++ b/Makeconfig @@ -464,8 +464,10 @@ endif # Commands for linking programs with the C library. ifndef +link ifeq (yes,$(build-shared)) -ifeq (yes,$(build-pie-default)) +ifeq (yes,$(cc-pie-default)) no-pie-ldflag = -no-pie +endif +ifeq (yes,$(build-pie-default)) +link = $(+link-pie) +link-tests = $(+link-pie-tests) +link-printers-tests = $(+link-pie-printers-tests) diff --git a/config.make.in b/config.make.in index 04513dbb74..9e5e24b2c6 100644 --- a/config.make.in +++ b/config.make.in @@ -89,6 +89,7 @@ static-nss-crypt = @libc_cv_static_nss_crypt@ build-shared = @shared@ build-pic-default= @libc_cv_pic_default@ build-pie-default= @libc_cv_pie_default@ +cc-pie-default= @libc_cv_cc_pie_default@ build-profile = @profile@ build-static-nss = @static_nss@ cross-compiling = @cross_compiling@ diff --git a/configure b/configure index 9da9fb2736..7a8bd3f817 100755 --- a/configure +++ b/configure @@ -596,6 +596,7 @@ static_nss profile libc_cv_multidir libc_cv_pie_default +libc_cv_cc_pie_default libc_cv_pic_default shared static @@ -6748,22 +6749,24 @@ $as_echo "$libc_cv_pic_default" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -fPIE is default" >&5 $as_echo_n "checking whether -fPIE is default... " >&6; } -if ${libc_cv_pie_default+:} false; then : +if ${libc_cv_cc_pie_default+:} false; then : $as_echo_n "(cached) " >&6 else - libc_cv_pie_default=yes + libc_cv_cc_pie_default=yes cat > conftest.c <&5 1>&5"; then - libc_cv_pie_default=no + libc_cv_cc_pie_default=no fi rm -f conftest.* fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_pie_default" >&5 -$as_echo "$libc_cv_pie_default" >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_cc_pie_default" >&5 +$as_echo "$libc_cv_cc_pie_default" >&6; } +libc_cv_pie_default=$libc_cv_cc_pie_default + # Set the `multidir' variable by grabbing the variable from the compiler. diff --git a/configure.ac b/configure.ac index 8e4006f0a9..ca1282a6b3 100644 --- a/configure.ac +++ b/configure.ac @@ -1794,17 +1794,19 @@ fi rm -f conftest.*]) AC_SUBST(libc_cv_pic_default) -AC_CACHE_CHECK([whether -fPIE is default], libc_cv_pie_default, -[libc_cv_pie_default=yes +AC_CACHE_CHECK([whether -fPIE is default], libc_cv_cc_pie_default, +[libc_cv_cc_pie_default=yes cat > conftest.c <&AS_MESSAGE_LOG_FD 1>&AS_MESSAGE_LOG_FD"; then - libc_cv_pie_default=no + libc_cv_cc_pie_default=no fi rm -f conftest.*]) +libc_cv_pie_default=$libc_cv_cc_pie_default +AC_SUBST(libc_cv_cc_pie_default) AC_SUBST(libc_cv_pie_default) # Set the `multidir' variable by grabbing the variable from the compiler. -- cgit v1.2.3 From e69d994a63afc2d367f286a2a7df28cbf710f0fe Mon Sep 17 00:00:00 2001 From: Zack Weinberg Date: Fri, 29 Jun 2018 16:53:47 +0200 Subject: New configure option --disable-crypt. Some Linux distributions are experimenting with a new, separately maintained and hopefully more agile implementation of the crypt API. To facilitate this, add a configure option which disables glibc's embedded libcrypt. When this option is given, libcrypt.* and crypt.h will not be built nor installed. --- ChangeLog | 23 +++++++++++++++++++++++ INSTALL | 11 +++++++++++ Makeconfig | 9 +++++++-- NEWS | 12 ++++++++++++ config.make.in | 1 + configure | 18 ++++++++++++++++++ configure.ac | 11 +++++++++++ conform/Makefile | 11 +++++++---- crypt/Makefile | 4 ---- elf/Makefile | 27 +++++++++++++++++++-------- elf/tst-linkall-static.c | 4 +++- manual/install.texi | 11 +++++++++++ 12 files changed, 123 insertions(+), 19 deletions(-) (limited to 'configure.ac') diff --git a/ChangeLog b/ChangeLog index 9b6edb1f1f..09543433ac 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,26 @@ +2018-06-29 Zack Weinberg + + * configure.ac: New command-line option --disable-crypt. + Force --disable-nss-crypt when --disable-crypt is given, with a + warning if it was explicitly enabled. + * configure: Regenerate. + * config.make.in: New boolean substitution variable $(build-crypt). + * Makeconfig: Only include 'crypt' in all-subdirs and rpath-dirs + when $(build-crypt). + * manual/install.texi: Document --disable-crypt. + * INSTALL: Regenerate. + + * crypt/Makefile: Remove code conditional on $(crypt-in-libc), + which is never set. + * conform/Makefile: Only include libcrypt.a in + linknamespace-libs-xsi and linknamespace-libs-XPG4 + when $(build-crypt). + * elf/Makefile (CFLAGS-tst-linkall-static.c): Only define + USE_CRYPT to 1 when $(build-crypt). + (tst-linkall-static): Only link libcrypt.a when $(build-crypt). + (localplt-built-dso): Only add libcrypt.so when $(build-crypt). + * elf/tst-linkall-static.c: Only include crypt.h when USE_CRYPT. + 2018-06-29 Zack Weinberg * crypt/crypt.h, posix/unistd.h: Update comments and diff --git a/INSTALL b/INSTALL index 052b1b6f89..0a22aa7d01 100644 --- a/INSTALL +++ b/INSTALL @@ -197,6 +197,17 @@ if 'CFLAGS' is specified it must enable optimization. For example: libnss_nisplus are not built at all. Use this option to enable libnsl with all depending NSS modules and header files. +'--disable-crypt' + Do not install the passphrase-hashing library 'libcrypt' or the + header file 'crypt.h'. 'unistd.h' will still declare the function + 'crypt'. Using this option does not change the set of programs + that may need to be linked with '-lcrypt'; it only means that the + GNU C Library will not provide that library. + + This option is for hackers and distributions experimenting with + independently-maintained implementations of libcrypt. It may + become the default in a future release. + '--disable-experimental-malloc' By default, a per-thread cache is enabled in 'malloc'. While this cache can be disabled on a per-application basis using tunables diff --git a/Makeconfig b/Makeconfig index 1afe86475c..608ffe648c 100644 --- a/Makeconfig +++ b/Makeconfig @@ -566,7 +566,7 @@ link-libc-printers-tests = $(link-libc-rpath) \ $(link-libc-tests-after-rpath-link) # This is how to find at build-time things that will be installed there. -rpath-dirs = math elf dlfcn nss nis rt resolv crypt mathvec support +rpath-dirs = math elf dlfcn nss nis rt resolv mathvec support rpath-link = \ $(common-objdir):$(subst $(empty) ,:,$(patsubst ../$(subdir),.,$(rpath-dirs:%=$(common-objpfx)%))) else # build-static @@ -1205,9 +1205,14 @@ all-subdirs = csu assert ctype locale intl catgets math setjmp signal \ stdlib stdio-common libio malloc string wcsmbs time dirent \ grp pwd posix io termios resource misc socket sysvipc gmon \ gnulib iconv iconvdata wctype manual shadow gshadow po argp \ - crypt localedata timezone rt conform debug mathvec support \ + localedata timezone rt conform debug mathvec support \ dlfcn elf +ifeq ($(build-crypt),yes) +all-subdirs += crypt +rpath-dirs += crypt +endif + ifndef avoid-generated # sysd-sorted itself will contain rules making the sysd-sorted target # depend on Depend files. But if you just added a Depend file to an diff --git a/NEWS b/NEWS index ebe63a2f40..7a85a4012c 100644 --- a/NEWS +++ b/NEWS @@ -133,6 +133,18 @@ Deprecated and removed features, and other changes affecting compatibility: binaries. It was just another name for the standard function crypt, and it has not appeared in any header file in many years. +* We have tentative plans to hand off maintenance of the passphrase-hashing + library, libcrypt, to a separate development project that will, we hope, + keep up better with new passphrase-hashing algorithms. We will continue + to declare 'crypt' in , and programs that use 'crypt' or + 'crypt_r' should not need to change at all; however, distributions will + need to install and libcrypt from a separate project. + + In this release, if the configure option --disable-crypt is used, glibc + will not install or libcrypt, making room for the separate + project's versions of these files. The plan is to make this the default + behavior in a future release. + Changes to build and runtime requirements: [Add changes to build and runtime requirements here] diff --git a/config.make.in b/config.make.in index 9e5e24b2c6..d9891b2cd8 100644 --- a/config.make.in +++ b/config.make.in @@ -96,6 +96,7 @@ cross-compiling = @cross_compiling@ force-install = @force_install@ link-obsolete-rpc = @link_obsolete_rpc@ build-obsolete-nsl = @build_obsolete_nsl@ +build-crypt = @build_crypt@ build-nscd = @build_nscd@ use-nscd = @use_nscd@ build-hardcoded-path-in-tests= @hardcoded_path_in_tests@ diff --git a/configure b/configure index 7a8bd3f817..ef18302215 100755 --- a/configure +++ b/configure @@ -676,6 +676,7 @@ build_obsolete_nsl link_obsolete_rpc libc_cv_static_nss_crypt libc_cv_nss_crypt +build_crypt experimental_malloc enable_werror all_warnings @@ -779,6 +780,7 @@ enable_all_warnings enable_werror enable_multi_arch enable_experimental_malloc +enable_crypt enable_nss_crypt enable_obsolete_rpc enable_obsolete_nsl @@ -1448,6 +1450,8 @@ Optional Features: architectures --disable-experimental-malloc disable experimental malloc features + --disable-crypt do not build nor install the passphrase hashing + library, libcrypt --enable-nss-crypt enable libcrypt to use nss --enable-obsolete-rpc build and install the obsolete RPC code for link-time usage @@ -3505,6 +3509,15 @@ fi +# Check whether --enable-crypt was given. +if test "${enable_crypt+set}" = set; then : + enableval=$enable_crypt; build_crypt=$enableval +else + build_crypt=yes +fi + + + # Check whether --enable-nss-crypt was given. if test "${enable_nss_crypt+set}" = set; then : enableval=$enable_nss_crypt; nss_crypt=$enableval @@ -3512,6 +3525,11 @@ else nss_crypt=no fi +if test x$build_libcrypt = xno && test x$nss_crypt = xyes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: --enable-nss-crypt has no effect when libcrypt is disabled" >&5 +$as_echo "$as_me: WARNING: --enable-nss-crypt has no effect when libcrypt is disabled" >&2;} + nss_crypt=no +fi if test x$nss_crypt = xyes; then nss_includes=-I$(nss-config --includedir 2>/dev/null) if test $? -ne 0; then diff --git a/configure.ac b/configure.ac index ca1282a6b3..dc517017f5 100644 --- a/configure.ac +++ b/configure.ac @@ -302,11 +302,22 @@ AC_ARG_ENABLE([experimental-malloc], [experimental_malloc=yes]) AC_SUBST(experimental_malloc) +AC_ARG_ENABLE([crypt], + AC_HELP_STRING([--disable-crypt], + [do not build nor install the passphrase hashing library, libcrypt]), + [build_crypt=$enableval], + [build_crypt=yes]) +AC_SUBST(build_crypt) + AC_ARG_ENABLE([nss-crypt], AC_HELP_STRING([--enable-nss-crypt], [enable libcrypt to use nss]), [nss_crypt=$enableval], [nss_crypt=no]) +if test x$build_libcrypt = xno && test x$nss_crypt = xyes; then + AC_MSG_WARN([--enable-nss-crypt has no effect when libcrypt is disabled]) + nss_crypt=no +fi if test x$nss_crypt = xyes; then nss_includes=-I$(nss-config --includedir 2>/dev/null) if test $? -ne 0; then diff --git a/conform/Makefile b/conform/Makefile index 864fdeca21..74fbda0786 100644 --- a/conform/Makefile +++ b/conform/Makefile @@ -193,13 +193,11 @@ linknamespace-libs-thr = $(linknamespace-libs-isoc) \ $(common-objpfx)rt/librt.a $(static-thread-library) linknamespace-libs-posix = $(linknamespace-libs-thr) \ $(common-objpfx)dlfcn/libdl.a -linknamespace-libs-xsi = $(linknamespace-libs-posix) \ - $(common-objpfx)crypt/libcrypt.a +linknamespace-libs-xsi = $(linknamespace-libs-posix) linknamespace-libs-ISO = $(linknamespace-libs-isoc) linknamespace-libs-ISO99 = $(linknamespace-libs-isoc) linknamespace-libs-ISO11 = $(linknamespace-libs-isoc) -linknamespace-libs-XPG4 = $(linknamespace-libs-isoc) \ - $(common-objpfx)crypt/libcrypt.a +linknamespace-libs-XPG4 = $(linknamespace-libs-isoc) linknamespace-libs-XPG42 = $(linknamespace-libs-XPG4) linknamespace-libs-POSIX = $(linknamespace-libs-thr) linknamespace-libs-UNIX98 = $(linknamespace-libs-xsi) @@ -209,6 +207,11 @@ linknamespace-libs-XOPEN2K8 = $(linknamespace-libs-xsi) linknamespace-libs = $(foreach std,$(conformtest-standards),\ $(linknamespace-libs-$(std))) +ifeq ($(build-crypt),yes) +linknamespace-libs-xsi += $(common-objpfx)crypt/libcrypt.a +linknamespace-libs-XPG4 += $(common-objpfx)crypt/libcrypt.a +endif + $(linknamespace-symlist-stdlibs-tests): $(objpfx)symlist-stdlibs-%: \ $(linknamespace-libs) LC_ALL=C $(READELF) -W -s $(linknamespace-libs-$*) > $@; \ diff --git a/crypt/Makefile b/crypt/Makefile index 303800df73..3811b6e298 100644 --- a/crypt/Makefile +++ b/crypt/Makefile @@ -32,10 +32,6 @@ libcrypt-routines := crypt-entry md5-crypt sha256-crypt sha512-crypt crypt \ tests := cert md5c-test sha256c-test sha512c-test badsalttest -ifeq ($(crypt-in-libc),yes) -routines += $(libcrypt-routines) -endif - ifeq ($(nss-crypt),yes) nss-cpp-flags := -DUSE_NSS \ -I$(shell nss-config --includedir) -I$(shell nspr-config --includedir) diff --git a/elf/Makefile b/elf/Makefile index f221422de3..0eb7c8114e 100644 --- a/elf/Makefile +++ b/elf/Makefile @@ -387,14 +387,21 @@ $(objpfx)tst-_dl_addr_inside_object: $(objpfx)dl-addr-obj.os CFLAGS-tst-_dl_addr_inside_object.c += $(PIE-ccflag) endif -# By default tst-linkall-static should try to use crypt routines to test -# static libcrypt use. +# We can only test static libcrypt use if libcrypt has been built, +# and either NSS crypto is not in use, or static NSS libraries are +# available. +ifeq ($(build-crypt),no) +CFLAGS-tst-linkall-static.c += -DUSE_CRYPT=0 +else +ifeq ($(nss-crypt),no) +CFLAGS-tst-linkall-static.c += -DUSE_CRYPT=1 +else +ifeq ($(static-nss-crypt),no) +CFLAGS-tst-linkall-static.c += -DUSE_CRYPT=0 +else CFLAGS-tst-linkall-static.c += -DUSE_CRYPT=1 -# However, if we are using NSS crypto and we don't have a static -# library, then we exclude the use of crypt functions in the test. -# We similarly exclude libcrypt.a from the static link (see below). -ifeq (yesno,$(nss-crypt)$(static-nss-crypt)) -CFLAGS-tst-linkall-static.c += -UUSE_CRYPT -DUSE_CRYPT=0 +endif +endif endif include ../Rules @@ -1115,7 +1122,6 @@ localplt-built-dso := $(addprefix $(common-objpfx),\ rt/librt.so \ dlfcn/libdl.so \ resolv/libresolv.so \ - crypt/libcrypt.so \ ) ifeq ($(build-mathvec),yes) localplt-built-dso += $(addprefix $(common-objpfx), mathvec/libmvec.so) @@ -1123,6 +1129,9 @@ endif ifeq ($(have-thread-library),yes) localplt-built-dso += $(filter-out %_nonshared.a, $(shared-thread-library)) endif +ifeq ($(build-crypt),yes) +localplt-built-dso += $(addprefix $(common-objpfx), crypt/libcrypt.so) +endif vpath localplt.data $(+sysdep_dirs) @@ -1410,6 +1419,7 @@ $(objpfx)tst-linkall-static: \ $(common-objpfx)resolv/libanl.a \ $(static-thread-library) +ifeq ($(build-crypt),yes) # If we are using NSS crypto and we have the ability to link statically # then we include libcrypt.a, otherwise we leave out libcrypt.a and # link as much as we can into the tst-linkall-static test. This assumes @@ -1425,6 +1435,7 @@ ifeq (no,$(nss-crypt)) $(objpfx)tst-linkall-static: \ $(common-objpfx)crypt/libcrypt.a endif +endif # The application depends on the DSO, and the DSO loads the plugin. # The plugin also depends on the DSO. This creates the circular diff --git a/elf/tst-linkall-static.c b/elf/tst-linkall-static.c index e8df38f74e..d0f2592e67 100644 --- a/elf/tst-linkall-static.c +++ b/elf/tst-linkall-static.c @@ -18,7 +18,9 @@ #include #include -#include +#if USE_CRYPT +# include +#endif #include #include #include diff --git a/manual/install.texi b/manual/install.texi index 4bbbfcffa5..422da1447e 100644 --- a/manual/install.texi +++ b/manual/install.texi @@ -230,6 +230,17 @@ libnss_nisplus are not built at all. Use this option to enable libnsl with all depending NSS modules and header files. +@item --disable-crypt +Do not install the passphrase-hashing library @file{libcrypt} or the +header file @file{crypt.h}. @file{unistd.h} will still declare the +function @code{crypt}. Using this option does not change the set of +programs that may need to be linked with @option{-lcrypt}; it only +means that @theglibc{} will not provide that library. + +This option is for hackers and distributions experimenting with +independently-maintained implementations of libcrypt. It may become +the default in a future release. + @item --disable-experimental-malloc By default, a per-thread cache is enabled in @code{malloc}. While this cache can be disabled on a per-application basis using tunables -- cgit v1.2.3 From f2873d2da0ac9802e0b570e8e0b9e7e04a82bf55 Mon Sep 17 00:00:00 2001 From: Florian Weimer Date: Wed, 4 Jul 2018 15:27:24 +0200 Subject: testrun.sh: Implement --tool=strace, --tool=valgrind MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit $(file …) appears to be the only convenient way to create files with newlines and make substitution variables. This needs make 4.0 (released in 2013), so update the requirement to match. Reviewed-by: Carlos O'Donell --- ChangeLog | 11 +++++++++++ INSTALL | 8 +------- Makefile | 55 +++++++++++++++++++++++++++++++++++++++++++++++------ NEWS | 2 +- configure | 2 +- configure.ac | 2 +- manual/install.texi | 8 +------- 7 files changed, 65 insertions(+), 23 deletions(-) (limited to 'configure.ac') diff --git a/ChangeLog b/ChangeLog index c17caff776..a8b15be55f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2018-07-04 Florian Weimer + + testrun.sh: Implement --tool=strace, --tool=valgrind + * Makefile (testrun-script): Define variable. + (testrun.sh): Use variable. + * manual/install.texi (Tools for Compilation): make 4.0 or later + is required. + * configure.ac: Check for make 4.0 or later. + * INSTALL: Regenerate. + * configure: Likewise. + 2018-07-04 Adhemerval Zanella [BZ #23233] diff --git a/INSTALL b/INSTALL index 0a22aa7d01..3c656fb7a6 100644 --- a/INSTALL +++ b/INSTALL @@ -426,13 +426,7 @@ Recommended Tools for Compilation We recommend installing the following GNU tools before attempting to build the GNU C Library: - * GNU 'make' 3.79 or newer - - You need the latest version of GNU 'make'. Modifying the GNU C - Library to work with other 'make' programs would be so difficult - that we recommend you port GNU 'make' instead. *Really.* We - recommend GNU 'make' version 3.79. All earlier versions have - severe bugs or lack features. + * GNU 'make' 4.0 or newer * GCC 4.9 or newer diff --git a/Makefile b/Makefile index bea4e27f8d..d3f25a525a 100644 --- a/Makefile +++ b/Makefile @@ -128,17 +128,60 @@ ifeq (yes,$(build-shared)) lib: $(common-objpfx)libc.so $(common-objpfx)linkobj/libc.so endif # $(build-shared) +# Used to build testrun.sh. +define testrun-script +#!/bin/bash +builddir=`dirname "$$0"` +GCONV_PATH="$${builddir}/iconvdata" + +usage () { + echo "usage: $$0 [--tool=strace] PROGRAM [ARGUMENTS...]" 2>&1 + echo " $$0 --tool=valgrind PROGRAM [ARGUMENTS...]" 2>&1 +} + +toolname=default +while test $$# -gt 0 ; do + case "$$1" in + --tool=*) + toolname="$${1:7}" + shift + ;; + --*) + usage + ;; + *) + break + ;; + esac +done + +if test $$# -eq 0 ; then + usage +fi + +case "$$toolname" in + default) + exec $(subst $(common-objdir),"$${builddir}", $(test-program-prefix)) \ + $${1+"$$@"} + ;; + strace) + exec strace $(patsubst %, -E%, $(run-program-env)) \ + $(test-via-rtld-prefix) $${1+"$$@"} + ;; + valgrind) + exec env $(run-program-env) valgrind $(test-via-rtld-prefix) $${1+"$$@"} + ;; + *) + usage + ;; +esac +endef # This is a handy script for running any dynamically linked program against # the current libc build for testing. $(common-objpfx)testrun.sh: $(common-objpfx)config.make \ $(..)Makeconfig $(..)Makefile - (echo '#!/bin/sh'; \ - echo 'builddir=`dirname "$$0"`'; \ - echo 'GCONV_PATH="$${builddir}/iconvdata" \'; \ - echo 'exec $(subst $(common-objdir),"$${builddir}",\ - $(test-program-prefix)) $${1+"$$@"}'; \ - ) > $@T + $(file >$@T, $(testrun-script)) chmod a+x $@T mv -f $@T $@ postclean-generated += testrun.sh diff --git a/NEWS b/NEWS index 21b457a050..b1ce067d27 100644 --- a/NEWS +++ b/NEWS @@ -154,7 +154,7 @@ Deprecated and removed features, and other changes affecting compatibility: Changes to build and runtime requirements: - [Add changes to build and runtime requirements here] + GNU make 4.0 or later is now required to build glibc. Security related changes: diff --git a/configure b/configure index ef18302215..eac7f292b4 100755 --- a/configure +++ b/configure @@ -4705,7 +4705,7 @@ $as_echo_n "checking version of $MAKE... " >&6; } ac_prog_version=`$MAKE --version 2>&1 | sed -n 's/^.*GNU Make[^0-9]*\([0-9][0-9.]*\).*$/\1/p'` case $ac_prog_version in '') ac_prog_version="v. ?.??, bad"; ac_verc_fail=yes;; - 3.79* | 3.[89]* | [4-9].* | [1-9][0-9]*) + [4-9].* | [1-9][0-9]*) ac_prog_version="$ac_prog_version, ok"; ac_verc_fail=no;; *) ac_prog_version="$ac_prog_version, bad"; ac_verc_fail=yes;; diff --git a/configure.ac b/configure.ac index dc517017f5..f41ed6decb 100644 --- a/configure.ac +++ b/configure.ac @@ -945,7 +945,7 @@ fi AC_CHECK_TOOL_PREFIX AC_CHECK_PROG_VER(MAKE, gnumake gmake make, --version, [GNU Make[^0-9]*\([0-9][0-9.]*\)], - [3.79* | 3.[89]* | [4-9].* | [1-9][0-9]*], critic_missing="$critic_missing make") + [[4-9].* | [1-9][0-9]*], critic_missing="$critic_missing make") AC_CHECK_PROG_VER(MSGFMT, gnumsgfmt gmsgfmt msgfmt, --version, [GNU gettext.* \([0-9]*\.[0-9.]*\)], diff --git a/manual/install.texi b/manual/install.texi index 422da1447e..42e9954199 100644 --- a/manual/install.texi +++ b/manual/install.texi @@ -473,13 +473,7 @@ build @theglibc{}: @itemize @bullet @item -GNU @code{make} 3.79 or newer - -You need the latest version of GNU @code{make}. Modifying @theglibc{} -to work with other @code{make} programs would be so difficult that -we recommend you port GNU @code{make} instead. @strong{Really.} We -recommend GNU @code{make} version 3.79. All earlier versions have severe -bugs or lack features. +GNU @code{make} 4.0 or newer @item GCC 4.9 or newer -- cgit v1.2.3 From f753fa7dea3367bd3eb7b543103ff8cda182a3fa Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Mon, 16 Jul 2018 14:08:15 -0700 Subject: x86: Support IBT and SHSTK in Intel CET [BZ #21598] Intel Control-flow Enforcement Technology (CET) instructions: https://software.intel.com/sites/default/files/managed/4d/2a/control-flow-en forcement-technology-preview.pdf includes Indirect Branch Tracking (IBT) and Shadow Stack (SHSTK). GNU_PROPERTY_X86_FEATURE_1_IBT is added to GNU program property to indicate that all executable sections are compatible with IBT when ENDBR instruction starts each valid target where an indirect branch instruction can land. Linker sets GNU_PROPERTY_X86_FEATURE_1_IBT on output only if it is set on all relocatable inputs. On an IBT capable processor, the following steps should be taken: 1. When loading an executable without an interpreter, enable IBT and lock IBT if GNU_PROPERTY_X86_FEATURE_1_IBT is set on the executable. 2. When loading an executable with an interpreter, enable IBT if GNU_PROPERTY_X86_FEATURE_1_IBT is set on the interpreter. a. If GNU_PROPERTY_X86_FEATURE_1_IBT isn't set on the executable, disable IBT. b. Lock IBT. 3. If IBT is enabled, when loading a shared object without GNU_PROPERTY_X86_FEATURE_1_IBT: a. If legacy interwork is allowed, then mark all pages in executable PT_LOAD segments in legacy code page bitmap. Failure of legacy code page bitmap allocation causes an error. b. If legacy interwork isn't allowed, it causes an error. GNU_PROPERTY_X86_FEATURE_1_SHSTK is added to GNU program property to indicate that all executable sections are compatible with SHSTK where return address popped from shadow stack always matches return address popped from normal stack. Linker sets GNU_PROPERTY_X86_FEATURE_1_SHSTK on output only if it is set on all relocatable inputs. On a SHSTK capable processor, the following steps should be taken: 1. When loading an executable without an interpreter, enable SHSTK if GNU_PROPERTY_X86_FEATURE_1_SHSTK is set on the executable. 2. When loading an executable with an interpreter, enable SHSTK if GNU_PROPERTY_X86_FEATURE_1_SHSTK is set on interpreter. a. If GNU_PROPERTY_X86_FEATURE_1_SHSTK isn't set on the executable or any shared objects loaded via the DT_NEEDED tag, disable SHSTK. b. Otherwise lock SHSTK. 3. After SHSTK is enabled, it is an error to load a shared object without GNU_PROPERTY_X86_FEATURE_1_SHSTK. To enable CET support in glibc, --enable-cet is required to configure glibc. When CET is enabled, both compiler and assembler must support CET. Otherwise, it is a configure-time error. To support CET run-time control, 1. _dl_x86_feature_1 is added to the writable ld.so namespace to indicate if IBT or SHSTK are enabled at run-time. It should be initialized by init_cpu_features. 2. For dynamic executables: a. A l_cet field is added to struct link_map to indicate if IBT or SHSTK is enabled in an ELF module. _dl_process_pt_note or _rtld_process_pt_note is called to process PT_NOTE segment for GNU program property and set l_cet. b. _dl_open_check is added to check IBT and SHSTK compatibilty when dlopening a shared object. 3. Replace i386 _dl_runtime_resolve and _dl_runtime_profile with _dl_runtime_resolve_shstk and _dl_runtime_profile_shstk, respectively if SHSTK is enabled. CET run-time control can be changed via GLIBC_TUNABLES with $ export GLIBC_TUNABLES=glibc.tune.x86_shstk=[permissive|on|off] $ export GLIBC_TUNABLES=glibc.tune.x86_ibt=[permissive|on|off] 1. permissive: SHSTK is disabled when dlopening a legacy ELF module. 2. on: IBT or SHSTK are always enabled, regardless if there are IBT or SHSTK bits in GNU program property. 3. off: IBT or SHSTK are always disabled, regardless if there are IBT or SHSTK bits in GNU program property. from CET-enabled GCC is automatically included by assembly codes to add GNU_PROPERTY_X86_FEATURE_1_IBT and GNU_PROPERTY_X86_FEATURE_1_SHSTK to GNU program property. _CET_ENDBR is added at the entrance of all assembly functions whose address may be taken. _CET_NOTRACK is used to insert NOTRACK prefix with indirect jump table to support IBT. It is defined as notrack when _CET_NOTRACK is defined in . [BZ #21598] * configure.ac: Add --enable-cet. * configure: Regenerated. * elf/Makefille (all-built-dso): Add a comment. * elf/dl-load.c (filebuf): Moved before "dynamic-link.h". Include . (_dl_map_object_from_fd): Call _dl_process_pt_note on PT_NOTE segment. * elf/dl-open.c: Include . (dl_open_worker): Call _dl_open_check. * elf/rtld.c: Include . (dl_main): Call _rtld_process_pt_note on PT_NOTE segment. Call _rtld_main_check. * sysdeps/generic/dl-prop.h: New file. * sysdeps/i386/dl-cet.c: Likewise. * sysdeps/unix/sysv/linux/x86/cpu-features.c: Likewise. * sysdeps/unix/sysv/linux/x86/dl-cet.h: Likewise. * sysdeps/x86/cet-tunables.h: Likewise. * sysdeps/x86/check-cet.awk: Likewise. * sysdeps/x86/configure: Likewise. * sysdeps/x86/configure.ac: Likewise. * sysdeps/x86/dl-cet.c: Likewise. * sysdeps/x86/dl-procruntime.c: Likewise. * sysdeps/x86/dl-prop.h: Likewise. * sysdeps/x86/libc-start.h: Likewise. * sysdeps/x86/link_map.h: Likewise. * sysdeps/i386/dl-trampoline.S (_dl_runtime_resolve): Add _CET_ENDBR. (_dl_runtime_profile): Likewise. (_dl_runtime_resolve_shstk): New. (_dl_runtime_profile_shstk): Likewise. * sysdeps/linux/x86/Makefile (sysdep-dl-routines): Add dl-cet if CET is enabled. (CFLAGS-.o): Add -fcf-protection if CET is enabled. (CFLAGS-.os): Likewise. (CFLAGS-.op): Likewise. (CFLAGS-.oS): Likewise. (asm-CPPFLAGS): Add -fcf-protection -include cet.h if CET is enabled. (tests-special): Add $(objpfx)check-cet.out. (cet-built-dso): New. (+$(cet-built-dso:=.note)): Likewise. (common-generated): Add $(cet-built-dso:$(common-objpfx)%=%.note). ($(objpfx)check-cet.out): New. (generated): Add check-cet.out. * sysdeps/x86/cpu-features.c: Include and . (TUNABLE_CALLBACK (set_x86_ibt)): New prototype. (TUNABLE_CALLBACK (set_x86_shstk)): Likewise. (init_cpu_features): Call get_cet_status to check CET status and update dl_x86_feature_1 with CET status. Call TUNABLE_CALLBACK (set_x86_ibt) and TUNABLE_CALLBACK (set_x86_shstk). Disable and lock CET in libc.a. * sysdeps/x86/cpu-tunables.c: Include . (TUNABLE_CALLBACK (set_x86_ibt)): New function. (TUNABLE_CALLBACK (set_x86_shstk)): Likewise. * sysdeps/x86/sysdep.h (_CET_NOTRACK): New. (_CET_ENDBR): Define if not defined. (ENTRY): Add _CET_ENDBR. * sysdeps/x86/dl-tunables.list (glibc.tune): Add x86_ibt and x86_shstk. * sysdeps/x86_64/dl-trampoline.h (_dl_runtime_resolve): Add _CET_ENDBR. (_dl_runtime_profile): Likewise. --- ChangeLog | 67 ++++++ configure | 11 + configure.ac | 6 + elf/Makefile | 2 + elf/dl-load.c | 60 ++--- elf/dl-open.c | 3 + elf/rtld.c | 9 + sysdeps/generic/dl-prop.h | 54 +++++ sysdeps/i386/dl-cet.c | 67 ++++++ sysdeps/i386/dl-trampoline.S | 72 ++++++ sysdeps/unix/sysv/linux/x86/cpu-features.c | 38 ++++ sysdeps/unix/sysv/linux/x86/dl-cet.h | 37 +++ sysdeps/x86/Makefile | 42 ++++ sysdeps/x86/cet-tunables.h | 29 +++ sysdeps/x86/check-cet.awk | 53 +++++ sysdeps/x86/configure | 69 ++++++ sysdeps/x86/configure.ac | 46 ++++ sysdeps/x86/cpu-features.c | 60 +++++ sysdeps/x86/cpu-tunables.c | 48 ++++ sysdeps/x86/dl-cet.c | 346 +++++++++++++++++++++++++++++ sysdeps/x86/dl-procruntime.c | 68 ++++++ sysdeps/x86/dl-prop.h | 153 +++++++++++++ sysdeps/x86/dl-tunables.list | 6 + sysdeps/x86/libc-start.h | 25 +++ sysdeps/x86/link_map.h | 26 +++ sysdeps/x86/sysdep.h | 8 + sysdeps/x86_64/dl-trampoline.h | 2 + 27 files changed, 1382 insertions(+), 25 deletions(-) create mode 100644 sysdeps/generic/dl-prop.h create mode 100644 sysdeps/i386/dl-cet.c create mode 100644 sysdeps/unix/sysv/linux/x86/cpu-features.c create mode 100644 sysdeps/unix/sysv/linux/x86/dl-cet.h create mode 100644 sysdeps/x86/cet-tunables.h create mode 100644 sysdeps/x86/check-cet.awk create mode 100644 sysdeps/x86/configure create mode 100644 sysdeps/x86/configure.ac create mode 100644 sysdeps/x86/dl-cet.c create mode 100644 sysdeps/x86/dl-procruntime.c create mode 100644 sysdeps/x86/dl-prop.h create mode 100644 sysdeps/x86/libc-start.h create mode 100644 sysdeps/x86/link_map.h (limited to 'configure.ac') diff --git a/ChangeLog b/ChangeLog index 65dd07f41c..05d05f7d41 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,70 @@ +2018-07-16 H.J. Lu + + [BZ #21598] + * configure.ac: Add --enable-cet. + * configure: Regenerated. + * elf/Makefille (all-built-dso): Add a comment. + * elf/dl-load.c (filebuf): Moved before "dynamic-link.h". + Include . + (_dl_map_object_from_fd): Call _dl_process_pt_note on PT_NOTE + segment. + * elf/dl-open.c: Include . + (dl_open_worker): Call _dl_open_check. + * elf/rtld.c: Include . + (dl_main): Call _rtld_process_pt_note on PT_NOTE segment. Call + _rtld_main_check. + * sysdeps/generic/dl-prop.h: New file. + * sysdeps/i386/dl-cet.c: Likewise. + * sysdeps/unix/sysv/linux/x86/cpu-features.c: Likewise. + * sysdeps/unix/sysv/linux/x86/dl-cet.h: Likewise. + * sysdeps/x86/cet-tunables.h: Likewise. + * sysdeps/x86/check-cet.awk: Likewise. + * sysdeps/x86/configure: Likewise. + * sysdeps/x86/configure.ac: Likewise. + * sysdeps/x86/dl-cet.c: Likewise. + * sysdeps/x86/dl-procruntime.c: Likewise. + * sysdeps/x86/dl-prop.h: Likewise. + * sysdeps/x86/libc-start.h: Likewise. + * sysdeps/x86/link_map.h: Likewise. + * sysdeps/i386/dl-trampoline.S (_dl_runtime_resolve): Add + _CET_ENDBR. + (_dl_runtime_profile): Likewise. + (_dl_runtime_resolve_shstk): New. + (_dl_runtime_profile_shstk): Likewise. + * sysdeps/linux/x86/Makefile (sysdep-dl-routines): Add dl-cet + if CET is enabled. + (CFLAGS-.o): Add -fcf-protection if CET is enabled. + (CFLAGS-.os): Likewise. + (CFLAGS-.op): Likewise. + (CFLAGS-.oS): Likewise. + (asm-CPPFLAGS): Add -fcf-protection -include cet.h if CET + is enabled. + (tests-special): Add $(objpfx)check-cet.out. + (cet-built-dso): New. + (+$(cet-built-dso:=.note)): Likewise. + (common-generated): Add $(cet-built-dso:$(common-objpfx)%=%.note). + ($(objpfx)check-cet.out): New. + (generated): Add check-cet.out. + * sysdeps/x86/cpu-features.c: Include and + . + (TUNABLE_CALLBACK (set_x86_ibt)): New prototype. + (TUNABLE_CALLBACK (set_x86_shstk)): Likewise. + (init_cpu_features): Call get_cet_status to check CET status + and update dl_x86_feature_1 with CET status. Call + TUNABLE_CALLBACK (set_x86_ibt) and TUNABLE_CALLBACK + (set_x86_shstk). Disable and lock CET in libc.a. + * sysdeps/x86/cpu-tunables.c: Include . + (TUNABLE_CALLBACK (set_x86_ibt)): New function. + (TUNABLE_CALLBACK (set_x86_shstk)): Likewise. + * sysdeps/x86/sysdep.h (_CET_NOTRACK): New. + (_CET_ENDBR): Define if not defined. + (ENTRY): Add _CET_ENDBR. + * sysdeps/x86/dl-tunables.list (glibc.tune): Add x86_ibt and + x86_shstk. + * sysdeps/x86_64/dl-trampoline.h (_dl_runtime_resolve): Add + _CET_ENDBR. + (_dl_runtime_profile): Likewise. + 2018-07-16 Rogerio A. Cardoso [BZ #21895] diff --git a/configure b/configure index eac7f292b4..fde57d63fe 100755 --- a/configure +++ b/configure @@ -790,6 +790,7 @@ enable_nscd enable_pt_chown enable_tunables enable_mathvec +enable_cet with_cpu ' ac_precious_vars='build_alias @@ -1465,6 +1466,8 @@ Optional Features: 'no' and 'valstring' --enable-mathvec Enable building and installing mathvec [default depends on architecture] + --enable-cet enable Intel Control-flow Enforcement Technology + (CET), x86 only Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] @@ -3759,6 +3762,14 @@ else fi +# Check whether --enable-cet was given. +if test "${enable_cet+set}" = set; then : + enableval=$enable_cet; enable_cet=$enableval +else + enable_cet=no +fi + + # We keep the original values in `$config_*' and never modify them, so we # can write them unchanged into config.make. Everything else uses # $machine, $vendor, and $os, and changes them whenever convenient. diff --git a/configure.ac b/configure.ac index f41ed6decb..014e09a5d5 100644 --- a/configure.ac +++ b/configure.ac @@ -464,6 +464,12 @@ AC_ARG_ENABLE([mathvec], [build_mathvec=$enableval], [build_mathvec=notset]) +AC_ARG_ENABLE([cet], + AC_HELP_STRING([--enable-cet], + [enable Intel Control-flow Enforcement Technology (CET), x86 only]), + [enable_cet=$enableval], + [enable_cet=no]) + # We keep the original values in `$config_*' and never modify them, so we # can write them unchanged into config.make. Everything else uses # $machine, $vendor, and $os, and changes them whenever convenient. diff --git a/elf/Makefile b/elf/Makefile index 41cc3681be..84107f6dbb 100644 --- a/elf/Makefile +++ b/elf/Makefile @@ -1058,6 +1058,8 @@ $(objpfx)tst-piemod1.so: $(libsupport) $(objpfx)tst-pie1: $(objpfx)tst-piemod1.so ifeq (yes,$(build-shared)) +# NB: Please keep cet-built-dso in sysdeps/x86/Makefile in sync with +# all-built-dso here. all-built-dso := $(common-objpfx)elf/ld.so $(common-objpfx)libc.so \ $(filter-out $(common-objpfx)linkobj/libc.so, \ $(sort $(wildcard $(addprefix $(common-objpfx), \ diff --git a/elf/dl-load.c b/elf/dl-load.c index 09185ab68d..c51e4b3718 100644 --- a/elf/dl-load.c +++ b/elf/dl-load.c @@ -30,6 +30,32 @@ #include #include #include + +/* Type for the buffer we put the ELF header and hopefully the program + header. This buffer does not really have to be too large. In most + cases the program header follows the ELF header directly. If this + is not the case all bets are off and we can make the header + arbitrarily large and still won't get it read. This means the only + question is how large are the ELF and program header combined. The + ELF header 32-bit files is 52 bytes long and in 64-bit files is 64 + bytes long. Each program header entry is again 32 and 56 bytes + long respectively. I.e., even with a file which has 10 program + header entries we only have to read 372B/624B respectively. Add to + this a bit of margin for program notes and reading 512B and 832B + for 32-bit and 64-bit files respecitvely is enough. If this + heuristic should really fail for some file the code in + `_dl_map_object_from_fd' knows how to recover. */ +struct filebuf +{ + ssize_t len; +#if __WORDSIZE == 32 +# define FILEBUF_SIZE 512 +#else +# define FILEBUF_SIZE 832 +#endif + char buf[FILEBUF_SIZE] __attribute__ ((aligned (__alignof (ElfW(Ehdr))))); +}; + #include "dynamic-link.h" #include #include @@ -44,6 +70,7 @@ #include #include #include +#include #include #include @@ -69,31 +96,6 @@ int __stack_prot attribute_hidden attribute_relro #endif -/* Type for the buffer we put the ELF header and hopefully the program - header. This buffer does not really have to be too large. In most - cases the program header follows the ELF header directly. If this - is not the case all bets are off and we can make the header - arbitrarily large and still won't get it read. This means the only - question is how large are the ELF and program header combined. The - ELF header 32-bit files is 52 bytes long and in 64-bit files is 64 - bytes long. Each program header entry is again 32 and 56 bytes - long respectively. I.e., even with a file which has 10 program - header entries we only have to read 372B/624B respectively. Add to - this a bit of margin for program notes and reading 512B and 832B - for 32-bit and 64-bit files respecitvely is enough. If this - heuristic should really fail for some file the code in - `_dl_map_object_from_fd' knows how to recover. */ -struct filebuf -{ - ssize_t len; -#if __WORDSIZE == 32 -# define FILEBUF_SIZE 512 -#else -# define FILEBUF_SIZE 832 -#endif - char buf[FILEBUF_SIZE] __attribute__ ((aligned (__alignof (ElfW(Ehdr))))); -}; - /* This is the decomposed LD_LIBRARY_PATH search path. */ static struct r_search_path_struct env_path_list attribute_relro; @@ -1152,6 +1154,14 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd, l->l_relro_addr = ph->p_vaddr; l->l_relro_size = ph->p_memsz; break; + + case PT_NOTE: + if (_dl_process_pt_note (l, ph, fd, fbp)) + { + errstring = N_("cannot process note segment"); + goto call_lose; + } + break; } if (__glibc_unlikely (nloadcmds == 0)) diff --git a/elf/dl-open.c b/elf/dl-open.c index 9dde4acfbc..f6c8ef1043 100644 --- a/elf/dl-open.c +++ b/elf/dl-open.c @@ -35,6 +35,7 @@ #include #include +#include /* We must be careful not to leave us in an inconsistent state. Thus we @@ -291,6 +292,8 @@ dl_open_worker (void *a) _dl_debug_state (); LIBC_PROBE (map_complete, 3, args->nsid, r, new); + _dl_open_check (new); + /* Print scope information. */ if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_SCOPES)) _dl_show_scope (new, 0); diff --git a/elf/rtld.c b/elf/rtld.c index 8c732adb68..1b0c74739f 100644 --- a/elf/rtld.c +++ b/elf/rtld.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #include #include @@ -1241,6 +1242,12 @@ of this helper program; chances are you did not intend to run this program.\n\ main_map->l_relro_addr = ph->p_vaddr; main_map->l_relro_size = ph->p_memsz; break; + + case PT_NOTE: + if (_rtld_process_pt_note (main_map, ph)) + _dl_error_printf ("\ +ERROR: '%s': cannot process note segment.\n", _dl_argv[0]); + break; } /* Adjust the address of the TLS initialization image in case @@ -2110,6 +2117,8 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n", _dl_show_scope (l, 0); } + _rtld_main_check (main_map, _dl_argv[0]); + if (prelinked) { if (main_map->l_info [ADDRIDX (DT_GNU_CONFLICT)] != NULL) diff --git a/sysdeps/generic/dl-prop.h b/sysdeps/generic/dl-prop.h new file mode 100644 index 0000000000..a2b1d38c79 --- /dev/null +++ b/sysdeps/generic/dl-prop.h @@ -0,0 +1,54 @@ +/* Support for GNU properties. Generic version. + Copyright (C) 2018 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 + . */ + +#ifndef _DL_PROP_H +#define _DL_PROP_H + +/* The following functions are used by the dynamic loader and the + dlopen machinery to process PT_NOTE entries in the binary or + shared object. The notes can be used to change the behaviour of + the loader, and as such offer a flexible mechanism for hooking in + various checks related to ABI tags or implementing "flag day" ABI + transitions. */ + +static inline void __attribute__ ((always_inline)) +_rtld_main_check (struct link_map *m, const char *program) +{ +} + +static inline void __attribute__ ((always_inline)) +_dl_open_check (struct link_map *m) +{ +} + +#ifdef FILEBUF_SIZE +static inline int __attribute__ ((always_inline)) +_dl_process_pt_note (struct link_map *l, const ElfW(Phdr) *ph, + int fd, struct filebuf *fbp) +{ + return 0; +} +#endif + +static inline int __attribute__ ((always_inline)) +_rtld_process_pt_note (struct link_map *l, const ElfW(Phdr) *ph) +{ + return 0; +} + +#endif /* _DL_PROP_H */ diff --git a/sysdeps/i386/dl-cet.c b/sysdeps/i386/dl-cet.c new file mode 100644 index 0000000000..5d9a4e8d51 --- /dev/null +++ b/sysdeps/i386/dl-cet.c @@ -0,0 +1,67 @@ +/* Linux/i386 CET initializers function. + Copyright (C) 2018 Free Software Foundation, Inc. + + 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 + . */ + + +#define LINKAGE static inline +#define _dl_cet_check cet_check +#include +#undef _dl_cet_check + +#ifdef SHARED +void +_dl_cet_check (struct link_map *main_map, const char *program) +{ + cet_check (main_map, program); + + if ((GL(dl_x86_feature_1)[0] & GNU_PROPERTY_X86_FEATURE_1_SHSTK)) + { + /* Replace _dl_runtime_resolve and _dl_runtime_profile with + _dl_runtime_resolve_shstk and _dl_runtime_profile_shstk, + respectively if SHSTK is enabled. */ + extern void _dl_runtime_resolve (Elf32_Word) attribute_hidden; + extern void _dl_runtime_resolve_shstk (Elf32_Word) attribute_hidden; + extern void _dl_runtime_profile (Elf32_Word) attribute_hidden; + extern void _dl_runtime_profile_shstk (Elf32_Word) attribute_hidden; + unsigned int i; + struct link_map *l; + Elf32_Addr *got; + + if (main_map->l_info[DT_JMPREL]) + { + got = (Elf32_Addr *) D_PTR (main_map, l_info[DT_PLTGOT]); + if (got[2] == (Elf32_Addr) &_dl_runtime_resolve) + got[2] = (Elf32_Addr) &_dl_runtime_resolve_shstk; + else if (got[2] == (Elf32_Addr) &_dl_runtime_profile) + got[2] = (Elf32_Addr) &_dl_runtime_profile_shstk; + } + + i = main_map->l_searchlist.r_nlist; + while (i-- > 0) + { + l = main_map->l_initfini[i]; + if (l->l_info[DT_JMPREL]) + { + got = (Elf32_Addr *) D_PTR (l, l_info[DT_PLTGOT]); + if (got[2] == (Elf32_Addr) &_dl_runtime_resolve) + got[2] = (Elf32_Addr) &_dl_runtime_resolve_shstk; + else if (got[2] == (Elf32_Addr) &_dl_runtime_profile) + got[2] = (Elf32_Addr) &_dl_runtime_profile_shstk; + } + } + } +} +#endif diff --git a/sysdeps/i386/dl-trampoline.S b/sysdeps/i386/dl-trampoline.S index 8bf86f8fd9..6dc0319216 100644 --- a/sysdeps/i386/dl-trampoline.S +++ b/sysdeps/i386/dl-trampoline.S @@ -32,6 +32,7 @@ .align 16 _dl_runtime_resolve: cfi_adjust_cfa_offset (8) + _CET_ENDBR pushl %eax # Preserve registers otherwise clobbered. cfi_adjust_cfa_offset (4) pushl %ecx @@ -50,14 +51,85 @@ _dl_runtime_resolve: cfi_endproc .size _dl_runtime_resolve, .-_dl_runtime_resolve +# The SHSTK compatible version. + .text + .globl _dl_runtime_resolve_shstk + .type _dl_runtime_resolve_shstk, @function + cfi_startproc + .align 16 +_dl_runtime_resolve_shstk: + cfi_adjust_cfa_offset (8) + _CET_ENDBR + pushl %eax # Preserve registers otherwise clobbered. + cfi_adjust_cfa_offset (4) + pushl %edx + cfi_adjust_cfa_offset (4) + movl 12(%esp), %edx # Copy args pushed by PLT in register. Note + movl 8(%esp), %eax # that `fixup' takes its parameters in regs. + call _dl_fixup # Call resolver. + movl (%esp), %edx # Get register content back. + movl %eax, %ecx # Store the function address. + movl 4(%esp), %eax # Get register content back. + addl $16, %esp # Adjust stack: PLT1 + PLT2 + %eax + %edx + cfi_adjust_cfa_offset (-16) + jmp *%ecx # Jump to function address. + cfi_endproc + .size _dl_runtime_resolve_shstk, .-_dl_runtime_resolve_shstk #ifndef PROF +# The SHSTK compatible version. + .globl _dl_runtime_profile_shstk + .type _dl_runtime_profile_shstk, @function + cfi_startproc + .align 16 +_dl_runtime_profile_shstk: + cfi_adjust_cfa_offset (8) + _CET_ENDBR + pushl %esp + cfi_adjust_cfa_offset (4) + addl $8, (%esp) # Account for the pushed PLT data + pushl %ebp + cfi_adjust_cfa_offset (4) + pushl %eax # Preserve registers otherwise clobbered. + cfi_adjust_cfa_offset (4) + pushl %ecx + cfi_adjust_cfa_offset (4) + pushl %edx + cfi_adjust_cfa_offset (4) + movl %esp, %ecx + subl $8, %esp + cfi_adjust_cfa_offset (8) + movl $-1, 4(%esp) + leal 4(%esp), %edx + movl %edx, (%esp) + pushl %ecx # Address of the register structure + cfi_adjust_cfa_offset (4) + movl 40(%esp), %ecx # Load return address + movl 36(%esp), %edx # Copy args pushed by PLT in register. Note + movl 32(%esp), %eax # that `fixup' takes its parameters in regs. + call _dl_profile_fixup # Call resolver. + cfi_adjust_cfa_offset (-8) + movl (%esp), %edx + testl %edx, %edx + jns 1f + movl 4(%esp), %edx # Get register content back. + movl %eax, %ecx # Store the function address. + movl 12(%esp), %eax # Get register content back. + # Adjust stack: PLT1 + PLT2 + %esp + %ebp + %eax + %ecx + %edx + # + free. + addl $32, %esp + cfi_adjust_cfa_offset (-32) + jmp *%ecx # Jump to function address. + cfi_endproc + .size _dl_runtime_profile_shstk, .-_dl_runtime_profile_shstk + .globl _dl_runtime_profile .type _dl_runtime_profile, @function cfi_startproc .align 16 _dl_runtime_profile: cfi_adjust_cfa_offset (8) + _CET_ENDBR pushl %esp cfi_adjust_cfa_offset (4) addl $8, (%esp) # Account for the pushed PLT data diff --git a/sysdeps/unix/sysv/linux/x86/cpu-features.c b/sysdeps/unix/sysv/linux/x86/cpu-features.c new file mode 100644 index 0000000000..7c9df9b794 --- /dev/null +++ b/sysdeps/unix/sysv/linux/x86/cpu-features.c @@ -0,0 +1,38 @@ +/* Initialize CPU feature data for Linux/x86. + This file is part of the GNU C Library. + Copyright (C) 2018 Free Software Foundation, Inc. + + 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 + . */ + +#if CET_ENABLED +static inline int __attribute__ ((always_inline)) +get_cet_status (void) +{ + return 0; +} + +# ifndef SHARED +static inline void +x86_setup_tls (void) +{ + __libc_setup_tls (); + THREAD_SETMEM (THREAD_SELF, header.feature_1, GL(dl_x86_feature_1)[0]); +} + +# define ARCH_SETUP_TLS() x86_setup_tls () +# endif +#endif + +#include diff --git a/sysdeps/unix/sysv/linux/x86/dl-cet.h b/sysdeps/unix/sysv/linux/x86/dl-cet.h new file mode 100644 index 0000000000..ae81e2f2ca --- /dev/null +++ b/sysdeps/unix/sysv/linux/x86/dl-cet.h @@ -0,0 +1,37 @@ +/* Linux/x86 CET initializers function. + Copyright (C) 2018 Free Software Foundation, Inc. + + 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 + . */ + +static inline int __attribute__ ((always_inline)) +dl_cet_allocate_legacy_bitmap (unsigned long *legacy_bitmap) +{ + /* FIXME: Need syscall support. */ + return -1; +} + +static inline int __attribute__ ((always_inline)) +dl_cet_disable_cet (unsigned int cet_feature) +{ + /* FIXME: Need syscall support. */ + return -1; +} + +static inline int __attribute__ ((always_inline)) +dl_cet_lock_cet (void) +{ + /* FIXME: Need syscall support. */ + return -1; +} diff --git a/sysdeps/x86/Makefile b/sysdeps/x86/Makefile index 65292f4032..e9b2d0b35d 100644 --- a/sysdeps/x86/Makefile +++ b/sysdeps/x86/Makefile @@ -13,3 +13,45 @@ ifeq ($(subdir),setjmp) gen-as-const-headers += jmp_buf-ssp.sym sysdep_routines += __longjmp_cancel endif + +ifeq ($(enable-cet),yes) +ifeq ($(subdir),elf) +sysdep-dl-routines += dl-cet +endif + +# Add -fcf-protection to CFLAGS when CET is enabled. +CFLAGS-.o += -fcf-protection +CFLAGS-.os += -fcf-protection +CFLAGS-.op += -fcf-protection +CFLAGS-.oS += -fcf-protection + +# Compile assembly codes with when CET is enabled. +asm-CPPFLAGS += -fcf-protection -include cet.h + +ifeq ($(subdir),elf) +ifeq (yes,$(build-shared)) +tests-special += $(objpfx)check-cet.out +endif + +# FIXME: Can't use all-built-dso in elf/Makefile since this file is +# processed before elf/Makefile. Duplicate it here. +cet-built-dso := $(common-objpfx)elf/ld.so $(common-objpfx)libc.so \ + $(filter-out $(common-objpfx)linkobj/libc.so, \ + $(sort $(wildcard $(addprefix $(common-objpfx), \ + */lib*.so \ + iconvdata/*.so)))) + +$(cet-built-dso:=.note): %.note: % + @rm -f $@T + LC_ALL=C $(READELF) -n $< > $@T + test -s $@T + mv -f $@T $@ +common-generated += $(cet-built-dso:$(common-objpfx)%=%.note) + +$(objpfx)check-cet.out: $(..)sysdeps/x86/check-cet.awk \ + $(cet-built-dso:=.note) + LC_ALL=C $(AWK) -f $^ > $@; \ + $(evaluate-test) +generated += check-cet.out +endif +endif diff --git a/sysdeps/x86/cet-tunables.h b/sysdeps/x86/cet-tunables.h new file mode 100644 index 0000000000..ca023053ee --- /dev/null +++ b/sysdeps/x86/cet-tunables.h @@ -0,0 +1,29 @@ +/* x86 CET tuning. + This file is part of the GNU C Library. + Copyright (C) 2018 Free Software Foundation, Inc. + + 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 + . */ + +/* Valid control values: + 0: Enable CET features based on ELF property note. + 1: Always disable CET features. + 2: Always enable CET features. + 3: Enable CET features permissively. + */ +#define CET_ELF_PROPERTY 0 +#define CET_ALWAYS_OFF 1 +#define CET_ALWAYS_ON 2 +#define CET_PERMISSIVE 3 +#define CET_MAX CET_PERMISSIVE diff --git a/sysdeps/x86/check-cet.awk b/sysdeps/x86/check-cet.awk new file mode 100644 index 0000000000..380d998caf --- /dev/null +++ b/sysdeps/x86/check-cet.awk @@ -0,0 +1,53 @@ +# Verify that all shared objects contain the CET property. +# Copyright (C) 2018 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 +# . + +# This awk script expects to get command-line files that are each +# the output of 'readelf -n' on a single shared object. +# It exits successfully (0) if all of them contained the CET property. +# It fails (1) if any didn't contain the CET property +# It fails (2) if the input did not take the expected form. + +BEGIN { result = cet = sanity = 0 } + +function check_one(name) { + if (!sanity) { + print name ": *** input did not look like readelf -n output"; + result = 2; + } else if (cet) { + print name ": OK"; + } else { + print name ": *** no CET property found"; + result = result ? result : 1; + } + + cet = sanity = 0; +} + +FILENAME != lastfile { + if (lastfile) + check_one(lastfile); + lastfile = FILENAME; +} + +index ($0, "Displaying notes") != 0 { sanity = 1 } +index ($0, "IBT") != 0 && index ($0, "SHSTK") != 0 { cet = 1 } + +END { + check_one(lastfile); + exit(result); +} diff --git a/sysdeps/x86/configure b/sysdeps/x86/configure new file mode 100644 index 0000000000..b1ff281249 --- /dev/null +++ b/sysdeps/x86/configure @@ -0,0 +1,69 @@ +# This file is generated from configure.ac by Autoconf. DO NOT EDIT! + # Local configure fragment for sysdeps/x86. + +if test x"$enable_cet" = xyes; then + # Check if CET can be enabled. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether CET can be enabled" >&5 +$as_echo_n "checking whether CET can be enabled... " >&6; } +if ${libc_cv_x86_cet_available+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat > conftest.c <&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_x86_cet_available=yes + else + libc_cv_x86_cet_available=no + fi + rm -rf conftest* +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_x86_cet_available" >&5 +$as_echo "$libc_cv_x86_cet_available" >&6; } + if test $libc_cv_x86_cet_available = yes; then + enable_cet=yes + else + if test x"$enable_cet" = xdefault; then + enable_cet=no + else + as_fn_error $? "$CC doesn't support CET" "$LINENO" 5 + fi + fi +fi +if test $enable_cet = yes; then + # Check if assembler supports CET. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $AS supports CET" >&5 +$as_echo_n "checking whether $AS supports CET... " >&6; } +if ${libc_cv_x86_cet_as+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat > conftest.s <&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_x86_cet_as=yes + else + libc_cv_x86_cet_as=no + fi + rm -rf conftest* +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_x86_cet_as" >&5 +$as_echo "$libc_cv_x86_cet_as" >&6; } + if test $libc_cv_x86_cet_as = no; then + as_fn_error $? "$AS doesn't support CET" "$LINENO" 5 + fi +fi +config_vars="$config_vars +enable-cet = $enable_cet" diff --git a/sysdeps/x86/configure.ac b/sysdeps/x86/configure.ac new file mode 100644 index 0000000000..a909b073af --- /dev/null +++ b/sysdeps/x86/configure.ac @@ -0,0 +1,46 @@ +GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory. +# Local configure fragment for sysdeps/x86. + +if test x"$enable_cet" = xyes; then + # Check if CET can be enabled. + AC_CACHE_CHECK(whether CET can be enabled, + libc_cv_x86_cet_available, [dnl +cat > conftest.c <&AS_MESSAGE_LOG_FD); then + libc_cv_x86_cet_available=yes + else + libc_cv_x86_cet_available=no + fi + rm -rf conftest*]) + if test $libc_cv_x86_cet_available = yes; then + enable_cet=yes + else + if test x"$enable_cet" = xdefault; then + enable_cet=no + else + AC_MSG_ERROR([$CC doesn't support CET]) + fi + fi +fi +if test $enable_cet = yes; then + # Check if assembler supports CET. + AC_CACHE_CHECK(whether $AS supports CET, + libc_cv_x86_cet_as, [dnl +cat > conftest.s <&AS_MESSAGE_LOG_FD); then + libc_cv_x86_cet_as=yes + else + libc_cv_x86_cet_as=no + fi + rm -rf conftest*]) + if test $libc_cv_x86_cet_as = no; then + AC_MSG_ERROR([$AS doesn't support CET]) + fi +fi +LIBC_CONFIG_VAR([enable-cet], [$enable_cet]) diff --git a/sysdeps/x86/cpu-features.c b/sysdeps/x86/cpu-features.c index d41ebde823..0627f145e0 100644 --- a/sysdeps/x86/cpu-features.c +++ b/sysdeps/x86/cpu-features.c @@ -28,6 +28,15 @@ extern void TUNABLE_CALLBACK (set_hwcaps) (tunable_val_t *) attribute_hidden; + +# if CET_ENABLED +# include +# include +extern void TUNABLE_CALLBACK (set_x86_ibt) (tunable_val_t *) + attribute_hidden; +extern void TUNABLE_CALLBACK (set_x86_shstk) (tunable_val_t *) + attribute_hidden; +# endif #endif static void @@ -449,4 +458,55 @@ no_cpuid: else if (CPU_FEATURES_ARCH_P (cpu_features, I586)) GLRO(dl_platform) = "i586"; #endif + +#if CET_ENABLED +# if HAVE_TUNABLES + TUNABLE_GET (x86_ibt, tunable_val_t *, + TUNABLE_CALLBACK (set_x86_ibt)); + TUNABLE_GET (x86_shstk, tunable_val_t *, + TUNABLE_CALLBACK (set_x86_shstk)); +# endif + + /* Check CET status. */ + unsigned int cet_status = get_cet_status (); + + if (cet_status) + { + GL(dl_x86_feature_1)[0] = cet_status; + +# ifndef SHARED + /* Check if IBT and SHSTK are enabled by kernel. */ + if ((cet_status & GNU_PROPERTY_X86_FEATURE_1_IBT) + || (cet_status & GNU_PROPERTY_X86_FEATURE_1_SHSTK)) + { + /* Disable IBT and/or SHSTK if they are enabled by kernel, but + disabled by environment variable: + + GLIBC_TUNABLES=glibc.tune.hwcaps=-IBT,-SHSTK + */ + unsigned int cet_feature = 0; + if (!HAS_CPU_FEATURE (IBT)) + cet_feature |= GNU_PROPERTY_X86_FEATURE_1_IBT; + if (!HAS_CPU_FEATURE (SHSTK)) + cet_feature |= GNU_PROPERTY_X86_FEATURE_1_SHSTK; + + if (cet_feature) + { + int res = dl_cet_disable_cet (cet_feature); + + /* Clear the disabled bits in dl_x86_feature_1. */ + if (res == 0) + GL(dl_x86_feature_1)[0] &= ~cet_feature; + } + + /* Lock CET if IBT or SHSTK is enabled in executable. Don't + lock CET if SHSTK is enabled permissively. */ + if (((GL(dl_x86_feature_1)[1] >> CET_MAX) + & ((1 << CET_MAX) - 1)) + != CET_PERMISSIVE) + dl_cet_lock_cet (); + } +# endif + } +#endif } diff --git a/sysdeps/x86/cpu-tunables.c b/sysdeps/x86/cpu-tunables.c index af761dcbbc..69155a8f44 100644 --- a/sysdeps/x86/cpu-tunables.c +++ b/sysdeps/x86/cpu-tunables.c @@ -334,4 +334,52 @@ TUNABLE_CALLBACK (set_hwcaps) (tunable_val_t *valp) } while (*p != '\0'); } + +# if CET_ENABLED +# include + +attribute_hidden +void +TUNABLE_CALLBACK (set_x86_ibt) (tunable_val_t *valp) +{ + if (DEFAULT_MEMCMP (valp->strval, "on", sizeof ("on")) == 0) + { + GL(dl_x86_feature_1)[1] &= ~((1 << CET_MAX) - 1); + GL(dl_x86_feature_1)[1] |= CET_ALWAYS_ON; + } + else if (DEFAULT_MEMCMP (valp->strval, "off", sizeof ("off")) == 0) + { + GL(dl_x86_feature_1)[1] &= ~((1 << CET_MAX) - 1); + GL(dl_x86_feature_1)[1] |= CET_ALWAYS_OFF; + } + else if (DEFAULT_MEMCMP (valp->strval, "permissive", + sizeof ("permissive")) == 0) + { + GL(dl_x86_feature_1)[1] &= ~((1 << CET_MAX) - 1); + GL(dl_x86_feature_1)[1] |= CET_PERMISSIVE; + } +} + +attribute_hidden +void +TUNABLE_CALLBACK (set_x86_shstk) (tunable_val_t *valp) +{ + if (DEFAULT_MEMCMP (valp->strval, "on", sizeof ("on")) == 0) + { + GL(dl_x86_feature_1)[1] &= ~(((1 << CET_MAX) - 1) << CET_MAX); + GL(dl_x86_feature_1)[1] |= (CET_ALWAYS_ON << CET_MAX); + } + else if (DEFAULT_MEMCMP (valp->strval, "off", sizeof ("off")) == 0) + { + GL(dl_x86_feature_1)[1] &= ~(((1 << CET_MAX) - 1) << CET_MAX); + GL(dl_x86_feature_1)[1] |= (CET_ALWAYS_OFF << CET_MAX); + } + else if (DEFAULT_MEMCMP (valp->strval, "permissive", + sizeof ("permissive")) == 0) + { + GL(dl_x86_feature_1)[1] &= ~(((1 << CET_MAX) - 1) << CET_MAX); + GL(dl_x86_feature_1)[1] |= (CET_PERMISSIVE << CET_MAX); + } +} +# endif #endif diff --git a/sysdeps/x86/dl-cet.c b/sysdeps/x86/dl-cet.c new file mode 100644 index 0000000000..b82ba14e75 --- /dev/null +++ b/sysdeps/x86/dl-cet.c @@ -0,0 +1,346 @@ +/* x86 CET initializers function. + Copyright (C) 2018 Free Software Foundation, Inc. + + 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 + . */ + +#include +#include +#include +#include +#include +#include + +/* GNU_PROPERTY_X86_FEATURE_1_IBT and GNU_PROPERTY_X86_FEATURE_1_SHSTK + are defined in , which are only available for C sources. + X86_FEATURE_1_IBT and X86_FEATURE_1_SHSTK are defined in + which are available for both C and asm sources. They must match. */ +#if GNU_PROPERTY_X86_FEATURE_1_IBT != X86_FEATURE_1_IBT +# error GNU_PROPERTY_X86_FEATURE_1_IBT != X86_FEATURE_1_IBT +#endif +#if GNU_PROPERTY_X86_FEATURE_1_SHSTK != X86_FEATURE_1_SHSTK +# error GNU_PROPERTY_X86_FEATURE_1_SHSTK != X86_FEATURE_1_SHSTK +#endif + +static int +dl_cet_mark_legacy_region (struct link_map *l) +{ + /* Mark PT_LOAD segments with PF_X in legacy code page bitmap. */ + size_t i, phnum = l->l_phnum; + const ElfW(Phdr) *phdr = l->l_phdr; +#ifdef __x86_64__ + typedef unsigned long long word_t; +#else + typedef unsigned long word_t; +#endif + unsigned int bits_to_set; + word_t mask_to_set; +#define BITS_PER_WORD (sizeof (word_t) * 8) +#define BITMAP_FIRST_WORD_MASK(start) \ + (~((word_t) 0) << ((start) & (BITS_PER_WORD - 1))) +#define BITMAP_LAST_WORD_MASK(nbits) \ + (~((word_t) 0) >> (-(nbits) & (BITS_PER_WORD - 1))) + + word_t *bitmap = (word_t *) GL(dl_x86_legacy_bitmap)[0]; + word_t bitmap_size = GL(dl_x86_legacy_bitmap)[1]; + word_t *p; + size_t page_size = GLRO(dl_pagesize); + + for (i = 0; i < phnum; i++) + if (phdr[i].p_type == PT_LOAD && (phdr[i].p_flags & PF_X)) + { + /* One bit in legacy bitmap represents a page. */ + ElfW(Addr) start = (phdr[i].p_vaddr + l->l_addr) / page_size; + ElfW(Addr) len = (phdr[i].p_memsz + page_size - 1) / page_size; + ElfW(Addr) end = start + len; + + if ((end / 8) > bitmap_size) + return -EINVAL; + + p = bitmap + (start / BITS_PER_WORD); + bits_to_set = BITS_PER_WORD - (start % BITS_PER_WORD); + mask_to_set = BITMAP_FIRST_WORD_MASK (start); + + while (len >= bits_to_set) + { + *p |= mask_to_set; + len -= bits_to_set; + bits_to_set = BITS_PER_WORD; + mask_to_set = ~((word_t) 0); + p++; + } + if (len) + { + mask_to_set &= BITMAP_LAST_WORD_MASK (end); + *p |= mask_to_set; + } + } + + return 0; +} + +/* Check if object M is compatible with CET. */ + +static void +dl_cet_check (struct link_map *m, const char *program) +{ + /* Check how IBT should be enabled. */ + unsigned int enable_ibt_type + = GL(dl_x86_feature_1)[1] & ((1 << CET_MAX) - 1); + /* Check how SHSTK should be enabled. */ + unsigned int enable_shstk_type + = ((GL(dl_x86_feature_1)[1] >> CET_MAX) & ((1 << CET_MAX) - 1)); + + /* No legacy object check if both IBT and SHSTK are always on. */ + if (enable_ibt_type == CET_ALWAYS_ON + && enable_shstk_type == CET_ALWAYS_ON) + return; + + /* Check if IBT is enabled by kernel. */ + bool ibt_enabled + = (GL(dl_x86_feature_1)[0] & GNU_PROPERTY_X86_FEATURE_1_IBT) != 0; + /* Check if SHSTK is enabled by kernel. */ + bool shstk_enabled + = (GL(dl_x86_feature_1)[0] & GNU_PROPERTY_X86_FEATURE_1_SHSTK) != 0; + + if (ibt_enabled || shstk_enabled) + { + struct link_map *l = NULL; + + /* Check if IBT and SHSTK are enabled in object. */ + bool enable_ibt = (ibt_enabled + && enable_ibt_type != CET_ALWAYS_OFF); + bool enable_shstk = (shstk_enabled + && enable_shstk_type != CET_ALWAYS_OFF); + if (program) + { + /* Enable IBT and SHSTK only if they are enabled in executable. + NB: IBT and SHSTK may be disabled by environment variable: + + GLIBC_TUNABLES=glibc.tune.hwcaps=-IBT,-SHSTK + */ + enable_ibt &= (HAS_CPU_FEATURE (IBT) + && (enable_ibt_type == CET_ALWAYS_ON + || (m->l_cet & lc_ibt) != 0)); + enable_shstk &= (HAS_CPU_FEATURE (SHSTK) + && (enable_shstk_type == CET_ALWAYS_ON + || (m->l_cet & lc_shstk) != 0)); + } + + /* ld.so is CET-enabled by kernel. But shared objects may not + support IBT nor SHSTK. */ + if (enable_ibt || enable_shstk) + { + int res; + unsigned int i; + unsigned int first_legacy, last_legacy; + bool need_legacy_bitmap = false; + + i = m->l_searchlist.r_nlist; + while (i-- > 0) + { + /* Check each shared object to see if IBT and SHSTK are + enabled. */ + l = m->l_initfini[i]; + + if (l->l_init_called) + continue; + +#ifdef SHARED + /* Skip CET check for ld.so since ld.so is CET-enabled. + CET will be disabled later if CET isn't enabled in + executable. */ + if (l == &GL(dl_rtld_map) + || l->l_real == &GL(dl_rtld_map) + || (program && l == m)) + continue; +#endif + + if (enable_ibt + && enable_ibt_type != CET_ALWAYS_ON + && !(l->l_cet & lc_ibt)) + { + /* Remember the first and last legacy objects. */ + if (!need_legacy_bitmap) + last_legacy = i; + first_legacy = i; + need_legacy_bitmap = true; + } + + /* SHSTK is enabled only if it is enabled in executable as + well as all shared objects. */ + enable_shstk &= (enable_shstk_type == CET_ALWAYS_ON + || (l->l_cet & lc_shstk) != 0); + } + + if (need_legacy_bitmap) + { + if (GL(dl_x86_legacy_bitmap)[0]) + { + /* Change legacy bitmap to writable. */ + if (__mprotect ((void *) GL(dl_x86_legacy_bitmap)[0], + GL(dl_x86_legacy_bitmap)[1], + PROT_READ | PROT_WRITE) < 0) + { +mprotect_failure: + if (program) + _dl_fatal_printf ("%s: mprotect legacy bitmap failed\n", + l->l_name); + else + _dl_signal_error (EINVAL, l->l_name, "dlopen", + N_("mprotect legacy bitmap failed")); + } + } + else + { + /* Allocate legacy bitmap. */ + int res = dl_cet_allocate_legacy_bitmap + (GL(dl_x86_legacy_bitmap)); + if (res != 0) + { + if (program) + _dl_fatal_printf ("%s: legacy bitmap isn't available\n", + l->l_name); + else + _dl_signal_error (EINVAL, l->l_name, "dlopen", + N_("legacy bitmap isn't available")); + } + } + + /* Put legacy shared objects in legacy bitmap. */ + for (i = first_legacy; i <= last_legacy; i++) + { + l = m->l_initfini[i]; + + if (l->l_init_called || (l->l_cet & lc_ibt)) + continue; + +#ifdef SHARED + if (l == &GL(dl_rtld_map) + || l->l_real == &GL(dl_rtld_map) + || (program && l == m)) + continue; +#endif + + /* If IBT is enabled in executable and IBT isn't enabled + in this shard object, mark PT_LOAD segments with PF_X + in legacy code page bitmap. */ + res = dl_cet_mark_legacy_region (l); + if (res != 0) + { + if (program) + _dl_fatal_printf ("%s: failed to mark legacy code region\n", + l->l_name); + else + _dl_signal_error (-res, l->l_name, "dlopen", + N_("failed to mark legacy code region")); + } + } + + /* Change legacy bitmap to read-only. */ + if (__mprotect ((void *) GL(dl_x86_legacy_bitmap)[0], + GL(dl_x86_legacy_bitmap)[1], PROT_READ) < 0) + goto mprotect_failure; + } + } + + bool cet_feature_changed = false; + + if (enable_ibt != ibt_enabled || enable_shstk != shstk_enabled) + { + if (!program + && enable_shstk_type != CET_PERMISSIVE) + { + /* When SHSTK is enabled, we can't dlopening a shared + object without SHSTK. */ + if (enable_shstk != shstk_enabled) + _dl_signal_error (EINVAL, l->l_name, "dlopen", + N_("shadow stack isn't enabled")); + return; + } + + /* Disable IBT and/or SHSTK if they are enabled by kernel, but + disabled in executable or shared objects. */ + unsigned int cet_feature = 0; + + /* Disable IBT only during program startup. */ + if (program && !enable_ibt) + cet_feature |= GNU_PROPERTY_X86_FEATURE_1_IBT; + if (!enable_shstk) + cet_feature |= GNU_PROPERTY_X86_FEATURE_1_SHSTK; + + int res = dl_cet_disable_cet (cet_feature); + if (res != 0) + { + if (program) + _dl_fatal_printf ("%s: can't disable CET\n", program); + else + _dl_signal_error (-res, l->l_name, "dlopen", + N_("can't disable CET")); + } + + /* Clear the disabled bits in dl_x86_feature_1. */ + GL(dl_x86_feature_1)[0] &= ~cet_feature; + + cet_feature_changed = true; + } + +#ifdef SHARED + if (program + && (!shstk_enabled + || enable_shstk_type != CET_PERMISSIVE) + && (ibt_enabled || shstk_enabled)) + { + /* Lock CET if IBT or SHSTK is enabled in executable. Don't + lock CET if SHSTK is enabled permissively. */ + int res = dl_cet_lock_cet (); + if (res != 0) + _dl_fatal_printf ("%s: can't lock CET\n", program); + + cet_feature_changed = true; + } +#endif + + if (cet_feature_changed) + { + unsigned int feature_1 = 0; + if (enable_ibt) + feature_1 |= GNU_PROPERTY_X86_FEATURE_1_IBT; + if (enable_shstk) + feature_1 |= GNU_PROPERTY_X86_FEATURE_1_SHSTK; + struct pthread *self = THREAD_SELF; + THREAD_SETMEM (self, header.feature_1, feature_1); + } + } +} + +void +_dl_cet_open_check (struct link_map *l) +{ + dl_cet_check (l, NULL); +} + +#ifdef SHARED + +# ifndef LINKAGE +# define LINKAGE +# endif + +LINKAGE +void +_dl_cet_check (struct link_map *main_map, const char *program) +{ + dl_cet_check (main_map, program); +} +#endif /* SHARED */ diff --git a/sysdeps/x86/dl-procruntime.c b/sysdeps/x86/dl-procruntime.c new file mode 100644 index 0000000000..eddbde6a31 --- /dev/null +++ b/sysdeps/x86/dl-procruntime.c @@ -0,0 +1,68 @@ +/* Data for processor runtime information. x86 version. + Copyright (C) 2018 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 + . */ + +/* This information must be kept in sync with the _DL_HWCAP_COUNT, + HWCAP_PLATFORMS_START and HWCAP_PLATFORMS_COUNT definitions in + dl-hwcap.h. + + If anything should be added here check whether the size of each string + is still ok with the given array size. + + All the #ifdefs in the definitions are quite irritating but + necessary if we want to avoid duplicating the information. There + are three different modes: + + - PROCINFO_DECL is defined. This means we are only interested in + declarations. + + - PROCINFO_DECL is not defined: + + + if SHARED is defined the file is included in an array + initializer. The .element = { ... } syntax is needed. + + + if SHARED is not defined a normal array initialization is + needed. + */ + +#ifndef PROCINFO_CLASS +# define PROCINFO_CLASS +#endif + +#if !IS_IN (ldconfig) +# if !defined PROCINFO_DECL && defined SHARED + ._dl_x86_feature_1 +# else +PROCINFO_CLASS unsigned int _dl_x86_feature_1[2] +# endif +# if !defined SHARED || defined PROCINFO_DECL +; +# else +, +# endif + +# if !defined PROCINFO_DECL && defined SHARED + ._dl_x86_legacy_bitmap +# else +PROCINFO_CLASS unsigned long _dl_x86_legacy_bitmap[2] +# endif +# if !defined SHARED || defined PROCINFO_DECL +; +# else +, +# endif +#endif diff --git a/sysdeps/x86/dl-prop.h b/sysdeps/x86/dl-prop.h new file mode 100644 index 0000000000..d56e20a6dc --- /dev/null +++ b/sysdeps/x86/dl-prop.h @@ -0,0 +1,153 @@ +/* Support for GNU properties. x86 version. + Copyright (C) 2018 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 + . */ + +#ifndef _DL_PROP_H +#define _DL_PROP_H + +#include + +extern void _dl_cet_check (struct link_map *, const char *) + attribute_hidden; +extern void _dl_cet_open_check (struct link_map *) + attribute_hidden; + +static inline void __attribute__ ((always_inline)) +_rtld_main_check (struct link_map *m, const char *program) +{ +#if CET_ENABLED + _dl_cet_check (m, program); +#endif +} + +static inline void __attribute__ ((always_inline)) +_dl_open_check (struct link_map *m) +{ +#if CET_ENABLED + _dl_cet_open_check (m); +#endif +} + +static inline void __attribute__ ((unused)) +_dl_process_cet_property_note (struct link_map *l, + const ElfW(Nhdr) *note, + const ElfW(Addr) size, + const ElfW(Addr) align) +{ +#if CET_ENABLED + /* The NT_GNU_PROPERTY_TYPE_0 note must be aliged to 4 bytes in + 32-bit objects and to 8 bytes in 64-bit objects. Skip notes + with incorrect alignment. */ + if (align != (__ELF_NATIVE_CLASS / 8)) + return; + + const ElfW(Addr) start = (ElfW(Addr)) note; + + while ((ElfW(Addr)) (note + 1) - start < size) + { + /* Find the NT_GNU_PROPERTY_TYPE_0 note. */ + if (note->n_namesz == 4 + && note->n_type == NT_GNU_PROPERTY_TYPE_0 + && memcmp (note + 1, "GNU", 4) == 0) + { + /* Check for invalid property. */ + if (note->n_descsz < 8 + || (note->n_descsz % sizeof (ElfW(Addr))) != 0) + break; + + /* Start and end of property array. */ + unsigned char *ptr = (unsigned char *) (note + 1) + 4; + unsigned char *ptr_end = ptr + note->n_descsz; + + while (1) + { + unsigned int type = *(unsigned int *) ptr; + unsigned int datasz = *(unsigned int *) (ptr + 4); + + ptr += 8; + if ((ptr + datasz) > ptr_end) + break; + + if (type == GNU_PROPERTY_X86_FEATURE_1_AND + && datasz == 4) + { + unsigned int feature_1 = *(unsigned int *) ptr; + if ((feature_1 & GNU_PROPERTY_X86_FEATURE_1_IBT)) + l->l_cet |= lc_ibt; + if ((feature_1 & GNU_PROPERTY_X86_FEATURE_1_SHSTK)) + l->l_cet |= lc_shstk; + break; + } + } + } + + /* NB: Note sections like .note.ABI-tag and .note.gnu.build-id are + aligned to 4 bytes in 64-bit ELF objects. */ + note = ((const void *) note + + ELF_NOTE_NEXT_OFFSET (note->n_namesz, note->n_descsz, + align)); + } +#endif +} + +#ifdef FILEBUF_SIZE +static inline int __attribute__ ((unused)) +_dl_process_pt_note (struct link_map *l, const ElfW(Phdr) *ph, + int fd, struct filebuf *fbp) +{ +# if CET_ENABLED + const ElfW(Nhdr) *note; + ElfW(Nhdr) *note_malloced = NULL; + ElfW(Addr) size = ph->p_filesz; + + if (ph->p_offset + size <= (size_t) fbp->len) + note = (const void *) (fbp->buf + ph->p_offset); + else + { + if (size < __MAX_ALLOCA_CUTOFF) + note = alloca (size); + else + { + note_malloced = malloc (size); + note = note_malloced; + } + __lseek (fd, ph->p_offset, SEEK_SET); + if (__read_nocancel (fd, (void *) note, size) != size) + { + if (note_malloced) + free (note_malloced); + return -1; + } + } + + _dl_process_cet_property_note (l, note, size, ph->p_align); + if (note_malloced) + free (note_malloced); +# endif + return 0; +} +#endif + +static inline int __attribute__ ((unused)) +_rtld_process_pt_note (struct link_map *l, const ElfW(Phdr) *ph) +{ + const ElfW(Nhdr) *note = (const void *) (ph->p_vaddr + l->l_addr); + _dl_process_cet_property_note (l, note, ph->p_memsz, ph->p_align); + return 0; +} + +#endif /* _DL_PROP_H */ diff --git a/sysdeps/x86/dl-tunables.list b/sysdeps/x86/dl-tunables.list index 7c3236a68f..73886b1352 100644 --- a/sysdeps/x86/dl-tunables.list +++ b/sysdeps/x86/dl-tunables.list @@ -21,6 +21,12 @@ glibc { hwcaps { type: STRING } + x86_ibt { + type: STRING + } + x86_shstk { + type: STRING + } x86_non_temporal_threshold { type: SIZE_T } diff --git a/sysdeps/x86/libc-start.h b/sysdeps/x86/libc-start.h new file mode 100644 index 0000000000..6f44262bf4 --- /dev/null +++ b/sysdeps/x86/libc-start.h @@ -0,0 +1,25 @@ +/* X86 definitions for libc main startup. + Copyright (C) 2018 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 + . */ + +#ifndef SHARED +# define ARCH_SETUP_IREL() apply_irel () +# define ARCH_APPLY_IREL() +# ifndef ARCH_SETUP_TLS +# define ARCH_SETUP_TLS() __libc_setup_tls () +# endif +#endif /* !SHARED */ diff --git a/sysdeps/x86/link_map.h b/sysdeps/x86/link_map.h new file mode 100644 index 0000000000..ef1206a9d2 --- /dev/null +++ b/sysdeps/x86/link_map.h @@ -0,0 +1,26 @@ +/* Additional fields in struct link_map. Linux/x86 version. + Copyright (C) 2018 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 + . */ + +/* If this object is enabled with CET. */ +enum + { + lc_none = 0, /* Not enabled with CET. */ + lc_ibt = 1 << 0, /* Enabled with IBT. */ + lc_shstk = 1 << 1, /* Enabled with STSHK. */ + lc_ibt_and_shstk = lc_ibt | lc_shstk /* Enabled with both. */ + } l_cet:2; diff --git a/sysdeps/x86/sysdep.h b/sysdeps/x86/sysdep.h index 976566aa37..8776ad8374 100644 --- a/sysdeps/x86/sysdep.h +++ b/sysdeps/x86/sysdep.h @@ -52,6 +52,13 @@ enum cf_protection_level /* Syntactic details of assembler. */ +#ifdef _CET_ENDBR +# define _CET_NOTRACK notrack +#else +# define _CET_ENDBR +# define _CET_NOTRACK +#endif + /* ELF uses byte-counts for .align, most others use log2 of count of bytes. */ #define ALIGNARG(log2) 1<