Deferred Dependencies
A deferred dependency identifies a dependency
for which all references to that dependency are deferred.
Deferred dependencies are established at link-edit time
using the link-editors -z deferred
option.
$ cc -G -o libdef.so.1 def.c -lfoo -z deferred -lbar -lc
The deferred nature of these references can be observed from the symbol information and dynamic information defined within the referring object.
$ elfdump -d libdef.so.1 | egrep "NEEDED|POSFLAG" [0] NEEDED 0x85 libfoo.so [1] POSFLAG_1 0x4 [ DEFERRED ] [2] NEEDED 0x8f libbar.so [3] NEEDED 0x99 libc.so $ elfdump -y libdep.so.1 | egrep "foo|bar" [4] [ DEPEND DEFERRED ] [2] libbar.so bar1 [7] [ DEPEND ] [0] libfoo.so foo1 ...
Having established libbar.so.1
as a
deferred dependency, at runtime a
dlsym(RTLD_PROBE)
against one of
the bar
() symbols can be used to
determine whether the family of symbols are available. On
success, the members of the family can be called as direct
function calls. These calls are much more legible and easier
to write, and allow the compiler to catch errors in their
calling sequences.
void dep() { if (dlsym(RTLD_PROBE, "bar1")) { bar1(arg1); bar2(arg2); .... } }
Deferred dependencies offer an additional level of
flexibility. Provided the dependency has not already been
loaded, the dependency can be changed at runtime. This
mechanism offers a level of flexibility similar to
dlopen
(3C), where different objects can
be loaded and bound to by the caller.
If the original dependency name is known, then the original
dependency can be exchanged for a new dependency using
dlinfo
(3C) with the
RTLD_DI_DEFERRED
argument. Alternatively, a deferred symbol that is
associated with the dependency can be used to identify the
deferred dependency using
dlinfo
(3C) with the
RTLD_DI_DEFERRED_SYM
argument.