Jakub Wilk wrote:
> * Jonathan Nieder <[email protected]>, 2011-10-17, 23:49:

> | Unfortunately one cannot even get lucky and find the symbol from
> | liblzma2 used from time to time: versioned symbols take precedence over
> | unversioned ones when resolving unversioned references.
>
> As far as I can tell, this is not the case.

For those who were in suspense: yeah, you're totally right.  It's all
coming back to me now...

Resolution of unversioned symbols seems (though I haven't found time
to check carefully yet) to happen on a first-library-mapped-wins
basis.  In practice:

 Consider a library libcallee:

        #include <stdio.h>
        void doit(void) { puts("hello, v" VERSION "!"); }

 A library libcaller:

        extern void doit(void);
        void doit_indirectly(void) { doit(); }

 An application app1:

        extern void doit(void), doit_indirectly(void);
        int main(void) { doit_indirectly(); doit(); return 0; }

 And an application app2:

        extern void doit(void), doit_indirectly(void);
        int main(void) { doit(); doit_indirectly(); }

 Now build:

        libcallee.so.1.0.0, VERSION="1"
        libcallee.so.2.0.0, VERSION="2", using symbol versioning
        libcaller.so.1.0.0, linked against libcallee.so.1
        libcaller.so.1.0.1, linked against libcallee.so.2

        app1-old, linked against libcaller.so.1 and libcallee.so.1
        app2-old, linked against libcaller.so.1 and libcallee.so.1
        app1-new, linked against libcaller.so.1 and libcallee.so.2
        app2-new, linked against libcaller.so.1 and libcallee.so.2

 Result:

        With libcaller.so.1.0.0 providing libcaller.so.1:

        binary          desired output          actual output
        ~~~~~~          ~~~~~~~~~~~~~~          ~~~~~~~~~~~~~
        app1-old        v1, v1                  v1, v1
        app1-new        v1, v2                  v2, v2
        app2-old        v1, v1                  v1, v1
        app2-new        v2, v1                  v2, v2

        With libcaller.so.1.0.1 providing libcaller.so.1:

        app1-old        v2, v1                  v1, v1
        app1-new        v2, v2                  v2, v2
        app2-old        v1, v2                  v1, v1
        app2-new        v2, v2                  v2, v2

In the cases where the actual result is "v2, v2" instead of one
implementation being used directly and another indirectly (think:
demo-app/wheezy with libkdecore5/squeeze), providing a base symbol in
libcallee.so.2 makes libcaller behave as expected again.  It helps.

On the other hand, in the cases where the actual result is "v1, v1"
instead of the expected mixture of implementations (think:
demo-app/squeeze with libkdecore5/wheezy), there's nothing we can do.
Luckily, in the case of liblzma, _all_ routines from liblzma2 work
just fine as implementations of the liblzma5 ABI, since the only
possibly relevant ABI mismatch is the added padding at the end of the
lzma_stream struct, which liblzma2 happily ignores.  So libcaller
behaves just fine, and we are safe, barely.

What is annoying about this is that I had worked it all out while
preparing for squeeze and breathed a sigh of relief, then promptly
forgot about it.  The result was the nonsense rationale I wrote ---
not good.  Thanks for a sanity check.


-- 
To UNSUBSCRIBE, email to [email protected]
with a subject of "unsubscribe". Trouble? Contact [email protected]
Archive: http://lists.debian.org/[email protected]

Reply via email to