Linux, GNU GCC, ld, version scripts and the ELF binary format -- How does it work?
This doesn't exactly answer your question, but...
First of all, ELF is the specification use by Linux for executable files (programs), shared libraries, and also object files which are the intermediate files found when compiling software. Object files end in .o, shared libraries end with .so followed by zero or more digits separated by periods, and executable files don't have any extension normally.
There are typically three forms to name a shared library, the first form simply ends in .so. For example, a library called readline is stored in a file called libreadline.so and is located under one of /lib, /usr/lib, or /usr/local/lib normally. That file is located when compiling software with an option like -lreadline. -l tells the compiler to link with the following library. Because libraries change from time to time, it may become obsolete so libraries embed something called a SONAME. The SONAME for readline might look like libreadline.so.2 for the second version major version of libreadline. There may also be many minor versions of readline that are compatible and do not require software to be recompiled. A minor version of readline might be named libreadline.so.2.14. Normally libreadline.so is just a symbolic link to the most recent major version of readline, libreadline.so.2 in this case. libreadline.so.2 is also a symbolic link to libreadline.so.2.14 which is actually the file being used.
The SONAME of a library is embedded inside the library file itself. Somewhere inside the file libreadline.so.2.14 is the string libreadline.so.2. When a program is compiled and linked with readline, it will look for the file libreadline.so and read the SONAME embedded in it. Later, when the program is actually executed, it will load libreadline.so.2, not just libreadline.so, since that was the SONAME that was read when it was first linked. This allows a system to have multiple incompatible versions of readline installed, and each program will load the appropriate major version it was linked with. Also, when upgrading readline, say, to 2.17, I can just install libreadline.so.2.17 alongside the existing library, and once I move the symbolic link libreadline.so.2 from libreadline.so.2.13 to libreadline.so.2.17, all software using that same major version will now see the new minor update to it.
Related videos on Youtube
themoondothshine
Updated on September 17, 2022Comments
-
themoondothshine almost 2 years
I'm trying to learn more about library versioning in Linux and how to put it all to work. Here's the context:
-- I have two versions of a dynamic library which expose the same set of interfaces, say
libsome1.so
andlibsome2.so
.-- An application is linked against
libsome1.so
.-- This application uses
libdl.so
to dynamically load another module, saylibmagic.so
.-- Now
libmagic.so
is linked againstlibsome2.so
. Obviously, without using linker scripts to hide symbols inlibmagic.so
, at run-time all calls to interfaces inlibsome2.so
are resolved tolibsome1.so
. This can be confirmed by checking the value returned bylibVersion()
against the value of the macroLIB_VERSION
.-- So I try next to compile and link
libmagic.so
with a linker script which hides all symbols except 3 which are defined inlibmagic.so
and are exported by it. This works... Or at leastlibVersion()
andLIB_VERSION
values match (and it reports version 2 not 1).-- However, when some data structures are serialized to disk, I noticed some corruption. In the application's directory if I delete
libsome1.so
and create a soft link in its place to point tolibsome2.so
, everything works as expected and the same corruption does not happen.I can't help but think that this may be caused due to some conflict in the run-time linker's resolution of symbols. I've tried many things, like trying to link
libsome2.so
so that all symbols are alised tosymbol@@VER_2
(which I am still confused about because the commandnm -CD libsome2.so
still lists symbols assymbol
and notsymbol@@VER_2
)... Nothing seems to work!!! Help!!!!!!-
RobotHumans over 13 yearsYour last approach is the one I would have started with. And I agree that the corruption is probably some symbol confusion. Sadly I don't have an answer for you.
-
xenoterracide over 13 yearsthis might do better on SO, though tbh I don't understand it enough to say for sure. flag it if you'd like us to move it.
-
stribika over 13 yearsTry the
RTLD_LOCAL
andRTLD_DEEPBIND
dlopen flags in you app. I don't have time to test this now but it should work based on the manpage.
-