Page 1 of 1

C++, ld, and Solaris weirdness

Posted: Thu Jan 27, 2005 1:45 pm
by Colonel Kernel
I'm wondering if anyone can help me with a linker-related problem I'm having on Solaris 8...

There's a really old shared library being built with an equally old makefile... Once upon a time it only contained C code, but somewhat recently some C++ stuff has been added to it, including a few static objects.

Through a painful process of diagnosis, I have figured out that the ld switch '-B symbolic' is for some reason preventing the constructors of static C++ objects in the .so from being called. I have no idea why. The problem is, if I remove -B symbolic, some other things break somewhat mysteriously. One of my colleagues hypothesizes that a global variable declare in a static lib that is linked into the .so is conflicting with (being merged with...?) the same variable in another copy of the static lib that is linked into the executable that is loading the .so, and that -B symbolic may have been added to the makefile years ago specifically to address this problem.

If that was confusing, here is some ASCII art:

mylib.a defines global variable 'foo'.

a.out -> mylib.a -> foo <-------------------+
| |
+----> mysharedlib.so -> mylib.a -> foo ---+

I don't understand enough details to verify his hypothesis... I've read the ld man pages ad nauseum... Can anyone give me a simpler explanation (or a link to one... no pun intended)? :)

Re:C++, ld, and Solaris weirdness

Posted: Fri Jan 28, 2005 12:51 am
by AR
I'm not sure how to fix it, but I have been studying the ELF ABI and Dynamic Linking recently.

The symbolic tag shouldn't stop the static constructors from working, the constructors are ment to be called in .init and destructors by .fini (try objdump-ing it to make sure they exist), -Bsymbolic causes the dynamic linker to link the GOT to symbols inside the library before searching the executable and other libraries (The default is to link to the function/variable in the executable before searching the libraries [including itself]).

You'll probably need to make sure there aren't 2 classes with the same name since the dynamic linker may link against the wrong one. Something to note about ELF is that it has an "executable namespace" as opposed to Windows PE which has individual namespaces for each library, this means that basically any variable/class/function with the same name as something else in any library, static or not, linked to the executable will conflict.

Re:C++, ld, and Solaris weirdness

Posted: Fri Jan 28, 2005 1:48 pm
by Colonel Kernel
Thanks for the info.

Do you know whether or not Solaris even uses ELF? I haven't been able to figure that out. In case it's relevant -- the problem is being observed on a Sparc machine... I haven't tried to repro it on Solaris x86 yet.

Also, do you know of a Sun equivalent for objdump? We're using Forte, not GCC.

One more thing... What you've described about the dynamic linker and "executable namespaces" makes sense, but does it also apply if the .so is being loaded via dlopen()? In the example I showed above, assume that a.out is loading mysharedlib.so using dlopen(). Does this problem with conflicting symbols still apply in this case? You can assume that a.out will not be trying to access foo via dlsym()...

Re:C++, ld, and Solaris weirdness

Posted: Fri Jan 28, 2005 2:32 pm
by Colonel Kernel
Ok, Solaris does use ELF... the relevant command is elfdump.

My question about dlopen() still stands though...

Re:C++, ld, and Solaris weirdness

Posted: Fri Jan 28, 2005 7:52 pm
by Colonel Kernel
Ok, I did an experiment, and dlopen() behaves the same way as "implicit" run-time linking. Bleah! Not the behaviour I would have expected...