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