Copy relocations against versioned symbols with aliases without a default version
H.J. Lu
hjl.tools@gmail.com
Tue Mar 7 20:39:00 GMT 2017
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.
More information about the Binutils
mailing list