This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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


On Fri, Apr 17, 2015 at 5:36 AM, H.J. Lu <hjl.tools@gmail.com> wrote:
> On Fri, Apr 17, 2015 at 4:59 AM, Jakub Jelinek <jakub@redhat.com> wrote:
>> On Fri, Apr 17, 2015 at 04:48:48AM -0700, H.J. Lu wrote:
>>> > I don't like it.  Nonshared libgcc is libgcc.a, period.  No sense in
>>> > creating yet another library for that.
>>> > So, IMHO beyond making the __cpu* entrypoints compat symbols only (@ instead
>>> > of @@ symbol versions) the right fix is simply tweak init_gcc_spec, so that
>>> > static_name is always linked in, in the switch combinations that it isn't
>>> > right now of course after shared_name rather than before that.
>>> > I thought we've fixed that years ago...
>>> >
>>>
>>> We never pass -lgcc to linker when building C++ DSO:
>>>
>>>  /usr/libexec/gcc/x86_64-redhat-linux/4.9.2/collect2 -plugin
>>> /usr/libexec/gcc/x86_64-redhat-linux/4.9.2/liblto_plugin.so
>>> -plugin-opt=/usr/libexec/gcc/x86_64-redhat-linux/4.9.2/lto-wrapper
>>> -plugin-opt=-fresolution=/tmp/ccZC7iqy.res
>>> -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lc
>>> -plugin-opt=-pass-through=-lgcc_s --build-id --no-add-needed
>>> --eh-frame-hdr --hash-style=gnu -m elf_x86_64 -shared
>>> /usr/lib/gcc/x86_64-redhat-linux/4.9.2/../../../../lib64/crti.o
>>> /usr/lib/gcc/x86_64-redhat-linux/4.9.2/crtbeginS.o
>>> -L/usr/lib/gcc/x86_64-redhat-linux/4.9.2
>>> -L/usr/lib/gcc/x86_64-redhat-linux/4.9.2/../../../../lib64
>>> -L/lib/../lib64 -L/usr/lib/../lib64
>>> -L/usr/lib/gcc/x86_64-redhat-linux/4.9.2/../../.. x.o -lstdc++ -lm
>>> -lgcc_s -lc -lgcc_s /usr/lib/gcc/x86_64-redhat-linux/4.9.2/crtendS.o
>>> /usr/lib/gcc/x86_64-redhat-linux/4.9.2/../../../../lib64/crtn.o
>>> [hjl@gnu-32 tmp]$
>>>
>>> That is why libgcc_nonshared.a is needed.
>>
>> See what I wrote.  I think it is a bug that we don't do that, in your case
>> we should pass -lgcc_s -lgcc -lc -lgcc_s -lgcc.
>> Or, if you don't want to change that, as the multi-versioning change is
>> i386/x86_64 only change, just ensure that those targets have
>> t-slibgcc-libgcc in libgcc/config.host and thus behave like most other linux
>> targets where -lgcc is linked in always after -lgcc_s.
>>
>>         Jakub
>
> This patch works for me.  OK for trunk?

H.J:  This patch assumes that libgcc.a is built with
-fvisibility=hidden and __cpu_indicator_init is LOCAL to libgcc.a.  We
have a config where libgcc.a is not built with hidden visibility.  Can
we consider this additional patch to make this explicit, mark
__cpu_indicator_init with hidden visiblity explicitly when not
building shared object.


--- config/i386/cpuinfo.c (revision 225800)
+++ config/i386/cpuinfo.c (working copy)
@@ -34,6 +34,9 @@
 #endif

 int __cpu_indicator_init (void)
+#if !defined(SHARED)
+__attribute__ ((visibility("hidden")))
+#endif
   __attribute__ ((constructor CONSTRUCTOR_PRIORITY));

 /* Get the specific type of AMD CPU.  */
@@ -321,6 +324,9 @@
    needs to be called explicitly there.  */

 int __attribute__ ((constructor CONSTRUCTOR_PRIORITY))
+#if !defined(SHARED)
+__attribute__ ((visibility("hidden")))
+#endif
 __cpu_indicator_init (void)


Also,  gold and ld have an incompatibility with symbol versioning as
discussed here:  https://sourceware.org/bugzilla/show_bug.cgi?id=18703

H.J. suggested this nice fix to solve this problem where BFD ld is
always used to build libgcc_s.so.1:

You can pass -fuse-ld=bfd to build libgcc_s.so.1 on Linux:

diff --git a/libgcc/config/i386/t-linux b/libgcc/config/i386/t-linux
index 11bb46e..12aab16 100644
--- a/libgcc/config/i386/t-linux
+++ b/libgcc/config/i386/t-linux
@@ -3,4 +3,8 @@
 # t-slibgcc-elf-ver and t-linux
 SHLIB_MAPFILES = libgcc-std.ver $(srcdir)/config/i386/libgcc-glibc.ver

+# Work around gold bug:
+# https://sourceware.org/bugzilla/show_bug.cgi?id=18703
+SHLIB_LDFLAGS += -fuse-ld=bfd
+
 HOST_LIBGCC2_CFLAGS += -mlong-double-80 -DUSE_ELF_SYMVER


Thanks
Sri

>
> gcc/testsuite/
>
> PR target/65612
> * g++.dg/ext/mv18.C: New test.
> * g++.dg/ext/mv19.C: Likewise.
> * g++.dg/ext/mv20.C: Likewise.
> * g++.dg/ext/mv21.C: Likewise.
> * g++.dg/ext/mv22.C: Likewise.
> * g++.dg/ext/mv23.C: Likewise.
>
> libgcc/
>
> PR target/65612
> * config.host (tmake_file): Add t-slibgcc-libgcc for Linux/x86.
> * config/i386/cpuinfo.c (__cpu_model): Initialize.
> (__cpu_indicator_init@GCC_4.8.0): New.
> (__cpu_model@GCC_4.8.0): Likewise.
> * config/i386/t-linux (HOST_LIBGCC2_CFLAGS): Add
> -DUSE_ELF_SYMVER.
>
> Thanks.
>
> --
> H.J.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]