Subject: rpath and dynamic linking bugs
To: None <tech-toolchain@netbsd.org>
From: None <erh@nimenees.com>
List: tech-toolchain
Date: 03/28/2000 19:01:06
	I've been trying to build a program that creates some temporary
(not installed) shared libraries.  It then creates a program which uses
the libraries during the build.  The program is linked with the appropriate
-rpath args so it should work fine even though the libraries reside in
some arbitrary directory.
	It doesn't: lib2 links against lib1 program links against lib1
and lib2 with rpath specifying where to look but when trying to run,
ld.elf_so appears to be ignoring the rpath specified in the program when
resolving the location of lib1 for lib2.  running ldd on the program gives
something like this:
 foo:
	-lc.12 => /usr/lib/libc.so.12
	-l1 => ../lib1/lib1.so
	-l1 => notfound
	-l2 => ../lib2/lib2.so

	ok, so it seems like I need to add a -rpath arg when building
lib2.  I did that.  It seems to work.  however, if I set the rpath for
lib2 to point to a different lib1 than the rpath for the program points
to ldd lists both of the lib1's but only actually uses the one the
program's rpath points to.
	for instance:
if program=>lib1=>afunc() spits out "asdf"
and lib2=>lib1=>afunc() spits out "qwerty"
I would expect calling afunc() from a function in lib2 to
spit out "qwerty", but it doesn't, it gets the first reference.

I see a couple possible solutions to this problem:

1) Enhance ld.elf_so to set things up so that lib2 gets the functions
in the library referenced by its rpath argument.

2) If ld.elf_so can find a library by using the rpath any component of
the final binary then it should not complain.  Specifically, if one
component doesn't have an rpath listed and the library isn't in one of
the system lib directories the dynamic linker can assume one the rpath
specified elsewhere is correct.  However, if any two components
want different major versions of a particular library then it should fail.

3) All rpath references are required to match or the library must exist
in one of the directories in ld.so.conf.


I think that options #2 would be preferrable since it is more compatible
with other unices.  Also because trying to do #1 would imply that multiple
versions of a library would be in memory and data objects from one might
try to get passed to another.  i.e. a FILE * from one version of libc
might get used with a function from the other version.A
	I also think option #2 would help in the case of supporting
previous major version of libraries since it would allow us to add
-l<whatever> args to each library in the tree to keep track of what
major version are it expects without needing to specify an explicit path
so that doing stuff like linking against a local copy of libc would
still work.
	Option #3 sucks because it precludes the possibility of linking
against a local library.

Comments?  (anyone who knows this better than I care to implement it?)

eric