cvs commit: src/lib/libc/gen fts-compat.c fts-compat.h

Daniel Eischen deischen at freebsd.org
Thu Aug 30 01:39:10 PDT 2007


On Thu, 30 Aug 2007, Yar Tikhiy wrote:

> On Wed, Aug 29, 2007 at 10:03:41AM -0400, Daniel Eischen wrote:
>> On Wed, 29 Aug 2007, Yar Tikhiy wrote:
>>
>>> On the one hand, John's approach depends on alias symbols in HEAD
>>> so, e.g., both foo at FBSD-1.9 (public) and foo at FBSD-current-1.8.5
>>> (interim) can point to the same implementation for the "foo" interface
>>> after STABLE with foo at FBSD-1.9 was branched.  However, the GNU build
>>> tools don't seem to provide a straight way to that, they return an
>>> error if multiple versions reference the same function, so more
>>> stub code will be needed in the library, which will add to complexity
>>> of the approach.
>>
>> I think you can use -z muldefs or --allow-multiple-definition as a
>> linker argument to work around that.  libpthread once did that (or
>> something like it) so it could be compatible with libpthread.so.1
>> which used LIBPTHREAD_1_0 instead of FBSD_1_0.
>
> I'm afraid the ld trick won't work because the error is from as(1),
> e.g.:
>
> : $ make
> : cc -O2 -fno-strict-aliasing -pipe   -c foo.c
> : {standard input}: Assembler messages:
> : {standard input}:4: Error: multiple versions [`foo at FBSD_1.1'|`foo at FBSD_1.0'] for symbol `foo0'
> : *** Error code 1
>
> : $ cat foo.c
> : #include <sys/cdefs.h>
> :
> : int
> : foo0(int n)
> : {
> :         return (n + 1);
> : }
> :
> : __sym_compat(foo, foo0, FBSD_1.0);
> : __sym_compat(foo, foo0, FBSD_1.1);
> :
> : int
> : foo(int n)
> : {
> :         return (n + 3);
> : }
>
> Did I do anything wrong?

Hmm, I guess it's not that simple.  Take a look at the hack I had to make in
libpthread/thread/thr_private.h (line ~67).  I had to create weak references
to the functions, so for your example, you'd need something like:

__weak_reference(foo0, foo0_10);
__weak_refefence(foo0, foo0_11);
__sym_compat(foo, foo0_10, FBSD_1.0);
__sym_compat(foo, foo0_11, FBSD_1.1);

I think I also needed to make the latest symbol the default, changing
the last line above to __sym_compat_default(foo, foo0_11, FBSD_1.1),
but I seem to recall earlier email from you saying this shouldn't
be needed.  I _think_ I needed to for libpthread, but perhaps that
is because I had the symbols (e.g. foo) listed in both sections of
the map file:

 	LIBPTHREAD_1_0 {
 		pthread_foo;
 	};

 	FBSD_1_0 {
 		pthread_foo;
 	};

See r.19 of libpthread/pthread.map.

But this hackery isn't very pretty and is a little confusing, so
perhaps that is an argument against taking this approach?  Or maybe
not, if you can come up with a set of macros that can be easily
changed to do one thing in -current and a different thing in
release brannches - you might be able to avoid changing the
compat shims when branching -current to a release or MFC'ing.

>>> On the other hand, Symbol.map files should not contain duplicate
>>> symbol names as it seems to violate ld(1) semantics.  Therefore,
>>> if following Daniel's way, we'll need to track which symbols moved
>>> by more than one version since the last STABLE branch to find interim
>>> versions.  This shouldn't be too hard, but the implementation details
>>> are somewhat different.
>>
>> When someone changes the ABI, he's going to add a new set of symbols
>> to a Symbol.map file.  At this point before he commits he should
>> notice that there are duplicated symbols.  If he does, then he
>> removes them and updates ObsoleteVersions.  If he doesn't, then
>> you have duplicate symbols ;-)  Or you just have a script that
>> does this for you (version_gen.awk might be a good starting
>> point!).
>
> For the beginning, version_gen.awk could just complain about
> duplicated symbols and suggest adding them to ObsoleteVersions as
> there shouldn't be any duplicates in the whole version map generated.
> Is that reasonable?  BTW, what is a good place for ObsoleteVersions?
> src/lib/${libname}, along with Versions.def?  Or next to Symbol.map?

Since duplicates might not ever occur, you would probably have an
empty ObsoleteVersions file, so I'd recommend just one of them in
src/lib/${libname}.  Yes, I think having version_gen.awk complain
and abort if it encounters duplicates might be good enough for now.
Before a branch from -current, we can also manually check the
libraries to make sure there are no duplicate symbols from the last
branch (readelf -sW | awk ' {print $8}' | sort | some other magic).

-- 
DE


More information about the cvs-src mailing list