[PATCH] as: Replace the removed symbol with the versioned symbol

Fangrui Song i@maskray.me
Thu Aug 12 22:52:29 GMT 2021


On 2021-08-12, H.J. Lu wrote:
>On Wed, Aug 11, 2021 at 6:11 PM Fangrui Song <i@maskray.me> wrote:
>>
>>
>> On 2021-08-11, H.J. Lu wrote:
>> >On Tue, Aug 10, 2021 at 2:56 PM Fangrui Song <i@maskray.me> wrote:
>> >>
>> >> On 2021-08-01, H.J. Lu via Binutils wrote:
>> >> >When a symbol removed by .symver is used in relocation and there is one
>> >> >and only one versioned symbol, don't remove the symbol.  Instead, mark
>> >> >it to be removed and replace the removed symbol used in relocation with
>> >> >the versioned symbol before generating relocation.
>> >>
>> >> Thanks for the patch.
>> >> The behavior looks good.
>> >>
>> >> .symver foo, foo@v1, remove
>> >> .globl foo
>> >> foo:
>> >>    call foo   # R_X86_64_PLT32 foo@v1
>> >>
>> >>
>> >>
>> >> I think this can be extended to non-remove one-@ as well.
>> >> The unadorned symbol and relocations referencing it just add complexity
>> >> to linker internals.
>> >>
>> >> .symver foo, foo@v1
>> >
>> >This usage is perfectly fine and quite normal.
>>
>> It isn't.
>>
>> cat > a.s <<eof
>> .symver foo, foo@v1
>> .globl foo
>> foo:
>> eof
>
>We must keep foo since there may be relocations
>against foo in this file as well as in other files.

In practice, no project uses this.
(OK, I am less confident on glibc but I am hoping it mostly does the right thing.)

Unversioned 'foo' references from other files should bind the default versioned definition,
not foo@v1.

If 'foo' does not have a default version definition, the references
should be versioned (`.symver foo, foo@@@v1`).

>> cat > a.ver <<eof
>> v1 {};
>> v2 { foo*; };
>> eof
>> cc -c a.s
>>
>> % ld.bfd --version-script=a.ver -shared a.o -o a.so && nm -D a.so
>> 0000000000001000 R foo@v1
>> 0000000000000000 A v1
>> 0000000000000000 A v2
>
>This looks normal.

I'd argue that the good design should leave a dynamic `foo@@v2`,
matching the case below.
Linkers would have been doing this if gas had done the right thing in
the first place.

>>
>> If
>> .symver foo_v1, foo@v1
>>
>> % ld.bfd --version-script=a.ver -shared a.o -o a.so && nm -D a.so
>> 0000000000001000 R foo@v1
>> 0000000000001000 R foo_v1@@v2
>> 0000000000000000 A v1
>> 0000000000000000 A v2
>
>This looks normal.

This is indeed normal.

>>
>> Merging (unadorned) foo and (non-default versioned) foo@v1 is a hack, in all of GNU ld, gold, and ld.lld.
>
>
>
>-- 
>H.J.


More information about the Binutils mailing list