On 09/05/15 19:57, Szabolcs Nagy wrote: > * H.J. Lu <hjl.to...@gmail.com> [2015-05-09 10:41:41 -0700]: >> There are >> >> 4: 0000000000002b70 806 FUNC GLOBAL DEFAULT 12 >> __cpu_indicator_init@GCC_4.8.0 >> 38: 00000000002153d0 16 OBJECT GLOBAL DEFAULT 25 >> __cpu_model@GCC_4.8.0 >> >> and >> >> 000000000215000 0000000400000001 R_X86_64_64 >> 0000000000002b70 __cpu_indicator_init@GCC_4.8.0 + 0 >> 0000000000215220 0000002600000006 R_X86_64_GLOB_DAT >> 00000000002153d0 __cpu_model@GCC_4.8.0 + 0 >> >> in libgcc_s.so.1. Musl ld.so must be fixed to handle it. >>
Rich is looking at how to do this non-intrusively, but it seems non-trivial (some users of musl prefer not to resolve such versioned symbols). > > i think it might be enough to add __cpu_indicator_init_local > as an alias to __cpu_indicator_init in libgcc.a and then use > the *_local symbol from the ifunc resolver, that way no new > dependency is added to libgcc_s.so handling. i tried this approach and it seems to work: passes all multiversioning tests on x86_64. i think it's no worse than the symver approach. is it ok to change the current fix to this? libgcc/Changelog: 2015-05-11 Szabolcs Nagy <szabolcs.n...@arm.com> * config/i386/cpuinfo.c (__cpu_indicator_init_local): Add. (__cpu_indicator_init@GCC_4.8.0, __cpu_model@GCC_4.8.0): Remove. * config/i386/t-linux (HOST_LIBGCC2_CFLAGS): Remove -DUSE_ELF_SYMVER. gcc/Changelog: 2015-05-11 Szabolcs Nagy <szabolcs.n...@arm.com> * config/i386/i386.c (ix86_expand_builtin): Make __builtin_cpu_init call __cpu_indicator_init_local instead of __cpu_indicator_init.
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 7bd9ff3..7327cf3 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -38398,10 +38398,10 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget, { case IX86_BUILTIN_CPU_INIT: { - /* Make it call __cpu_indicator_init in libgcc. */ + /* Make it call __cpu_indicator_init_local in libgcc.a. */ tree call_expr, fndecl, type; type = build_function_type_list (integer_type_node, NULL_TREE); - fndecl = build_fn_decl ("__cpu_indicator_init", type); + fndecl = build_fn_decl ("__cpu_indicator_init_local", type); call_expr = build_call_expr (fndecl, 0); return expand_expr (call_expr, target, mode, EXPAND_NORMAL); } diff --git a/libgcc/config/i386/cpuinfo.c b/libgcc/config/i386/cpuinfo.c index f6f91dd..86b6d21 100644 --- a/libgcc/config/i386/cpuinfo.c +++ b/libgcc/config/i386/cpuinfo.c @@ -425,7 +425,7 @@ __cpu_indicator_init (void) return 0; } -#if defined SHARED && defined USE_ELF_SYMVER -__asm__ (".symver __cpu_indicator_init, __cpu_indicator_init@GCC_4.8.0"); -__asm__ (".symver __cpu_model, __cpu_model@GCC_4.8.0"); +#ifndef SHARED +int __cpu_indicator_init_local (void) + __attribute__ ((weak, alias ("__cpu_indicator_init"))); #endif diff --git a/libgcc/config/i386/t-linux b/libgcc/config/i386/t-linux index 11bb46e..4f47f7b 100644 --- a/libgcc/config/i386/t-linux +++ b/libgcc/config/i386/t-linux @@ -3,4 +3,4 @@ # t-slibgcc-elf-ver and t-linux SHLIB_MAPFILES = libgcc-std.ver $(srcdir)/config/i386/libgcc-glibc.ver -HOST_LIBGCC2_CFLAGS += -mlong-double-80 -DUSE_ELF_SYMVER +HOST_LIBGCC2_CFLAGS += -mlong-double-80