Why Ubuntu GCC 9.1 is faster than vanilla GCC 9.1 with these patches?

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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>

[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux