ld; extracting from libraries; and related questions

Gary Aitken freebsd at dreamchaser.org
Sat Dec 1 00:06:15 UTC 2012


On 11/29/12 14:00, Polytropon wrote:
> On Thu, 29 Nov 2012 13:54:02 -0700, Gary Aitken wrote:
>> Is it possible to extract a .o from a lib.a or lib.so, so I can compare
>> it to the .o built by the make?
> 
> If I remember correctly (which requires a travel into the
> distant past), I think "ar" - the library archiver - is
> the tool you need.
> 
> Check "man ar", the EXAMPLES section:
> 
>       To verbosely list the contents of archive ex.a, use:
>             ar -tv ex.a
> 
> So by using -x instead of -t, the members should be extracted.

Ah, those old brain cells aren't quite dead yet.

Interesting...

If I link against the libglib-2.0.a, and then the libglib-2.0.so.0 to 
resolve the undefined refs to _fini and _init, it reports the proper
version:
  
~/Computing/GIMP/gimp_2_8/work$ !1110
ld -o tst_version /usr/lib/crt1.o tst_version.o ~/Computing/GIMP/gimp_2_8/ports/devel/glib20/work/glib-2.34.1/glib/.libs/libglib-2.0.a ~/Computing/GIMP/gimp_2_8/ports/devel/glib20/work/glib-2.34.1/glib/.libs/libglib-2.0.so.0 -lc
~/Computing/GIMP/gimp_2_8/work$ ./tst_version
glib version=2.34.1

But if I link against the .so only I get the wrong version:

~/Computing/GIMP/gimp_2_8/work$ !1112
ld -o tst_version /usr/lib/crt1.o tst_version.o ~/Computing/GIMP/gimp_2_8/ports/devel/glib20/work/glib-2.34.1/glib/.libs/libglib-2.0.so.0 -lc
~/Computing/GIMP/gimp_2_8/work$ ./tst_version
glib version=2.28.8

Using ar I can extract the .o from the lib .a and objdump (unsuprisingly)
shows the right values for the fields, although the .o is not identical to 
the one compiled; may have some symbols stripped.

Unfortunately, ar can't be used to extract the .o from the lib .so.
Also, it doesn't appear possible to do that with ld.

I've regenerated the libs numerous times, and checked that the only instances
of gversion.o (the module where the version values are stored) is the one
with the 2.34.1.  The 2.28.8 is from the libglib-2.0.so installed in the 
standard place, /usr/local/lib.

I have vague recollections of reading something about shared libraries 
and mechanisms to prevent an imposter shared library from being loaded in
place of the "real" one.  I have a sneaking suspicion that may somehow be
getting in the way, although I haven't a clue how.

bingo!:

ldd tst_version
tst_version:
        libglib-2.0.so.0 => /usr/local/lib/libglib-2.0.so.0 (0x800849000)
        libc.so.7 => /lib/libc.so.7 (0x800b2b000)
        libintl.so.9 => /usr/local/lib/libintl.so.9 (0x800e71000)
        libiconv.so.3 => /usr/local/lib/libiconv.so.3 (0x80107a000)
        libpcre.so.1 => /usr/local/lib/libpcre.so.1 (0x801376000)

ugh.  So...  How does one install and use a newer version of a shared lib
in a place other than the standard place, for specific programs?  Is that even possible?  Unfortunately, the versioning of the library is the same,
libglib-2.0.so.0. 

thanks for any insights,

Gary


More information about the freebsd-questions mailing list