I ran into an issue with the relocation of global symbols.
The attached tarball contains 3 C files (and a Makefile that shows how to reproduce the behaviour):
- sim.c (compiled into executable "sim")
- system.c (compiled into shared object "system.so")
- host.c (compiled into shared object "host.so")
The sim module does a dlopen of "system.so" which in its turn does a dlopen of the "host.so". Both dlopen calls have the RTDL_GLOBAL flag as an argument. All 3 modules contain a global "print" function. All 3 modules contain a call to "the" "print" function.
Since the system and host modules are compiled into shared libraries I would expect that they end up calling the print function defined in their own module (since those references have been resolved already, both shared objects contain no undefined reference to "print").
However, both host.c and system.c end up calling the "print" function defined in system.c, while I expected that the host.c would call it's own print function (the output shows the line "hello from system" twice instead of "hello from host" and "hello from system").
Perhaps my understanding and/or expectations are wrong.. I'm not sure.. I was hoping someone could either confirm this is a bug or tell me how to get my expected behaviour. I've read all of the gcc, ld and dlopen manpages, but I can't find anything.
Here's some info on the platform I'm running on:
> uname -a
Linux belegund 2.4.21-40.ELsmp #1 SMP Thu Feb 2 22:13:55 EST 2006 x86_64 x86_64 x86_64 GNU/Linux
> cat /etc/redhat-release
Red Hat Enterprise Linux WS release 3 (Taroon Update 7)
> gcc --version
gcc (GCC) 4.1.1
> gcc -Wl,--version
GNU ld version 2.16.1
I can reproduce the same behaviour with gcc 3.4.3 by the way.