Dependencies - perhaps they can be lazily loaded |
Rod Evans Tuesday July 27, 2004
In a previous posting, I stated that you should only record those dependencies you need, and nothing else. There's another step you can take to reduce start-up processing overhead.
Dynamic objects need to resolve symbolic references from each other. Function calls are typically implemented through an indirection that allows the function binding to be deferred until the function call is first made. See When Relocations Are Performed. Because of this deferral, it is also possible to cause the defining dependency to be loaded when the function call is first made. This model is referred to as Lazy Loading.
To establish lazy loading, you must pass the -z lazyload
option to
% cat wally.c extern void foo(), bar(); void wally(int who) { who ? foo() : bar(); } % cc -o wally.so wally.c -G -Kpic -zdefs -zlazyload -R'$ORIGIN' foo.so bar.so
The lazy loading attribute of these dependencies can be displayed with
% elfdump -d wally.so | egrep "NEEDED|POSFLAG" [0] POSFLAG_1 0x1 [ LAZY ] [1] NEEDED 0x66 foo.so [2] POSFLAG_1 0x1 [ LAZY ] [3] NEEDED 0x6d bar.so
By default,
% ldd -Ld wally.so %
Once function relocations are processed, both dependencies are loaded to resolve the function reference.
% ldd -Lr wally.so foo.so => ./foo.so bar.so => ./bar.so
ldd(1) becomes a convenient tool for discovering whether lazy
loading might be applicable. Suppose we rebuilt
% cc -o wally.so wally.c -G -Kpic -zdefs -R'$ORIGIN' foo.so bar.so % ldd -Ldu wally.so foo.so => ./foo.so bar.so => ./bar.so unused object=./foo.so unused object=./bar.so
This has revealed that loading
Lazy loading can be observed at runtime using the runtime linkers
debugging capabilities (LD_DEBUG=files). For example, if
wally() was called with a zero argument, we'd see
% LD_DEBUG=files main ..... 25670: 1: transferring control: ./main ..... 25608: 1: file=bar.so; lazy loading from file=./wally.so: symbol=bar .....
Note, not only on does lazy loading have the potential of reducing the cost of start-up processing, but if lazy loading references are never called, the dependencies will never be loaded as part of the process.
[4] Linker Alien Spotting | [6] Lazy Loading fall back |