From patchwork Wed Jun 24 20:57:54 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Szabolcs Nagy X-Patchwork-Id: 488211 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from arrakis.dune.hu (arrakis.dune.hu [78.24.191.176]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 533E614030B for ; Thu, 25 Jun 2015 06:58:15 +1000 (AEST) Received: from arrakis.dune.hu (localhost [127.0.0.1]) by arrakis.dune.hu (Postfix) with ESMTP id 36E6C28013B; Wed, 24 Jun 2015 22:57:55 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on arrakis.dune.hu X-Spam-Level: X-Spam-Status: No, score=-1.5 required=5.0 tests=BAYES_00, T_RP_MATCHES_RCVD autolearn=unavailable version=3.3.2 Received: from arrakis.dune.hu (localhost [127.0.0.1]) by arrakis.dune.hu (Postfix) with ESMTP id 1B0792800F7 for ; Wed, 24 Jun 2015 22:57:51 +0200 (CEST) X-policyd-weight: using cached result; rate: -7.6 Received: from port70.net (port70.net [81.7.13.123]) by arrakis.dune.hu (Postfix) with ESMTP for ; Wed, 24 Jun 2015 22:57:48 +0200 (CEST) Received: by port70.net (Postfix, from userid 1002) id 9A543ABEC072; Wed, 24 Jun 2015 22:57:54 +0200 (CEST) Date: Wed, 24 Jun 2015 22:57:54 +0200 From: Szabolcs Nagy To: Ted Hess Message-ID: <20150624205754.GB7066@port70.net> Mail-Followup-To: Ted Hess , OpenWrt developers , musl@lists.openwall.com References: <44CCF70F861243A79B82BF5799B76F9B@fortmeadow.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <44CCF70F861243A79B82BF5799B76F9B@fortmeadow.com> User-Agent: Mutt/1.5.23 (2014-03-12) Cc: OpenWrt developers , musl@lists.openwall.com Subject: Re: [OpenWrt-Devel] Alsa-lib (libasound) segfaults on TLS variable (musl on mips) X-BeenThere: openwrt-devel@lists.openwrt.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: OpenWrt Development List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: openwrt-devel-bounces@lists.openwrt.org Sender: "openwrt-devel" * Ted Hess [2015-06-23 18:04:35 -0400]: > Segfault in 'snd_lib_error_set_local' (error.c) referencing > static __thread snd_local_error_handler_t local_error; > > Program received signal SIGSEGV, Segmentation fault. > 0x0041b164 in snd_lib_error_set_local () > (gdb) bt > #0 0x0041b164 in snd_lib_error_set_local () > #1 0x0041fb68 in try_config () > #2 0x00420d80 in snd_device_name_hint () > #3 0x0040a3be in pcm_list () > #4 0x0040e92a in main () > (gdb) disas > Dump of assembler code for function snd_lib_error_set_local: > 0x0041b12c <+0>: lui gp,0x8 > 0x0041b130 <+4>: addiu gp,gp,23668 > 0x0041b134 <+8>: addu gp,gp,t9 > 0x0041b138 <+12>: addiu sp,sp,-16 > 0x0041b13c <+16>: lw t9,-29872(gp) > 0x0041b140 <+20>: sw ra,12(sp) > 0x0041b144 <+24>: sw s0,8(sp) > 0x0041b148 <+28>: sw gp,0(sp) > 0x0041b14c <+32>: move s0,a0 > 0x0041b150 <+36>: addiu a0,gp,-29376 > 0x0041b154 <+40>: jalr t9 > 0x0041b158 <+44>: nop > 0x0041b15c <+48>: lui v1,0x0 > 0x0041b160 <+52>: addu v1,v1,v0 > => 0x0041b164 <+56>: lw v0,-32768(v1) > 0x0041b168 <+60>: sw s0,-32768(v1) thanks for the report the bug is that mips tls access uses a hard coded -32768 offset relative to whatever __tls_get_addr returned. and musl did not account for this offset. the attached patch fixes the issue for me, we will fix it in musl soon. diff --git a/arch/mips/pthread_arch.h b/arch/mips/pthread_arch.h index f8e35ae..626b9bb 100644 --- a/arch/mips/pthread_arch.h +++ b/arch/mips/pthread_arch.h @@ -13,4 +13,6 @@ static inline struct pthread *__pthread_self() #define TLS_ABOVE_TP #define TP_ADJ(p) ((char *)(p) + sizeof(struct pthread) + 0x7000) +#define DTV_OFFSET 0x8000 + #define CANCEL_REG_IP (3-(union {int __i; char __b;}){1}.__b) diff --git a/src/thread/__tls_get_addr.c b/src/thread/__tls_get_addr.c index 3633396..bcc9be3 100644 --- a/src/thread/__tls_get_addr.c +++ b/src/thread/__tls_get_addr.c @@ -1,6 +1,10 @@ #include #include "pthread_impl.h" +#ifndef DTV_OFFSET +#define DTV_OFFSET 0 +#endif + void *__tls_get_addr(size_t *v) { pthread_t self = __pthread_self(); @@ -8,9 +12,9 @@ void *__tls_get_addr(size_t *v) __attribute__((__visibility__("hidden"))) void *__tls_get_new(size_t *); if (v[0]<=(size_t)self->dtv[0]) - return (char *)self->dtv[v[0]]+v[1]; - return __tls_get_new(v); + return (char *)self->dtv[v[0]]+v[1]+DTV_OFFSET; + return (char *)__tls_get_new(v)+DTV_OFFSET; #else - return (char *)self->dtv[1]+v[1]; + return (char *)self->dtv[1]+v[1]+DTV_OFFSET; #endif }