Issue
I'm encountering an issue which has been elaborated in a good article Shared Library Symbol Conflicts (on Linux). The problem is that when the execution and .so have defined the same name functions, if the .so calls this function name, it would call into that one in execution rather than this one in .so itself.
Let's talk about the case in this article. I understand the DoLayer()
function in layer.o
has an external function dependency of DoThing()
when compiling layer.o
.
But when compiling the libconflict.so
, shouldn't the external function dependency be resolved in-place and just replaced with the address of conflict.o/DoThing()
statically?
Why does the layer.o/DoLayer()
still use dynamic linking to find DoThing()
? Is this a designed behavior?
Solution
Is this a designed behavior?
Yes.
At the time of introduction of shared libraries on UNIX, the goal was to pretend that they work just as if the code was in a regular (archive) library.
Suppose you have foo()
defined in both libfoo
and libbar
, and bar()
in libbar
calls foo()
.
The design goal was that cc main.c -lfoo -lbar
works the same regardless of whether libfoo
and libbar
are archive or a shared libraries. The only way to achieve this is to have libbar.so
use dynamic linking to resolve call from bar()
to foo()
, despite having a local version of foo()
.
This design makes it impossible to create a self-contained libbar.so
-- its behavior (which functions it ends up calling) depends on what other functions are linked into the process. This is also the opposite of how Windows DLLs work.
Creating self-contained DSOs was not a consideration at the time, since UNIX was effectively open-source.
You can change the rules with special linker flags, such as -Bsymbolic
. But the rules get complicated very quickly, and (since that isn't the default) you may encounter bugs in the linker or the runtime loader.
Answered By - Employed Russian