Re: Documenting the (dynamic) linking rules for symbol versioning

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 04/20/2017 04:09 PM, Michael Kerrisk (man-pages) wrote:
> On 04/20/2017 03:45 PM, Florian Weimer wrote:
>> On 04/20/2017 03:15 PM, Siddhesh Poyarekar wrote:
>>> On Thursday 20 April 2017 06:31 PM, Florian Weimer wrote:
>>>>> Hmm interesting, I thought 'latest' would imply the last version in the
>>>>> sequence of versions in the map, but I guess it kinda makes sense that
>>>>> it is the @@ default, similar to how a static linker would pick it up.
>>>>
>>>> It might be another instance of bug 12977.  At least its fix will
>>>> involve preferring the default version in this case.  I don't know what
>>>
>>>  From Michael's test case it seems like it already is preferring the
>>> default version.  The fix would have to be to the comment that says
>>> prefer the oldest version for regular unversioned lookups and the
>>> *latest* for the dlsym lookups.
>>>
>>> That or I misunderstood what you said.
>>
>> I think it picked the default version by accident because of the way the 
>> linker ordered the list.  But I could be mistaken.
> 
> How could I test your hypothesis? Just a longer chain of versions,
> maybe? Or oddly named version tags?

So, some quick testing.

1. A map file that have tags VER_1 through VER_5.
2. A C file with five implementations of xyz corresponding
   to those 5 VER_* tags.
3. My 'dynload' program that loads a shared library and looks up
   (dlsym) and calls the named function symbol.

I tried variously marking all five versions of xyz with '@@',
rebuilding the library, and running the command

    ./dynload libsv.o xyz

In each case, it was the xyz@@ symbol that was found by
dlsym().

If I marked none of five versions of xyz as default (i.e., @@),
then I get the error:

    dlsym: ./libsv.so: undefined symbol: xyz

All of this *suggests* that the observed behavior is not accidental.

And then there is this comment in elf/dl-lookup.c::check_match():

      /* No specific version is selected.  There are two ways we
         can got here:

         - a binary which does not include versioning information
         is loaded

         - dlsym() instead of dlvsym() is used to get a symbol which
         might exist in more than one form

         If the library does not provide symbol version information
         there is no problem at all: we simply use the symbol if it
         is defined.

         These two lookups need to be handled differently if the
         library defines versions.  In the case of the old
         unversioned application the oldest (default) version
         should be used.  In case of a dlsym() call the latest and
         public interface should be returned.  */

The last sentence doesn't seem quite right though: it appears
that it is the default symbol that is returned, not the latest
(which would always have been VER_5 in my example).

Cheers,

Michael


-- 
Michael Kerrisk
Linux man-pages maintainer; http://www.kernel.org/doc/man-pages/
Linux/UNIX System Programming Training: http://man7.org/training/
--
To unsubscribe from this list: send the line "unsubscribe linux-man" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Kernel Documentation]     [Netdev]     [Linux Ethernet Bridging]     [Linux Wireless]     [Kernel Newbies]     [Security]     [Linux for Hams]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux Admin]     [Samba]

  Powered by Linux