------- Comment #3 from pinskia at gmail dot com 2009-03-18 14:22 ------- Subject: Re: New: [Mips] No space for arguments when implicitely calling __get_tls_addr
Sent from my iPhone On Mar 18, 2009, at 7:05 AM, "joel dot porquet at gmail dot com" <gcc-bugzi...@gcc.gnu.org > wrote: > 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. __get_tls_addr is a special function and does not have to follow that part of the ABI but a different part which should be documented about tls and dynamic tls. > > 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 > -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=39493