diff mbox

PATCH] PR target/65612: Multiversioning doesn't work with DSO nor PIE

Message ID 20150330022527.GA4148@gmail.com
State New
Headers show

Commit Message

H.J. Lu March 30, 2015, 2:25 a.m. UTC
We shouldn't call external function, __cpu_indicator_init, while an object
is being relocated since its .got.plt section hasn't been updated.  It
works for non-PIE since no update on .got.plt section is required.  This
patch hides __cpu_indicator_init/__cpu_model from linker to force linker
to resolve __cpu_indicator_init/__cpu_model to their hidden definitions
in libgcc.a while providing backward binary compatibility.

OK for trunk, 4.9 and 4.9 branches?

Thanks.


H.J.
---
libgcc/

	PR target/65612
	* config/i386/cpuinfo.c (__cpu_model): Initialize.
	(__cpu_indicator_init@GCC_4.8.0): New.
	(__cpu_model@GCC_4.8.0): Likewise.

gcc/testsuite/

	PR target/65612
	* g++.dg/ext/mv18.C: New test.
	* g++.dg/ext/mv19.C: Likewise.
	* g++.dg/ext/mv20.C: Likewise.
---
 gcc/testsuite/g++.dg/ext/mv18.C | 7 +++++++
 gcc/testsuite/g++.dg/ext/mv19.C | 7 +++++++
 gcc/testsuite/g++.dg/ext/mv20.C | 7 +++++++
 libgcc/config/i386/cpuinfo.c    | 7 ++++++-
 4 files changed, 27 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/g++.dg/ext/mv18.C
 create mode 100644 gcc/testsuite/g++.dg/ext/mv19.C
 create mode 100644 gcc/testsuite/g++.dg/ext/mv20.C

Comments

H.J. Lu March 30, 2015, 2:34 a.m. UTC | #1
On Sun, Mar 29, 2015 at 7:25 PM, H.J. Lu <hjl.tools@gmail.com> wrote:
> We shouldn't call external function, __cpu_indicator_init, while an object
> is being relocated since its .got.plt section hasn't been updated.  It
> works for non-PIE since no update on .got.plt section is required.  This
> patch hides __cpu_indicator_init/__cpu_model from linker to force linker
> to resolve __cpu_indicator_init/__cpu_model to their hidden definitions
> in libgcc.a while providing backward binary compatibility.
>
> OK for trunk, 4.9 and 4.9 branches?
>
> Thanks.
>
>
> H.J.
> ---
> libgcc/
>
>         PR target/65612
>         * config/i386/cpuinfo.c (__cpu_model): Initialize.
>         (__cpu_indicator_init@GCC_4.8.0): New.
>         (__cpu_model@GCC_4.8.0): Likewise.
>
> gcc/testsuite/
>
>         PR target/65612
>         * g++.dg/ext/mv18.C: New test.
>         * g++.dg/ext/mv19.C: Likewise.
>         * g++.dg/ext/mv20.C: Likewise.

It doesn' work for shared C++ library:

/export/build/gnu/gcc-x32/release/usr/gcc-5.0.0-x32/bin/g++ -O2    -c
-o main.o main.cc
/export/build/gnu/gcc-x32/release/usr/gcc-5.0.0-x32/bin/g++ -shared
-fPIC -O2  -o libmv20.so mv20.cc
/export/build/gnu/gcc-x32/release/usr/gcc-5.0.0-x32/bin/g++ -O2  -o x
main.o libmv20.so -Wl,-R,.
/usr/local/bin/ld: x: hidden symbol `__cpu_model' in
/export/build/gnu/gcc-x32/release/usr/gcc-5.0.0-x32/bin/../lib/gcc/x86_64-unknown-linux-gnu/5.0.0/libgcc.a(cpuinfo.o)
is referenced by DSO
/usr/local/bin/ld: final link failed: Bad value
collect2: error: ld returned 1 exit status
Makefile:12: recipe for target 'x' failed
make: *** [x] Error 1
[hjl@gnu-tools-1 pr65612]$
H.J. Lu March 30, 2015, 2:40 a.m. UTC | #2
On Sun, Mar 29, 2015 at 7:34 PM, H.J. Lu <hjl.tools@gmail.com> wrote:
> On Sun, Mar 29, 2015 at 7:25 PM, H.J. Lu <hjl.tools@gmail.com> wrote:
>> We shouldn't call external function, __cpu_indicator_init, while an object
>> is being relocated since its .got.plt section hasn't been updated.  It
>> works for non-PIE since no update on .got.plt section is required.  This
>> patch hides __cpu_indicator_init/__cpu_model from linker to force linker
>> to resolve __cpu_indicator_init/__cpu_model to their hidden definitions
>> in libgcc.a while providing backward binary compatibility.
>>
>> OK for trunk, 4.9 and 4.9 branches?
>>
>> Thanks.
>>
>>
>> H.J.
>> ---
>> libgcc/
>>
>>         PR target/65612
>>         * config/i386/cpuinfo.c (__cpu_model): Initialize.
>>         (__cpu_indicator_init@GCC_4.8.0): New.
>>         (__cpu_model@GCC_4.8.0): Likewise.
>>
>> gcc/testsuite/
>>
>>         PR target/65612
>>         * g++.dg/ext/mv18.C: New test.
>>         * g++.dg/ext/mv19.C: Likewise.
>>         * g++.dg/ext/mv20.C: Likewise.
>
> It doesn' work for shared C++ library:
>
> /export/build/gnu/gcc-x32/release/usr/gcc-5.0.0-x32/bin/g++ -O2    -c
> -o main.o main.cc
> /export/build/gnu/gcc-x32/release/usr/gcc-5.0.0-x32/bin/g++ -shared
> -fPIC -O2  -o libmv20.so mv20.cc
> /export/build/gnu/gcc-x32/release/usr/gcc-5.0.0-x32/bin/g++ -O2  -o x
> main.o libmv20.so -Wl,-R,.
> /usr/local/bin/ld: x: hidden symbol `__cpu_model' in
> /export/build/gnu/gcc-x32/release/usr/gcc-5.0.0-x32/bin/../lib/gcc/x86_64-unknown-linux-gnu/5.0.0/libgcc.a(cpuinfo.o)
> is referenced by DSO
> /usr/local/bin/ld: final link failed: Bad value
> collect2: error: ld returned 1 exit status
> Makefile:12: recipe for target 'x' failed
> make: *** [x] Error 1
> [hjl@gnu-tools-1 pr65612]$
>
> --
> H.J.

We need something like libgcc_nonshared.a, which contains cpuinfo.o, and
link together with -lgcc_s when creating executable or DSO.
diff mbox

Patch

diff --git a/gcc/testsuite/g++.dg/ext/mv18.C b/gcc/testsuite/g++.dg/ext/mv18.C
new file mode 100644
index 0000000..1f024de
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/mv18.C
@@ -0,0 +1,7 @@ 
+/* Test case to check if Multiversioning works.  */
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
+/* { dg-require-ifunc "" }  */
+/* { dg-require-effective-target pie } */
+/* { dg-options "-O2 -fPIE -pie" } */
+
+#include "mv1.C"
diff --git a/gcc/testsuite/g++.dg/ext/mv19.C b/gcc/testsuite/g++.dg/ext/mv19.C
new file mode 100644
index 0000000..d1ea788
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/mv19.C
@@ -0,0 +1,7 @@ 
+/* Test case to check if Multiversioning works.  */
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
+/* { dg-require-ifunc "" }  */
+/* { dg-require-effective-target pie } */
+/* { dg-options "-O2 -fPIE -pie -march=x86-64" } */
+
+#include "mv14.C"
diff --git a/gcc/testsuite/g++.dg/ext/mv20.C b/gcc/testsuite/g++.dg/ext/mv20.C
new file mode 100644
index 0000000..98f7408
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/mv20.C
@@ -0,0 +1,7 @@ 
+/* Test case to check if Multiversioning works.  */
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
+/* { dg-require-ifunc "" }  */
+/* { dg-require-effective-target pie } */
+/* { dg-options "-O2 -fPIE -pie -march=x86-64" } */
+
+#include "mv15.C"
diff --git a/libgcc/config/i386/cpuinfo.c b/libgcc/config/i386/cpuinfo.c
index eaf2f10..9639c8d 100644
--- a/libgcc/config/i386/cpuinfo.c
+++ b/libgcc/config/i386/cpuinfo.c
@@ -109,7 +109,7 @@  struct __processor_model
   unsigned int __cpu_type;
   unsigned int __cpu_subtype;
   unsigned int __cpu_features[1];
-} __cpu_model;
+} __cpu_model = { };
 
 
 /* Get the specific type of AMD CPU.  */
@@ -424,3 +424,8 @@  __cpu_indicator_init (void)
 
   return 0;
 }
+
+#if defined SHARED && !defined _WIN32
+__asm__ (".symver __cpu_indicator_init, __cpu_indicator_init@GCC_4.8.0");
+__asm__ (".symver __cpu_model, __cpu_model@GCC_4.8.0");
+#endif