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