TLS on ARM and MIPS

Andrew Turner andrew at fubar.geek.nz
Sat Apr 7 02:19:40 UTC 2012


On Thu, 5 Apr 2012 22:58:22 +0200
Kristof Provost <kristof at sigsegv.be> wrote:

> On 2012-04-04 22:00:57 (-0700), Jason Evans <jasone at canonware.com>
> wrote:
> > On Apr 3, 2012, at 5:41 PM, Oleksandr Tymoshenko wrote:
> > > I tested it for MIPS - works fine. Unfortunately I don't have
> > > ARM hardware that works with HEAD so can't test ARM part of the
> > > change.
> > 
> > Thanks for testing MIPS.  I'm going to just assume that TLS works
> > everywhere. If it doesn't, we'll find out soon enough. =)
> > 
> It appears to be rather broken on ARM, at least in combination with
> shared libraries.
> 
> I'm trying to run on an OpenRD board (Kirkwood ARM core) and I see
> alignment faults whenever TLS is used. Considering that malloc appears
> to use it that'd be pretty much everywhere.
> 
> A minimal test case is to have a shared library expose a __thread
> variable and then to write to it from outside the library.
> 
> The assembly looks like this:
> int main(int argc, char **argv)
> {
>     8774:       e52de004        push    {lr}            ; (str lr,
> [sp, #-4]!)
>   kp_int = 4;
>     8778:       e59f3014        ldr     r3, [pc, #20]   ; 8794
> <main+0x20>
>     877c:       e79f3003        ldr     r3, [pc, r3]
>     8780:       ebffff4c        bl      84b8 <_init+0x58>

This is a call to __aeabi_read_tp. It is specified in the ARM EABI
documentation to be special and preserve r1-r3 unlike other functions.
The current implementation of __aeabi_read_tp trashes r3 as this is
normally safe. In this case however it uses it when loading the ARM tp
address. This then causes the fault you are seeing.

>     8784:       e3a02004        mov     r2, #4  ; 0x4
>     8788:       e7802003        str     r2, [r0, r3]
> 
>   return 0;
> }
> 
> The faulting instruction is 0x8788. At that point r0 is 0x20036000, r3
> is 0xffff1fff.
> 
> Let me know if you need to know anything else.
> In the mean time I'll keep trying to figure out how it's supposed to
> be working in the first place :)

Can you try the patch at [1]. It should fix the issue you are seeing.
It appears to create a correct version of __aeabi_read_tp but I'm
waiting on buildworld/installworld to finish.

Andrew

[1] http://people.freebsd.org/~andrew/arm_tls_2.diff

-- 
Andrew Turner
WhiteQueue Consulting http://whitequeue.com/
Custom FreeBSD and Linux development



More information about the freebsd-arch mailing list