https://sourceware.org/bugzilla/show_bug.cgi?id=33577

Ali Bahrami <ali_swbugzilla at emvision dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |ali_swbugzilla at emvision dot 
com

--- Comment #3 from Ali Bahrami <ali_swbugzilla at emvision dot com> ---
Is it usual here to close bugs immediately, without a chance to discuss? I'd
like to ask that it be reopened, and that the discussion continue.

No one claimed that linker scripts control references. They don't, but that's
not the issue being reported. The issue is that this reference symbol is being
added to a version *definition* section. If it was being added to a version
needed section, that would be another matter. Here, the linker script doesn't
control the version assigned to show_undef_weak, but it does serve to enable
the versioning plumbing generally, and that seems to be involved.

Let's look closer, using gld on Solaris, because that's what I'm running, but I
would expect that it will be the same on Linux. To provide a point of
reference, I've added a call to printf() to the original source file:

    % cat  vers33.c
    #include <stdio.h>

    extern void show_undef_weak (void) __attribute__((weak));

    void
    foo (void)
    {
      if (show_undef_weak)
        show_undef_weak ();

      printf("done");
    }

Start with a .o:

    % gcc -fPIC -shared -c vers33.c

Linking it without the linker script, we get the expected result:

    % gld --shared /usr/lib/64/crti.o vers33.o /usr/lib/64/crtn.o -lc
    % elfdump -v a.out

    Version Needed Section:  .gnu.version_r
      index  file       version   
        [2]  libc.so.1  SUNW_0.7
    % pvs -os a.out
    a.out - libc.so.1 (SUNW_0.7): printf;

That's all reasonable: printf() has been assigned to a version needed section
for libc, and otherwise, there's no versioning in play.

Now, see what happens when we add in the linker script:

    % ld --shared /usr/lib/64/crti.o vers33.o --version-script vers33.map
/usr/lib/64/crtn.o -lc
    % elfdump -v a.out

    Version Definition Section:  .gnu.version_d
      index  version    dependency
        [1]  a.out                  [ BASE ]
        [2]  VERS_1     

    Version Needed Section:  .gnu.version_r
      index  file       version   
        [3]  libc.so.1  SUNW_0.7
    % pvs -os a.out
    a.out - libc.so.1 (SUNW_0.7): printf;
    a.out - a.out: _PROCEDURE_LINKAGE_TABLE_;
    a.out - a.out: _edata;
    a.out - a.out: _etext;
    a.out - a.out: _end;
    a.out - a.out: _DYNAMIC;
    a.out - a.out: show_undef_weak;
    a.out - a.out: _GLOBAL_OFFSET_TABLE_;
    a.out - VERS_1: foo;

Note that show_undef_weak has been assigned to the Version Definition Section,
and not a Version Needed Section (like printf). Doesn't it seem like something
is off here? I agree with your point that "linker doesn't know where/if/how
show_undef_weak is defined at run-time", but it certainly does know that it
wasn't defined by the object it is building (a.out). My guess is that this is
an unhandled case that simply "fell through" to the base definition, and not
really the intended outcome.

That leaves the question of where it should be assigned. As you said, "It can
be unversioned or have some other version". However, in this case, it can only
be unversioned, because the only mention of it is in the declaration:

    extern void show_undef_weak (void) __attribute__((weak));

For it to have some other version, that symbol would need to have been seen in
a dependency (like printf is seen in libc), which would then cause a Version
Needed Record to be created. Here, there is nothing, so unversioned would seem
to be the only valid option.

???

-- 
You are receiving this mail because:
You are on the CC list for the bug.

Reply via email to