From patchwork Wed Jan 29 17:58:56 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Waldemar Brodkorb X-Patchwork-Id: 315174 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from whitealder.osuosl.org (whitealder.osuosl.org [140.211.166.138]) by ozlabs.org (Postfix) with ESMTP id E29A42C00BF for ; Thu, 30 Jan 2014 04:59:05 +1100 (EST) Received: from localhost (localhost [127.0.0.1]) by whitealder.osuosl.org (Postfix) with ESMTP id 1134F8F6A5; Wed, 29 Jan 2014 17:59:04 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from whitealder.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id dr3Yvzra80wL; Wed, 29 Jan 2014 17:59:02 +0000 (UTC) Received: from ash.osuosl.org (ash.osuosl.org [140.211.166.34]) by whitealder.osuosl.org (Postfix) with ESMTP id A23CD8F592; Wed, 29 Jan 2014 17:59:02 +0000 (UTC) X-Original-To: uclibc@lists.busybox.net Delivered-To: uclibc@osuosl.org Received: from whitealder.osuosl.org (whitealder.osuosl.org [140.211.166.138]) by ash.osuosl.org (Postfix) with ESMTP id 6B2BB1CE7D5 for ; Wed, 29 Jan 2014 17:59:01 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by whitealder.osuosl.org (Postfix) with ESMTP id 67F5B8F592 for ; Wed, 29 Jan 2014 17:59:01 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from whitealder.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id T-l6kofWB9Jb for ; Wed, 29 Jan 2014 17:59:00 +0000 (UTC) X-Greylist: from auto-whitelisted by SQLgrey-1.7.6 Received: from helium.waldemar-brodkorb.de (helium.waldemar-brodkorb.de [89.238.66.15]) by whitealder.osuosl.org (Postfix) with ESMTPS id 093FD8F4C6 for ; Wed, 29 Jan 2014 17:58:59 +0000 (UTC) Received: by helium.waldemar-brodkorb.de (Postfix, from userid 1000) id A095527E004; Wed, 29 Jan 2014 18:58:56 +0100 (CET) Date: Wed, 29 Jan 2014 18:58:56 +0100 From: Waldemar Brodkorb To: uclibc@uclibc.org Subject: [PATCH] Fix setjmp/longjmp for MIPS64 N64 ABI Message-ID: <20140129175856.GA3796@waldemar-brodkorb.de> MIME-Version: 1.0 Content-Disposition: inline X-Operating-System: Linux 3.2.0-4-amd64 x86_64 User-Agent: Mutt/1.5.21 (2010-09-15) X-BeenThere: uclibc@uclibc.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "Discussion and development of uClibc \(the embedded C library\)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: uclibc-bounces@uclibc.org Sender: uclibc-bounces@uclibc.org When booting a Linux system with qemu-system-mips64 the execution of $(pwd) in the ash shell triggers a segmentation fault. Ash uses setjmp/longjmp for exception handling. After looking at the glibc implementation, I found some differences, with this patch tries to resolve. Now the system boots up fine and no segmentation faults occur. The global pointer should be restored and the types for the register values should be wide enough. See: http://www.cygwin.com/ml/libc-alpha/2003-03/msg00363.html Signed-off-by: Waldemar Brodkorb --- libc/sysdeps/linux/mips/bits/setjmp.h | 14 ++++++++++---- libc/sysdeps/linux/mips/setjmp.S | 1 + libc/sysdeps/linux/mips/setjmp_aux.c | 8 ++++---- 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/libc/sysdeps/linux/mips/bits/setjmp.h b/libc/sysdeps/linux/mips/bits/setjmp.h index 4d2a26e..375e537 100644 --- a/libc/sysdeps/linux/mips/bits/setjmp.h +++ b/libc/sysdeps/linux/mips/bits/setjmp.h @@ -25,13 +25,19 @@ #include +#if _MIPS_SIM == _MIPS_SIM_ABI32 +#define ptrsize void * +#else +#define ptrsize long long +#endif + typedef struct { /* Program counter. */ - void * __pc; + ptrsize __pc; /* Stack pointer. */ - void * __sp; + ptrsize __sp; /* Callee-saved registers s0 through s7. */ #if _MIPS_SIM == _MIPS_SIM_ABI32 @@ -41,10 +47,10 @@ typedef struct #endif /* The frame pointer. */ - void * __fp; + ptrsize __fp; /* The global pointer. */ - void * __gp; + ptrsize __gp; /* Floating point status register. */ int __fpc_csr; diff --git a/libc/sysdeps/linux/mips/setjmp.S b/libc/sysdeps/linux/mips/setjmp.S index 6d80a31..59b76cc 100644 --- a/libc/sysdeps/linux/mips/setjmp.S +++ b/libc/sysdeps/linux/mips/setjmp.S @@ -52,6 +52,7 @@ __sigsetjmp: PTR_LA t9, __sigsetjmp_aux #if _MIPS_SIM != _MIPS_SIM_ABI32 .cpreturn + move a4, gp #endif jr t9 #else diff --git a/libc/sysdeps/linux/mips/setjmp_aux.c b/libc/sysdeps/linux/mips/setjmp_aux.c index 559fe4e..9cffcc6 100644 --- a/libc/sysdeps/linux/mips/setjmp_aux.c +++ b/libc/sysdeps/linux/mips/setjmp_aux.c @@ -28,7 +28,7 @@ int #if _MIPS_SIM == _MIPS_SIM_ABI64 -__sigsetjmp_aux (jmp_buf env, int savemask, long sp, long fp) +__sigsetjmp_aux (jmp_buf env, int savemask, long long sp, long long fp, long long gp) #else /* O32 || N32 */ __sigsetjmp_aux (jmp_buf env, int savemask, int sp, int fp) #endif /* O32 || N32 */ @@ -62,14 +62,14 @@ __sigsetjmp_aux (jmp_buf env, int savemask, int sp, int fp) #endif /* .. and the stack pointer; */ - env[0].__jmpbuf[0].__sp = (void *) sp; + env[0].__jmpbuf[0].__sp = (ptrsize) sp; /* .. and the FP; it'll be in s8. */ - env[0].__jmpbuf[0].__fp = (void *) fp; + env[0].__jmpbuf[0].__fp = (ptrsize) fp; /* .. and the GP; */ #if _MIPS_SIM == _MIPS_SIM_ABI64 - __asm__ __volatile__ ("sd $gp, %0" : : "m" (env[0].__jmpbuf[0].__gp)); + env[0].__jmpbuf[0].__gp = (ptrsize) gp; #else __asm__ __volatile__ ("sw $gp, %0" : : "m" (env[0].__jmpbuf[0].__gp)); #endif