public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c++/33169]  New: Compiler generates two different relocs for the same symbol
@ 2007-08-23 22:45 atgraham at gmail dot com
  2007-08-24  0:40 ` [Bug c++/33169] " atgraham at gmail dot com
                   ` (10 more replies)
  0 siblings, 11 replies; 12+ messages in thread
From: atgraham at gmail dot com @ 2007-08-23 22:45 UTC (permalink / raw)
  To: gcc-bugs

The compiler generates two different relocs for the same function call, which
causes the linker to get confused.

----- Input -----
#include "pthread.h"
#include <map>
#include <ext/pool_allocator.h>
typedef __gnu_cxx::__pool_alloc<std::pair<int const, int> > myalloc;
int main() {
  std::map<int, int, std::less<int>, myalloc> y;
  pthread_mutex_lock(0);
}
-----------------
build with:
  mipsel-linux-g++ -Os -fno-inline -c foo.cc
(No command line flags are required; they don't appear to make a difference,
but the examples here will reflect those above.)

In this code chunk, pthread_mutex_lock is called from two places.  The first is
from inside the allocator, the second is directly in main.  From the allocator,
a R_MIPS_GOT16/R_MIPS_LO16 reloc is generated.  From main(), a R_MIPS_CALL16
reloc is generated.

0000001c <__gthread_mutex_lock(pthread_mutex_t*)>:
  1c:   3c1c0000        lui     gp,0x0
                        1c: R_MIPS_HI16 _gp_disp
  20:   279c0000        addiu   gp,gp,0
                        20: R_MIPS_LO16 _gp_disp
  24:   0399e021        addu    gp,gp,t9
  28:   27bdffe0        addiu   sp,sp,-32
  2c:   afbf001c        sw      ra,28(sp)
  30:   afb00018        sw      s0,24(sp)
  34:   afbc0010        sw      gp,16(sp)
  38:   8f990000        lw      t9,0(gp)
                        38: R_MIPS_GOT16        .text
  3c:   27390000        addiu   t9,t9,0
                        3c: R_MIPS_LO16 .text
  40:   0320f809        jalr    t9
  44:   00808021        move    s0,a0
  48:   10400008        beqz    v0,6c
<__gthread_mutex_lock(pthread_mutex_t*)+0x
50>
  4c:   8fbc0010        lw      gp,16(sp)
  50:   8f990000        lw      t9,0(gp)
                        50: R_MIPS_GOT16        pthread_mutex_lock
  54:   02002021        move    a0,s0
  58:   8fbf001c        lw      ra,28(sp)
  5c:   8fb00018        lw      s0,24(sp)
  60:   27390000        addiu   t9,t9,0
                        60: R_MIPS_LO16 pthread_mutex_lock
  64:   03200008        jr      t9
  68:   27bd0020        addiu   sp,sp,32
  6c:   8fbf001c        lw      ra,28(sp)
  70:   8fb00018        lw      s0,24(sp)
  74:   03e00008        jr      ra
  78:   27bd0020        addiu   sp,sp,32

000000dc <main>:
  dc:   3c1c0000        lui     gp,0x0
                        dc: R_MIPS_HI16 _gp_disp
  e0:   279c0000        addiu   gp,gp,0
                        e0: R_MIPS_LO16 _gp_disp
  e4:   0399e021        addu    gp,gp,t9
  e8:   27bdffc8        addiu   sp,sp,-56
  ec:   afbf0034        sw      ra,52(sp)
  f0:   afb00030        sw      s0,48(sp)
  f4:   afbc0010        sw      gp,16(sp)
  f8:   8f990000        lw      t9,0(gp)
                        f8: R_MIPS_CALL16       std::map<int, int,
std::less<int
>, __gnu_cxx::__pool_alloc<std::pair<int const, int> > >::map()
  fc:   27b00018        addiu   s0,sp,24
 100:   0320f809        jalr    t9
 104:   02002021        move    a0,s0
 108:   8fbc0010        lw      gp,16(sp)
 10c:   8f990000        lw      t9,0(gp)
                        10c: R_MIPS_CALL16      pthread_mutex_lock
 110:   0320f809        jalr    t9
 114:   00002021        move    a0,zero
 118:   8fbc0010        lw      gp,16(sp)
 11c:   8f990000        lw      t9,0(gp)
                        11c: R_MIPS_CALL16      std::map<int, int,
std::less<int
>, __gnu_cxx::__pool_alloc<std::pair<int const, int> > >::~map()
 120:   0320f809        jalr    t9
 124:   02002021        move    a0,s0
 128:   8fbc0010        lw      gp,16(sp)
 12c:   8fbf0034        lw      ra,52(sp)
 130:   8fb00030        lw      s0,48(sp)
 134:   00001021        move    v0,zero
 138:   03e00008        jr      ra
 13c:   27bd0038        addiu   sp,sp,56

When the linker sees the R_MIPS_CALL16, it decides that a PLT entry should be
generated for the symbol, and thusly changes its object-modification behavior
for *all* invocations of the function.  The R_MIPS_CALL16 relocs are then
linked correctly, but the R_MIPS_GOT16 are linked incorrectly.

This is just as likely a bug in the linker as it is in the compiler, but gcc
4.0.0 (the only other version I have tested) doesn't have this problem.  It is
more consistent and generates R_MIPS_CALL16 in both cases.  If this is not a
bug in the compiler, I'll report to binutils.


-- 
           Summary: Compiler generates two different relocs for the same
                    symbol
           Product: gcc
           Version: 4.2.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: atgraham at gmail dot com
  GCC host triplet: i686-pc-linux-gnu
GCC target triplet: mipsel-linux


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33169


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

* [Bug c++/33169] Compiler generates two different relocs for the same symbol
  2007-08-23 22:45 [Bug c++/33169] New: Compiler generates two different relocs for the same symbol atgraham at gmail dot com
@ 2007-08-24  0:40 ` atgraham at gmail dot com
  2007-08-24  9:23 ` [Bug target/33169] " pinskia at gcc dot gnu dot org
                   ` (9 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: atgraham at gmail dot com @ 2007-08-24  0:40 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #1 from atgraham at gmail dot com  2007-08-24 00:40 -------
This problem is due to the fact that GTHREAD_USE_WEAK is incorrectly defined
for this architecture.


-- 

atgraham at gmail dot com changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
          Component|target                      |c++


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33169


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

* [Bug target/33169] Compiler generates two different relocs for the same symbol
  2007-08-23 22:45 [Bug c++/33169] New: Compiler generates two different relocs for the same symbol atgraham at gmail dot com
  2007-08-24  0:40 ` [Bug c++/33169] " atgraham at gmail dot com
@ 2007-08-24  9:23 ` pinskia at gcc dot gnu dot org
  2007-08-24 16:01 ` atgraham at gmail dot com
                   ` (8 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: pinskia at gcc dot gnu dot org @ 2007-08-24  9:23 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #2 from pinskia at gcc dot gnu dot org  2007-08-24 09:23 -------
MIPS-linux uses elf which has weak support.

So I don't see why you think GTHREAD_USE_WEAK should not be defined.


-- 

pinskia at gcc dot gnu dot org changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
          Component|c++                         |target


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33169


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

* [Bug target/33169] Compiler generates two different relocs for the same symbol
  2007-08-23 22:45 [Bug c++/33169] New: Compiler generates two different relocs for the same symbol atgraham at gmail dot com
  2007-08-24  0:40 ` [Bug c++/33169] " atgraham at gmail dot com
  2007-08-24  9:23 ` [Bug target/33169] " pinskia at gcc dot gnu dot org
@ 2007-08-24 16:01 ` atgraham at gmail dot com
  2007-08-24 16:07 ` pinskia at gcc dot gnu dot org
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: atgraham at gmail dot com @ 2007-08-24 16:01 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #3 from atgraham at gmail dot com  2007-08-24 16:00 -------
Here is a smaller bit of code for reproducing this problem.  This doesn't
depend on any C++.

#include "pthread.h"
static __typeof(pthread_mutex_lock) __gthrw_pthread_mutex_lock __attribute__
((__weakref__("pthread_mutex_lock")));
int main() {
  __gthrw_pthread_mutex_lock(0);
  pthread_mutex_lock(0);
}

This (mipsel-linux-gcc -Os) generates the following object code:

00000000 <main>:
   0:   3c1c0000        lui     gp,0x0
                        0: R_MIPS_HI16  _gp_disp
   4:   279c0000        addiu   gp,gp,0
                        4: R_MIPS_LO16  _gp_disp
   8:   0399e021        addu    gp,gp,t9
   c:   27bdffe0        addiu   sp,sp,-32
  10:   afbf0018        sw      ra,24(sp)
  14:   afbc0010        sw      gp,16(sp)
  18:   8f990000        lw      t9,0(gp)
                        18: R_MIPS_GOT16        pthread_mutex_lock
  1c:   27390000        addiu   t9,t9,0
                        1c: R_MIPS_LO16 pthread_mutex_lock
  20:   0320f809        jalr    t9
  24:   00002021        move    a0,zero
  28:   8fbc0010        lw      gp,16(sp)
  2c:   8f990000        lw      t9,0(gp)
                        2c: R_MIPS_CALL16       pthread_mutex_lock
  30:   0320f809        jalr    t9
  34:   00002021        move    a0,zero
  38:   8fbc0010        lw      gp,16(sp)
  3c:   8fbf0018        lw      ra,24(sp)
  40:   00001021        move    v0,zero
  44:   03e00008        jr      ra
  48:   27bd0020        addiu   sp,sp,32
  4c:   00000000        nop

Which gets linked (using binutils 2.17) to this:

00400750 <main>:
  400750:       3c1c0005        lui     gp,0x5
  400754:       279c8290        addiu   gp,gp,-32112
  400758:       0399e021        addu    gp,gp,t9
  40075c:       27bdffe0        addiu   sp,sp,-32
  400760:       afbf0018        sw      ra,24(sp)
  400764:       afbc0010        sw      gp,16(sp)
  400768:       8f998058        lw      t9,-32680(gp)
  40076c:       27393c60        addiu   t9,t9,15456 <-- adds offset to GOT
  400770:       0320f809        jalr    t9
  400774:       00002021        move    a0,zero
  400778:       8fbc0010        lw      gp,16(sp)
  40077c:       8f998058        lw      t9,-32680(gp)
  400780:       0320f809        jalr    t9          <-- no additional offset
  400784:       00002021        move    a0,zero
  400788:       8fbc0010        lw      gp,16(sp)
  40078c:       8fbf0018        lw      ra,24(sp)
  400790:       00001021        move    v0,zero
  400794:       03e00008        jr      ra
  400798:       27bd0020        addiu   sp,sp,32
  40079c:       00000000        nop

The "fix" that I mentioned previously, disabling weak support, is only a
workaround for my particular instance of the problem.  Using a weak symbol
appears to force the compiler to generate a GOT16 reloc.  In any case, it seems
that the linker should be able to "work around" the problem by simply setting
the LO16 offset to 0.  So I don't know if this is really a bug in the compiler
or not.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33169


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

* [Bug target/33169] Compiler generates two different relocs for the same symbol
  2007-08-23 22:45 [Bug c++/33169] New: Compiler generates two different relocs for the same symbol atgraham at gmail dot com
                   ` (2 preceding siblings ...)
  2007-08-24 16:01 ` atgraham at gmail dot com
@ 2007-08-24 16:07 ` pinskia at gcc dot gnu dot org
  2007-08-24 16:12 ` atgraham at gmail dot com
                   ` (6 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: pinskia at gcc dot gnu dot org @ 2007-08-24 16:07 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #4 from pinskia at gcc dot gnu dot org  2007-08-24 16:06 -------
So what is happening is that you are using the function directly and also via a
weakref.  Can you give the output of GCC (that is the -S file)?  This might be
really a binutils bug.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33169


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

* [Bug target/33169] Compiler generates two different relocs for the same symbol
  2007-08-23 22:45 [Bug c++/33169] New: Compiler generates two different relocs for the same symbol atgraham at gmail dot com
                   ` (3 preceding siblings ...)
  2007-08-24 16:07 ` pinskia at gcc dot gnu dot org
@ 2007-08-24 16:12 ` atgraham at gmail dot com
  2007-08-24 16:17 ` pinskia at gcc dot gnu dot org
                   ` (5 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: atgraham at gmail dot com @ 2007-08-24 16:12 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #5 from atgraham at gmail dot com  2007-08-24 16:12 -------
Created an attachment (id=14104)
 --> (http://gcc.gnu.org/bugzilla/attachment.cgi?id=14104&action=view)
Output of "mipsel-linux-gcc -Os -s tworelocs.c"

gcc output attached.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33169


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

* [Bug target/33169] Compiler generates two different relocs for the same symbol
  2007-08-23 22:45 [Bug c++/33169] New: Compiler generates two different relocs for the same symbol atgraham at gmail dot com
                   ` (4 preceding siblings ...)
  2007-08-24 16:12 ` atgraham at gmail dot com
@ 2007-08-24 16:17 ` pinskia at gcc dot gnu dot org
  2007-08-24 16:34 ` atgraham at gmail dot com
                   ` (4 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: pinskia at gcc dot gnu dot org @ 2007-08-24 16:17 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #6 from pinskia at gcc dot gnu dot org  2007-08-24 16:16 -------
So one goes the GOT (the weakref) while the other does not (straight call).

I am guess this is really a bug in binutils if a bug at all.  Though two
different relocs for the same symbol should be ok.

>and thusly changes its object-modification behavior for *all* invocations of the function.

This is a bug in the linker.  You should report this to binutils
(http://sourceware.org/bugzilla/ ).


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33169


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

* [Bug target/33169] Compiler generates two different relocs for the same symbol
  2007-08-23 22:45 [Bug c++/33169] New: Compiler generates two different relocs for the same symbol atgraham at gmail dot com
                   ` (5 preceding siblings ...)
  2007-08-24 16:17 ` pinskia at gcc dot gnu dot org
@ 2007-08-24 16:34 ` atgraham at gmail dot com
  2007-09-06 18:25 ` rsandifo at gcc dot gnu dot org
                   ` (3 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: atgraham at gmail dot com @ 2007-08-24 16:34 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #7 from atgraham at gmail dot com  2007-08-24 16:34 -------
binutils bug created:

http://sourceware.org/bugzilla/show_bug.cgi?id=4959


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33169


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

* [Bug target/33169] Compiler generates two different relocs for the same symbol
  2007-08-23 22:45 [Bug c++/33169] New: Compiler generates two different relocs for the same symbol atgraham at gmail dot com
                   ` (6 preceding siblings ...)
  2007-08-24 16:34 ` atgraham at gmail dot com
@ 2007-09-06 18:25 ` rsandifo at gcc dot gnu dot org
  2007-10-03  5:31 ` atgraham at gmail dot com
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: rsandifo at gcc dot gnu dot org @ 2007-09-06 18:25 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #8 from rsandifo at gcc dot gnu dot org  2007-09-06 18:25 -------
Created an attachment (id=14164)
 --> (http://gcc.gnu.org/bugzilla/attachment.cgi?id=14164&action=view)
The patch that I think fixed this on mainline

This is a compiler bug rather than a linker bug.
The compiler must only apply %lo to local GOT entries,
not global ones.

I'm pretty certain this is the bug I fixed on mainline with:

    http://gcc.gnu.org/ml/gcc-patches/2006-10/msg01451.html

(The problem being that weakrefs are an odd case: they're weak,
but !TREE_PUBLIC.)

The patch applies cleanly to 4.2, and I've attached it here for
convenience.  Aaron, could you confirm it fixes the bug you're seeing?
(Also, please could you close the binutils bug?  The assembly code is,
as you suspected, invalid.)


-- 

rsandifo at gcc dot gnu dot org changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
         AssignedTo|unassigned at gcc dot gnu   |rsandifo at gcc dot gnu dot
                   |dot org                     |org
             Status|UNCONFIRMED                 |ASSIGNED


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33169


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

* [Bug target/33169] Compiler generates two different relocs for the same symbol
  2007-08-23 22:45 [Bug c++/33169] New: Compiler generates two different relocs for the same symbol atgraham at gmail dot com
                   ` (7 preceding siblings ...)
  2007-09-06 18:25 ` rsandifo at gcc dot gnu dot org
@ 2007-10-03  5:31 ` atgraham at gmail dot com
  2007-10-22 20:11 ` rsandifo at gcc dot gnu dot org
  2007-10-22 20:15 ` rsandifo at gcc dot gnu dot org
  10 siblings, 0 replies; 12+ messages in thread
From: atgraham at gmail dot com @ 2007-10-03  5:31 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #9 from atgraham at gmail dot com  2007-10-03 05:31 -------
The patch from Richard appears to fix the problem.  With his patch applied, the
compiler output is correct.


-- 

atgraham at gmail dot com changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|ASSIGNED                    |RESOLVED
         Resolution|                            |FIXED


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33169


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

* [Bug target/33169] Compiler generates two different relocs for the same symbol
  2007-08-23 22:45 [Bug c++/33169] New: Compiler generates two different relocs for the same symbol atgraham at gmail dot com
                   ` (8 preceding siblings ...)
  2007-10-03  5:31 ` atgraham at gmail dot com
@ 2007-10-22 20:11 ` rsandifo at gcc dot gnu dot org
  2007-10-22 20:15 ` rsandifo at gcc dot gnu dot org
  10 siblings, 0 replies; 12+ messages in thread
From: rsandifo at gcc dot gnu dot org @ 2007-10-22 20:11 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #10 from rsandifo at gcc dot gnu dot org  2007-10-22 20:11 -------
Subject: Bug 33169

Author: rsandifo
Date: Mon Oct 22 20:11:19 2007
New Revision: 129559

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=129559
Log:
gcc/
        PR target/33169
        Backport from mainline:

        2006-10-29  Richard Sandiford  <richard@codesourcery.com>

        * config/mips/mips.c (mips_classify_symbol): Test DECL_WEAK as well
        as TREE_PUBLIC when deciding whether to return SYMBOL_GOT_GLOBAL.


Modified:
    branches/gcc-4_2-branch/gcc/ChangeLog
    branches/gcc-4_2-branch/gcc/config/mips/mips.c


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33169


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

* [Bug target/33169] Compiler generates two different relocs for the same symbol
  2007-08-23 22:45 [Bug c++/33169] New: Compiler generates two different relocs for the same symbol atgraham at gmail dot com
                   ` (9 preceding siblings ...)
  2007-10-22 20:11 ` rsandifo at gcc dot gnu dot org
@ 2007-10-22 20:15 ` rsandifo at gcc dot gnu dot org
  10 siblings, 0 replies; 12+ messages in thread
From: rsandifo at gcc dot gnu dot org @ 2007-10-22 20:15 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #11 from rsandifo at gcc dot gnu dot org  2007-10-22 20:14 -------
Aaron,

Thanks for the testing.  I've now applied the patch to the 4.2 branch.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33169


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

end of thread, other threads:[~2007-10-22 20:15 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-08-23 22:45 [Bug c++/33169] New: Compiler generates two different relocs for the same symbol atgraham at gmail dot com
2007-08-24  0:40 ` [Bug c++/33169] " atgraham at gmail dot com
2007-08-24  9:23 ` [Bug target/33169] " pinskia at gcc dot gnu dot org
2007-08-24 16:01 ` atgraham at gmail dot com
2007-08-24 16:07 ` pinskia at gcc dot gnu dot org
2007-08-24 16:12 ` atgraham at gmail dot com
2007-08-24 16:17 ` pinskia at gcc dot gnu dot org
2007-08-24 16:34 ` atgraham at gmail dot com
2007-09-06 18:25 ` rsandifo at gcc dot gnu dot org
2007-10-03  5:31 ` atgraham at gmail dot com
2007-10-22 20:11 ` rsandifo at gcc dot gnu dot org
2007-10-22 20:15 ` rsandifo at gcc dot gnu dot org

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