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

H.J. Lu hjl.tools@gmail.com
Fri Aug 13 21:01:31 GMT 2021


On Thu, Aug 12, 2021 at 3:52 PM Fangrui Song <i@maskray.me> wrote:
>
>
> 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.)

This is the standard usage in glibc.

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

Unversioned 'foo' references from other files will be resolved to the
unversioned
foo definition which will be turned into a local symbol.

>
> 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.



-- 
H.J.


More information about the Binutils mailing list