rtld: Implement DT_RUNPATH and -z nodefaultlib
authorJohn Marino <draco@marino.st>
Sat, 24 Mar 2012 05:40:50 +0000 (06:40 +0100)
committerJohn Marino <draco@marino.st>
Sat, 24 Mar 2012 18:17:28 +0000 (19:17 +0100)
commit4f0bc915b65fcf5a23214f6d221d65c80be68ad4
treeefaade44ec1213ea6a53ccdf752b53c9020515c5
parentccb6967fac71c16437b0430f2d38fd8501de8ad7
rtld: Implement DT_RUNPATH and -z nodefaultlib

DT_RUNPATH is incorrectly being considered as an alias of DT_RPATH.  The
purpose of DT_RUNPATH is to have two different types of rpath: one that
can be overridden by the environment variable LD_LIBRARY_PATH and one that
can't.  With the currently implementation, LD_LIBRARY_PATH will always
trump any embedded rpath or runpath tags.

Current path search order by rtld:
==================================
LD_LIBRARY_PATH
DT_RPATH / DT_RUNPATH (always the same)
ldconfig hints file (default: /var/run/ld-elf.so.hints)
/usr/lib

New path search order by rtld:
==============================
DT_RPATH of the calling object if no DT_RUNPATH
DT_RPATH of the main binary if no DT_RUNPATH and binary isn't calling obj
LD_LIBRARY_PATH
DT_RUNPATH
ldconfig hints file
/usr/lib

The new path search matches how the linux runtime loader works.  The other
major added feature is support for linker flag "-z nodefaultlib".  When
this flag is passed to the linker, rtld will skip all references to the
standard library search path ("/usr/lib" in this case but it could handle
more color delimited paths) except in DT_RPATH and DT_RUNPATH.

New path search order by rtld with -z nodefaultlib flag set:
============================================================
DT_RPATH of the calling object if no DT_RUNPATH
DT_RPATH of the main binary if no DT_RUNPATH and binary isn't calling obj
LD_LIBRARY_PATH
DT_RUNPATH
ldconfig hints file (skips all references to /usr/lib)

Currently gcc41 and gcc44 are embedding /usr/lib directly in every
DT_RPATH tag of every binary and shared library it creates.  This is
both unnecessary due to rtld default search path order and it also
defaults the purpose of -z nodefaultlib, so this behavior must be
changed before the flag works.  This will be done in a separate commit.
libexec/rtld-elf/rtld.c
libexec/rtld-elf/rtld.h