diff mbox series

[uclibc-ng-devel] xtensa: fix _dl_tlsdesc_dynamic

Message ID 1516128211-4509-1-git-send-email-jcmvbkbc@gmail.com
State Accepted
Headers show
Series [uclibc-ng-devel] xtensa: fix _dl_tlsdesc_dynamic | expand

Commit Message

Max Filippov Jan. 16, 2018, 6:43 p.m. UTC
There are multiple errors in _dl_tlsdesc_dynamic:

- the reference C implementation should return pointer to the
  thread-local variable, not offset from the thread pointer, because the
  xtensa ABI expects TLSDESC_FN to return pointer to the TLS variable;
- addx8 used for indexing into dtv has its second and third registers in
  wrong order, the index must be multiplied by 8, not the base;
- the same addx8 uses wrong base: instead of dtv it adds the offset to
  the threadptr;
- the return value in the fast path is calculated as
  td->tlsinfo.ti_offset - __builtin_thread_pointer, not what was
  intended;
- both fast and slow paths should not subtract __builtin_thread_pointer
  from the result.

Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
---
 ldso/ldso/xtensa/dl-tlsdesc.S | 21 +++++++++------------
 1 file changed, 9 insertions(+), 12 deletions(-)

Comments

Waldemar Brodkorb Jan. 21, 2018, 12:37 p.m. UTC | #1
Hi Max,
Max Filippov wrote,

> There are multiple errors in _dl_tlsdesc_dynamic:
> 
> - the reference C implementation should return pointer to the
>   thread-local variable, not offset from the thread pointer, because the
>   xtensa ABI expects TLSDESC_FN to return pointer to the TLS variable;
> - addx8 used for indexing into dtv has its second and third registers in
>   wrong order, the index must be multiplied by 8, not the base;
> - the same addx8 uses wrong base: instead of dtv it adds the offset to
>   the threadptr;
> - the return value in the fast path is calculated as
>   td->tlsinfo.ti_offset - __builtin_thread_pointer, not what was
>   intended;
> - both fast and slow paths should not subtract __builtin_thread_pointer
>   from the result.
> 
> Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>

Applied and pushed,
 Thanks
  Waldemar
diff mbox series

Patch

diff --git a/ldso/ldso/xtensa/dl-tlsdesc.S b/ldso/ldso/xtensa/dl-tlsdesc.S
index 6f417f61a98b..426f2180b3c0 100644
--- a/ldso/ldso/xtensa/dl-tlsdesc.S
+++ b/ldso/ldso/xtensa/dl-tlsdesc.S
@@ -39,7 +39,7 @@  END (_dl_tlsdesc_return)
 	   The assembly code that follows is a rendition of the following
 	   C code, hand-optimized a little bit.
 
-	   ptrdiff_t
+	   void *
 	   _dl_tlsdesc_dynamic(struct tlsdesc_dynamic_arg *td)
 	   {
 	     dtv_t *dtv = (dtv_t *)THREAD_DTV();
@@ -47,8 +47,8 @@  END (_dl_tlsdesc_return)
 	         && dtv[td->tlsinfo.ti_module].pointer.val
 	            != TLS_DTV_UNALLOCATED)
 	       return dtv[td->tlsinfo.ti_module].pointer.val
-	              + td->tlsinfo.ti_offset - __builtin_thread_pointer();
-	     return __tls_get_addr (&td->tlsinfo) - __builtin_thread_pointer();
+	              + td->tlsinfo.ti_offset;
+	     return __tls_get_addr (&td->tlsinfo);
 	   }
 	 */
 
@@ -65,33 +65,30 @@  HIDDEN_ENTRY (_dl_tlsdesc_dynamic)
 
 	/* && dtv[td->tlsinfo.ti_module].pointer.val != TLS_DTV_UNALLOCATED) */
 	l32i	a6, a2, TLSDESC_MODID
-	addx8	a6, a3, a6
+	addx8	a6, a6, a4
 	l32i	a6, a6, 0
 	beqi	a6, -1, .Lslow
 
 	/* return dtv[td->tlsinfo.ti_module].pointer.val
-	     + td->tlsinfo.ti_offset - __builtin_thread_pointer(); */
-	l32i	a6, a2, TLSDESC_MODOFF
-	sub	a2, a6, a3
+	     + td->tlsinfo.ti_offset; */
+	l32i	a5, a2, TLSDESC_MODOFF
+	add	a2, a6, a5
 	abi_ret
 
-	/* return __tls_get_addr (&td->tlsinfo) - __builtin_thread_pointer(); */
+	/* return __tls_get_addr (&td->tlsinfo); */
 .Lslow:
 #if defined(__XTENSA_WINDOWED_ABI__)
 	mov	a6, a2
 	movi	a4, __tls_get_addr
 	callx4	a4
-	sub	a2, a6, a3
+	mov	a2, a6
 	retw
 #elif defined(__XTENSA_CALL0_ABI__)
 	addi	a1, a1, -16
 	s32i	a0, a1, 0
-	s32i	a3, a1, 4
 	movi	a0, __tls_get_addr
 	callx0	a0
-	l32i	a3, a1, 4
 	l32i	a0, a1, 0
-	sub	a2, a2, a3
 	addi	a1, a1, 16
 	ret
 #else