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