bug-binutils
[Top][All Lists]
Advanced

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

[Bug gold/18703] Symbol version and Version script incompatibility with


From: tmsriram at google dot com
Subject: [Bug gold/18703] Symbol version and Version script incompatibility with BFD ld
Date: Wed, 22 Jul 2015 01:03:59 +0000

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
<address@hidden> 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
address@hidden

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
> <address@hidden> 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
>> <address@hidden> 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
>>> address@hidden (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.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]