This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: Copy relocations against versioned symbols with aliases without a default version
- From: "H.J. Lu" <hjl dot tools at gmail dot com>
- To: Florian Weimer <fweimer at redhat dot com>
- Cc: Binutils <binutils at sourceware dot org>
- Date: Tue, 7 Mar 2017 12:39:18 -0800
- Subject: Re: Copy relocations against versioned symbols with aliases without a default version
- Authentication-results: sourceware.org; auth=none
- References: <a39553eb-9bbb-64fc-217a-641d8b5cb184@redhat.com> <CAMe9rOpiaun7=_AhzDK93M8BGmNJvCCHH-f4xiPi3q8UvTJHUw@mail.gmail.com> <1023e2ac-d81b-3bbd-a0a7-93f576311f4b@redhat.com>
On Tue, Mar 7, 2017 at 8:51 AM, Florian Weimer <fweimer@redhat.com> wrote:
> On 03/07/2017 04:52 PM, H.J. Lu wrote:
>>
>> On Tue, Mar 7, 2017 at 6:57 AM, Florian Weimer <fweimer@redhat.com> wrote:
>>>
>>> I'm trying to clean up the timezone code in glibc. Historically, we
>>> export
>>> both tzname and __tzname, and the symbols are aliased:
>>>
>>> 271: 0000000000399380 16 OBJECT GLOBAL DEFAULT 33
>>> __tzname@@GLIBC_2.2.5
>>> 589: 0000000000399380 16 OBJECT WEAK DEFAULT 33
>>> tzname@@GLIBC_2.2.5
>>>
>>> __tzname was exported more or less by accident, so I want to turn it into
>>> a
>>> compat symbol, resulting in:
>>>
>>> 271: 0000000000399380 16 OBJECT GLOBAL DEFAULT 33
>>> __tzname@GLIBC_2.2.5
>>> 589: 0000000000399380 16 OBJECT WEAK DEFAULT 33
>>> tzname@@GLIBC_2.2.5
>>>
>>> When linking an object file with an R_X86_64_32S relocation against
>>> tzname
>>>
>>> bb: 4d 8b 64 dd 00 mov 0x0(%r13,%rbx,8),%r12
>>> c0: 48 8b 2c dd 00 00 00 mov 0x0(,%rbx,8),%rbp
>>> c7: 00
>>> c4: R_X86_64_32S tzname
>>> c8: 4c 89 e6 mov %r12,%rsi
>>>
>>> to this variant, I get this error:
>>>
>>> /usr/bin/ld: …/tst-timezone.o(.text+0xc4): unresolvable R_X86_64_32S
>>> relocation against symbol `tzname@@GLIBC_2.2.5'
>>>
>>> This is really unexpected. It seems that something causes the hidden bit
>>> to
>>> be set on the compat symbol version for __tzname. I assume ld treats
>>> this
>>> as an indication that a hidden alias symbol exists, so that it cannot
>>> create
>>> a copy relocation without breaking the alias.
>>>
>>> This is really fishy. The hidden bit is documented as “If the highest
>>> bit
>>> (bit 15) is set this is a hidden symbol which cannot be referenced from
>>> outside the object.” in
>>> <https://www.akkadia.org/drepper/symbol-versioning>,
>>> but this is not what is implemented because references to these
>>> supposedly-hidden symbols work just fine if you specify an explicit
>>> symbol
>>> version, both at static link time and at run time (which is not something
>>> we
>>> can change in the dynamic linker because we have many existing binaries
>>> which use hidden symbol versions for supposedly-exported non-default
>>> compat
>>> symbols). So there is no real reason why the static linker has to refuse
>>> to
>>> create a copy relocation in such a cases.
>>>
>>> Comments?
>>
>>
>> Do you have a standalone testcase?
>
>
> Not really, I only have the attached glibc patch (against current master),
> which causes a link failure in timezone/tst-timezone.
>
> Thanks,
> Florian
Works for me with GCC 6.3.1 and binutils 2.28.51:
[hjl@gnu-6 build-x86_64-linux]$ nm timezone/tst-timezone.o | grep tzname
U tzname
[hjl@gnu-6 build-x86_64-linux]$ nm timezone/tst-timezone | grep tzname
00000000006041a0 B __tzname@GLIBC_2.2.5
00000000006041a0 V tzname@@GLIBC_2.2.5
[hjl@gnu-6 build-x86_64-linux]$ readelf -sW libc.so| grep tzname
269: 00000000003993a0 16 OBJECT GLOBAL DEFAULT 33 __tzname@GLIBC_2.2.5
587: 00000000003993a0 16 OBJECT WEAK DEFAULT 33 tzname@@GLIBC_2.2.5
--
H.J.