Moving to -discuss as this has nothing to do with the development of
illumos...

On Sun, Dec 09, 2012 at 04:58:24PM +0100, Richard PALO wrote:

> In particular, shared libraries seem to build just fine, but there are 
> cases where some programs which reference 
> ../dirname/.libs/libraryname.so during a libtool link will have the path 
> hardcoded into the program.

Recall the rules for encoding DT_NEEDED entries:

1. If the referenced object has a DT_SONAME field, use its contents.

2. Otherwise, use the filename.

Further recall the rules for runtime searches for libraries referenced
by DT_NEEDED entries:

1. Search LD_LIBRARY_PATH or related paths.

2. Search DT_RPATH/DT_RUNPATH.

3. Search crle configured paths.

4. Search the default paths (which can also be set by crle), /usr/lib
and/lib.

There are variations depending on how something is built, whether the
executable is setuid, etc., but that's the basic path.  So, a few
questions to help diagnose this, ignoring for the moment exactly what
libtool is doing wrong or how to fix it:

1. What's DT_SONAME set to in librarian.so?  (It looks from your command
line below in libtool that it should be getting set, but...)

2. Is this getting correctly set in rarian-sk-preinstall's DT_NEEDED?
The core of your question seems to be whether DT_SONAME is actually used
if one passes the library filename itself on the link-editor's command
line, and this should provide your basic answer.

3. Does rarian-sk-preinstall's DT_RPATH include a path to librarian.so,
or whatever filename is in its DT_NEEDED reference?  If not, none of the
rest of this matters.  You won't be able to execute this program until
librarian.so (or whatever's in DT_NEEDED) is in the correct location in
the filesystem.

You can find all this stuff with elfdump -d.

In my own testing here, if the library has a DT_SONAME entry, it is
always encoded in the consumer's DT_NEEDED, regardless of whether it is
linked in with -L/path -lfoo or ../../path/to/libfoo.so.1.  That said,
if my library is built incorrectly such that it does NOT have a
DT_SONAME field, then I see what you are seeing.

wesolows at playground2 in ~/src
$ gcc -G -o ./foo/bar/libfoo.so libfoo.o
wesolows at playground2 in ~/src
$ elfdump -d ./foo/bar/libfoo.so | grep SONAME
wesolows at playground2 in ~/src
$ gcc -o main main.c ./foo/bar/libfoo.so
wesolows at playground2 in ~/src
$ elfdump -d ./main | grep NEEDED
       [0]  NEEDED            0x249               ./foo/bar/libfoo.so
       [1]  NEEDED            0x223               libc.so.1
wesolows at playground2 in ~/src
$ ldd ./main
        ./foo/bar/libfoo.so =>   ./foo/bar/libfoo.so
        libc.so.1 =>     /lib/libc.so.1
        libm.so.2 =>     /lib/libm.so.2

Contrast with:

wesolows at playground2 in ~/src
$ gcc -G -Wl,-h,libfoo.so.1 -o ./foo/bar/libfoo.so.1 libfoo.o
wesolows at playground2 in ~/src
$ ln -s libfoo.so.1 ./foo/bar/libfoo.so
wesolows at playground2 in ~/src
$ gcc -o main main.c ./foo/bar/libfoo.so
wesolows at playground2 in ~/src
$ elfdump -d ./foo/bar/libfoo.so | grep SONAME
       [3]  SONAME            0xb                 libfoo.so.1
wesolows at playground2 in ~/src
$ elfdump -d ./main | grep NEEDED
       [0]  NEEDED            0x249               libfoo.so.1
       [1]  NEEDED            0x223               libc.so.1
wesolows at playground2 in ~/src
$ ldd ./main
        libfoo.so.1 =>   (file not found)
        libc.so.1 =>     /lib/libc.so.1
        libm.so.2 =>     /lib/libm.so.2
wesolows at playground2 in ~/src
$ LD_LIBRARY_PATH=./foo/bar ldd ./main
        libfoo.so.1 =>   ./foo/bar/libfoo.so.1
        libc.so.1 =>     /lib/libc.so.1
        libm.so.2 =>     /lib/libm.so.2

All of this is the behaviour that I would expect.  In all likelihood,
your copy of ../librarian/.libs/librarian.so either is, or is a symlink
to, a library that does not have a DT_SONAME entry.  You will need to
figure out why that is and fix it.  Could be a bug in libtool, could be
a bug in librarian's build system.  As always with libtool, the only way
to win is not to play.

> Here is an example, building rarian where the shared library is librarian:
> 
> richard@devzoneX:/tmp/pkgsrc/textproc/rarian/work/rarian-0.8.1/librarian/.libs$
>  
> ldd -d librarian.so
>         libstdc++.so.6 =>        /opt/pkg/gcc47/lib/amd64/libstdc++.so.6
>         libm.so.2 =>     /lib/64/libm.so.2
>         libc.so.1 =>     /lib/64/libc.so.1
>         libgcc_s.so.1 =>         /opt/pkg/gcc47/lib/amd64/libgcc_s.so.1
> 
> richard@devzoneX:/tmp/pkgsrc/textproc/rarian/work/rarian-0.8.1/util/.libs$ 
> ldd -d rarian-sk-preinstall
>         ../librarian/.libs/librarian.so =>       (file not found)
>         libstdc++.so.6 =>        /opt/pkg/gcc47/lib/amd64/libstdc++.so.6
>         libm.so.2 =>     /lib/64/libm.so.2
>         libgcc_s.so.1 =>         /opt/pkg/gcc47/lib/amd64/libgcc_s.so.1
>         libc.so.1 =>     /lib/64/libc.so.1
> 
> 
> /bin/bash ../libtool --tag=CXX   --mode=link g++  -O -I/opt/pkg/include 
> -I/opt/pkg/include/gettext -I/usr/include 
> -L/opt/pkg/gcc47/lib/gcc/x86_64-sun-solaris2.11/4.7.2 
> -Wl,-R/opt/pkg/gcc47/lib/gcc/x86_64-sun-solaris2.11/4.7.2 
> -L/opt/pkg/gcc47/lib -Wl,-R/opt/pkg/gcc47/lib -L/opt/pkg/lib 
> -Wl,-R/opt/pkg/lib -L/usr/lib -Wl,-R/usr/lib -o rarian-sk-preinstall 
> rarian-sk-preinstall.o tinystr.o tinyxml.o tinyxmlerror.o 
> tinyxmlparser.o ../librarian/librarian.la
> libtool: link: g++ -O 
> -I/tmp/pkgsrc/textproc/rarian/work/.buildlink/include 
> -I/tmp/pkgsrc/textproc/rarian/work/.buildlink/include/gettext 
> -Wl,-R/opt/pkg/gcc47/lib/gcc/x86_64-sun-solaris2.11/4.7.2 
> -Wl,-R/opt/pkg/gcc47/lib -Wl,-R/opt/pkg/lib -o 
> .libs/rarian-sk-preinstall rarian-sk-preinstall.o tinystr.o tinyxml.o 
> tinyxmlerror.o tinyxmlparser.o 
> -L/opt/pkg/gcc47/lib/gcc/x86_64-sun-solaris2.11/4.7.2 
> -L/opt/pkg/gcc47/lib -L/tmp/pkgsrc/textproc/rarian/work/.buildlink/lib 
> ../librarian/.libs/librarian.so /opt/pkg/gcc47/lib/libstdc++.so -lm 
> -Wl,-R -Wl,/opt/pkg/lib -Wl,-R -Wl,/opt/pkg/gcc47/lib
> 
> As can be seen here, librarian.so is being linked to directly with a 
> directory relative reference...
> 
> This, to me, seems to indicate that the linker is indeed hardcoding the 
> direct reference.
> 
> Here are the settings according the latest libtool:
> 
> # Commands used to build a shared archive.
> archive_cmds="\$CC -shared \$pic_flag \${wl}-z \${wl}text \${wl}-h 
> \${wl}\$soname -o \$lib \$libobjs \$deplibs \$compiler_flags"
> archive_expsym_cmds="echo \\\"{ global:\\\" > \$lib.exp~cat 
> \$export_symbols | \$SED -e \\\"s/\\\\(.*\\\\)/\\\\1;/\\\" >> 
> \$lib.exp~echo \\\"local: *; };\\\" >> \$lib.exp~
>         \$CC -shared \$pic_flag \${wl}-z \${wl}text \${wl}-M 
>         \${wl}\$lib.exp \${wl}-h \${wl}\$soname -o \$lib \$libobjs \$deplibs 
> \$compiler_flags~\$RM \$lib.exp"
> 
> # Commands used to build a loadable module if different from building
> # a shared archive.
> module_cmds=""
> module_expsym_cmds=""
> 
> # Whether we are building with GNU ld or not.
> with_gnu_ld="no"
> 
> # Flag that allows shared libraries with undefined symbols to be built.
> allow_undefined_flag=""
> 
> # Flag that enforces no undefined symbols.
> no_undefined_flag=" -z defs"
> 
> # Flag to hardcode $libdir into a binary during linking.
> # This must work even if $libdir does not exist
> hardcode_libdir_flag_spec="-R\$libdir"
> 
> # Whether we need a single "-rpath" flag with a separated argument.
> hardcode_libdir_separator=""
> 
> # Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes
> # DIR into the resulting binary.
> hardcode_direct=no
> 
> # Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes
> # DIR into the resulting binary and the resulting library dependency is
> # "absolute",i.e impossible to change by setting ${shlibpath_var} if the
> # library is relocated.
> hardcode_direct_absolute=no
> 
> # Set to "yes" if using the -LDIR flag during linking hardcodes DIR
> # into the resulting binary.
> hardcode_minus_L=no
> 
> # Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR
> # into the resulting binary.
> hardcode_shlibpath_var=no
> 
> # Set to "yes" if building a shared library automatically hardcodes DIR
> # into the library and all subsequent libraries and executables linked
> # against it.
> hardcode_automatic=no
> 
> # Set to yes if linker adds runtime paths of dependent libraries
> # to runtime path list.
> inherit_rpath=no
> 
> =================
> is it possible that
> 'hardcode_direct=yes'
> is actually the case with the illumos 64 link editor?
> 
> 
> I found this ages-old reference, seems like the issue has come up 
> before, but I have no idea the state of things...
> http://lists.gnu.org/archive/html/libtool-patches/2001-02/msg00019.html
> 
> Since rich lowe is deep into things about the linker, perhaps he is able 
> to steer me in a useable direction...  Since I've recently rebuilt
> libtool 2.4.2 on pkgsrc, I can test some patches quite easily at the moment.
> 
> cheers, and thanks in advance.
> 
> 
> 
> -------------------------------------------
> illumos-developer
> Archives: https://www.listbox.com/member/archive/182179/=now
> RSS Feed: 
> https://www.listbox.com/member/archive/rss/182179/22141656-d68fbd4e
> Modify Your Subscription: 
> https://www.listbox.com/member/?&;
> Powered by Listbox: http://www.listbox.com


-------------------------------------------
illumos-discuss
Archives: https://www.listbox.com/member/archive/182180/=now
RSS Feed: https://www.listbox.com/member/archive/rss/182180/21175430-2e6923be
Modify Your Subscription: 
https://www.listbox.com/member/?member_id=21175430&id_secret=21175430-6a77cda4
Powered by Listbox: http://www.listbox.com

Reply via email to