Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 9 Apr 2012 16:14:53 +1200
From:      Andrew Turner <andrew@fubar.geek.nz>
To:        Juli Mallett <jmallett@FreeBSD.org>
Cc:        svn-src-head@freebsd.org, svn-src-all@freebsd.org, src-committers@freebsd.org
Subject:   Re: svn commit: r234014 - head/lib/libc/arm/gen
Message-ID:  <20120409161453.29d1f3de@fubar.geek.nz>
In-Reply-To: <CACVs6=8SW9PhZaxc4KRnVyo5p6NyhdD09_cAowLCbgczDqBsVg@mail.gmail.com>
References:  <201204080436.q384aRXS093116@svn.freebsd.org> <20120408164521.55aecdd1@fubar.geek.nz> <CACVs6=8SW9PhZaxc4KRnVyo5p6NyhdD09_cAowLCbgczDqBsVg@mail.gmail.com>

next in thread | previous in thread | raw e-mail | index | archive | help
--MP_/MUAtSxdUM4O2DLeLY2lu62S
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
Content-Disposition: inline

On Sun, 8 Apr 2012 18:36:45 -0700
Juli Mallett <jmallett@FreeBSD.org> wrote:

> On Sat, Apr 7, 2012 at 21:45, Andrew Turner <andrew@fubar.geek.nz>
> wrote:
> > On Sun, 8 Apr 2012 04:36:27 +0000 (UTC)
> > Andrew Turner <andrew@FreeBSD.org> wrote:
> >
> >> Author: andrew
> >> Date: Sun Apr =C2=A08 04:36:27 2012
> >> New Revision: 234014
> >> URL: http://svn.freebsd.org/changeset/base/234014
> >>
> >> Log:
> >> =C2=A0 Unlike other functions __aeabi_read_tp function must preserve
> >> r1-r3. The currently generated code clobbers r3. Fix this by
> >> loading ARM_TP_ADDRESS using inline assembly.
> >>
> >> =C2=A0 Approved by: =C2=A0 =C2=A0 =C2=A0 =C2=A0imp (mentor)
> >
> > This fixes thread local storage on ARM in cases when the compiler
> > loads the offset of the variable in r3 before calling
> > __aeabi_read_tp as has been observed when the variable is in a
> > shared library.
>=20
> I don't believe this is safe unless you specify __attribute__
> ((__naked__)) in the declaration =E2=80=94 currently the compiler is free=
 to
> clobber registers that the calling convention/ABI allows it to
> clobber.  I don't see the benefit of implementing this in C over using
> an assembly file, that said, although GCC does have this attribute
> precisely to allow one to write assembly in a C source file without
> having to worry about unexpected behavior.

We can implement it as a naked function but we will need to store all
registers other than r0 and pc which seems a waste.

The problem implementing it in an assembly file is we are unable to use
ARM_TP_ADDRESS is defined as:
#define ARM_TP_ADDRESS (ARM_VECTORS_HIGH + 0x1000)

Where ARM_VECTORS_HIGH is defined as:
#define ARM_VECTORS_HIGH 0xffff0000U

Binutils fails because of the U in ARM_VECTORS_HIGH eith the following:
Error: missing ')'
Error: junk at end of line, first unrecognized character is `U'

I could remove the U from ARM_VECTORS_HIGH however I'm not sure on the
implications of that change.


> How do you know GCC won't allocate r2 to be used as a temporary in
> between the assembly and the return?

The compiler is free to use r2 with the current code. I have attached a
patch that fools the compiler into thinking we are using r1-r3 by
placing them in the clobber list.

Andrew

--MP_/MUAtSxdUM4O2DLeLY2lu62S
Content-Type: text/x-patch
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename=arm_tls.patch

Index: lib/libc/arm/gen/__aeabi_read_tp.c
===================================================================
--- lib/libc/arm/gen/__aeabi_read_tp.c	(revision 234031)
+++ lib/libc/arm/gen/__aeabi_read_tp.c	(working copy)
@@ -39,7 +39,8 @@
 {
 	void *_tp;
 
-	asm("ldr %0, [%1]\n" : "=r"(_tp) : "r"(ARM_TP_ADDRESS));
+	asm("ldr %0, [%1]\n" : "=r"(_tp) : "r"(ARM_TP_ADDRESS)
+	    : "r1", "r2", "r3");
 
 	return _tp;
 }

--MP_/MUAtSxdUM4O2DLeLY2lu62S--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20120409161453.29d1f3de>