This is the mail archive of the binutils@sourceware.cygnus.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: R_PPC_LOCAL24PC c++ linking problems with current binutils


   Date: Tue, 20 Jul 1999 12:17:08 +1000
   From: Geoff Keating <geoffk@ozemail.com.au>

   The problem is that the following is happening:

   1. g++ is defining the symbol 
    '__default_alloc_template<true, 0>::_S_chunk_alloc(unsigned int, int &)'
      (in demangled form, which I'll just call `...' from now on :-)
      weak in a linkonce section.
   2. In libstdc++.so, the symbol is not defined weak.
   3. In the same linkonce section, there is 'bl ...@local'.  The @local
      is because it's a recursive call.
   4. ld finds the strong definition, in the shared object.
   5. The symbol is not therefore defined locally, and linking fails.

   I assume ld is correct in emitting the linkonce section even though
   it will actually be using the shared object symbol.  I may be wrong.

I believe the linker is acting correctly.  linkonce sections are
handled entirely based on the section name.  The linker arranges to
include a single copy of each linkonce section by name in the final
output.

The fact that in this case the linkonce section defines only a single
globally visible symbol, and that that symbol will never be called
because it is a weak symbol which was overridden by a shared library,
is irrelevant.

g++ may want some different semantics, and indeed we could change to
different semantics.  But I think the current semantics are quite
straightforward and easy to understand.

   Other fixes would be:
   (i) define the libstdc++ symbol weak, and/or
   (ii) don't use @local on weak symbols and/or 

As I noted in an earlier message, I believe that it is simply
incorrect to use @local on weak symbols.  Don't let the linkonce
section here mislead you.  Consider a case like

#pragma weak fn
int fn () { return 1; }
int foo () { return fn (); }

When you compile this code, gcc will presumably use @local in the call
to fn from foo.  Now put this code into a shared library.  Then
arrange to define fn as a strong definition in the main executable.
In this case, foo should actually call fn in the main executable,
which it of course can not do using @local.

   (iii) make @local relocs point to the symbol defined in this object
   whether or not there is a stronger definition elsewhere.

That will lead to incorrect results in the example I just gave.

   (ii) implies that it is not legal to have a weak nested procedure (at
   present the register used for the static chain conflicts with
   registers clobbered in the PLT), but I'm not sure this makes sense
   anyway.

According to the gcc documentation, nested procedures are not globally
visible.  That is, they are always file static.  Therefore they can
not be weak.

   (iii) might be hard.  It means we have to keep track of multiple
   symbol definitions in ld.  It is probably also the correct solution
   :-(.

As noted above, I do not believe this is correct.  I believe that if
an @local reloc refers to a symbol defined in another object, it is
correct to report an error.

So I now think the linker is behaving entirely correctly in this
example, and that this is actually a bug in gcc.

Ian

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