This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

question on version script for a C++ shared library


Hi all, 

we have a C++ application that runs on Linux/ppc (an embedded device, if you
like) and uses plugins stored in shared libraries, also written in C++. We've
had some problems recently with name clashes between plugins (due to the way ELF
symbol resolution works), especially when linking with certain static libraries
(for which there are no dynamic counterparts yet). So I decided to have a go at
using a version script for ld (we have version 2.15 in the toolchain) in which
to limit the symbols exported. Trouble is, there are some dynamic_casts going on
in the main executable in order to determine if the plugin is of the right type
and if it has certain capabilities so, as far as I understood from
http://gcc.gnu.org/faq.html#dso, I had to also export some typeinfo stuff. 

What I have now works, I'm just trying to understand what is actually needed,
and to verify that my assumptions and approach are correct. I'd also be
interested if other approaches would be better (i.e. Ulrich Drepper's DSO howto
suggests using hidden visibility and explicitly marking functions to be exported
in the code, but we don't use gcc > 4.0 yet in our toolchain, we only have 3.3). 

I have a class, say MyPlugin, which inherits from DPlugin, which inherits from
BasePlugin. At a certain point, the plugin loader code reads the plugin as
BasePlugin and the dynamic_casts it to DPlugin - I guess the typeinfo for
DPlugin has to be exported from the shared library. Also, there is a class which
we'll call MyLayer which inherits from some classes named something like
BaseLayer::<Capability>. Each of them has a certain function you'd need to
override in order to support that capability. The loader code also dynamic_casts
the pointer to BasePlugin to each of the capability classes, so I've also
exported the typeinfo for those. For function calls, I guess Currently my export
map is something like: 

{
    global:
        extern "C++" {
           this_plugin*;
           *BaseLayer::*;
           *DPlugin;
           *BasePlugin;
           *MyPlugin::*;
           *MyLayer::*;
        };
    local:
        *;
};

this_plugin is a symbol defined in each shared library, it has to be exported.
I've put * in front of the symbols in order to catch both typeinfo and vtable
stuff. 

So, is this correct? Can this be trimmed down? Any other ways to achieve this? 


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]