This is the mail archive of the
mailing list for the binutils project.
Global symbol table, problems with library version conflicts andWine
- From: Mike Hearn <mike at theoretic dot com>
- To: binutils at sources dot redhat dot com
- Date: 14 Dec 2002 23:26:40 +0000
- Subject: Global symbol table, problems with library version conflicts andWine
I'm trying to make distro neutral packages as part of the autopackage
project (autopackage.org), and as part of that we've run into the
problems caused by a program indirectly linking in two versions of the
same library. Please note I learnt all I know about dynamic linking from
so I'm no expert on the matter.
For example, if I have app1 which links against glib2 and libfoo, and
libfoo in turn links against glib1 the symbols will conflict inside the
linkers global symbol table and bad things will happen.
As you might imagine, this makes producing binaries that will work on a
variety of different distros rather difficult, especially for closed
source vendors. One example of this was the libpng break:
which caused problems because an app that used libpng3 and libSDL
implicitly imported libpng2, something went wrong (symbol conflicts?)
and the app would segfault.
So, I have a few questions about this issue.
The first is, why does ld.so produce a global symbol table for every
single library and the executable all together? My reading of the
article is that it was done to preserve the semantics of the old static
linking (where of course all symbols were in the same namespace at link
time), and partly for efficiency reasons.
This causes a couple of problems, one being the problem with having
multiple major versions of the same library loaded into the address
space at once, and the other being that all libraries must manually
namespace symbols - for instance at one point Konqueror would crash on
any page that used Flash because there was a symbol conflict between the
flash plugin and GLUT, two entirely unrelated libs. Esp in the case of
closed source stuff like the flash plugin this causes big problems.
The second is, would it be possible to alter the linker so that symbols
did not conflict? Instead of loading the libraries and all the symbols
into the global symbol table/hash chain, the linker loads the
executable, looks at the libraries it needs, and loads the first one.
Then it links the symbols together, before dropping the symbol table and
moving onto the next lib and so on. This would mean you could include
multiple versions of the same lib in the same app.
I think perhaps that approach would cause issues with late binding? I'm
Another approach might be to namespace symbols, so each one is perhaps
prefixed by the soname. That way, you could also avoid problems like the
Please tell me if I'm suggesting something really dumb, I came here for
advice from the experts :) Oh, but things like "don't try building
distro neutral packages, it's impossible" don't help much, I get enough
of that on IRC.
Finally, while I'm here I might as well point out that the Wine team are
having to use all sorts of nasty hacks to get around the fact that the
linker runs C++ static initializers before WineLib gets a chance to
initialize. Would it be possible to perhaps provide a plugin mechanism
so some code can be run before static initialisers were executed, or
maybe even add support for PE directly to the linker?
Many thanks for your time -mike
Mike Hearn <firstname.lastname@example.org>