From patchwork Wed Oct 27 20:35:29 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Botcazou X-Patchwork-Id: 69407 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id BF07CB6EF2 for ; Thu, 28 Oct 2010 07:36:39 +1100 (EST) Received: (qmail 27569 invoked by alias); 27 Oct 2010 20:36:04 -0000 Received: (qmail 27392 invoked by uid 22791); 27 Oct 2010 20:36:03 -0000 X-SWARE-Spam-Status: No, hits=-2.0 required=5.0 tests=AWL,BAYES_00 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; Wed, 27 Oct 2010 20:35:57 +0000 Received: from localhost (localhost [127.0.0.1]) by filtered-smtp.eu.adacore.com (Postfix) with ESMTP id 61B30CB028A for ; Wed, 27 Oct 2010 22:35:55 +0200 (CEST) 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 Z51CSRsUYRLR for ; Wed, 27 Oct 2010 22:35:55 +0200 (CEST) Received: from [192.168.1.2] (bon31-9-83-155-120-49.fbx.proxad.net [83.155.120.49]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mel.act-europe.fr (Postfix) with ESMTP id 33760CB01EA for ; Wed, 27 Oct 2010 22:35:55 +0200 (CEST) From: Eric Botcazou To: gcc-patches@gcc.gnu.org Subject: [SPARC] Unwind through signal handler on newer Solaris 10 Date: Wed, 27 Oct 2010 22:35:29 +0200 User-Agent: KMail/1.9.9 MIME-Version: 1.0 Message-Id: <201010272235.29372.ebotcazou@adacore.com> Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org The DWARF2 unwinder doesn't work correctly on newer Solaris 10 releases. This is a matter of adjusting the pattern matching code. Tested on SPARC/Solaris 8, 9 and 10, applied on the mainline and 4.5 branch. 2010-10-27 Eric Botcazou * config/sparc/sol2-unwind.h (sparc64_fallback_frame_state): Adjust for newer Solaris 10 release. (sparc_fallback_frame_state): Likewise. Index: config/sparc/sol2-unwind.h =================================================================== --- config/sparc/sol2-unwind.h (revision 165910) +++ config/sparc/sol2-unwind.h (working copy) @@ -1,5 +1,5 @@ /* DWARF2 EH unwinding support for SPARC Solaris. - Copyright (C) 2009 Free Software Foundation, Inc. + Copyright (C) 2009, 2010 Free Software Foundation, Inc. This file is part of GCC. @@ -118,7 +118,27 @@ sparc64_fallback_frame_state (struct _Un unsigned int cuh_pattern = *(unsigned int *)(*(unsigned long *)(this_cfa + 15*8) - 4); - if (cuh_pattern == 0x9410001a || cuh_pattern == 0x94100013) + if (cuh_pattern == 0xd25fa7ef) + { + /* This matches the call_user_handler pattern for Solaris 10. + There are 2 cases so we look for the return address of the + caller's caller frame in order to do more pattern matching. */ + unsigned int sah_pattern + = *(unsigned int *)(*(unsigned long *)(this_cfa + 176 + 15*8) - 4); + + if (sah_pattern == 0x92100019) + /* This is the same setup as for Solaris 9, see below. */ + regs_off = 176 + 176 + 176 + 304; + else + /* We need to move up three frames (the kernel frame, the + call_user_handler frame, the __sighndlr frame). Two of them + have the minimum stack frame size (kernel and __sighndlr + frames) of 176 bytes, and there is another with a stack frame + of 304 bytes (the call_user_handler frame). The ucontext_t + structure is after this offset. */ + regs_off = 176 + 176 + 304; + } + else if (cuh_pattern == 0x9410001a || cuh_pattern == 0x94100013) /* This matches the call_user_handler pattern for Solaris 9 and for Solaris 8 running inside Solaris Containers respectively. We need to move up four frames (the kernel frame, the signal @@ -152,7 +172,7 @@ sparc64_fallback_frame_state (struct _Un fpu_save_off = regs_off + (8*10) + 176; /* The fpregs field contains 32 extended words at the beginning that - contain the fpu state. Then there are 2 extended words and two + contain the FPU state. Then there are 2 extended words and two bytes. */ fpu_save = *(unsigned char *)(this_cfa + fpu_save_off + (8*32) + (2*8) + 2); @@ -195,7 +215,7 @@ sparc64_fallback_frame_state (struct _Un fs->regs.reg[i + 16].loc.offset = i*8; } - /* Check whether we need to restore fpu registers. */ + /* Check whether we need to restore FPU registers. */ if (fpu_save) { for (i = 0; i < 64; i++) @@ -347,14 +367,25 @@ sparc_fallback_frame_state (struct _Unwi = *(unsigned int *)(*(unsigned int *)(this_cfa + 15*4) - 4); if (cuh_pattern == 0xd407a04c) - /* This matches the call_user_handler pattern for Solaris 10. - We need to move up three frames (the kernel frame, the - call_user_handler frame, the __sighndlr frame). Two of them - have the minimum stack frame size (kernel and __sighndlr - frames) of 96 bytes, and there is another with a stack frame - of 160 bytes (the call_user_handler frame). The ucontext_t - structure is after this offset. */ - regs_off = 96 + 96 + 160; + { + /* This matches the call_user_handler pattern for Solaris 10. + There are 2 cases so we look for the return address of the + caller's caller frame in order to do more pattern matching. */ + unsigned int sah_pattern + = *(unsigned int *)(*(unsigned int *)(this_cfa + 96 + 15*4) - 4); + + if (sah_pattern == 0x92100019) + /* This is the same setup as for Solaris 9, see below. */ + regs_off = 96 + 96 + 96 + 160; + else + /* We need to move up three frames (the kernel frame, the + call_user_handler frame, the __sighndlr frame). Two of them + have the minimum stack frame size (kernel and __sighndlr + frames) of 96 bytes, and there is another with a stack frame + of 160 bytes (the call_user_handler frame). The ucontext_t + structure is after this offset. */ + regs_off = 96 + 96 + 160; + } else if (cuh_pattern == 0x9410001a || cuh_pattern == 0x9410001b) /* This matches the call_user_handler pattern for Solaris 9 and for Solaris 8 running inside Solaris Containers respectively. @@ -389,7 +420,7 @@ sparc_fallback_frame_state (struct _Unwi fpu_save_off = regs_off + (4*10) + (4*20); /* The fpregs field contains 32 words at the beginning that contain - the fpu state. Then there are 2 words and two bytes. */ + the FPU state. Then there are 2 words and two bytes. */ fpu_save = *(unsigned char *)(this_cfa + fpu_save_off + (4*32) + (2*4) + 2); /* We need to get the frame pointer for the kernel frame that @@ -429,7 +460,7 @@ sparc_fallback_frame_state (struct _Unwi fs->regs.reg[i + 16].loc.offset = i*4; } - /* Check whether we need to restore fpu registers. */ + /* Check whether we need to restore FPU registers. */ if (fpu_save) { for (i = 0; i < 32; i++)