This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: Fwd: Mips, -fpie and TLS management
2009/3/12 Daniel Jacobowitz <drow@false.org>:
> On Thu, Mar 12, 2009 at 02:02:36PM +0100, Joel Porquet wrote:
>> > Check what symbol is at, or near, 0x40030000 + 22368. ?It's probably
>> > the GOT plus a constant bias.
>>
>> It seems there is nothing at this address. Here is the program header:
>
> Don't know then. ?Look at compiler-generated assembly instead of
> disassembly; that often helps.
Do you mean the object file produced by gcc before linkage?
If yes, the code looks like:
3c050000 lui a1,0x0
40: R_MIPS_TLS_DTPREL_HI16 a
which will be computed later as
3c054003 lui a1,0x4003
>> By the way, how did you test the code of TLS for mips? I mean, uclibc
>> seems the more advanced lib for mips, and although this lib seems to
>> have the necessary code to manage tls once it is "installed", the ldso
>> doesn't contain any code for handling TLS (relocation, tls allocation,
>> etc)...
>
> That statement about uclibc strikes me as bizarre. ?I tested it with
> glibc, naturally. ?GLIBC has a much more reliable TLS implementation
> than uclibc's in-progress one.
I just downloaded the glibc archive without noticing that the mips
port was in another archive... My mistake..
>> >> Last question, is there a difference between DSO and PIE objects other
>> >> than the INTERP entry in the program header?
>> >
>> > Yes. ?Symbol preemption is allowed for DSOs but not for PIEs or normal
>> > executables. ?That explains the different choice of model.
>>
>> But this is only a property, isn't it? I was meaning, how can you
>> differenciate them at loading time, when you "analyse" the elf file.
>
> You can't.
>
>> As you surely know, ELF_R_SYM() macro performs (val>>8) which gives
>> the symbol index in order to retrieve the name of the symbol. This
>> name then allows to look up the symbol. Unfortunately, in the case of
>> local-dynamic, ELF_R_SYM will return 0 which is not correct (the same
>> for global-dynamic will return 9): we can see by the way that readelf
>> is not able to get the symbol name. What do you think about this?
>
> This is a *module* relocation. ?In local dynamic the module is always
> the current DSO; it does not need a symbol.
But what if the DSO access other module's TLS?
Finally, I noticed another problem. GCC seems to not make room for the
4 arguments as specified in the ABI, when calling __get_tls_addr.
For example, here is an extract of the code for calling (we see that
data are stored directly at the top of the stack):
...
5ffe0bfc: 27bdfff0 addiu sp,sp,-16
5ffe0c00: afbf000c sw ra,12(sp)
5ffe0c04: afbc0000 sw gp,0(sp)
5ffe0c08: afa40010 sw a0,16(sp)
5ffe0c0c: 1000000d b 5ffe0c44 <puts+0x54>
5ffe0c10: 00000000 nop
5ffe0c14: 8f998030 lw t9,-32720(gp)
5ffe0c18: 27848038 addiu a0,gp,-32712
5ffe0c1c: 0320f809 jalr t9
5ffe0c20: 00000000 nop
5ffe0c24: 8fbc0000 lw gp,0(sp)
...
The "jalr t9" is the call to get_tls_addr whose code is:
...
5ffe0b40: 27bdffe8 addiu sp,sp,-24
5ffe0b44: afbc0000 sw gp,0(sp)
5ffe0b48: afa40018 sw a0,24(sp)
5ffe0b4c: 7c03e83b 0x7c03e83b
...
We notice then that "sw a0, 24(sp)" will erase $gp which was saved at
the same place ("sw gp, 0(gp)") by the caller.
Regards,
Joel