Sample code: #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-4.2.1 -Os -c) 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 Using a weak symbol appears to force gcc to use a GOT16 reloc. A CALL16 reloc is used otherwise. If either one or the other are used, the linker functions correctly, but if they are both used, the linker only functions correctly in the case of the CALL16 reloc. A bug was submitted to GCC bugzilla (#33169) and it was determined that generating two different relocs for the same symbol is not a bug. The linker should be able to handle it by using 0 for the LO16 offset. This problem will occur if pthreads are used directly in a C++ program that uses weak pthread linkage indirectly through libstdc++ (not very rare, I think). -- Summary: Multiple relocs for the same symbol are not handled correctly Product: binutils Version: 2.17 Status: NEW Severity: normal Priority: P2 Component: binutils AssignedTo: unassigned at sources dot redhat dot com ReportedBy: atgraham at gmail dot com CC: bug-binutils at gnu dot org GCC host triplet: i386-pc-linux-gnu GCC target triplet: mipsel-linux http://sourceware.org/bugzilla/show_bug.cgi?id=4959 ------- You are receiving this mail because: ------- You are on the CC list for the bug, or are watching someone who is. _______________________________________________ bug-binutils mailing list bug-binutils@gnu.org http://lists.gnu.org/mailman/listinfo/bug-binutils