Mips ABI specifies to let the space for 4 arguments in stack when calling a function. This is not respected when accessing tls variable with a dynamic model: gcc implicitely calls __get_tls_addr without making rooms for the arguments. The top of the stack is then likely to be erase. Here is an example:
- test.c: extern void* __get_tls_addr(void*); extern __thread int a; void func(void) { a++; } Compiled and linked with: mipsel-unknown-elf-gcc -fpic -mshared -nostdinc -nostdlib -fno-builtin -mips2 -EL -mabicalls -G0 -c -o test.o test.c mipsel-unknown-elf-ld -shared test.o -o test.so Result in assembly: 5ffe0390 <func>: 5ffe0390: 3c1c0001 lui gp,0x1 5ffe0394: 279c9090 addiu gp,gp,-28528 5ffe0398: 0399e021 addu gp,gp,t9 5ffe039c: 27bdffe8 addiu sp,sp,-24 5ffe03a0: afbf0014 sw ra,20(sp) 5ffe03a4: afbe0010 sw s8,16(sp) 5ffe03a8: afb0000c sw s0,12(sp) 5ffe03ac: 03a0f021 move s8,sp 5ffe03b0: afbc0000 sw gp,0(sp) 5ffe03b4: 8f99802c lw t9,-32724(gp) 5ffe03b8: 27848030 addiu a0,gp,-32720 5ffe03bc: 0320f809 jalr t9 5ffe03c0: 00000000 nop 5ffe03c4: 8fdc0000 lw gp,0(s8) 5ffe03c8: 8c420000 lw v0,0(v0) ... We can see than $gp is saved directly at the top of the stack 0($sp), and is likely to be erase in the callee function. A temporarily workaround is to insert a real function call in the same function which uses a tls variable. Example: extern void* __get_tls_addr(void*); extern __thread int a; static inline void fake(void){} void func(void) { fake(); a++; } This result is then: 5ffe0390 <func>: 5ffe0390: 3c1c0001 lui gp,0x1 5ffe0394: 279c90c0 addiu gp,gp,-28480 5ffe0398: 0399e021 addu gp,gp,t9 5ffe039c: 27bdffd8 addiu sp,sp,-40 5ffe03a0: afbf0024 sw ra,36(sp) 5ffe03a4: afbe0020 sw s8,32(sp) 5ffe03a8: afb0001c sw s0,28(sp) 5ffe03ac: 03a0f021 move s8,sp 5ffe03b0: afbc0010 sw gp,16(sp) 5ffe03b4: 8f828018 lw v0,-32744(gp) 5ffe03b8: 24590418 addiu t9,v0,1048 5ffe03bc: 0320f809 jalr t9 5ffe03c0: 00000000 nop 5ffe03c4: 8fdc0010 lw gp,16(s8) ... We can now see that $gp is stored at 16($sp), which gives the required spare space for the 4 arguments in stack. -- Summary: [Mips] No space for arguments when implicitely calling __get_tls_addr Product: gcc Version: 4.3.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: joel dot porquet at gmail dot com GCC host triplet: i486-linux-gnu GCC target triplet: mipsel-unknown-elf http://gcc.gnu.org/bugzilla/show_bug.cgi?id=39493