public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* R_PPC_LOCAL24PC c++ linking problems with current binutils
@ 1999-07-19 15:21 Franz Sirl
  1999-07-19 16:49 ` Ian Lance Taylor
  1999-07-19 19:30 ` Geoff Keating
  0 siblings, 2 replies; 9+ messages in thread
From: Franz Sirl @ 1999-07-19 15:21 UTC (permalink / raw)
  To: binutils; +Cc: drow, geoffk

Hi,

linking this little program currently fails on Linux/PPC, glibc-2.1:

mmaptest.cc:
#include <string>
class FileFd
{
public:
   int iFd;
   unsigned long Flags;
   string FileName;


   FileFd(int Fd,bool) : iFd(Fd), Flags(0) {};
   virtual ~FileFd();
};


Compiling with c++ -o mmaptest.so -fPIC -shared mmaptest.cc gives:
mmaptest.o: In function `__default_alloc_template<true, 0>::_S_chunk_alloc(unsigned int, int &)':
mmaptest.o(.__default_alloc_template<true, 0>::gnu.linkonce.t._S_chunk_alloc(unsigned int, int &)+0x234): undefined reference to `__default_alloc_template<true, 0>::_S_chunk_alloc(unsigned int, int &)'
mmaptest.o(.__default_alloc_template<true, 0>::gnu.linkonce.t._S_chunk_alloc(unsigned int, int &)+0x2a8): undefined reference to `__default_alloc_template<true, 0>::_S_chunk_alloc(unsigned int, int &)'
collect2: ld returned 1 exit status

The relevant code in elf32-ppc.c looks like:

        /* Relocations that need no special processing.  */
        case (int)R_PPC_LOCAL24PC:
          /* It makes no sense to point a local relocation
             at a symbol not in this object.  */
          if (h != NULL
              && (h->root.type == bfd_link_hash_defined
                  || h->root.type == bfd_link_hash_defweak)
              && sec->output_section == NULL)
            {
              if (! (*info->callbacks->undefined_symbol) (info,
                                                          h->root.root.string,
                                                          input_bfd,
                                                          input_section,
                                                          rel->r_offset))
                return false;
              continue;
            }
          break;

We enter here with h->root.type == bfd_link_hash_defined and
sec->output_section == NULL for the symbols in question. This didn't happen
older binutils (2.9.1) and it maybe related to the following patch:

Tue Jun  2 13:51:00 1998  Geoff Keating  <geoffk@ozemail.com.au>

        * elf32-ppc.c (ppc_elf_relocate_section): The target of an
        R_PPC_LOCAL24PC relocation should be local; if not, print an error
        message instead of crashing.

I'm lost here for the moment. If I can test anything else, please let me know.

Franz.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: R_PPC_LOCAL24PC c++ linking problems with current binutils
  1999-07-19 15:21 R_PPC_LOCAL24PC c++ linking problems with current binutils Franz Sirl
@ 1999-07-19 16:49 ` Ian Lance Taylor
  1999-07-19 17:49   ` Daniel Jacobowitz
  1999-07-19 20:07   ` Daniel Jacobowitz
  1999-07-19 19:30 ` Geoff Keating
  1 sibling, 2 replies; 9+ messages in thread
From: Ian Lance Taylor @ 1999-07-19 16:49 UTC (permalink / raw)
  To: Franz.Sirl-kernel; +Cc: binutils, drow, geoffk

   From: Franz Sirl <Franz.Sirl-kernel@lauterbach.com>
   Date: Tue, 20 Jul 1999 00:07:53 +0200

   Compiling with c++ -o mmaptest.so -fPIC -shared mmaptest.cc gives:
   mmaptest.o: In function `__default_alloc_template<true, 0>::_S_chunk_alloc(unsigned int, int &)':
   mmaptest.o(.__default_alloc_template<true, 0>::gnu.linkonce.t._S_chunk_alloc(unsigned int, int &)+0x234): undefined reference to `__default_alloc_template<true, 0>::_S_chunk_alloc(unsigned int, int &)'
   mmaptest.o(.__default_alloc_template<true, 0>::gnu.linkonce.t._S_chunk_alloc(unsigned int, int &)+0x2a8): undefined reference to `__default_alloc_template<true, 0>::_S_chunk_alloc(unsigned int, int &)'
   collect2: ld returned 1 exit status

	     /* It makes no sense to point a local relocation
		at a symbol not in this object.  */
	     if (h != NULL
		 && (h->root.type == bfd_link_hash_defined
		     || h->root.type == bfd_link_hash_defweak)
		 && sec->output_section == NULL)

I think the last is the wrong test.  sec->output_section will be NULL
for a linkonce section which is being discarded.  More appropriate
would be a test whether ELF_LINK_HASH_DEF_REGULAR is set in
h->elf_link_hash_flags.

Ian

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: R_PPC_LOCAL24PC c++ linking problems with current binutils
  1999-07-19 16:49 ` Ian Lance Taylor
@ 1999-07-19 17:49   ` Daniel Jacobowitz
  1999-07-19 19:56     ` Ian Lance Taylor
  1999-07-19 20:07   ` Daniel Jacobowitz
  1 sibling, 1 reply; 9+ messages in thread
From: Daniel Jacobowitz @ 1999-07-19 17:49 UTC (permalink / raw)
  To: Ian Lance Taylor; +Cc: Franz.Sirl-kernel, binutils, geoffk

On Mon, Jul 19, 1999 at 07:49:24PM -0400, Ian Lance Taylor wrote:
>    From: Franz Sirl <Franz.Sirl-kernel@lauterbach.com>
>    Date: Tue, 20 Jul 1999 00:07:53 +0200
> 
>    Compiling with c++ -o mmaptest.so -fPIC -shared mmaptest.cc gives:
>    mmaptest.o: In function `__default_alloc_template<true, 0>::_S_chunk_alloc(unsigned int, int &)':
>    mmaptest.o(.__default_alloc_template<true, 0>::gnu.linkonce.t._S_chunk_alloc(unsigned int, int &)+0x234): undefined reference to `__default_alloc_template<true, 0>::_S_chunk_alloc(unsigned int, int &)'
>    mmaptest.o(.__default_alloc_template<true, 0>::gnu.linkonce.t._S_chunk_alloc(unsigned int, int &)+0x2a8): undefined reference to `__default_alloc_template<true, 0>::_S_chunk_alloc(unsigned int, int &)'
>    collect2: ld returned 1 exit status
> 
> 	     /* It makes no sense to point a local relocation
> 		at a symbol not in this object.  */
> 	     if (h != NULL
> 		 && (h->root.type == bfd_link_hash_defined
> 		     || h->root.type == bfd_link_hash_defweak)
> 		 && sec->output_section == NULL)
> 
> I think the last is the wrong test.  sec->output_section will be NULL
> for a linkonce section which is being discarded.  More appropriate
> would be a test whether ELF_LINK_HASH_DEF_REGULAR is set in
> h->elf_link_hash_flags.


I don't claim to understand this section, but if it truly makes no
sense to point a local relocation at a symbol not in _this object_,
then perhaps it is not safe to generate 'bl symbol@local' when symbol
is in a linkonce section?


Dan

/--------------------------------\  /--------------------------------\
|       Daniel Jacobowitz        |__|        SCS Class of 2002       |
|   Debian GNU/Linux Developer    __    Carnegie Mellon University   |
|         dan@debian.org         |  |       dmj+@andrew.cmu.edu      |
\--------------------------------/  \--------------------------------/

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: R_PPC_LOCAL24PC c++ linking problems with current binutils
  1999-07-19 15:21 R_PPC_LOCAL24PC c++ linking problems with current binutils Franz Sirl
  1999-07-19 16:49 ` Ian Lance Taylor
@ 1999-07-19 19:30 ` Geoff Keating
  1999-07-19 20:05   ` Daniel Jacobowitz
  1999-07-20  9:43   ` Ian Lance Taylor
  1 sibling, 2 replies; 9+ messages in thread
From: Geoff Keating @ 1999-07-19 19:30 UTC (permalink / raw)
  To: Franz.Sirl-kernel; +Cc: binutils, drow

> From: Franz Sirl <Franz.Sirl-kernel@lauterbach.com>
> Date: Tue, 20 Jul 1999 00:07:53 +0200
> Cc: drow@false.org, geoffk@ozemail.com.au
> 
> Hi,
> 
> linking this little program currently fails on Linux/PPC, glibc-2.1:
> 
> mmaptest.cc:
> #include <string>
> class FileFd
> {
> public:
>    int iFd;
>    unsigned long Flags;
>    string FileName;
> 
> 
>    FileFd(int Fd,bool) : iFd(Fd), Flags(0) {};
>    virtual ~FileFd();
> };
> 
> 
> Compiling with c++ -o mmaptest.so -fPIC -shared mmaptest.cc gives:
> mmaptest.o: In function `__default_alloc_template<true, 0>::_S_chunk_alloc(unsigned int, int &)':
> mmaptest.o(.__default_alloc_template<true, 0>::gnu.linkonce.t._S_chunk_alloc(unsigned int, int &)+0x234): undefined reference to `__default_alloc_template<true, 0>::_S_chunk_alloc(unsigned int, int &)'
> mmaptest.o(.__default_alloc_template<true, 0>::gnu.linkonce.t._S_chunk_alloc(unsigned int, int &)+0x2a8): undefined reference to `__default_alloc_template<true, 0>::_S_chunk_alloc(unsigned int, int &)'
> collect2: ld returned 1 exit status

OK, I see it.

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.
Certainly it doesn't seem to make much sense to do this.

Other fixes would be:
(i) define the libstdc++ symbol weak, and/or
(ii) don't use @local on weak symbols and/or 
(iii) make @local relocs point to the symbol defined in this object
whether or not there is a stronger definition elsewhere.

(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.

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

Note that it is not valid to just ignore the @local, because calling
through the PLT is allowed to trash certain registers and @local is
not.

-- 
Geoffrey Keating <geoffk@cygnus.com> <geoffk@ozemail.com.au>

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: R_PPC_LOCAL24PC c++ linking problems with current binutils
  1999-07-19 17:49   ` Daniel Jacobowitz
@ 1999-07-19 19:56     ` Ian Lance Taylor
  0 siblings, 0 replies; 9+ messages in thread
From: Ian Lance Taylor @ 1999-07-19 19:56 UTC (permalink / raw)
  To: drow; +Cc: Franz.Sirl-kernel, binutils, geoffk

   Date: Mon, 19 Jul 1999 20:51:35 -0400
   From: Daniel Jacobowitz <drow@false.org>

   I don't claim to understand this section, but if it truly makes no
   sense to point a local relocation at a symbol not in _this object_,
   then perhaps it is not safe to generate 'bl symbol@local' when symbol
   is in a linkonce section?

I think it's OK, although I'm not completely certain.

Note that ``this object'' in this case means ``this executable'' or
``this shared library.''

My reading of the egcs code is that gcc will use @local if the symbol
is static, or if it has already emitted code for the function in
question.  It's unlikely that gcc will generate a linkonce section for
a static function, so most likely this is the case in which it has
already emitted code for the function.  In that case, the only time
the linkonce section will not be used is when there is another
linkonce section of the same name in the ``same object,'' which
implies that it provides the same function, and that @local is OK.

I do wonder if there is a bug in gcc when it comes to calling a weak
function.  It looks as though gcc will generate @local when calling a
weak function, but that is unsafe.  I expect it would break cases in
which non-PIC code is put into a shared library, an operation which is
odd but legal.

Ian

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: R_PPC_LOCAL24PC c++ linking problems with current binutils
  1999-07-19 19:30 ` Geoff Keating
@ 1999-07-19 20:05   ` Daniel Jacobowitz
  1999-07-20  9:43   ` Ian Lance Taylor
  1 sibling, 0 replies; 9+ messages in thread
From: Daniel Jacobowitz @ 1999-07-19 20:05 UTC (permalink / raw)
  To: Geoff Keating; +Cc: Franz.Sirl-kernel, binutils

On Tue, Jul 20, 1999 at 12:17:08PM +1000, Geoff Keating wrote:
> OK, I see it.
> 
> 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.
> Certainly it doesn't seem to make much sense to do this.
> 
> Other fixes would be:
> (i) define the libstdc++ symbol weak, and/or
> (ii) don't use @local on weak symbols and/or 
> (iii) make @local relocs point to the symbol defined in this object
> whether or not there is a stronger definition elsewhere.

As I prepare to expose my underlying ignorance of how binutils works...

It seems to me that we know before we try to relocate anything inside
of the linkonce section whether or not we will be using this
section - either we do, or we should fairly easily be able to
determine.

If this is the case, then is it possible to simply not perform the
relocation in this case?

Dan

/--------------------------------\  /--------------------------------\
|       Daniel Jacobowitz        |__|        SCS Class of 2002       |
|   Debian GNU/Linux Developer    __    Carnegie Mellon University   |
|         dan@debian.org         |  |       dmj+@andrew.cmu.edu      |
\--------------------------------/  \--------------------------------/

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: R_PPC_LOCAL24PC c++ linking problems with current binutils
  1999-07-19 16:49 ` Ian Lance Taylor
  1999-07-19 17:49   ` Daniel Jacobowitz
@ 1999-07-19 20:07   ` Daniel Jacobowitz
  1999-07-20  9:33     ` Ian Lance Taylor
  1 sibling, 1 reply; 9+ messages in thread
From: Daniel Jacobowitz @ 1999-07-19 20:07 UTC (permalink / raw)
  To: Ian Lance Taylor; +Cc: Franz.Sirl-kernel, binutils, geoffk

On Mon, Jul 19, 1999 at 07:49:24PM -0400, Ian Lance Taylor wrote:
>    From: Franz Sirl <Franz.Sirl-kernel@lauterbach.com>
>    Date: Tue, 20 Jul 1999 00:07:53 +0200
> 
>    Compiling with c++ -o mmaptest.so -fPIC -shared mmaptest.cc gives:
>    mmaptest.o: In function `__default_alloc_template<true, 0>::_S_chunk_alloc(unsigned int, int &)':
>    mmaptest.o(.__default_alloc_template<true, 0>::gnu.linkonce.t._S_chunk_alloc(unsigned int, int &)+0x234): undefined reference to `__default_alloc_template<true, 0>::_S_chunk_alloc(unsigned int, int &)'
>    mmaptest.o(.__default_alloc_template<true, 0>::gnu.linkonce.t._S_chunk_alloc(unsigned int, int &)+0x2a8): undefined reference to `__default_alloc_template<true, 0>::_S_chunk_alloc(unsigned int, int &)'
>    collect2: ld returned 1 exit status
> 
> 	     /* It makes no sense to point a local relocation
> 		at a symbol not in this object.  */
> 	     if (h != NULL
> 		 && (h->root.type == bfd_link_hash_defined
> 		     || h->root.type == bfd_link_hash_defweak)
> 		 && sec->output_section == NULL)
> 
> I think the last is the wrong test.  sec->output_section will be NULL
> for a linkonce section which is being discarded.  More appropriate
> would be a test whether ELF_LINK_HASH_DEF_REGULAR is set in
> h->elf_link_hash_flags.

A brief experiment showed that sec->output_section == NULL for the
symbols in question, and (h->elf_link_hash_flags &
ELF_LINK_HASH_DEF_REGULAR) == 0.  So that doesn't quite seem to be the
problem.

Dan

/--------------------------------\  /--------------------------------\
|       Daniel Jacobowitz        |__|        SCS Class of 2002       |
|   Debian GNU/Linux Developer    __    Carnegie Mellon University   |
|         dan@debian.org         |  |       dmj+@andrew.cmu.edu      |
\--------------------------------/  \--------------------------------/

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: R_PPC_LOCAL24PC c++ linking problems with current binutils
  1999-07-19 20:07   ` Daniel Jacobowitz
@ 1999-07-20  9:33     ` Ian Lance Taylor
  0 siblings, 0 replies; 9+ messages in thread
From: Ian Lance Taylor @ 1999-07-20  9:33 UTC (permalink / raw)
  To: drow; +Cc: Franz.Sirl-kernel, binutils, geoffk

   Date: Mon, 19 Jul 1999 23:09:13 -0400
   From: Daniel Jacobowitz <drow@false.org>

   A brief experiment showed that sec->output_section == NULL for the
   symbols in question, and (h->elf_link_hash_flags &
   ELF_LINK_HASH_DEF_REGULAR) == 0.  So that doesn't quite seem to be the
   problem.

Yes, now I understand that it really is trying to call a symbol in
another object, and the test is correct to report failure.

Ian

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: R_PPC_LOCAL24PC c++ linking problems with current binutils
  1999-07-19 19:30 ` Geoff Keating
  1999-07-19 20:05   ` Daniel Jacobowitz
@ 1999-07-20  9:43   ` Ian Lance Taylor
  1 sibling, 0 replies; 9+ messages in thread
From: Ian Lance Taylor @ 1999-07-20  9:43 UTC (permalink / raw)
  To: geoffk; +Cc: Franz.Sirl-kernel, binutils, drow

   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

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~1999-07-20  9:43 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1999-07-19 15:21 R_PPC_LOCAL24PC c++ linking problems with current binutils Franz Sirl
1999-07-19 16:49 ` Ian Lance Taylor
1999-07-19 17:49   ` Daniel Jacobowitz
1999-07-19 19:56     ` Ian Lance Taylor
1999-07-19 20:07   ` Daniel Jacobowitz
1999-07-20  9:33     ` Ian Lance Taylor
1999-07-19 19:30 ` Geoff Keating
1999-07-19 20:05   ` Daniel Jacobowitz
1999-07-20  9:43   ` Ian Lance Taylor

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).