https://sourceware.org/bugzilla/show_bug.cgi?id=18703
--- Comment #8 from Sriraman Tallam <tmsriram at google dot com> --- On Tue, Jul 21, 2015 at 5:07 PM, ccoutant at gmail dot com <sourceware-bugzi...@sourceware.org> wrote: > https://sourceware.org/bugzilla/show_bug.cgi?id=18703 > > --- Comment #3 from Cary Coutant <ccoutant at gmail dot com> --- > Sorry, I need more context than that. You've said that the symbol is > not versioned, but in fact it is. The only differences between the two > linkers that I see are: Hi Cary, I am just learning symbol versioning after running into this bug so apologies if I misunderstood. The particular bug I am running into this. I am looking at libgcc_s.so.1 linked with GNU-ld and linked with the gold linker. Based on your comments, I think I understand this a little better so let me atleast try to get explain my problem: With GNU ld linked libgcc_s.so.1, symbol __cpu_indicator_init looks like this in the .dynsym: 4: 0000000000002bb0 815 FUNC GLOBAL DEFAULT 11 __cpu_indicator_init@GCC_4.8.0 whereas with gold linked libgcc_s.so.1, symbol __cpu_indicator_init shows up as: 15: 0000000000002c10 783 FUNC GLOBAL DEFAULT 12 __cpu_indicator_init@@GCC_4.8.0 I see the extra "@" now, I almost missed it last time as I did not know about this! What is happening because of this subtle change is a bug with function multi-versioning and shared objects. foomv.cc ----------- __attribute__((target("default"))) void foo() { printf("This is default\n"); } __attribute__((target("avx"))) void foo() { printf("This is AVX\n"); } int callfoo() { foo(); } If I use the GNU ld linked libgcc_s.so.1, $ g++ -fPIC -shared foomv.cc -o libfoomv.so -Wl,-z,now -Wl,-y,__cpu_indicator_init libgcc_s.so.1: definition of __cpu_indicator_init libgcc.a(cpuinfo.o): definition of __cpu_indicator_init The definition of __cpu_indicator_init always comes from libgcc.a even if it found libgcc_s.so.1 earlier. whereas if I use gold linked libgcc_s.so.1 $ g++ -fPIC -shared foomv.cc -o libfoomv.so -Wl,-z,now -Wl,-y,__cpu_indicator_init libgcc_s.so.1: definition of __cpu_indicator_init it uses the definition in the shared object. The problem with this is it creates a plt entry for __cpu_indicator_init and __cpu_indicator_init gets called from an ifunc function before the DSO can be relocated leading to a seg fault. >From your later comments, it does look like the difference is because of the extra "@" added by gold to make it the default symbol. Thanks Sri > > (1) The name that appears in the linker symbol table, which shouldn't > matter to the loader at all. If this is causing a problem, can you > point to the section in the linker manual that describes the correct > behavior? I don't think gold was designed with the intent of > propagating @-style version information into the output binary. We > only use the version sections, and, as far as I know, the dynamic > loader only uses version sections. > > (2) Gold defines the symbol as a default version, while Gnu ld > doesn't. If this is the problem, I'll need to understand what the > proper logic is for determining whether a symbol should be marked as > the default version. > > You said this affects building libgcc_s.so in trunk, but you haven't > said what is actually failing. > > -cary > > > On Tue, Jul 21, 2015 at 4:51 PM, tmsriram at google dot com > <sourceware-bugzi...@sourceware.org> wrote: >> https://sourceware.org/bugzilla/show_bug.cgi?id=18703 >> >> --- Comment #2 from Sriraman Tallam <tmsriram at google dot com> --- >> On Tue, Jul 21, 2015 at 11:03 AM, ccoutant at gmail dot com >> <sourceware-bugzi...@sourceware.org> wrote: >>> https://sourceware.org/bugzilla/show_bug.cgi?id=18703 >>> >>> --- Comment #1 from Cary Coutant <ccoutant at gmail dot com> --- >>> You're looking at the linker symbol table with nm. (And nm does not show >>> versioning information from the .gnu.version* sections.) >>> >>> When I build this with gold, readelf -Vs shows: >>> >>> Symbol table '.dynsym' contains 13 entries: >>> Num: Value Size Type Bind Vis Ndx Name >>> 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND >>> 1: 0000000000000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__ >>> 2: 0000000000000000 0 NOTYPE WEAK DEFAULT UND >>> _ITM_deregisterTMCloneTab >>> 3: 0000000000000000 0 FUNC WEAK DEFAULT UND >>> __cxa_finalize@GLIBC_2.2.5 (3) >>> 4: 0000000000000000 0 NOTYPE WEAK DEFAULT UND >>> _ITM_registerTMCloneTable >>> 5: 0000000000000000 0 NOTYPE WEAK DEFAULT UND >>> _Jv_RegisterClasses >>> 6: 00000000000006f5 11 FUNC GLOBAL DEFAULT 12 foo@@VERS_1.1 >>> 7: 0000000000002018 0 NOTYPE GLOBAL DEFAULT ABS _edata >>> 8: 0000000000002019 0 NOTYPE GLOBAL DEFAULT ABS _end >>> 9: 00000000000005c0 0 FUNC GLOBAL DEFAULT 10 _init >>> 10: 0000000000002018 0 NOTYPE GLOBAL DEFAULT ABS __bss_start >>> 11: 0000000000000700 0 FUNC GLOBAL DEFAULT 13 _fini >>> 12: 0000000000000000 0 OBJECT GLOBAL DEFAULT ABS VERS_1.1 >>> >>> ... >>> >>> Version symbols section '.gnu.version' contains 13 entries: >>> Addr: 0000000000000458 Offset: 0x000458 Link: 2 (.dynsym) >>> 000: 0 (*local*) 0 (*local*) 0 (*local*) 3 >>> (GLIBC_2.2.5) >>> 004: 0 (*local*) 0 (*local*) 2 (VERS_1.1) 1 (*global*) >>> 008: 1 (*global*) 1 (*global*) 1 (*global*) 1 (*global*) >>> 00c: 2 (VERS_1.1) >>> >>> Version definition section '.gnu.version_d' contains 2 entries: >>> Addr: 0x0000000000000474 Offset: 0x000474 Link: 3 (.dynstr) 000000: >>> Rev: 1 >>> Flags: BASE Index: 1 Cnt: 1 Name: ver1.so >>> 0x001c: Rev: 1 Flags: none Index: 2 Cnt: 1 Name: VERS_1.1 >>> >>> Version needs section '.gnu.version_r' contains 1 entries: >>> Addr: 0x00000000000004ac Offset: 0x0004ac Link: 3 (.dynstr) >>> 000000: Version: 1 File: libc.so.6 Cnt: 1 >>> 0x0010: Name: GLIBC_2.2.5 Flags: none Version: 3 >>> >>> I think this is working as intended, although comparing with Gnu ld output, >>> I >>> see that gold defines it as a default version ("@@") where Gnu ld does not. >>> I'm >>> not sure what the logic ought to be for that. Without the __asm__ in the .c >>> file, Gnu ld also makes it a default version. >> >> Some context: >> >> https://gcc.gnu.org/ml/gcc-patches/2015-04/msg00878.html >> >> This was used to hide symbols __cpu_indicator_init and __cpu_model >> defined in libgcc_s.so so that this symbol is always obtained from >> libgcc.a. Now, this works with GNU ld and not with gold. Isnt this an >> incompatibility. If this is not well defined, is there another well >> defined way of achieving the same result? >> >> Thanks >> Sri >> >> >>> >>> -- >>> You are receiving this mail because: >>> You reported the bug. >> >> -- >> You are receiving this mail because: >> You are on the CC list for the bug. >> You are the assignee for the bug. > > -- > You are receiving this mail because: > You reported the bug. -- You are receiving this mail because: You are on the CC list for the bug. _______________________________________________ bug-binutils mailing list bug-binutils@gnu.org https://lists.gnu.org/mailman/listinfo/bug-binutils