Bug 16936 - $ORIGIN in shared library's rpath not used to find library dependencies at link time
Summary: $ORIGIN in shared library's rpath not used to find library dependencies at li...
Status: RESOLVED DUPLICATE of bug 20535
Alias: None
Product: binutils
Classification: Unclassified
Component: ld (show other bugs)
Version: 2.23
: P2 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2014-05-12 17:09 UTC by Steven Vormwald
Modified: 2017-08-07 06:42 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Steven Vormwald 2014-05-12 17:09:29 UTC
On Linux x86_64, it looks like ld does not respect $ORIGIN when used in a library's DT_RPATH entry, unlike the runtime loader.  This leads to link errors due to undefined symbols, which the runtime loader can actually find.  Additionally, adding directories to the linker's search path with -L does not suffice to find these dependent libraries, --rpath-link must be used.  A short example is below:

$ cat lib/libbar.c
int bar( void )
{
    return 0;
}
$ cat lib/libfoo.c
extern int bar( void );

int foo( void )
{
    return bar();
}
$ cat main.c
extern int foo();

int main()
{
    return foo();
}
$ readelf -d lib/libfoo_fullpath.so

Dynamic section at offset 0x798 contains 23 entries:
  Tag        Type                         Name/Value
 0x0000000000000001 (NEEDED)             Shared library: [libbar.so]
 0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]
 0x000000000000000e (SONAME)             Library soname: [libfoo_fullpath.so]
 0x000000000000000f (RPATH)              Library rpath: [/ptmp/sdvormwa/ld_bug/lib]
 0x000000000000000c (INIT)               0x4c8
 0x000000000000000d (FINI)               0x6a8
 0x0000000000000004 (HASH)               0x158
 0x0000000000000005 (STRTAB)             0x2f8
 0x0000000000000006 (SYMTAB)             0x1a8
 0x000000000000000a (STRSZ)              212 (bytes)
 0x000000000000000b (SYMENT)             24 (bytes)
 0x0000000000000003 (PLTGOT)             0x200970
 0x0000000000000002 (PLTRELSZ)           48 (bytes)
 0x0000000000000014 (PLTREL)             RELA
 0x0000000000000017 (JMPREL)             0x498
 0x0000000000000007 (RELA)               0x408
 0x0000000000000008 (RELASZ)             144 (bytes)
 0x0000000000000009 (RELAENT)            24 (bytes)
 0x000000006ffffffe (VERNEED)            0x3e8
 0x000000006fffffff (VERNEEDNUM)         1
 0x000000006ffffff0 (VERSYM)             0x3cc
 0x000000006ffffff9 (RELACOUNT)          1
 0x0000000000000000 (NULL)               0x0
$ readelf -d lib/libfoo_origin.so

Dynamic section at offset 0x798 contains 23 entries:
  Tag        Type                         Name/Value
 0x0000000000000001 (NEEDED)             Shared library: [libbar.so]
 0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]
 0x000000000000000e (SONAME)             Library soname: [libfoo.so]
 0x000000000000000f (RPATH)              Library rpath: [$ORIGIN]
 0x000000000000000c (INIT)               0x4c8
 0x000000000000000d (FINI)               0x6a8
 0x0000000000000004 (HASH)               0x158
 0x0000000000000005 (STRTAB)             0x2f8
 0x0000000000000006 (SYMTAB)             0x1a8
 0x000000000000000a (STRSZ)              208 (bytes)
 0x000000000000000b (SYMENT)             24 (bytes)
 0x0000000000000003 (PLTGOT)             0x200970
 0x0000000000000002 (PLTRELSZ)           48 (bytes)
 0x0000000000000014 (PLTREL)             RELA
 0x0000000000000017 (JMPREL)             0x498
 0x0000000000000007 (RELA)               0x408
 0x0000000000000008 (RELASZ)             144 (bytes)
 0x0000000000000009 (RELAENT)            24 (bytes)
 0x000000006ffffffe (VERNEED)            0x3e8
 0x000000006fffffff (VERNEEDNUM)         1
 0x000000006ffffff0 (VERSYM)             0x3c8
 0x000000006ffffff9 (RELACOUNT)          1
 0x0000000000000000 (NULL)               0x0
$ ldd lib/libfoo_fullpath.so
        linux-vdso.so.1 =>  (0x00007ffff81cb000)
        libbar.so => /ptmp/sdvormwa/ld_bug/lib/libbar.so (0x00007fc04c466000)
        libc.so.6 => /lib64/libc.so.6 (0x00007fc04c08c000)
        /lib64/ld-linux-x86-64.so.2 (0x00007fc04c86a000)
$ ldd lib/libfoo_origin.so
        linux-vdso.so.1 =>  (0x00007fff0e3ff000)
        libbar.so => /ptmp/sdvormwa/ld_bug/lib/libbar.so (0x00007f027c5de000)
        libc.so.6 => /lib64/libc.so.6 (0x00007f027c203000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f027c9e1000)
$ gcc main.c -Llib/ -lfoo_fullpath && echo PASS
PASS
$ gcc main.c -Llib/ -lfoo_origin && echo PASS
${CUSTOM_LD_PATH}/x86_64-unknown-linux-gnu/bin/ld: warning: libbar.so, needed by lib//libfoo.so, not found (try using -rpath or -rpath-link)
lib//libfoo.so: undefined reference to `bar'
collect2: ld returned 1 exit status
$ gcc main.c -Llib/ -lfoo_origin -Wl,--rpath-link=lib/ && echo PASS
PASS
$ ${CUSTOM_LD_PATH}/x86_64-unknown-linux-gnu/bin/ld --version
GNU ld (GNU Binutils) 2.23.1
Copyright 2012 Free Software Foundation, Inc.
This program is free software; you may redistribute it under the terms of
the GNU General Public License version 3 or (at your option) a later version.
This program has absolutely no warranty.
Comment 1 Steven Vormwald 2014-05-12 17:14:48 UTC
(In reply to Steven Vormwald from comment #0)
> ${CUSTOM_LD_PATH}/x86_64-unknown-linux-gnu/bin/ld: warning: libbar.so,
> needed by lib//libfoo.so, not found (try using -rpath or -rpath-link)
> lib//libfoo.so: undefined reference to `bar'
> collect2: ld returned 1 exit status

Oops, cut-and-paste error here.  I copied and edited (to remove employer-specific paths) the failure from before I tried building a version of the library without $ORIGIN.  Here's the correct error:

${CUSTOM_LD_PATH}/x86_64-unknown-linux-gnu/bin/ld: warning: libbar.so, needed by lib//libfoo_origin.so, not found (try using -rpath or -rpath-link)
lib//libfoo_origin.so: undefined reference to `bar'
collect2: ld returned 1 exit status
Comment 2 Steven Vormwald 2014-05-12 20:18:24 UTC
(In reply to Steven Vormwald from comment #0)
> GNU ld (GNU Binutils) 2.23.1

This problem also occurs in 2.24.
Comment 3 Ichthyostega 2015-08-10 02:30:59 UTC
Can confirm this problem on Debian/Jessie X86_64, which uses binutils 2.25

We build our software such that it can be executed from a subtree, without the need for explicit installation into the system. We have several shared modules, with transitive dependencies. And we set up the RPATH with $ORIGIN and a relative path spec. (Actually, its the RUNPATH, since we link with --enable-new-dtags )

We link with --no-undefined and --as-needed. This whole setup worked in the past (on Debian/Wheezy) without problems. But now, linking any executables fails, which need to locate transitive dependencies this way.

If we "help" the linker with --rpath-link and an explicit location within the build tree, the resulting executable is still able to locate the transitive dependencies at runtime as intended.


Incidentally, note that the new version of ld does no longer include the RPATH when --enable-new-dtags is given. So there *was* some change in this area, not sure if this observation is relevant in any way to our problem here
Comment 4 Florian Weimer 2017-08-07 06:42:03 UTC
Fixed in binutils 2.28.

*** This bug has been marked as a duplicate of bug 20535 ***