Bug 2290 - ld searches for implicit shared library dependencies in the wrong order (in particular, differently from linux's ld.so)
Summary: ld searches for implicit shared library dependencies in the wrong order (in p...
Status: RESOLVED FIXED
Alias: None
Product: binutils
Classification: Unclassified
Component: ld (show other bugs)
Version: 2.15
: P2 normal
Target Milestone: ---
Assignee: unassigned
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2006-02-06 23:24 UTC by Jeremy Brown
Modified: 2008-03-20 22:22 UTC (History)
3 users (show)

See Also:
Host: x86_64-redhat-linux
Target: x86_64-redhat-linux
Build: x86_64-redhat-linux
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Jeremy Brown 2006-02-06 23:24:13 UTC
When ld looks up dependent libraries, it searches a variety of
locations, with the final two sets being first, the system directories
/lib and /usr/lib; and second and finally, in directories listed in
/etc/ld.so.conf This order is documented in the info pages, see [1]

On GNU/Linux (Fedora core 3), ld.so will look for shared libraries in
a variety of places, with the final two places searched being, first,
entries cached in /etc/ld.so.cache; and second (and finally), /lib and
then /usr/lib.  This order is documented in the man page, see [2]

This means that unless you explicitly use the -rpath-link flag to ld
to replicate the contents of /etc/ld.so.conf, the directories searched
will be different at link-time and run-time.  This effect is
demonstrated by the sequence of commands at the bottom of this
message, see [3]   These commands are tailored for x86_64; you may need
to tweak them if you're on a 32-bit-only box.

I believe ld is doing the wrong thing here (although it is
*documentedly* doing the wrong thing;) it should favor paths in
/etc/ld.so.conf ahead of hard-coded system paths.

At the bottom of this email is a sequence of commands that illustrates
this conflicting behavior on my Fedora core 3 x86_64 box.  Here's the
most interesting part of the output from running them.

------------------------------------------------------------
1 sh-3.00#  gcc -Xlinker -verbose foo.c -o foo -lgnome-2 2>&1 | grep libxml2
2 libxml2.so.2 needed by /usr/lib64/libgnomevfs-2.so.0
3 found libxml2.so.2 at /usr/lib64/libxml2.so.2  
4 sh-3.00#  ldd foo | grep libxml2
5         libxml2.so.2 => /usr/lib/test/libxml2.so.2 (0x00002aaaac16b000)
6 sh-3.00#  LD_DEBUG=libs ./foo 2>&1 | grep libxml2
7      24661:     find library=libxml2.so.2 [0]; searching
8      24661:       trying file=/usr/lib/test/libxml2.so.2
9      24661:     calling init: /usr/lib/test/libxml2.so.2
10     24661:     calling fini: /usr/lib/test/libxml2.so.2 [0]
------------------------------------------------------------

Note that at line 3, the linker reports finding libxml2 at
/usr/lib64/libxml2, while at line 5, ldd finds it in /usr/lib/test/ As
another check, lines 8-10 show that ld.so also finds it in
/usr/lib/test

Obviously, if I have different versions of the library in a custom
path and a system path, I may have real trouble at link-time or
run-time.

Thanks for your time,
Jeremy



------------------------------------------------------------
[1]:  From the GNU ld info page documentation on -rpath-link:

       7. The default directories, normally `/lib' and `/usr/lib'.

       8. For a native linker on an ELF system, if the file
          `/etc/ld.so.conf' exists, the list of directories found in
          that file.

------------------------------------------------------------
[2]:  From the GNU/Linux man page on ld.so (Fedora):

       o      From  the  cache file /etc/ld.so.cache which contains a compiled
              list of candidate libraries previously found  in  the  augmented
              library  path.  If, however, the binary was linked with -z node-
              flib linker option, libraries in the default library  paths  are
              skipped.

       o      In  the default path /lib, and then /usr/lib.  If the binary was
              linked with -z nodeflib linker option, this step is skipped.

------------------------------------------------------------
[3] The following sequence of commands demonstrates the problem.
    It relies on the implicit dependency of libgnome-2 on libxml2.  
    It needs to be run as root, because it adjusts (and then resets) 
    ld.so.conf.

 mkdir -p /usr/lib/test
 echo '/usr/lib/test' | cat - /etc/ld.so.conf > /etc/ld.so.conf.new
 mv /etc/ld.so.conf /etc/ld.so.conf.old
 mv /etc/ld.so.conf.new /etc/ld.so.conf
 cd /usr/lib/test
 cp -s /usr/lib64/libxml2.* .
 ldconfig
 cd /tmp
 echo 'int main(int argc, char **argv) { return 0;}' > foo.c
 gcc -Xlinker -verbose foo.c -o foo -lgnome-2 2>&1 | grep libxml2
 ldd foo | grep libxml2
 LD_DEBUG=libs ./foo 2>&1 | grep libxml2
 gcc -Xlinker -rpath-link /usr/lib/test -Xlinker -verbose foo.c -o foo -lgnome-2
2>&1 | grep libxml2
 ldd foo | grep libxml2
 mv /etc/ld.so.conf.old /etc/ld.so.conf
 rm -r /usr/lib/test
 ldconfig
Comment 1 Jeremy Brown 2006-02-07 15:07:03 UTC
I should have mentioned the OS:  this is on Fedora Core 3.
Comment 2 H.J. Lu 2006-02-09 00:14:21 UTC
A patch is posted at

http://sourceware.org/ml/binutils/2006-02/msg00127.html
Comment 3 H.J. Lu 2006-02-09 01:05:44 UTC
Fixed.