From patchwork Mon Jul 8 17:50:06 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Petr Salinger X-Patchwork-Id: 257581 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]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client CN "localhost", Issuer "www.qmailtoaster.com" (not verified)) by ozlabs.org (Postfix) with ESMTPS id 714012C02A1 for ; Tue, 9 Jul 2013 03:50:37 +1000 (EST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:subject:message-id:mime-version:content-type; q=dns; s= default; b=d56l0xLOM2UJ5euMRujgGiBwW7zZA1DTW+ow1tjB1MPLEWyi6vFA4 mHY2EWDiCg8UKBysfpBH65JBuZisyue5G54E3DrglADGUqzSKvE8drD7OXD77y/U uaXr8HFfy485NXHFKcLHZrtd9PrphBhdmg9eVPxC6TkTa/INBZEMhQ= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:subject:message-id:mime-version:content-type; s= default; bh=pBuT/WYJXLZJcZsBeEs8idaXGVc=; b=mmT/pCpmb0puf9eVaGlI s4srPHQO4u0bwDvCaCDfDvcOwHyDgQ4Hv57HjLFW9lUv1cV+ZtjF6SCG9MKZ6Y/F qmMrOC3lvqkGUotwIegJBy0yMXSrf4mzcWb3zSvnZrNTpK0NaFDcqa0NiLa0ZsbR QIGKx/0tfD2UDT08jeD2s+w= Received: (qmail 14799 invoked by alias); 8 Jul 2013 17:50:30 -0000 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 Received: (qmail 14785 invoked by uid 89); 8 Jul 2013 17:50:30 -0000 X-Spam-SWARE-Status: No, score=-0.1 required=5.0 tests=AWL, BAYES_00, FREEMAIL_FROM, SPF_NEUTRAL autolearn=no version=3.3.1 Received: from relay.felk.cvut.cz (HELO relay.felk.cvut.cz) (147.32.80.7) by sourceware.org (qpsmtpd/0.84/v0.84-167-ge50287c) with ESMTP; Mon, 08 Jul 2013 17:50:28 +0000 Received: from contest.felk.cvut.cz (contest.felk.cvut.cz [147.32.83.100]) by relay.felk.cvut.cz (8.14.5/8.14.5) with ESMTP id r68Ho6iR083038 for ; Mon, 8 Jul 2013 19:50:07 +0200 (CEST) (envelope-from Petr.Salinger@seznam.cz) Date: Mon, 8 Jul 2013 19:50:06 +0200 (CEST) From: Petr Salinger To: gcc-patches@gcc.gnu.org Subject: [i386] add unwinding via signal trampoline for kfreebsd*-gnu Message-ID: User-Agent: Alpine 2.00 (LNX 1167 2008-08-23) MIME-Version: 1.0 X-FELK-MailScanner-Information: X-MailScanner-ID: r68Ho6iR083038 X-FELK-MailScanner: Found to be clean X-FELK-MailScanner-SpamCheck: not spam, SpamAssassin (not cached, score=0.28, required 6, BAYES_00 -0.50, FREEMAIL_FROM 0.00, SPF_NEUTRAL 0.78) X-FELK-MailScanner-From: petr.salinger@seznam.cz X-FELK-MailScanner-To: gcc-patches@gcc.gnu.org X-FELK-MailScanner-Watermark: 1373910608.18828@mIK6wULdtwyiQn4XqMoVhQ X-Virus-Found: No Please add support for unwinding through signal handler for GNU/kFreeBSD. The attached patch is tested on GNU/kFreeBSD, both 32-bit and 64-bit. The i386/freebsd-unwind.h is probably also suitable for plain FreeBSD. As suggested in http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57851 I am posting it here. The patch mainly add new libgcc/config/i386/freebsd-unwind.h based on linux one. Thanks Petr # # unwinding via signal trampoline # --- a/src/libgcc/config.host +++ b/src/libgcc/config.host @@ -523,7 +523,12 @@ tmake_file="${tmake_file} i386/t-crtpc i386/t-crtfm i386/t-crtstuff t-dfprules" md_unwind_header=i386/linux-unwind.h ;; -i[34567]86-*-kfreebsd*-gnu | i[34567]86-*-knetbsd*-gnu | i[34567]86-*-gnu* | i[34567]86-*-kopensolaris*-gnu) +i[34567]86-*-kfreebsd*-gnu) + extra_parts="$extra_parts crtprec32.o crtprec64.o crtprec80.o crtfastmath.o" + tmake_file="${tmake_file} i386/t-crtpc i386/t-crtfm i386/t-crtstuff t-dfprules" + md_unwind_header=i386/freebsd-unwind.h + ;; +i[34567]86-*-knetbsd*-gnu | i[34567]86-*-gnu* | i[34567]86-*-kopensolaris*-gnu) extra_parts="$extra_parts crtprec32.o crtprec64.o crtprec80.o crtfastmath.o" tmake_file="${tmake_file} i386/t-crtpc i386/t-crtfm i386/t-crtstuff t-dfprules" ;; @@ -532,7 +537,12 @@ tmake_file="${tmake_file} i386/t-crtpc i386/t-crtfm i386/t-crtstuff t-dfprules" md_unwind_header=i386/linux-unwind.h ;; -x86_64-*-kfreebsd*-gnu | x86_64-*-knetbsd*-gnu) +x86_64-*-kfreebsd*-gnu) + extra_parts="$extra_parts crtprec32.o crtprec64.o crtprec80.o crtfastmath.o" + tmake_file="${tmake_file} i386/t-crtpc i386/t-crtfm i386/t-crtstuff t-dfprules" + md_unwind_header=i386/freebsd-unwind.h + ;; +x86_64-*-knetbsd*-gnu) extra_parts="$extra_parts crtprec32.o crtprec64.o crtprec80.o crtfastmath.o" tmake_file="${tmake_file} i386/t-crtpc i386/t-crtfm i386/t-crtstuff t-dfprules" ;; --- a/src/libgcc/config/i386/freebsd-unwind.h +++ b/src/libgcc/config/i386/freebsd-unwind.h @@ -0,0 +1,190 @@ +/* DWARF2 EH unwinding support for AMD x86-64 and x86. + Copyright (C) 2004-2013 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. + Don't use this at all if inhibit_libc is used. */ + +#ifndef inhibit_libc + +#include +#include +#include + +#ifdef __x86_64__ + +#define MD_FALLBACK_FRAME_STATE_FOR x86_64_fb_fallback_frame_state + +static _Unwind_Reason_Code +x86_64_fb_fallback_frame_state (struct _Unwind_Context *context, + _Unwind_FrameState *fs) +{ + unsigned int *pc = context->ra; + struct sigframe *sf; + long new_cfa; + +/* sys/amd64/amd64/sigtramp.S: + + 48 8d 7c 24 10 lea 0x10(%rsp),%rdi + 6a 00 pushq $0x0 + 48 c7 c0 a1 01 00 00 mov $0x1a1,%rax + 0f 05 syscall +*/ + + if ( (pc[0] == 0x247c8d48U) + && (pc[1] == 0x48006a10U) + && (pc[2] == 0x01a1c0c7U) + && (pc[3] == 0x050f0000U)) + { + sf = (struct sigframe *) context->cfa; + } + else + return _URC_END_OF_STACK; + + new_cfa = sf->sf_uc.uc_mcontext.mc_rsp; + fs->regs.cfa_how = CFA_REG_OFFSET; + /* Register 7 is rsp */ + fs->regs.cfa_reg = 7; + fs->regs.cfa_offset = new_cfa - (long) context->cfa; + + /* The SVR4 register numbering macros aren't usable in libgcc. */ + fs->regs.reg[0].how = REG_SAVED_OFFSET; + fs->regs.reg[0].loc.offset = (long)&sf->sf_uc.uc_mcontext.mc_rax - new_cfa; + fs->regs.reg[1].how = REG_SAVED_OFFSET; + fs->regs.reg[1].loc.offset = (long)&sf->sf_uc.uc_mcontext.mc_rdx - new_cfa; + fs->regs.reg[2].how = REG_SAVED_OFFSET; + fs->regs.reg[2].loc.offset = (long)&sf->sf_uc.uc_mcontext.mc_rcx - new_cfa; + fs->regs.reg[3].how = REG_SAVED_OFFSET; + fs->regs.reg[3].loc.offset = (long)&sf->sf_uc.uc_mcontext.mc_rbx - new_cfa; + fs->regs.reg[4].how = REG_SAVED_OFFSET; + fs->regs.reg[4].loc.offset = (long)&sf->sf_uc.uc_mcontext.mc_rsi - new_cfa; + fs->regs.reg[5].how = REG_SAVED_OFFSET; + fs->regs.reg[5].loc.offset = (long)&sf->sf_uc.uc_mcontext.mc_rdi - new_cfa; + fs->regs.reg[6].how = REG_SAVED_OFFSET; + fs->regs.reg[6].loc.offset = (long)&sf->sf_uc.uc_mcontext.mc_rbp - new_cfa; + fs->regs.reg[8].how = REG_SAVED_OFFSET; + fs->regs.reg[8].loc.offset = (long)&sf->sf_uc.uc_mcontext.mc_r8 - new_cfa; + fs->regs.reg[9].how = REG_SAVED_OFFSET; + fs->regs.reg[9].loc.offset = (long)&sf->sf_uc.uc_mcontext.mc_r9 - new_cfa; + fs->regs.reg[10].how = REG_SAVED_OFFSET; + fs->regs.reg[10].loc.offset = (long)&sf->sf_uc.uc_mcontext.mc_r10 - new_cfa; + fs->regs.reg[11].how = REG_SAVED_OFFSET; + fs->regs.reg[11].loc.offset = (long)&sf->sf_uc.uc_mcontext.mc_r11 - new_cfa; + fs->regs.reg[12].how = REG_SAVED_OFFSET; + fs->regs.reg[12].loc.offset = (long)&sf->sf_uc.uc_mcontext.mc_r12 - new_cfa; + fs->regs.reg[13].how = REG_SAVED_OFFSET; + fs->regs.reg[13].loc.offset = (long)&sf->sf_uc.uc_mcontext.mc_r13 - new_cfa; + fs->regs.reg[14].how = REG_SAVED_OFFSET; + fs->regs.reg[14].loc.offset = (long)&sf->sf_uc.uc_mcontext.mc_r14 - new_cfa; + fs->regs.reg[15].how = REG_SAVED_OFFSET; + fs->regs.reg[15].loc.offset = (long)&sf->sf_uc.uc_mcontext.mc_r15 - new_cfa; + fs->regs.reg[16].how = REG_SAVED_OFFSET; + fs->regs.reg[16].loc.offset = (long)&sf->sf_uc.uc_mcontext.mc_rip - new_cfa; + fs->retaddr_column = 16; + fs->signal_frame = 1; + return _URC_NO_REASON; +} + +#else /* ifdef __x86_64__ */ + +#define MD_FALLBACK_FRAME_STATE_FOR x86_fb_fallback_frame_state + +static _Unwind_Reason_Code +x86_fb_fallback_frame_state (struct _Unwind_Context *context, + _Unwind_FrameState *fs) +{ + unsigned int *pc = context->ra; + struct sigframe *sf; + long new_cfa; + +/* sys/amd64/ia32/ia32_sigtramp.S + + 8d 44 24 20 lea 0x20(%esp),%eax + 50 push %eax + b8 a1 01 00 00 mov $0x1a1,%eax + 50 push %eax + cd 80 int $0x80 + eb fe jmp - +*/ + +/* sys/i386/i386/locore.s: sigcode() + + 8d 44 24 20 lea 0x20(%esp),%eax + 50 push %eax + f7 40 54 00 00 02 00 testl $0x20000,0x54(%eax) + 75 03 jne + + 8e 68 14 mov 0x14(%eax),%gs + b8 a1 01 00 00 mov $0x1a1,%eax + 50 push %eax + cd 80 int $0x80 + eb fe jmp - +*/ + + if ((pc[0] == 0x2024448dU) + && (( + (pc[1] == 0x01a1b850U) + && (pc[2] == 0xcd500000U) + && ((pc[3] & 0xFF) == 0x80) + ) + + || ( + (pc[4] == 0x01a1b814U) + && (pc[5] == 0xcd500000U) + && ((pc[6] & 0xFF) == 0x80) + ))) + { + sf = (struct sigframe *) context->cfa; + } + else + return _URC_END_OF_STACK; + + new_cfa = sf->sf_uc.uc_mcontext.mc_esp; + fs->regs.cfa_how = CFA_REG_OFFSET; + fs->regs.cfa_reg = 4; + fs->regs.cfa_offset = new_cfa - (long) context->cfa; + + /* The SVR4 register numbering macros aren't usable in libgcc. */ + fs->regs.reg[0].how = REG_SAVED_OFFSET; + fs->regs.reg[0].loc.offset = (long)&sf->sf_uc.uc_mcontext.mc_eax - new_cfa; + fs->regs.reg[3].how = REG_SAVED_OFFSET; + fs->regs.reg[3].loc.offset = (long)&sf->sf_uc.uc_mcontext.mc_ebx - new_cfa; + fs->regs.reg[1].how = REG_SAVED_OFFSET; + fs->regs.reg[1].loc.offset = (long)&sf->sf_uc.uc_mcontext.mc_ecx - new_cfa; + fs->regs.reg[2].how = REG_SAVED_OFFSET; + fs->regs.reg[2].loc.offset = (long)&sf->sf_uc.uc_mcontext.mc_edx - new_cfa; + fs->regs.reg[6].how = REG_SAVED_OFFSET; + fs->regs.reg[6].loc.offset = (long)&sf->sf_uc.uc_mcontext.mc_esi - new_cfa; + fs->regs.reg[7].how = REG_SAVED_OFFSET; + fs->regs.reg[7].loc.offset = (long)&sf->sf_uc.uc_mcontext.mc_edi - new_cfa; + fs->regs.reg[5].how = REG_SAVED_OFFSET; + fs->regs.reg[5].loc.offset = (long)&sf->sf_uc.uc_mcontext.mc_ebp - new_cfa; + fs->regs.reg[8].how = REG_SAVED_OFFSET; + fs->regs.reg[8].loc.offset = (long)&sf->sf_uc.uc_mcontext.mc_eip - new_cfa; + fs->retaddr_column = 8; + fs->signal_frame = 1; + return _URC_NO_REASON; +} + +#endif /* ifdef __x86_64__ */ +#endif /* ifdef inhibit_libc */