This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Mips, -fpie and TLS management
- From: "Joel Porquet" <joel dot porquet at gmail dot com>
- To: gcc at gcc dot gnu dot org
- Date: Thu, 20 Nov 2008 17:28:16 +0100
- Subject: Mips, -fpie and TLS management
Hi,
I'm trying to compile a Position Independent Executable with a TLS but
gcc doesn't generate the expected code (at least, what i expect).
Here's an example:
__thread int test_loc;
void func()
{
test_loc = 2;
}
I compile the object with:
CFLAGS=-nostdinc -nostdlib -fno-builtin \
-Wall \
-fomit-frame-pointer \
-mips2 -EL -mno-branch-likely \
-mabicalls \
-G0 \
-Os
CPIE=-fpie
app.o: app.c
mipsel-unknown-elf-gcc $(CPIE) -c -o app.o app.c $(CFLAGS)
Then the generated code is:
Disassembly of section .text:
00000000 <func>:
0: 7c03e83b 0x7c03e83b
4: 3c020000 lui v0,0x0
4: R_MIPS_TLS_TPREL_HI16 test_loc
8: 00431021 addu v0,v0,v1
c: 24030002 li v1,2
10: 03e00008 jr ra
14: ac430000 sw v1,0(v0)
14: R_MIPS_TLS_TPREL_LO16 test_loc
Gcc is using local-exec tls model instead of global-dynamic. The
option -fpie is supposed to act as -fpic though (dixit the manual).
Here is the first problem...
If I force the use of global-dynamic through the -ftls-model option,
it doesn't change a thing.
Now, if I use the attribute:
void* __tls_get_addr(void* plop) /* just to avoid error the undefined
reference during the linking stage */
{
return 0;
}
__thread int test_loc __attribute((tls_model("global-dynamic")));
void func()
{
test_loc = 2;
}
The generated object seems correct:
20: 8f990000 lw t9,0(gp)
20: R_MIPS_CALL16 __tls_get_addr
24: 27840000 addiu a0,gp,0
24: R_MIPS_TLS_GD test_loc
28: 0320f809 jalr t9
2c: 00000000 nop
Thus I launch the linker with:
mipsel-unknown-elf-ld -pie app.o -o app.x
But then readelf tells me:
Relocation section '.rel.dyn' at offset 0x3d4 contains 2 entries:
Offset Info Type Sym.Value Sym. Name
00000000 00000000 R_MIPS_NONE
5ffe1460 00000026 R_MIPS_TLS_DTPMOD
The symbol name is missing and most of all, the offset type is missing
too: there should be a R_MIPS_TLS_DTPREL type with the
R_MIPS_TLS_DTPMOD, since for each tls variable in global dynamic
model, tls_get_addr must receive the module index and the offset. Here
is the second problem...
On the other hand, with DSO, it works perfectly.
For example, if I take the very same code (without the attribute) but
I compile it with -fpic instead of -fpie, and -shared instead of -pie,
I get the expected behavior:
Relocation section '.rel.dyn' at offset 0x3b4 contains 3 entries:
Offset Info Type Sym.Value Sym. Name
00000000 00000000 R_MIPS_NONE
5ffe1450 00000726 R_MIPS_TLS_DTPMOD 00000000 test_loc
5ffe1454 00000727 R_MIPS_TLS_DTPREL 00000000 test_loc
I would be glad if you could give me some feedback about this issue.
Regards,
Joel