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

Re: About symbol versioning, soname bumps and symbols files.

+ Michael Biebl (Tue, 21 Apr 2009 17:40:23 +0200):

> [not sure if debian-mentors is the right list, but I try anyway]

[I’m moving to -devel in search of a wider audience, and dropping
-mentors via Bcc to avoid the crosspost. Hopefully interested -mentor
readers can move to -devel without much inconvenience.

I’ll also note I’m not that well versed on these matters, but since
there’s been no answer to date, I’ll provide with my understanding of
the matter, and hopefully can jump in if it’s horribly wrong.]

> Hi,

> I maintain the lksctp-tools package, which builds the libsctp1 binary
> package. The package so fare has been fairly straight forward and for
> version 1.0.9 I used a symbols file for libsctp1 which looks like
> this:

> libsctp.so.1 libsctp1 #MINVER#
>  sctp_bindx@Base 1.0.6.dfsg
>  sctp_connectx@Base 1.0.6.dfsg
>  sctp_freeladdrs@Base 1.0.6.dfsg
>  sctp_freepaddrs@Base 1.0.6.dfsg
>  sctp_getaddrlen@Base 1.0.7.dfsg
>  sctp_getladdrs@Base 1.0.6.dfsg
>  sctp_getpaddrs@Base 1.0.6.dfsg
>  sctp_opt_info@Base 1.0.6.dfsg
>  sctp_peeloff@Base 1.0.6.dfsg
>  sctp_recvmsg@Base 1.0.6.dfsg
>  sctp_send@Base 1.0.6.dfsg
>  sctp_sendmsg@Base 1.0.6.dfsg

> Now, I started packaging the new upstream version 1.0.10. There were
> some API incompatible changes to sctp_connectx in 1.0.10 (an
> additional function argument was added).

(Just so that it’s noted: it’s an API *and* ABI incompatible change.)

> Instead of simply bumping the soname, upstream did the following:

> 1.) he added a version script
> VERS_1 {
>         global:
>                 sctp_getpaddrs;
>                 sctp_freepaddrs;
>                 sctp_getladdrs;
>                 sctp_freeladdrs;
>                 sctp_getaddrlen;
>                 sctp_bindx;
>                 sctp_connectx;
>                 sctp_opt_info;
>                 sctp_peeloff;
>                 sctp_recvmsg;
>                 sctp_sendmsg;
>                 sctp_send;

>         local:
>                 *;
> };

> VERS_2 {
>         global: sctp_connectx;
> } VERS_1;

> 2.) In the source code, he added
> __asm__(".symver __sctp_connectx, sctp_connectx@");
> __asm__(".symver sctp_connectx_orig, sctp_connectx@VERS_1");
> __asm__(".symver sctp_connectx_new, sctp_connectx@@VERS_2");
> ...

> int __sctp_connectx(int fd, struct sockaddr *addrs, int addrcnt)
> ...
> extern int sctp_connectx_orig (int)
>         __attribute ((alias ("__sctp_connectx")));
> ...
> int sctp_connectx_new(int fd, struct sockaddr *addrs, int addrcnt,
>                       sctp_assoc_t *id)

> This was done, to avoid bumping the soname while still allowing older
> applications linking against the old interface afaiui. [1]

> The generated, new symbols file looks something like:

> libsctp.so.1 libsctp1 #MINVER#
>  VERS_1@VERS_1 1.0.10+dfsg
>  VERS_2@VERS_2 1.0.10+dfsg
>  sctp_bindx@VERS_1 1.0.10+dfsg
>  sctp_connectx@Base 1.0.10+dfsg
>  sctp_connectx@VERS_1 1.0.10+dfsg
>  sctp_connectx@VERS_2 1.0.10+dfsg
>  sctp_freeladdrs@VERS_1 1.0.10+dfsg
>  sctp_freepaddrs@VERS_1 1.0.10+dfsg
>  sctp_getaddrlen@VERS_1 1.0.10+dfsg
>  sctp_getladdrs@VERS_1 1.0.10+dfsg
>  sctp_getpaddrs@VERS_1 1.0.10+dfsg
>  sctp_opt_info@VERS_1 1.0.10+dfsg
>  sctp_peeloff@VERS_1 1.0.10+dfsg
>  sctp_recvmsg@VERS_1 1.0.10+dfsg
>  sctp_send@VERS_1 1.0.10+dfsg
>  sctp_sendmsg@VERS_1 1.0.10+dfsg

> Note, the three different versions of sctp_connectx (Base, VERS_1, VERS_2).

> Now, I've never seen this technique used like this before.
> So I'd very much appreciate any advice.

> My questions are:
> 1.) Is it fine to use symbol versioning like this to avoid bumping the
> soname or is this crack? Does this approach have downsides?

Yes, if done correctly, it’s fine to use symbol version for this purpose
(and it’s actually cool that clued upstreams do :-). I guess one of the
downsides is having to maintain both/all versions of the function, but
that’s a matter for upstream.

> 2.) Why are *there* different versions of sctp_connectx (Base and
> VERS_1 being and alias). I would have understood if there are two,
> VERS_1 and VERS_2.

I’m unsure why assigning VERS_1 to all symbols works for preserving
compatibility, whereas old binaries use symbols not associated with any
version node (i.e., @Base). Maybe the first defined version node gets to
“answer” to all requests that come without a version node attached. :-)
It’d be nice if somebody could explain.

But, if that’s true, I don’t know why there have to exist both a @Base
and @VERS_1 versions of sctp_connectx. I’ll also note that the @VERS_1
has a different prototype than the aliased function!

> 3.) Should I just update the symbols file as shown above and not worry?

I’d wait a bit to see if somebody follows-up on -devel, and would go
ahead if not. I did a small test and (unsurprisingly) it works fine.

> [1] http://sourceware.org/binutils/docs/ld/VERSION.html#VERSION


- Are you sure we're good?
- Always.
        -- Rory and Lorelai

Reply to: