Hello, One month ago [1], I reported that building the GCC 9.1, whose release and source tarball were announced two months ago [2], in Ubuntu 16.04 x86_64 resulted in a C++ compiler executable (g++-9) that was slower by about 15% than the one built by Ubuntu from the same source tarball [3] when compiling Tice [7]. As Stefan Ring pointed out, it is because the Ubuntu GCC is built using `make profiledbootstrap' [4], more accurately, `make profiledbootstrap-lean'. Building the vanilla GCC using `make profiledbootstrap-lean' resulted in g++-9 that was almost as fast as the one built by Ubuntu when compiling Tice [5]. Nevertheless, the vanilla GCC build was still slower than the Ubuntu GCC by about 2%, which is about 5 seconds for [7] in my machine. So, I want to figure out why that is the case. First, I downloaded [7] whose test driver (a Bash script) will sequentially invoke g++-9 many times, each time on a different C++ program: $ cd /tmp $ git clone https://git.savannah.gnu.org/git/tice.git $ cd tice $ git checkout 8e6aa4c08574f7bf34908aa26ca58209edf3b7cc As the baseline, I built Ubuntu g++-9 from source [8], installed it, and ran the testcase of [7] with it as follows: $ apt-get source g++-9 $ cd gcc-9-9.1.0 $ DEB_BUILD_OPTIONS='nolang=jit,nvptx,ada,go,brig,d,fortran,objc,obj-c++,hppa64,biarch nocheck' debuild -J8 -us -uc -b $ cd .. $ sudo dpkg -i libstdc++-9-dev_9.1.0-2ubuntu2~16.04_amd64.deb libgcc-9-dev_9.1.0-2ubuntu2~16.04_amd64.deb cpp-9_9.1.0-2ubuntu2~16.04_amd64.deb gcc-9_9.1.0-2ubuntu2~16.04_amd64.deb g++-9_9.1.0-2ubuntu2~16.04_amd64.deb $ cd /tmp/tice/tests $ sed -i -e 's%g++-9%/usr/bin/g++-9%' v1_gcc_test $ time ./test '^v1_gcc_test$'; time ./test '^v1_gcc_test$'; time ./test '^v1_gcc_test$' [Not matching v1/test-v1_internals_utility-fail_3-result_gcc.txt: \(https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89741\|^v1/test-v1_internals_utility-fail_3.cpp:26:49: error: static assertion failed: Test$\)] /usr/bin/g++-9 -std=c++14 -Wfatal-errors -pedantic-errors -o/dev/null "v1/test-v1_internals_utility-fail_3.cpp" real 4m40.094s user 0m22.086s sys 0m2.733s [Not matching v1/test-v1_internals_utility-fail_3-result_gcc.txt: \(https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89741\|^v1/test-v1_internals_utility-fail_3.cpp:26:49: error: static assertion failed: Test$\)] /usr/bin/g++-9 -std=c++14 -Wfatal-errors -pedantic-errors -o/dev/null "v1/test-v1_internals_utility-fail_3.cpp" real 4m40.086s user 0m22.144s sys 0m2.718s [Not matching v1/test-v1_internals_utility-fail_3-result_gcc.txt: \(https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89741\|^v1/test-v1_internals_utility-fail_3.cpp:26:49: error: static assertion failed: Test$\)] /usr/bin/g++-9 -std=c++14 -Wfatal-errors -pedantic-errors -o/dev/null "v1/test-v1_internals_utility-fail_3.cpp" real 4m40.237s user 0m22.339s sys 0m2.497s The averages are: real 4m40.139s user 0m22.190s sys 0m2.649s I then performed the following clean up: $ git checkout v1_gcc_test $ sudo dpkg -P libstdc++-9-dev libgcc-9-dev cpp-9 gcc-9 g++-9 Second, I proceeded to build the vanilla GCC, installed it, and ran the testcase of [7] with it (x86_64-linux-gnu-gcc-8 and x86_64-linux-gnu-g++-8 are GCC version `Ubuntu 8.1.0-5ubuntu1~16.04' obtained from [3]): $ cd /home/eus/buildzone $ mkdir gcc-9 gcc-9-build $ tar xf gcc-9.1.0.tar.xz -C gcc-9 --strip-components=1 $ cd gcc-9-build $ CC="x86_64-linux-gnu-gcc-8" CXX="x86_64-linux-gnu-g++-8" ../gcc-9/configure --prefix=/home/eus/gcc-9 --srcdir=/home/eus/buildzone/gcc-9 --program-suffix=-9 --enable-languages=c,c++ --enable-threads=posix --enable-nls --without-included-gettext $ make -j8 profiledbootstrap-lean $ make install $ cd /tmp/tice/tests $ sed -i -e 's%g++-9%/home/eus/gcc-9/bin/g++-9%' v1_gcc_test $ time ./test '^v1_gcc_test$'; time ./test '^v1_gcc_test$'; time ./test '^v1_gcc_test$' [Not matching v1/test-v1_internals_utility-fail_3-result_gcc.txt: \(https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89741\|^v1/test-v1_internals_utility-fail_3.cpp:26:49: error: static assertion failed: Test$\)] /home/eus/gcc-9/bin/g++-9 -std=c++14 -Wfatal-errors -pedantic-errors -o/dev/null "v1/test-v1_internals_utility-fail_3.cpp" real 4m45.362s user 0m22.911s sys 0m2.801s [Not matching v1/test-v1_internals_utility-fail_3-result_gcc.txt: \(https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89741\|^v1/test-v1_internals_utility-fail_3.cpp:26:49: error: static assertion failed: Test$\)] /home/eus/gcc-9/bin/g++-9 -std=c++14 -Wfatal-errors -pedantic-errors -o/dev/null "v1/test-v1_internals_utility-fail_3.cpp" real 4m45.416s user 0m22.967s sys 0m2.658s [Not matching v1/test-v1_internals_utility-fail_3-result_gcc.txt: \(https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89741\|^v1/test-v1_internals_utility-fail_3.cpp:26:49: error: static assertion failed: Test$\)] /home/eus/gcc-9/bin/g++-9 -std=c++14 -Wfatal-errors -pedantic-errors -o/dev/null "v1/test-v1_internals_utility-fail_3.cpp" real 4m45.265s user 0m22.745s sys 0m2.862s The averages are: real 4m45.348s (2% slower than baseline's average) user 0m22.874s (3% slower than baseline's average) sys 0m2.774s (5% slower than baseline's average) Lastly, I applied to the vanilla GCC some (not all) patches that Ubuntu GCC applies as far as I could see from the terminal output of building the baseline as follows: $ cd /home/eus/buildzone/gcc-9 $ for x in svn-updates libstdc++-pic skip-bootstrap-multilib gcc-hash-style-gnu gcc-as-needed gcc-search-prefixed-as-ld libgomp-omp_h-multilib libffi-race-condition libffi-pax libitm-no-fortify-source t-libunwind-elf-Wl-z-defs gcc-default-relro gcc-auto-build gcc-target-include-asm; do patch -p2 < ../ubuntu/gcc-9-9.1.0/debian/patches/$x.diff || break; done $ for x in ./ gcc/ libcc1/ libdecnumber/ libffi/ libgcc/ libgfortran/ libgo/ libstdc++-v3/; do (cd $x && rm configure && AUTOM4TE=/usr/bin/autom4te autoconf); done I then configured and made the patched & reconfigured vanilla GCC based on what I saw from the terminal output of building the baseline as follows, which was then followed by installing it and running the testcase of [7] with it: $ cd .. $ rm -R /home/eus/gcc-9 $ rm -R gcc-9-build $ mkdir gcc-9-build $ cd gcc-9-build $ CC="x86_64-linux-gnu-gcc-8" CXX="x86_64-linux-gnu-g++-8" LIBCFLAGS="-g -O2 -fno-stack-protector" LIBCXXFLAGS="-g -O2 -fno-implicit-templates -fno-stack-protector" LDFLAGS_FOR_TARGET="-Wl,-z,relro" ../gcc-9/configure --prefix=/home/eus/gcc-9 --srcdir=/home/eus/buildzone/gcc-9 --program-suffix=-9 --enable-languages=c,c++ --with-gcc-major-version-only --enable-shared --enable-linker-build-id --without-included-gettext --enable-threads=posix --enable-nls --enable-bootstrap --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-plugin --with-system-zlib --with-target-system-zlib=auto --enable-objc-gc=auto --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu $ make -j8 profiledbootstrap-lean 'LIBCFLAGS=-g -O2 -fno-stack-protector' 'LIBCXXFLAGS=-g -O2 -fno-implicit-templates -fno-stack-protector' 'STAGE1_CFLAGS=-g -fno-stack-protector' 'BOOT_CFLAGS=-g -O2 -fno-stack-protector' BOOT_LDFLAGS=-Wl,-z,relro LDFLAGS_FOR_TARGET=-Wl,-z,relro $ make install $ cd /tmp/tice/tests $ time ./test '^v1_gcc_test$'; time ./test '^v1_gcc_test$'; time ./test '^v1_gcc_test$' [Not matching v1/test-v1_internals_utility-fail_3-result_gcc.txt: \(https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89741\|^v1/test-v1_internals_utility-fail_3.cpp:26:49: error: static assertion failed: Test$\)] /home/eus/gcc-9/bin/g++-9 -std=c++14 -Wfatal-errors -pedantic-errors -o/dev/null "v1/test-v1_internals_utility-fail_3.cpp" real 4m41.155s user 0m22.137s sys 0m2.800s [Not matching v1/test-v1_internals_utility-fail_3-result_gcc.txt: \(https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89741\|^v1/test-v1_internals_utility-fail_3.cpp:26:49: error: static assertion failed: Test$\)] /home/eus/gcc-9/bin/g++-9 -std=c++14 -Wfatal-errors -pedantic-errors -o/dev/null "v1/test-v1_internals_utility-fail_3.cpp" real 4m40.933s user 0m22.173s sys 0m2.656s [Not matching v1/test-v1_internals_utility-fail_3-result_gcc.txt: \(https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89741\|^v1/test-v1_internals_utility-fail_3.cpp:26:49: error: static assertion failed: Test$\)] /home/eus/gcc-9/bin/g++-9 -std=c++14 -Wfatal-errors -pedantic-errors -o/dev/null "v1/test-v1_internals_utility-fail_3.cpp" real 4m40.938s user 0m22.324s sys 0m2.565s The averages are: real 4m41.009s (0.3% slower than baseline's average) user 0m22.211s (0.1% slower than baseline's average) sys 0m2.674s (1.0% slower than baseline's average) However, if I applied four more patches to the previous patched & reconfigured vanilla GCC and rebuilt it in the same way as shown below, the resulting executable could run faster than Ubuntu GCC: $ cd /home/eus/buildzone/gcc-9 $ for x in gcc-default-fortify-source libffi-ro-eh_frame_sect pr67590 sys-auxv-header; do patch -p2 < ../ubuntu/gcc-9-9.1.0/debian/patches/$x.diff || break; done $ for x in ./ gcc/ libcc1/ libdecnumber/ libffi/ libgcc/ libgfortran/ libgo/ libstdc++-v3/; do (cd $x && rm configure && AUTOM4TE=/usr/bin/autom4te autoconf); done $ cd .. $ rm -R /home/eus/gcc-9 $ rm -R gcc-9-build $ mkdir gcc-9-build $ cd gcc-9-build $ CC="x86_64-linux-gnu-gcc-8" CXX="x86_64-linux-gnu-g++-8" LIBCFLAGS="-g -O2 -fno-stack-protector" LIBCXXFLAGS="-g -O2 -fno-implicit-templates -fno-stack-protector" LDFLAGS_FOR_TARGET="-Wl,-z,relro" ../gcc-9/configure --prefix=/home/eus/gcc-9 --srcdir=/home/eus/buildzone/gcc-9 --program-suffix=-9 --enable-languages=c,c++ --with-gcc-major-version-only --enable-shared --enable-linker-build-id --without-included-gettext --enable-threads=posix --enable-nls --enable-bootstrap --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-plugin --with-system-zlib --with-target-system-zlib=auto --enable-objc-gc=auto --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu $ make -j8 profiledbootstrap-lean 'LIBCFLAGS=-g -O2 -fno-stack-protector' 'LIBCXXFLAGS=-g -O2 -fno-implicit-templates -fno-stack-protector' 'STAGE1_CFLAGS=-g -fno-stack-protector' 'BOOT_CFLAGS=-g -O2 -fno-stack-protector' BOOT_LDFLAGS=-Wl,-z,relro LDFLAGS_FOR_TARGET=-Wl,-z,relro $ make install $ cd /tmp/tice/tests $ time ./test '^v1_gcc_test$'; time ./test '^v1_gcc_test$'; time ./test '^v1_gcc_test$' [Not matching v1/test-v1_internals_utility-fail_3-result_gcc.txt: \(https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89741\|^v1/test-v1_internals_utility-fail_3.cpp:26:49: error: static assertion failed: Test$\)] /home/eus/gcc-9/bin/g++-9 -std=c++14 -Wfatal-errors -pedantic-errors -o/dev/null "v1/test-v1_internals_utility-fail_3.cpp" real 4m39.841s user 0m22.187s sys 0m2.649s [Not matching v1/test-v1_internals_utility-fail_3-result_gcc.txt: \(https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89741\|^v1/test-v1_internals_utility-fail_3.cpp:26:49: error: static assertion failed: Test$\)] /home/eus/gcc-9/bin/g++-9 -std=c++14 -Wfatal-errors -pedantic-errors -o/dev/null "v1/test-v1_internals_utility-fail_3.cpp" real 4m39.447s user 0m22.073s sys 0m2.689s [Not matching v1/test-v1_internals_utility-fail_3-result_gcc.txt: \(https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89741\|^v1/test-v1_internals_utility-fail_3.cpp:26:49: error: static assertion failed: Test$\)] /home/eus/gcc-9/bin/g++-9 -std=c++14 -Wfatal-errors -pedantic-errors -o/dev/null "v1/test-v1_internals_utility-fail_3.cpp" real 4m39.943s user 0m22.167s sys 0m2.627s The averages are: real 4m39.744s (1.0% _faster_ than baseline's average) user 0m22.142s (0.2% _faster_ than baseline's average) sys 0m2.655s (0.2% slower than baseline's average) The question is: what are so special about the applied patches, which are also attached in this e-mail except for svn-updates due to its size? 1. svn-updates (this exists in trunk; so IMO nothing special here) 2. skip-bootstrap-multilib (this is to fix [9], but may also help provide better training data for profiledbootstrap) 3. libstdc++-pic (any idea why libstdc++ with PIC is faster?) 4. gcc-hash-style-gnu (this is needed to be able to apply the next patch, but can GNU hash style really speed things up?) 5. gcc-as-needed (any idea why the linker option `--as-needed' can speed up compilation?) 6. gcc-search-prefixed-as-ld (any idea why this matters?) 7. libgomp-omp_h-multilib (I guess this may provide better training data for profiledbootstrap, but any better idea?) 8. libffi-race-condition (any idea why C++ compilation needs to use libffi?) 9. libffi-pax (any idea why this speeds things up?) 10. libitm-no-fortify-source (I think this is related to the use of libgomp, but any better idea?) 11. t-libunwind-elf-Wl-z-defs (why stripping defs from libunwind can speed things up?) 12. gcc-default-relro (why does relro speed things up?) 13. gcc-auto-build (why using `-DGENERATOR_FILE' in CFLAGS is good for speed?) 14. gcc-target-include-asm (why using `-isystem $(CURDIR)/sys-include' is a good idea?) And the last four patches that beat the Ubuntu GCC: 15. gcc-default-fortify-source (isn't it counterintuitive that fortifying source speeds things up?) 16. sys-auxv-header (what is so special about enabling auxv access?) 17. libffi-ro-eh_frame_sect (why would this matter?) 18. pr67590 (I don't think this matter, do you?) What do you think about those patches? Thank you very much. [1] https://gcc.gnu.org/ml/gcc-help/2019-05/msg00118.html [2] https://gcc.gnu.org/ml/gcc/2019-05/msg00024.html [3] http://ppa.launchpad.net/ubuntu-toolchain-r/test/ubuntu/ [4] https://gcc.gnu.org/install/build.html#Building-with-profile-feedback [5] https://gcc.gnu.org/ml/gcc-help/2019-06/msg00028.html [6] http://ppa.launchpad.net/ubuntu-toolchain-r/test/ubuntu/pool/main/g/gcc-9/gcc-9_9.1.0-2ubuntu2~16.04.diff.gz [7] http://git.savannah.nongnu.org/cgit/tice.git/tree?id=8e6aa4c08574f7bf34908aa26ca58209edf3b7cc [8] http://ppa.launchpad.net/ubuntu-toolchain-r/test/ubuntu/pool/main/g/gcc-9/gcc-9_9.1.0-2ubuntu2~16.04.dsc [9] https://gcc.gnu.org/ml/gcc-help/2019-06/msg00027.html -- Best regards, Tadeus
# DP: Turn on -D_FORTIFY_SOURCE=2 by default for C, C++, ObjC, ObjC++, # DP: if the optimization level is > 0 --- gcc/doc/invoke.texi | 6 ++++++ gcc/c-family/c-cppbuiltin.c | 3 + 2 files changed, 9 insertions(+), 0 deletions(-) Index: b/src/gcc/doc/invoke.texi =================================================================== --- a/src/gcc/doc/invoke.texi +++ b/src/gcc/doc/invoke.texi @@ -7105,6 +7105,12 @@ also turns on the following optimization Please note the warning under @option{-fgcse} about invoking @option{-O2} on programs that use computed gotos. +NOTE: In Ubuntu 8.10 and later versions, @option{-D_FORTIFY_SOURCE=2} is +set by default, and is activated when @option{-O} is set to 2 or higher. +This enables additional compile-time and run-time checks for several libc +functions. To disable, specify either @option{-U_FORTIFY_SOURCE} or +@option{-D_FORTIFY_SOURCE=0}. + @item -O3 @opindex O3 Optimize yet more. @option{-O3} turns on all optimizations specified Index: b/src/gcc/c-family/c-cppbuiltin.c =================================================================== --- a/src/gcc/c-family/c-cppbuiltin.c +++ b/src/gcc/c-family/c-cppbuiltin.c @@ -1335,6 +1335,12 @@ c_cpp_builtins (cpp_reader *pfile) builtin_define_with_value ("__REGISTER_PREFIX__", REGISTER_PREFIX, 0); builtin_define_with_value ("__USER_LABEL_PREFIX__", user_label_prefix, 0); +#if !defined(ACCEL_COMPILER) + /* Fortify Source enabled by default for optimization levels > 0 */ + if (optimize) + builtin_define_with_int_value ("_FORTIFY_SOURCE", 2); +#endif + /* Misc. */ if (flag_gnu89_inline) cpp_define (pfile, "__GNUC_GNU_INLINE__");
# DP: Link using --hash-style=gnu (aarch64, alpha, amd64, armel, armhf, ia64, # DP: i386, powerpc, ppc64, riscv64, s390, sparc) 2006-07-11 Jakub Jelinek <jakub@xxxxxxxxxx> * config/i386/linux.h (LINK_SPEC): Add --hash-style=gnu. * config/i386/linux64.h (LINK_SPEC): Likewise. * config/rs6000/sysv4.h (LINK_OS_LINUX_SPEC): Likewise. * config/rs6000/linux64.h (LINK_OS_LINUX_SPEC32, LINK_OS_LINUX_SPEC64): Likewise. * config/s390/linux.h (LINK_SPEC): Likewise. * config/ia64/linux.h (LINK_SPEC): Likewise. * config/sparc/linux.h (LINK_SPEC): Likewise. * config/sparc/linux64.h (LINK_SPEC, LINK_ARCH32_SPEC, LINK_ARCH64_SPEC): Likewise. * config/alpha/linux-elf.h (LINK_SPEC): Likewise. 2009-12-21 Matthias Klose <doko@xxxxxxxxxx> * config/arm/linux-elf.h (LINK_SPEC): Add --hash-style=gnu. 2012-11-17 Matthias Klose <doko@xxxxxxxxxx> * config/aarch64/aarch64-linux.h (LINK_SPEC): Add --hash-style=gnu. 2018-03-02 Aurelien Jarno <aurelien@xxxxxxxxxxx> * config/riscv/linux.h (LINK_SPEC): Add --hash-style=gnu. --- gcc/config/alpha/linux-elf.h | 2 +- gcc/config/i386/linux.h | 2 +- gcc/config/i386/linux64.h | 2 +- gcc/config/ia64/linux.h | 2 +- gcc/config/rs6000/linux64.h | 4 ++-- gcc/config/rs6000/sysv4.h | 2 +- gcc/config/s390/linux.h | 2 +- gcc/config/sparc/linux.h | 2 +- 8 files changed, 9 insertions(+), 9 deletions(-) --- a/src/gcc/config/alpha/linux-elf.h +++ b/src/gcc/config/alpha/linux-elf.h @@ -37,7 +37,7 @@ along with GCC; see the file COPYING3. #define ELF_DYNAMIC_LINKER GNU_USER_DYNAMIC_LINKER -#define LINK_SPEC "-m elf64alpha %{G*} %{relax:-relax} \ +#define LINK_SPEC "-m elf64alpha --hash-style=gnu %{G*} %{relax:-relax} \ %{O*:-O3} %{!O*:-O1} \ %{shared:-shared} \ %{!shared: \ --- a/src/gcc/config/ia64/linux.h +++ b/src/gcc/config/ia64/linux.h @@ -58,7 +58,7 @@ do { \ #define GLIBC_DYNAMIC_LINKER "/lib/ld-linux-ia64.so.2" #undef LINK_SPEC -#define LINK_SPEC "\ +#define LINK_SPEC " --hash-style=gnu \ %{shared:-shared} \ %{!shared: \ %{!static: \ --- a/src/gcc/config/rs6000/linux64.h +++ b/src/gcc/config/rs6000/linux64.h @@ -473,13 +473,13 @@ extern int dot_symbols; " -m elf64ppc") #endif -#define LINK_OS_LINUX_SPEC32 LINK_OS_LINUX_EMUL32 " %{!shared: %{!static: \ +#define LINK_OS_LINUX_SPEC32 LINK_OS_LINUX_EMUL32 " --hash-style=gnu %{!shared: %{!static: \ %{!static-pie: \ %{rdynamic:-export-dynamic} \ -dynamic-linker " GNU_USER_DYNAMIC_LINKER32 "}}} \ %(link_os_extra_spec32)" -#define LINK_OS_LINUX_SPEC64 LINK_OS_LINUX_EMUL64 " %{!shared: %{!static: \ +#define LINK_OS_LINUX_SPEC64 LINK_OS_LINUX_EMUL64 " --hash-style=gnu %{!shared: %{!static: \ %{!static-pie: \ %{rdynamic:-export-dynamic} \ -dynamic-linker " GNU_USER_DYNAMIC_LINKER64 "}}} \ --- a/src/gcc/config/rs6000/sysv4.h +++ b/src/gcc/config/rs6000/sysv4.h @@ -790,7 +790,7 @@ GNU_USER_TARGET_CC1_SPEC #define GNU_USER_DYNAMIC_LINKER GLIBC_DYNAMIC_LINKER #endif -#define LINK_OS_LINUX_SPEC "-m elf32ppclinux %{!shared: %{!static: \ +#define LINK_OS_LINUX_SPEC "-m elf32ppclinux --hash-style=gnu %{!shared: %{!static: \ %{rdynamic:-export-dynamic} \ -dynamic-linker " GNU_USER_DYNAMIC_LINKER "}}" --- a/src/gcc/config/s390/linux.h +++ b/src/gcc/config/s390/linux.h @@ -77,7 +77,7 @@ along with GCC; see the file COPYING3. #undef LINK_SPEC #define LINK_SPEC \ - "%{m31:-m elf_s390}%{m64:-m elf64_s390} \ + "%{m31:-m elf_s390}%{m64:-m elf64_s390} --hash-style=gnu \ %{shared:-shared} \ %{!shared: \ %{static:-static} \ --- a/src/gcc/config/sparc/linux.h +++ b/src/gcc/config/sparc/linux.h @@ -87,7 +87,7 @@ extern const char *host_detect_local_cpu #define GLIBC_DYNAMIC_LINKER "/lib/ld-linux.so.2" #undef LINK_SPEC -#define LINK_SPEC "-m elf32_sparc %{shared:-shared} \ +#define LINK_SPEC "-m elf32_sparc --hash-style=gnu %{shared:-shared} \ %{!mno-relax:%{!r:-relax}} \ %{!shared: \ %{!static: \ --- a/src/gcc/config/arm/linux-elf.h +++ b/src/gcc/config/arm/linux-elf.h @@ -70,6 +70,7 @@ %{rdynamic:-export-dynamic} \ %{!shared:-dynamic-linker " GNU_USER_DYNAMIC_LINKER "}} \ -X \ + --hash-style=gnu \ %{mbig-endian:-EB} %{mlittle-endian:-EL}" \ SUBTARGET_EXTRA_LINK_SPEC --- a/src/gcc/config/i386/gnu-user.h +++ b/src/gcc/config/i386/gnu-user.h @@ -74,7 +74,7 @@ along with GCC; see the file COPYING3. { "link_emulation", GNU_USER_LINK_EMULATION },\ { "dynamic_linker", GNU_USER_DYNAMIC_LINKER } -#define GNU_USER_TARGET_LINK_SPEC "-m %(link_emulation) %{shared:-shared} \ +#define GNU_USER_TARGET_LINK_SPEC "-m %(link_emulation) --hash-style=gnu %{shared:-shared} \ %{!shared: \ %{!static: \ %{!static-pie: \ --- a/src/gcc/config/i386/gnu-user64.h +++ b/src/gcc/config/i386/gnu-user64.h @@ -56,6 +56,7 @@ see the files COPYING3 and COPYING.RUNTI "%{" SPEC_64 ":-m " GNU_USER_LINK_EMULATION64 "} \ %{" SPEC_32 ":-m " GNU_USER_LINK_EMULATION32 "} \ %{" SPEC_X32 ":-m " GNU_USER_LINK_EMULATIONX32 "} \ + --hash-style=gnu \ %{shared:-shared} \ %{!shared: \ %{!static: \ --- a/src/gcc/config/aarch64/aarch64-linux.h +++ b/src/gcc/config/aarch64/aarch64-linux.h @@ -35,6 +35,7 @@ #define CPP_SPEC "%{pthread:-D_REENTRANT}" #define LINUX_TARGET_LINK_SPEC "%{h*} \ + --hash-style=gnu \ %{static:-Bstatic} \ %{shared:-shared} \ %{symbolic:-Bsymbolic} \ --- a/src/gcc/config/riscv/linux.h +++ b/src/gcc/config/riscv/linux.h @@ -58,6 +58,7 @@ along with GCC; see the file COPYING3. "%{mabi=ilp32:_ilp32}" #define LINK_SPEC "\ +-hash-style=gnu \ -melf" XLEN_SPEC "lriscv" LD_EMUL_SUFFIX " \ %{mno-relax:--no-relax} \ %{shared} \
# DP: On linux targets pass --as-needed by default to the linker, but always # DP: link the sanitizer libraries with --no-as-needed. --- a/src/gcc/gcc.c +++ b/src/gcc/gcc.c @@ -705,8 +705,11 @@ proper position among the other output f #ifdef LIBASAN_EARLY_SPEC #define LIBASAN_SPEC STATIC_LIBASAN_LIBS #elif defined(HAVE_LD_STATIC_DYNAMIC) -#define LIBASAN_SPEC "%{static-libasan:" LD_STATIC_OPTION \ - "} -lasan %{static-libasan:" LD_DYNAMIC_OPTION "}" \ +#define LIBASAN_SPEC "%{static-libasan:" LD_STATIC_OPTION "}" \ + " %{!static-libasan:%{!fuse-ld=gold:--push-state }--no-as-needed}" \ + " -lasan " \ + " %{static-libasan:" LD_DYNAMIC_OPTION "}" \ + " %{!static-libasan:%{fuse-ld=gold:--as-needed;:--pop-state}}" \ STATIC_LIBASAN_LIBS #else #define LIBASAN_SPEC "-lasan" STATIC_LIBASAN_LIBS @@ -723,8 +726,11 @@ proper position among the other output f #ifdef LIBTSAN_EARLY_SPEC #define LIBTSAN_SPEC STATIC_LIBTSAN_LIBS #elif defined(HAVE_LD_STATIC_DYNAMIC) -#define LIBTSAN_SPEC "%{static-libtsan:" LD_STATIC_OPTION \ - "} -ltsan %{static-libtsan:" LD_DYNAMIC_OPTION "}" \ +#define LIBTSAN_SPEC "%{static-libtsan:" LD_STATIC_OPTION "}" \ + " %{!static-libtsan:%{!fuse-ld=gold:--push-state }--no-as-needed}" \ + " -ltsan " \ + " %{static-libtsan:" LD_DYNAMIC_OPTION "}" \ + " %{!static-libtsan:%{fuse-ld=gold:--as-needed;:--pop-state}}" \ STATIC_LIBTSAN_LIBS #else #define LIBTSAN_SPEC "-ltsan" STATIC_LIBTSAN_LIBS @@ -741,8 +747,11 @@ proper position among the other output f #ifdef LIBLSAN_EARLY_SPEC #define LIBLSAN_SPEC STATIC_LIBLSAN_LIBS #elif defined(HAVE_LD_STATIC_DYNAMIC) -#define LIBLSAN_SPEC "%{static-liblsan:" LD_STATIC_OPTION \ - "} -llsan %{static-liblsan:" LD_DYNAMIC_OPTION "}" \ +#define LIBLSAN_SPEC "%{static-liblsan:" LD_STATIC_OPTION "}" \ + " %{!static-liblsan:%{!fuse-ld=gold:--push-state }--no-as-needed}" \ + " -llsan " \ + " %{static-liblsan:" LD_DYNAMIC_OPTION "}" \ + " %{!static-liblsan:%{fuse-ld=gold:--as-needed;:--pop-state}}" \ STATIC_LIBLSAN_LIBS #else #define LIBLSAN_SPEC "-llsan" STATIC_LIBLSAN_LIBS @@ -757,8 +766,11 @@ proper position among the other output f #define STATIC_LIBUBSAN_LIBS \ " %{static-libubsan|static:%:include(libsanitizer.spec)%(link_libubsan)}" #ifdef HAVE_LD_STATIC_DYNAMIC -#define LIBUBSAN_SPEC "%{static-libubsan:" LD_STATIC_OPTION \ - "} -lubsan %{static-libubsan:" LD_DYNAMIC_OPTION "}" \ +#define LIBUBSAN_SPEC "%{static-libubsan:" LD_STATIC_OPTION "}" \ + " %{!static-libubsan:%{!fuse-ld=gold:--push-state }--no-as-needed}" \ + " -lubsan " \ + " %{static-libubsan:" LD_DYNAMIC_OPTION "}" \ + " %{!static-libubsan:%{fuse-ld=gold:--as-needed;:--pop-state}}" \ STATIC_LIBUBSAN_LIBS #else #define LIBUBSAN_SPEC "-lubsan" STATIC_LIBUBSAN_LIBS --- a/src/gcc/config/gnu-user.h +++ b/src/gcc/config/gnu-user.h @@ -136,17 +136,17 @@ see the files COPYING3 and COPYING.RUNTI #define LIBASAN_EARLY_SPEC "%{!shared:libasan_preinit%O%s} " \ "%{static-libasan:%{!shared:" \ LD_STATIC_OPTION " --whole-archive -lasan --no-whole-archive " \ - LD_DYNAMIC_OPTION "}}%{!static-libasan:-lasan}" + LD_DYNAMIC_OPTION "}}%{!static-libasan:%{!fuse-ld=gold:--push-state} --no-as-needed -lasan %{fuse-ld=gold:--as-needed;:--pop-state}}" #undef LIBTSAN_EARLY_SPEC #define LIBTSAN_EARLY_SPEC "%{!shared:libtsan_preinit%O%s} " \ "%{static-libtsan:%{!shared:" \ LD_STATIC_OPTION " --whole-archive -ltsan --no-whole-archive " \ - LD_DYNAMIC_OPTION "}}%{!static-libtsan:-ltsan}" + LD_DYNAMIC_OPTION "}}%{!static-libtsan:%{!fuse-ld=gold:--push-state} --no-as-needed -ltsan %{fuse-ld=gold:--as-needed;:--pop-state}}" #undef LIBLSAN_EARLY_SPEC #define LIBLSAN_EARLY_SPEC "%{!shared:liblsan_preinit%O%s} " \ "%{static-liblsan:%{!shared:" \ LD_STATIC_OPTION " --whole-archive -llsan --no-whole-archive " \ - LD_DYNAMIC_OPTION "}}%{!static-liblsan:-llsan}" + LD_DYNAMIC_OPTION "}}%{!static-liblsan:%{!fuse-ld=gold:--push-state} --no-as-needed -llsan %{fuse-ld=gold:--as-needed;:--pop-state}}" #endif #undef TARGET_F951_OPTIONS --- a/src/gcc/config/aarch64/aarch64-linux.h +++ b/src/gcc/config/aarch64/aarch64-linux.h @@ -36,6 +36,7 @@ #define LINUX_TARGET_LINK_SPEC "%{h*} \ --hash-style=gnu \ + --as-needed \ %{static:-Bstatic} \ %{shared:-shared} \ %{symbolic:-Bsymbolic} \ --- a/src/gcc/config/ia64/linux.h +++ b/src/gcc/config/ia64/linux.h @@ -58,7 +58,7 @@ do { \ #define GLIBC_DYNAMIC_LINKER "/lib/ld-linux-ia64.so.2" #undef LINK_SPEC -#define LINK_SPEC " --hash-style=gnu \ +#define LINK_SPEC " --hash-style=gnu --as-needed \ %{shared:-shared} \ %{!shared: \ %{!static: \ --- a/src/gcc/config/sparc/linux.h +++ b/src/gcc/config/sparc/linux.h @@ -87,7 +87,7 @@ extern const char *host_detect_local_cpu #define GLIBC_DYNAMIC_LINKER "/lib/ld-linux.so.2" #undef LINK_SPEC -#define LINK_SPEC "-m elf32_sparc --hash-style=gnu %{shared:-shared} \ +#define LINK_SPEC "-m elf32_sparc --hash-style=gnu --as-needed %{shared:-shared} \ %{!mno-relax:%{!r:-relax}} \ %{!shared: \ %{!static: \ --- a/src/gcc/config/s390/linux.h +++ b/src/gcc/config/s390/linux.h @@ -77,7 +77,7 @@ along with GCC; see the file COPYING3. #undef LINK_SPEC #define LINK_SPEC \ - "%{m31:-m elf_s390}%{m64:-m elf64_s390} --hash-style=gnu \ + "%{m31:-m elf_s390}%{m64:-m elf64_s390} --hash-style=gnu --as-needed \ %{shared:-shared} \ %{!shared: \ %{static:-static} \ --- a/src/gcc/config/rs6000/linux64.h +++ b/src/gcc/config/rs6000/linux64.h @@ -473,13 +473,13 @@ extern int dot_symbols; " -m elf64ppc") #endif -#define LINK_OS_LINUX_SPEC32 LINK_OS_LINUX_EMUL32 " --hash-style=gnu %{!shared: %{!static: \ +#define LINK_OS_LINUX_SPEC32 LINK_OS_LINUX_EMUL32 " --hash-style=gnu --as-needed %{!shared: %{!static: \ %{!static-pie: \ %{rdynamic:-export-dynamic} \ -dynamic-linker " GNU_USER_DYNAMIC_LINKER32 "}}} \ %(link_os_extra_spec32)" -#define LINK_OS_LINUX_SPEC64 LINK_OS_LINUX_EMUL64 " --hash-style=gnu %{!shared: %{!static: \ +#define LINK_OS_LINUX_SPEC64 LINK_OS_LINUX_EMUL64 " --hash-style=gnu --as-needed %{!shared: %{!static: \ %{!static-pie: \ %{rdynamic:-export-dynamic} \ -dynamic-linker " GNU_USER_DYNAMIC_LINKER64 "}}} \ --- a/src/gcc/config/rs6000/sysv4.h +++ b/src/gcc/config/rs6000/sysv4.h @@ -790,7 +790,7 @@ GNU_USER_TARGET_CC1_SPEC #define GNU_USER_DYNAMIC_LINKER GLIBC_DYNAMIC_LINKER #endif -#define LINK_OS_LINUX_SPEC "-m elf32ppclinux --hash-style=gnu %{!shared: %{!static: \ +#define LINK_OS_LINUX_SPEC "-m elf32ppclinux --hash-style=gnu --as-needed %{!shared: %{!static: \ %{rdynamic:-export-dynamic} \ -dynamic-linker " GNU_USER_DYNAMIC_LINKER "}}" --- a/src/gcc/config/i386/gnu-user64.h +++ b/src/gcc/config/i386/gnu-user64.h @@ -57,6 +57,7 @@ see the files COPYING3 and COPYING.RUNTI %{" SPEC_32 ":-m " GNU_USER_LINK_EMULATION32 "} \ %{" SPEC_X32 ":-m " GNU_USER_LINK_EMULATIONX32 "} \ --hash-style=gnu \ + --as-needed \ %{shared:-shared} \ %{!shared: \ %{!static: \ --- a/src/gcc/config/i386/gnu-user.h +++ b/src/gcc/config/i386/gnu-user.h @@ -74,7 +74,7 @@ along with GCC; see the file COPYING3. { "link_emulation", GNU_USER_LINK_EMULATION },\ { "dynamic_linker", GNU_USER_DYNAMIC_LINKER } -#define GNU_USER_TARGET_LINK_SPEC "-m %(link_emulation) --hash-style=gnu %{shared:-shared} \ +#define GNU_USER_TARGET_LINK_SPEC "-m %(link_emulation) --hash-style=gnu --as-needed %{shared:-shared} \ %{!shared: \ %{!static: \ %{!static-pie: \ --- a/src/gcc/config/alpha/linux-elf.h +++ b/src/gcc/config/alpha/linux-elf.h @@ -37,7 +37,7 @@ along with GCC; see the file COPYING3. #define ELF_DYNAMIC_LINKER GNU_USER_DYNAMIC_LINKER -#define LINK_SPEC "-m elf64alpha --hash-style=gnu %{G*} %{relax:-relax} \ +#define LINK_SPEC "-m elf64alpha --hash-style=gnu --as-needed %{G*} %{relax:-relax} \ %{O*:-O3} %{!O*:-O1} \ %{shared:-shared} \ %{!shared: \ --- a/src/gcc/config/arm/linux-elf.h +++ b/src/gcc/config/arm/linux-elf.h @@ -71,6 +71,7 @@ %{!shared:-dynamic-linker " GNU_USER_DYNAMIC_LINKER "}} \ -X \ --hash-style=gnu \ + --as-needed \ %{mbig-endian:-EB} %{mlittle-endian:-EL}" \ SUBTARGET_EXTRA_LINK_SPEC --- a/src/gcc/config/mips/gnu-user.h +++ b/src/gcc/config/mips/gnu-user.h @@ -55,6 +55,7 @@ along with GCC; see the file COPYING3. #undef GNU_USER_TARGET_LINK_SPEC #define GNU_USER_TARGET_LINK_SPEC "\ %{G*} %{EB} %{EL} %{mips*} %{shared} \ + -as-needed \ %{!shared: \ %{!static: \ %{rdynamic:-export-dynamic} \ --- a/src/gcc/config/riscv/linux.h +++ b/src/gcc/config/riscv/linux.h @@ -59,6 +59,7 @@ along with GCC; see the file COPYING3. #define LINK_SPEC "\ -hash-style=gnu \ +-as-needed \ -melf" XLEN_SPEC "lriscv" LD_EMUL_SUFFIX " \ %{mno-relax:--no-relax} \ %{shared} \
# DP: Fix cross building a native compiler. --- a/src/gcc/configure.ac +++ b/src/gcc/configure.ac @@ -1740,7 +1740,7 @@ else # Clearing GMPINC is necessary to prevent host headers being # used by the build compiler. Defining GENERATOR_FILE stops # system.h from including gmp.h. - CC="${CC_FOR_BUILD}" CFLAGS="${CFLAGS_FOR_BUILD}" \ + CC="${CC_FOR_BUILD}" CFLAGS="${CFLAGS_FOR_BUILD} -DGENERATOR_FILE" \ CXX="${CXX_FOR_BUILD}" CXXFLAGS="${CXXFLAGS_FOR_BUILD}" \ LD="${LD_FOR_BUILD}" LDFLAGS="${LDFLAGS_FOR_BUILD}" \ GMPINC="" CPPFLAGS="${CPPFLAGS} -DGENERATOR_FILE" \
# DP: Turn on -Wl,-z,relro by default. --- gcc/doc/invoke.texi | 3 +++ gcc/gcc.c | 1 + 2 files changed, 4 insertions(+), 0 deletions(-) Index: b/src/gcc/doc/invoke.texi =================================================================== --- a/src/gcc/doc/invoke.texi +++ b/src/gcc/doc/invoke.texi @@ -11813,6 +11813,9 @@ For example, @option{-Wl,-Map,output.map linker. When using the GNU linker, you can also get the same effect with @option{-Wl,-Map=output.map}. +NOTE: In Ubuntu 8.10 and later versions, for LDFLAGS, the option +@option{-Wl,-z,relro} is used. To disable, use @option{-Wl,-z,norelro}. + @item -u @var{symbol} @opindex u Pretend the symbol @var{symbol} is undefined, to force linking of Index: b/src/gcc/gcc.c =================================================================== --- a/src/gcc/gcc.c +++ b/src/gcc/gcc.c @@ -1037,6 +1037,11 @@ proper position among the other output f /* We pass any -flto flags on to the linker, which is expected to understand them. In practice, this means it had better be collect2. */ /* %{e*} includes -export-dynamic; see comment in common.opt. */ +#if defined(ACCEL_COMPILER) +# define RELRO_SPEC "" +#else +# define RELRO_SPEC "-z relro " +#endif #ifndef LINK_COMMAND_SPEC #define LINK_COMMAND_SPEC "\ %{!fsyntax-only:%{!c:%{!M:%{!MM:%{!E:%{!S:\ @@ -1045,6 +1050,7 @@ proper position among the other output f "%{flto|flto=*:%<fcompare-debug*} \ %{flto} %{fno-lto} %{flto=*} %l " LINK_PIE_SPEC \ "%{fuse-ld=*:-fuse-ld=%*} " LINK_COMPRESS_DEBUG_SPEC \ + RELRO_SPEC \ "%X %{o*} %{e*} %{N} %{n} %{r}\ %{s} %{t} %{u*} %{z} %{Z} %{!nostdlib:%{!nostartfiles:%S}} \ %{static:} %{L*} %(mfwrap) %(link_libgcc) " \
# DP: Search for the <triplet>-as / -ld before serching for as / ld. --- a/src/gcc/gcc.c +++ b/src/gcc/gcc.c @@ -2686,6 +2686,7 @@ for_each_path (const struct path_prefix { len = paths->max_len + extra_space + 1; len += MAX (MAX (suffix_len, multi_os_dir_len), multiarch_len); + len += multiarch_len + 2; /* triplet prefix for as, ld. */ path = XNEWVEC (char, len); } @@ -2899,6 +2900,24 @@ file_at_path (char *path, void *data) struct file_at_path_info *info = (struct file_at_path_info *) data; size_t len = strlen (path); + /* search for the <triplet>-as / -ld first. */ + if (! strcmp (info->name, "as") || ! strcmp (info->name, "ld")) + { + struct file_at_path_info prefix_info = *info; + char *prefixed_name = XNEWVEC (char, info->name_len + 2 + + strlen (DEFAULT_REAL_TARGET_MACHINE)); + strcpy (prefixed_name, DEFAULT_REAL_TARGET_MACHINE); + strcat (prefixed_name, "-"); + strcat (prefixed_name, info->name); + prefix_info.name = (const char *) prefixed_name; + prefix_info.name_len = strlen (prefixed_name); + if (file_at_path (path, &prefix_info)) + { + XDELETEVEC (prefixed_name); + return path; + } + XDELETEVEC (prefixed_name); + } memcpy (path + len, info->name, info->name_len); len += info->name_len;
# DP: Search $(builddir)/sys-include for the asm header files --- a/src/configure.ac +++ b/src/configure.ac @@ -3210,7 +3210,7 @@ fi # being built; programs in there won't even run. if test "${build}" = "${host}" && test -d ${srcdir}/gcc; then # Search for pre-installed headers if nothing else fits. - FLAGS_FOR_TARGET=$FLAGS_FOR_TARGET' -B$(build_tooldir)/bin/ -B$(build_tooldir)/lib/ -isystem $(build_tooldir)/include -isystem $(build_tooldir)/sys-include' + FLAGS_FOR_TARGET=$FLAGS_FOR_TARGET' -B$(build_tooldir)/bin/ -B$(build_tooldir)/lib/ -isystem $(build_tooldir)/include -isystem $(build_tooldir)/sys-include -isystem $(CURDIR)/sys-include' fi if test "x${use_gnu_ld}" = x &&
From 757876336c183f5b20b6620d674cc9817fd0d280 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20B=C3=BChler?= <buehler@xxxxxxxxxxxxxxxxxxxxx> Date: Wed, 7 Sep 2016 15:50:54 +0200 Subject: [PATCH 2/2] always check for PaX MPROTECT on linux, make EMUTRAMP experimental - ffi_prep_closure_loc doesn't necessarily generate trampolines recognized by PaX EMUTRAMP handler; there is no way to check before, and it isn't working on x86-64 right now -> experimental - if MPROTECT is enabled use the same workaround as is used for SELinux (double mmap()) --- configure.ac | 11 +++++++--- src/closures.c | 68 +++++++++++++++++++++++++++++++++++++++------------------- 2 files changed, 54 insertions(+), 25 deletions(-) --- a/src/libffi/configure.ac +++ b/src/libffi/configure.ac @@ -176,12 +176,17 @@ case "$TARGET" in ;; esac -# On PaX enable kernels that have MPROTECT enable we can't use PROT_EXEC. +# On PaX enable kernels that have MPROTECT enable we can't use PROT_EXEC; +# if EMUTRAMP is active too ffi could try mapping without PROT_EXEC, +# but the kernel needs to recognize the trampoline generated by ffi. +# Otherwise fallback to double mmap trick. AC_ARG_ENABLE(pax_emutramp, - [ --enable-pax_emutramp enable pax emulated trampolines, for we can't use PROT_EXEC], + [ --enable-pax_emutramp enable pax emulated trampolines (experimental)], if test "$enable_pax_emutramp" = "yes"; then + AC_MSG_WARN([EMUTRAMP is experimental only. Use --enable-pax_emutramp=experimental to enforce.]) + elif test "$enable_pax_emutramp" = "experimental"; then AC_DEFINE(FFI_MMAP_EXEC_EMUTRAMP_PAX, 1, - [Define this if you want to enable pax emulated trampolines]) + [Define this if you want to enable pax emulated trampolines (experimental)]) fi) FFI_EXEC_TRAMPOLINE_TABLE=0 --- a/src/libffi/src/closures.c +++ b/src/libffi/src/closures.c @@ -53,14 +53,18 @@ # endif #endif -#if FFI_MMAP_EXEC_WRIT && !defined FFI_MMAP_EXEC_SELINUX -# ifdef __linux__ +#if FFI_MMAP_EXEC_WRIT && defined __linux__ +# if !defined FFI_MMAP_EXEC_SELINUX /* When defined to 1 check for SELinux and if SELinux is active, don't attempt PROT_EXEC|PROT_WRITE mapping at all, as that might cause audit messages. */ # define FFI_MMAP_EXEC_SELINUX 1 -# endif -#endif +# endif /* !defined FFI_MMAP_EXEC_SELINUX */ +# if !defined FFI_MMAP_PAX +/* Also check for PaX MPROTECT */ +# define FFI_MMAP_PAX 1 +# endif /* !defined FFI_MMAP_PAX */ +#endif /* FFI_MMAP_EXEC_WRIT && defined __linux__ */ #if FFI_CLOSURES @@ -172,14 +176,18 @@ selinux_enabled_check (void) #endif /* !FFI_MMAP_EXEC_SELINUX */ -/* On PaX enable kernels that have MPROTECT enable we can't use PROT_EXEC. */ -#ifdef FFI_MMAP_EXEC_EMUTRAMP_PAX +/* On PaX enable kernels that have MPROTECT enabled we can't use PROT_EXEC. */ +#if defined FFI_MMAP_PAX #include <stdlib.h> -static int emutramp_enabled = -1; +enum { + PAX_MPROTECT = (1 << 0), + PAX_EMUTRAMP = (1 << 1), +}; +static int cached_pax_flags = -1; static int -emutramp_enabled_check (void) +pax_flags_check (void) { char *buf = NULL; size_t len = 0; @@ -193,9 +201,10 @@ emutramp_enabled_check (void) while (getline (&buf, &len, f) != -1) if (!strncmp (buf, "PaX:", 4)) { - char emutramp; - if (sscanf (buf, "%*s %*c%c", &emutramp) == 1) - ret = (emutramp == 'E'); + if (NULL != strchr (buf + 4, 'M')) + ret |= PAX_MPROTECT; + if (NULL != strchr (buf + 4, 'E')) + ret |= PAX_EMUTRAMP; break; } free (buf); @@ -203,9 +212,13 @@ emutramp_enabled_check (void) return ret; } -#define is_emutramp_enabled() (emutramp_enabled >= 0 ? emutramp_enabled \ - : (emutramp_enabled = emutramp_enabled_check ())) -#endif /* FFI_MMAP_EXEC_EMUTRAMP_PAX */ +#define get_pax_flags() (cached_pax_flags >= 0 ? cached_pax_flags \ + : (cached_pax_flags = pax_flags_check ())) +#define has_pax_flags(flags) ((flags) == ((flags) & get_pax_flags ())) +#define is_mprotect_enabled() (has_pax_flags (PAX_MPROTECT)) +#define is_emutramp_enabled() (has_pax_flags (PAX_EMUTRAMP)) + +#endif /* defined FFI_MMAP_PAX */ #elif defined (__CYGWIN__) || defined(__INTERIX) @@ -216,9 +229,10 @@ emutramp_enabled_check (void) #endif /* !defined(X86_WIN32) && !defined(X86_WIN64) */ -#ifndef FFI_MMAP_EXEC_EMUTRAMP_PAX -#define is_emutramp_enabled() 0 -#endif /* FFI_MMAP_EXEC_EMUTRAMP_PAX */ +#if !defined FFI_MMAP_PAX +# define is_mprotect_enabled() 0 +# define is_emutramp_enabled() 0 +#endif /* !defined FFI_MMAP_PAX */ /* Declare all functions defined in dlmalloc.c as static. */ static void *dlmalloc(size_t); @@ -525,13 +539,23 @@ dlmmap (void *start, size_t length, int printf ("mapping in %zi\n", length); #endif - if (execfd == -1 && is_emutramp_enabled ()) + /* -1 != execfd hints that we already decided to use dlmmap_locked + last time. */ + if (execfd == -1 && is_mprotect_enabled ()) { - ptr = mmap (start, length, prot & ~PROT_EXEC, flags, fd, offset); - return ptr; +#ifdef FFI_MMAP_EXEC_EMUTRAMP_PAX + if (is_emutramp_enabled ()) + { + /* emutramp requires the kernel recognizing the trampoline pattern + generated by ffi_prep_closure_loc; there is no way to test + in advance whether this will work, so this is experimental. */ + ptr = mmap (start, length, prot & ~PROT_EXEC, flags, fd, offset); + return ptr; + } +#endif + /* fallback to dlmmap_locked. */ } - - if (execfd == -1 && !is_selinux_enabled ()) + else if (execfd == -1 && !is_selinux_enabled ()) { ptr = mmap (start, length, prot | PROT_EXEC, flags, fd, offset);
From 48d2e46528fb6e621d95a7fa194069fd136b712d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20B=C3=BChler?= <buehler@xxxxxxxxxxxxxxxxxxxxx> Date: Wed, 7 Sep 2016 15:49:48 +0200 Subject: [PATCH 1/2] dlmmap_locked always needs locking as it always modifies execsize --- src/closures.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) --- a/src/libffi/src/closures.c +++ b/src/libffi/src/closures.c @@ -568,16 +568,11 @@ dlmmap (void *start, size_t length, int MREMAP_DUP and prot at this point. */ } - if (execsize == 0 || execfd == -1) - { - pthread_mutex_lock (&open_temp_exec_file_mutex); - ptr = dlmmap_locked (start, length, prot, flags, offset); - pthread_mutex_unlock (&open_temp_exec_file_mutex); + pthread_mutex_lock (&open_temp_exec_file_mutex); + ptr = dlmmap_locked (start, length, prot, flags, offset); + pthread_mutex_unlock (&open_temp_exec_file_mutex); - return ptr; - } - - return dlmmap_locked (start, length, prot, flags, offset); + return ptr; } /* Release memory at the given address, as well as the corresponding
# DP: PR libffi/47248, force a read only eh frame section. --- a/src/libffi/configure.ac +++ b/src/libffi/configure.ac @@ -274,6 +274,8 @@ if test "x$GCC" = "xyes"; then libffi_cv_hidden_visibility_attribute=yes fi fi + # FIXME: see PR libffi/47248 + libffi_cv_ro_eh_frame=yes rm -f conftest.* ]) if test $libffi_cv_hidden_visibility_attribute = yes; then
# DP: Build libitm with -U_FORTIFY_SOURCE on x86 and x86_64. --- a/src/libitm/configure.tgt +++ b/src/libitm/configure.tgt @@ -119,6 +119,12 @@ case "${target_cpu}" in ;; esac +# FIXME: ftbfs with -D_FORTIFY_SOURCE (error: invalid use of '__builtin_va_arg_pack ()) +case "${target}" in + *-*-linux*) + XCFLAGS="${XCFLAGS} -U_FORTIFY_SOURCE" +esac + # For the benefit of top-level configure, determine if the cpu is supported. test -d ${srcdir}/config/$ARCH || UNSUPPORTED=1
# DP: Fix up omp.h for multilibs. 2008-06-09 Jakub Jelinek <jakub@xxxxxxxxxx> * omp.h.in (omp_nest_lock_t): Fix up for Linux multilibs. 2015-03-25 Matthias Klose <doko@xxxxxxxxxx> * omp.h.in (omp_nest_lock_t): Limit the fix Linux. --- a/src/libgomp/omp.h.in +++ b/src/libgomp/omp.h.in @@ -40,8 +40,13 @@ typedef struct typedef struct { +#if defined(__linux__) + unsigned char _x[8 + sizeof (void *)] + __attribute__((__aligned__(sizeof (void *)))); +#else unsigned char _x[@OMP_NEST_LOCK_SIZE@] __attribute__((__aligned__(@OMP_NEST_LOCK_ALIGN@))); +#endif } omp_nest_lock_t; #endif
# DP: Fix PR67590, setting objdump macro. --- a/src/libcc1/configure.ac +++ b/src/libcc1/configure.ac @@ -71,6 +71,31 @@ if test "$GXX" = yes; then fi AC_SUBST(libsuffix) +# Figure out what objdump we will be using. +AS_VAR_SET_IF(gcc_cv_objdump,, [ +if test -f $gcc_cv_binutils_srcdir/configure.ac \ + && test -f ../binutils/Makefile \ + && test x$build = x$host; then + # Single tree build which includes binutils. + gcc_cv_objdump=../binutils/objdump$build_exeext +elif test -x objdump$build_exeext; then + gcc_cv_objdump=./objdump$build_exeext +elif ( set dummy $OBJDUMP_FOR_TARGET; test -x $[2] ); then + gcc_cv_objdump="$OBJDUMP_FOR_TARGET" +else + AC_PATH_PROG(gcc_cv_objdump, $OBJDUMP_FOR_TARGET) +fi]) + +AC_MSG_CHECKING(what objdump to use) +if test "$gcc_cv_objdump" = ../binutils/objdump$build_exeext; then + # Single tree build which includes binutils. + AC_MSG_RESULT(newly built objdump) +elif test x$gcc_cv_objdump = x; then + AC_MSG_RESULT(not found) +else + AC_MSG_RESULT($gcc_cv_objdump) +fi + dnl Test for -lsocket and -lnsl. Copied from libgo/configure.ac. AC_CACHE_CHECK([for socket libraries], libcc1_cv_lib_sockets, [libcc1_cv_lib_sockets=
# DP: Build and install libstdc++_pic.a library. --- a/src/libstdc++-v3/src/Makefile.am +++ b/src/libstdc++-v3/src/Makefile.am @@ -315,10 +315,12 @@ if GLIBCXX_BUILD_DEBUG STAMP_DEBUG = build-debug STAMP_INSTALL_DEBUG = install-debug CLEAN_DEBUG = debug +STAMP_INSTALL_PIC = install-pic else STAMP_DEBUG = STAMP_INSTALL_DEBUG = CLEAN_DEBUG = +STAMP_INSTALL_PIC = endif # Build a debug variant. @@ -353,6 +355,7 @@ build-debug: stamp-debug mv Makefile Makefile.tmp; \ sed -e 's,all-local: all-once,all-local:,' \ -e 's,install-data-local: install-data-once,install-data-local:,' \ + -e 's,install-exec-local:.*,install-exec-local:,' \ -e '/vpath/!s,src/c,src/debug/c,' \ < Makefile.tmp > Makefile ; \ rm -f Makefile.tmp ; \ @@ -363,3 +366,8 @@ build-debug: stamp-debug install-debug: build-debug (cd ${debugdir} && $(MAKE) CXXFLAGS='$(DEBUG_FLAGS)' \ toolexeclibdir=$(glibcxx_toolexeclibdir)/debug install) ; + +install-exec-local: $(STAMP_INSTALL_PIC) +$(STAMP_INSTALL_PIC): + $(MKDIR_P) $(DESTDIR)$(toolexeclibdir) + $(INSTALL_DATA) .libs/libstdc++convenience.a $(DESTDIR)$(toolexeclibdir)/libstdc++_pic.a --- a/src/libstdc++-v3/src/Makefile.in +++ b/src/libstdc++-v3/src/Makefile.in @@ -619,6 +619,8 @@ CXXLINK = \ @GLIBCXX_BUILD_DEBUG_TRUE@STAMP_INSTALL_DEBUG = install-debug @GLIBCXX_BUILD_DEBUG_FALSE@CLEAN_DEBUG = @GLIBCXX_BUILD_DEBUG_TRUE@CLEAN_DEBUG = debug +@GLIBCXX_BUILD_DEBUG_FALSE@STAMP_INSTALL_PIC = +@GLIBCXX_BUILD_DEBUG_TRUE@STAMP_INSTALL_PIC = install-pic # Build a debug variant. # Take care to fix all possibly-relative paths. @@ -885,7 +887,7 @@ install-dvi: install-dvi-recursive install-dvi-am: -install-exec-am: install-toolexeclibLTLIBRARIES +install-exec-am: install-exec-local install-toolexeclibLTLIBRARIES install-html: install-html-recursive @@ -935,11 +937,11 @@ uninstall-am: uninstall-toolexeclibLTLIB distclean-libtool distclean-tags dvi dvi-am html html-am info \ info-am install install-am install-data install-data-am \ install-data-local install-dvi install-dvi-am install-exec \ - install-exec-am install-html install-html-am install-info \ - install-info-am install-man install-pdf install-pdf-am \ - install-ps install-ps-am install-strip \ - install-toolexeclibLTLIBRARIES installcheck installcheck-am \ - installdirs installdirs-am maintainer-clean \ + install-exec-am install-exec-local install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip install-toolexeclibLTLIBRARIES installcheck \ + installcheck-am installdirs installdirs-am maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am \ @@ -1075,6 +1077,7 @@ build-debug: stamp-debug mv Makefile Makefile.tmp; \ sed -e 's,all-local: all-once,all-local:,' \ -e 's,install-data-local: install-data-once,install-data-local:,' \ + -e 's,install-exec-local:.*,install-exec-local:,' \ -e '/vpath/!s,src/c,src/debug/c,' \ < Makefile.tmp > Makefile ; \ rm -f Makefile.tmp ; \ @@ -1086,6 +1089,11 @@ install-debug: build-debug (cd ${debugdir} && $(MAKE) CXXFLAGS='$(DEBUG_FLAGS)' \ toolexeclibdir=$(glibcxx_toolexeclibdir)/debug install) ; +install-exec-local: $(STAMP_INSTALL_PIC) +$(STAMP_INSTALL_PIC): + $(MKDIR_P) $(DESTDIR)$(toolexeclibdir) + $(INSTALL_DATA) .libs/libstdc++convenience.a $(DESTDIR)$(toolexeclibdir)/libstdc++_pic.a + # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT:
# DP: Skip non-default multilib and libstdc++-v3 debug builds in bootstrap builds --- a/src/config-ml.in +++ b/src/config-ml.in @@ -479,6 +479,17 @@ esac # Tests like `if [ -n "$multidirs" ]' require it. multidirs=`echo "$multidirs" | sed -e 's/^[ ][ ]*//' -e 's/[ ][ ]*$//' -e 's/[ ][ ]*/ /g'` +# stage1 and stage2 builds of the non-default multilib configurations +# are not needed; skip these to save some build time. +if [ -f ../../stage_final ] && [ -f ../../stage_current ]; then + stage_final=`cat ../../stage_final` + stage_current=`cat ../../stage_current` + if [ "$stage_current" != "$stage_final" ]; then + echo "Skip `basename $ml_realsrcdir` non-default multilibs for bootstrap stage $stage_current" + multidirs= + fi +fi + # Add code to library's top level makefile to handle building the multilib # subdirs. --- a/src/libstdc++-v3/acinclude.m4 +++ b/src/libstdc++-v3/acinclude.m4 @@ -2900,7 +2900,20 @@ dnl AC_DEFUN([GLIBCXX_ENABLE_DEBUG], [ AC_MSG_CHECKING([for additional debug build]) GLIBCXX_ENABLE(libstdcxx-debug,$1,,[build extra debug library]) + if test x$enable_libstdcxx_debug = xyes; then + if test -f $toplevel_builddir/../stage_final && test -f $toplevel_builddir/../stage_current; then + stage_final=`cat $toplevel_builddir/../stage_final` + stage_current=`cat $toplevel_builddir/../stage_current` + if test x$stage_current != x$stage_final ; then + skip_debug_build=yes + enable_libstdcxx_debug=no + fi + fi + fi AC_MSG_RESULT($enable_libstdcxx_debug) + if test x$skip_debug_build = xyes ; then + AC_MSG_NOTICE([Skip libstdc++-v3 debug build for bootstrap stage $stage_current]) + fi GLIBCXX_CONDITIONAL(GLIBCXX_BUILD_DEBUG, test $enable_libstdcxx_debug = yes) ])
# DP: strip -z,defs from linker options for internal libunwind. --- a/src/libgcc/config/t-libunwind-elf +++ b/src/libgcc/config/t-libunwind-elf @@ -31,7 +31,7 @@ SHLIBUNWIND_SONAME = @shlib_base_name@.s SHLIBUNWIND_LINK = $(CC) $(LIBGCC2_CFLAGS) -shared \ -nodefaultlibs -Wl,-h,$(SHLIBUNWIND_SONAME) \ - -Wl,-z,text -Wl,-z,defs -o $(SHLIB_DIR)/$(SHLIBUNWIND_SONAME).tmp \ + -Wl,-z,text -o $(SHLIB_DIR)/$(SHLIBUNWIND_SONAME).tmp \ @multilib_flags@ $(SHLIB_OBJS) -lc && \ rm -f $(SHLIB_DIR)/$(SHLIB_SOLINK) && \ if [ -f $(SHLIB_DIR)/$(SHLIBUNWIND_SONAME) ]; then \
# DP: Check for the sys/auxv.h header file. --- a/src/gcc/configure.ac +++ b/src/gcc/configure.ac @@ -1140,6 +1140,7 @@ AC_HEADER_TIOCGWINSZ AC_CHECK_HEADERS(limits.h stddef.h string.h strings.h stdlib.h time.h iconv.h \ fcntl.h ftw.h unistd.h sys/file.h sys/time.h sys/mman.h \ sys/resource.h sys/param.h sys/times.h sys/stat.h \ + sys/auxv.h \ direct.h malloc.h langinfo.h ldfcn.h locale.h wchar.h) # Check for thread headers. --- a/src/gcc/config.in +++ b/src/gcc/config.in @@ -1765,6 +1765,12 @@ #endif +/* Define to 1 if you have the <sys/auxv.h> header file. */ +#ifndef USED_FOR_TARGET +#undef HAVE_SYS_AUXV_H +#endif + + /* Define to 1 if you have the <sys/file.h> header file. */ #ifndef USED_FOR_TARGET #undef HAVE_SYS_FILE_H --- a/src/gcc/config/rs6000/driver-rs6000.c +++ b/src/gcc/config/rs6000/driver-rs6000.c @@ -35,6 +35,10 @@ along with GCC; see the file COPYING3. # include <link.h> #endif +#ifdef HAVE_SYS_AUXV_H +# include <sys/auxv.h> +#endif + #if defined (__APPLE__) || (__FreeBSD__) # include <sys/types.h> # include <sys/sysctl.h>