From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 30706 invoked by alias); 26 Dec 2010 09:50:07 -0000 Received: (qmail 30694 invoked by uid 22791); 26 Dec 2010 09:50:06 -0000 X-SWARE-Spam-Status: No, hits=-0.5 required=5.0 tests=AWL,BAYES_50,TW_XD,TW_XF,T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mel.act-europe.fr (HELO mel.act-europe.fr) (194.98.77.210) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Sun, 26 Dec 2010 09:50:00 +0000 Received: from localhost (localhost [127.0.0.1]) by filtered-smtp.eu.adacore.com (Postfix) with ESMTP id 00CE3CB0222; Sun, 26 Dec 2010 10:49:58 +0100 (CET) Received: from mel.act-europe.fr ([127.0.0.1]) by localhost (smtp.eu.adacore.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 2ifhsViwE7+r; Sun, 26 Dec 2010 10:49:57 +0100 (CET) Received: from cardhu.act-europe.fr (cardhu.act-europe.fr [10.10.0.168]) by mel.act-europe.fr (Postfix) with ESMTP id CD80BCB01B2; Sun, 26 Dec 2010 10:49:57 +0100 (CET) Received: by cardhu.act-europe.fr (Postfix, from userid 546) id A83EB1D9; Sun, 26 Dec 2010 10:49:57 +0100 (CET) Date: Sun, 26 Dec 2010 20:53:00 -0000 From: Olivier Hainque To: gcc-patches@gcc.gnu.org Cc: hainque@adacore.com, ro@CeBiTec.Uni-Bielefeld.DE Subject: unwinding fallback for mips-irix6 n32 Message-ID: <20101226094957.GA13777@cardhu.act-europe.fr> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="jRHKVT23PllUwdXP" Content-Disposition: inline User-Agent: Mutt/1.4.1i X-IsSubscribed: yes Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org X-SW-Source: 2010-12/txt/msg01847.txt.bz2 --jRHKVT23PllUwdXP Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-length: 900 Hello, We have been using an unwinding fallback on mips-irix6/n32 for a while (number of years) across different versions of GCC (3.4, 4.1, 4.3, and 4.5 lately). We haven't submitted this for inclusion so far because of the pretty limited range of supported configurations (irix 6, n32 abi only). Exchanges offlist suggested that it could be of interest nevertheless, so here it is. Our latest port was to gcc 4.5. The attached patch is a minor adaptation of that to mainline. I tested that a non bootstrap build proceeds fine and that a basic test involving SEGV in Ada works as expected. Rainer kindly offered to perform more thorough testing, to validate that this indeed reduces the amount of failures he has been observing. Thanks :) Olivier 2010-12-26 Olivier Hainque * config/mips/iris6-unwind.h: New file. * config/mips/iris6.h (MD_UNWIND_SUPPORT): Define. --jRHKVT23PllUwdXP Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="iris6-fallback.dif" Content-length: 6400 Index: iris6-unwind.h =================================================================== *** iris6-unwind.h (revision 0) --- iris6-unwind.h (revision 0) *************** *** 0 **** --- 1,140 ---- + /* DWARF2 EH unwinding support for MIPS Irix 6. + Copyright (C) 2004, 2006 Free Software Foundation, Inc. + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + GCC is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + Under Section 7 of GPL version 3, you are granted additional + permissions described in the GCC Runtime Library Exception, version + 3.1, as published by the Free Software Foundation. + + You should have received a copy of the GNU General Public License and + a copy of the GCC Runtime Library Exception along with this program; + see the files COPYING3 and COPYING.RUNTIME respectively. If not, see + . */ + + /* Do code reading to identify a signal frame, and set the frame + state data appropriately. See unwind-dw2.c for the structs. */ + + /* This code was developed-for and only tested-in limited abi + configurations. Characterize that. */ + + #if defined (_ABIN32) + #define SUPPORTED_ABI 1 + #else + #define SUPPORTED_ABI 0 + #endif + + #include + + #define MD_FALLBACK_FRAME_STATE_FOR mips_fallback_frame_state + + #define UINT_AT(ADDR) (*(unsigned int *)(ADDR)) + + /* Look at the code around RA to see if it matches a sighandler caller with a + sigcontext_t * argument (SA_SIGINFO cleared). Return that pointer argument + if it does match, or 0 otherwise. */ + + static sigcontext_t * + sigcontext_for (void * ra, void * cfa) + { + /* IRIX 6.5, mono-threaded application. We're lucky enough to be able + to expect a short very sighandler specific sequence around. */ + if (UINT_AT (ra + 24) == 0x24020440 /* li v0,1088 (SYS_sigreturn) */ + && UINT_AT (ra + 28) == 0x0000000c) /* syscall */ + return (sigcontext_t *)(cfa + 0x30); + + /* IRIX 6.5 variants, multi-threaded application, pthreads. Nothing really + sighandler specific handy, so match a fairly long constant sequence. */ + if (UINT_AT (ra - 40) == 0xffb00000 /* sd s0,0(sp) */ + && UINT_AT (ra - 36) == 0x0004f880 /* sll ra,a0,0x2 */ + && (UINT_AT (ra - 32) == 0x27399058 /* addiu t9,t9,-28584 */ + || UINT_AT (ra - 32) == 0x273990d8) /* addiu t9,t9,-28456 */ + && UINT_AT (ra - 28) == 0x8c300edc /* lw s0,3804(at) */ + && UINT_AT (ra - 24) == 0x033fc821 /* addu t9,t9,ra */ + && UINT_AT (ra - 20) == 0x8f390000 /* lw t9,0(t9) */ + && UINT_AT (ra - 16) == 0xdc210e70 /* ld at,3696(at) */ + && UINT_AT (ra - 12) == 0xde120058 /* ld s2,88(s0) */ + && UINT_AT (ra - 8) == 0x0320f809 /* jalr t9 */ + && UINT_AT (ra - 4) == 0xfe010058) /* sd at,88(s0) */ + return (sigcontext_t *)(cfa + 0x60); + + return 0; + } + + #define SIGCTX_GREG_ADDR(REGNO,SIGCTX) \ + ((void *) &(SIGCTX)->sc_regs[REGNO]) + + #define SIGCTX_FPREG_ADDR(REGNO,SIGCTX) \ + ((void *) &(SIGCTX)->sc_fpregs[REGNO]) + + static _Unwind_Reason_Code + mips_fallback_frame_state (struct _Unwind_Context *context, + _Unwind_FrameState *fs) + { + /* Return address and CFA of the frame we're attempting to unwind through, + possibly a signal handler. */ + void *ctx_ra = (void *)context->ra; + void *ctx_cfa = (void *)context->cfa; + + /* CFA of the intermediate abstract kernel frame between the interrupted + code and the signal handler, if we're indeed unwinding through a signal + handler. */ + void *k_cfa; + + /* Pointer to the sigcontext_t structure pushed by the kernel when we're + unwinding through a signal handler setup with SA_SIGINFO cleared. */ + sigcontext_t *sigctx; + int i; + + if (! SUPPORTED_ABI) + return _URC_END_OF_STACK; + + sigctx = sigcontext_for (ctx_ra, ctx_cfa); + + if (sigctx == 0) + return _URC_END_OF_STACK; + + /* The abstract kernel frame's CFA is extactly the stack pointer + value at the interruption point. */ + k_cfa = *(void **)SIGCTX_GREG_ADDR (CTX_SP, sigctx); + + /* State the rules to compute the CFA we have the value of: use the + previous CFA and offset by the difference between the two. See + uw_update_context_1 for the supporting details. */ + fs->regs.cfa_how = CFA_REG_OFFSET; + fs->regs.cfa_reg = __builtin_dwarf_sp_column (); + fs->regs.cfa_offset = k_cfa - ctx_cfa; + + /* Fill the internal frame_state structure with information stating where + each register of interest can be found from the CFA. */ + for (i = 0; i <= 31; i ++) + { + fs->regs.reg[i].how = REG_SAVED_OFFSET; + fs->regs.reg[i].loc.offset = SIGCTX_GREG_ADDR (i, sigctx) - k_cfa; + } + + for (i = 0; i <= 31; i ++) + { + fs->regs.reg[32+i].how = REG_SAVED_OFFSET; + fs->regs.reg[32+i].loc.offset = SIGCTX_FPREG_ADDR (i, sigctx) - k_cfa; + } + + /* State the rules to find the kernel's code "return address", which is the + address of the active instruction when the signal was caught. */ + fs->retaddr_column = DWARF_FRAME_RETURN_COLUMN; + fs->regs.reg[fs->retaddr_column].how = REG_SAVED_OFFSET; + fs->regs.reg[fs->retaddr_column].loc.offset = (void *)&sigctx->sc_pc - k_cfa; + fs->signal_frame = 1; + + return _URC_NO_REASON; + } Index: iris6.h =================================================================== *** iris6.h (revision 167992) --- iris6.h (working copy) *************** along with GCC; see the file COPYING3. *** 62,67 **** --- 62,69 ---- as DWARF_OFFSET_SIZE. */ #define DWARF_INITIAL_LENGTH_SIZE DWARF_OFFSET_SIZE + #define MD_UNWIND_SUPPORT "config/mips/iris6-unwind.h" + /* MIPS assemblers don't have the usual .set foo,bar construct; .set is used for assembler options instead. */ #undef SET_ASM_OP --jRHKVT23PllUwdXP--