Reputation: 31
Lets say I define an api (sym1) in file spec_a.h There is an implementation of this api in lib_imp1.so. I can have an application that dlopen's this shared library, dlsym() sym1 and invoke it. Is it possible for the application to dlopen() some other shared library with sym1 as undefined and it gets resolved to sym1 in lib_imp1.so? If so, how do we do it?
If it is possible, then we can have two implementations, lib_imp1.so and lib_imp2.so with both having two different addresses for the same symbol sym1. If the application loads another shared library with unresolved sym1, can we have any control on which sym1 (lib_imp1.so or lib_imp2.so) it gets resolved to?
While generating lib_imp1.so, can we say that while we want sym1 to be exported, we do not want any unresolved symbol to be resolved to it? (sort of controlled export??)
thanks
Upvotes: 1
Views: 445
Reputation: 213506
I can have an application that dlopen's this shared library, dlsym() sym1 and invoke it. Is it possible for the application to dlopen() some other shared library with sym1 as undefined and it gets resolved to sym1 in lib_imp1.so?
Yes: if the first dlopen
uses RTLD_GLOBAL
, then all symbols exported from lib_imp1.so
(including sym1
) are entered into the global scope, and become visible to other libraries loaded later.
If it is possible, then we can have two implementations, lib_imp1.so and lib_imp2.so with both having two different addresses for the same symbol sym1.
Yes. This is ill-advised.
If the application loads another shared library with unresolved sym1, can we have any control on which sym1 (lib_imp1.so or lib_imp2.so) it gets resolved to?
No. Assuming you dlopen
ed both lib_imp1.so
and lib_imp2.so
with RTLD_GLOBAL
, any subsequent library will always bind to sym1
from the first dlopen
ed library that provides it (i.e. it will resolve to lib_imp1.so
definition).
Further, if lib_imp1.so
also exports sym2
, and anything in lib_imp2.so
calls sym2
, that symbol would also resolve to the definition inside lib_imp1.so
(unless you take special care and use -Bsymbolic
).
The end result is that UNIX .so
libraries behave much like archive libraries would, and not like windows DLL
s. That makes having two separate implementations that export the same interface largely non-workable in a single process.
While generating lib_imp1.so, can we say that while we want sym1 to be exported, we do not want any unresolved symbol to be resolved to it?
The dlsym
uses exactly the same resolution process. If you make the symbol not available for anything to resolve to it, dlsym
will not find it either. Conversely, exporting symbol means exactly "make it available for resolution" (by either dlopen
or just regular unresolved dependency resolution).
Upvotes: 1