This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]