This is the mail archive of the binutils@sources.redhat.com 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]

Re: KDE: C++ and shared libraries



Jakub,

Here is a simple suggestion regarding the linkonce issues described in your post
 http://gcc.gnu.org/ml/gcc/2001-09/msg00421.html
and in the thread initiated by Jason
 http://sources.redhat.com/ml/binutils/2001-07/msg00200.html.

I believe that there is a way to solve the problem that does not 
require the programmer to manipulate complicated compiler switches.

We all agree that the problem arises because there is no
simple way to specify what is the exported API of a shared object.

The correct solution would be to generate the shared objects 
using  the ld option "--retain-symbols-file" to specify a list of exported symbols.
This list of symbols could be generated by processing the
public header files, that is to say those header files that declare 
the exported API of the shared object.   I easily envision a gcc option 
such as "gcc --generate-exported-symbols-file  include/*.h". 

But this would not solve the problems caused by linkonce sections
containing template instantiations (same for out-of-line copies of inline functions).
Executables using this shared object often contain linkonce sections
with conflicting copies of these template instantiations.
Hence numerous prelinker conflicts that are useless
since both codes are the same.

The above mentionned thread envisions means to give linking
priority to the symbol contained in the shared object.
This reverses the usual linking priority and eliminates the conflict.
But this is a complicated semantic change and must be turned off 
in certain cases.  This leads to complicated compiler options that 
very few people will use properly...

An alternate solution would be to decide that each shared object 
always uses its own copies of the template instantiations and 
never exports them.   This obviously will hide those that are
not part of the exported API.   This will also hide those that are part
of the exported API, but this has no consequence since
these can be regenerated from the public header files.

There is some overhead in having duplicate copies of these instantiations.
This overhead is limited because there is only one copy per
shared object (and not one copy per object file).  
A simple way to manually control the overhead would be to 
export explicit template instantiations only.

There are two ways to implement this 
- The relevant linkonce section could bear a flag  (SHF_NO_EXPORT)
  specifying that the global symbols defined in this section should
  not be exported from shared objects.
- There could be a new symbol binding type  STB_GLOBAL_NO_EXPORT
  specifying that this symbol is global for linking purposes but should
  not be exported from shared objects.

The first solution possibly has less impact on binutils.
It would entail a change in binutils to understand the NO_EXPORT flag
and a change in g++ to set the flag on the appropriate sections.
Then everything would happen without the need for an additional
compiler option.

Comments ?

- Leon Bottou
  <leonb@research.att.com>


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