From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 27045 invoked by alias); 21 Oct 2013 12:52:58 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Received: (qmail 27027 invoked by uid 89); 21 Oct 2013 12:52:58 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.5 required=5.0 tests=AWL,BAYES_00,RP_MATCHES_RCVD,SPF_PASS,UNPARSEABLE_RELAY autolearn=ham version=3.3.2 X-HELO: userp1040.oracle.com Received: from userp1040.oracle.com (HELO userp1040.oracle.com) (156.151.31.81) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-SHA encrypted) ESMTPS; Mon, 21 Oct 2013 12:52:57 +0000 Received: from acsinet22.oracle.com (acsinet22.oracle.com [141.146.126.238]) by userp1040.oracle.com (Sentrion-MTA-4.3.1/Sentrion-MTA-4.3.1) with ESMTP id r9LCqhEw026827 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Mon, 21 Oct 2013 12:52:44 GMT Received: from aserz7022.oracle.com (aserz7022.oracle.com [141.146.126.231]) by acsinet22.oracle.com (8.14.4+Sun/8.14.4) with ESMTP id r9LCqgMT026555 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Mon, 21 Oct 2013 12:52:43 GMT Received: from abhmt119.oracle.com (abhmt119.oracle.com [141.146.116.71]) by aserz7022.oracle.com (8.14.4+Sun/8.14.4) with ESMTP id r9LCqgeL026543; Mon, 21 Oct 2013 12:52:42 GMT Received: from termi.oracle.com (/10.175.58.67) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Mon, 21 Oct 2013 05:52:42 -0700 From: jose.marchesi@oracle.com (Jose E. Marchesi) To: Mark Kettenis Cc: brobecker@adacore.com, tromey@redhat.com, gdb-patches@sourceware.org Subject: Re: [PATCH] [SPARC64] Figure out where a longjmp will land References: <87y563k71b.fsf@oracle.com> <87d2nffr53.fsf@fleche.redhat.com> <87txgrjupm.fsf@oracle.com> <20131017055736.GC3302@adacore.com> <87r4bk1694.fsf@oracle.com> <201310201932.r9KJWGfB025774@glazunov.sibelius.xs4all.nl> Date: Mon, 21 Oct 2013 12:52:00 -0000 In-Reply-To: <201310201932.r9KJWGfB025774@glazunov.sibelius.xs4all.nl> (Mark Kettenis's message of "Sun, 20 Oct 2013 21:32:16 +0200 (CEST)") Message-ID: <8738nuyeb1.fsf@oracle.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.3.50 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain X-IsSubscribed: yes X-SW-Source: 2013-10/txt/msg00622.txt.bz2 > Index: sparc-tdep.h > =================================================================== > RCS file: /cvs/src/src/gdb/sparc-tdep.h,v > retrieving revision 1.33 > diff -u -r1.33 sparc-tdep.h > --- sparc-tdep.h 1 Jan 2013 06:32:51 -0000 1.33 > +++ sparc-tdep.h 17 Oct 2013 11:27:05 -0000 > @@ -202,6 +202,12 @@ > extern void sparc_collect_rwindow (const struct regcache *regcache, > CORE_ADDR sp, int regnum); > > + > + > +extern int sparc_is_annulled_branch_insn (CORE_ADDR pc); > + > + > + Seems a bit excessive to put these additional ^L's in there. Amended in patch below. 2013-10-08 Jose E. Marchesi * sparc-tdep.c (sparc_is_annulled_branch_insn): New function. * sparc-tdep.h: And its prototype. * sparc64-linux-tdep.c (sparc64_linux_get_longjmp_target): New function. (sparc64_linux_init_abi): Register the get_longjmp_target hook. Index: sparc-tdep.c =================================================================== RCS file: /cvs/src/src/gdb/sparc-tdep.c,v retrieving revision 1.233 diff -u -r1.233 sparc-tdep.c --- sparc-tdep.c 24 Jun 2013 22:18:32 -0000 1.233 +++ sparc-tdep.c 17 Oct 2013 11:27:05 -0000 @@ -121,6 +121,17 @@ return ((insn & 0xc1c00000) == 0); } +/* Return non-zero if the instruction corresponding to PC is an + "annulled" branch, i.e. the annul bit is set. */ + +int +sparc_is_annulled_branch_insn (CORE_ADDR pc) +{ + const unsigned long insn = sparc_fetch_instruction (pc); + + return X_A (insn); +} + /* OpenBSD/sparc includes StackGhost, which according to the author's website http://stackghost.cerias.purdue.edu "... transparently and automatically protects applications' stack frames; more Index: sparc-tdep.h =================================================================== RCS file: /cvs/src/src/gdb/sparc-tdep.h,v retrieving revision 1.33 diff -u -r1.33 sparc-tdep.h --- sparc-tdep.h 1 Jan 2013 06:32:51 -0000 1.33 +++ sparc-tdep.h 21 Oct 2013 12:48:04 -0000 @@ -220,6 +220,8 @@ const struct regcache *regcache, int regnum, void *fpregs); +extern int sparc_is_annulled_branch_insn (CORE_ADDR pc); + /* Functions and variables exported from sparc-sol2-tdep.c. */ /* Register offsets for Solaris 2. */ Index: sparc64-linux-tdep.c =================================================================== RCS file: /cvs/src/src/gdb/sparc64-linux-tdep.c,v retrieving revision 1.31 diff -u -r1.31 sparc64-linux-tdep.c --- sparc64-linux-tdep.c 1 Jan 2013 06:32:51 -0000 1.31 +++ sparc64-linux-tdep.c 17 Oct 2013 11:27:05 -0000 @@ -233,6 +233,50 @@ } +/* Implement the "get_longjmp_target" gdbarch method. */ + +static int +sparc64_linux_get_longjmp_target (struct frame_info *frame, CORE_ADDR *pc) +{ + struct gdbarch *gdbarch = get_frame_arch (frame); + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + CORE_ADDR jb_addr; + gdb_byte buf[8]; + + jb_addr = get_frame_register_unsigned (frame, SPARC_O0_REGNUM); + + /* setjmp and longjmp in SPARC64 are implemented in glibc using the + setcontext and getcontext system calls respectively. These + system calls operate on ucontext_t structures, which happen to + partially have the same structure than jmp_buf. However the + ucontext returned by getcontext, and thus the jmp_buf structure + returned by setjmp, contains the context of the trap instruction + in the glibc __[sig]setjmp wrapper, not the context of the user + code calling setjmp. + + %o7 in the jmp_buf structure is stored at offset 18*8 in the + mc_gregs array, which is itself located at offset 32 into + jmp_buf. See bits/setjmp.h. This register contains the address + of the 'call setjmp' instruction in user code. + + In order to determine the longjmp target address in the + initiating frame we need to examine the call instruction itself, + in particular whether the annul bit is set. If it is not set + then we need to jump over the instruction at the delay slot. */ + + if (target_read_memory (jb_addr + 32 + (18 * 8), buf, 8)) + return 0; + + *pc = extract_unsigned_integer (buf, 8, gdbarch_byte_order (gdbarch)); + + if (!sparc_is_annulled_branch_insn (*pc)) + *pc += 4; /* delay slot insn */ + *pc += 4; /* call insn */ + + return 1; +} + + static void sparc64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) @@ -272,6 +316,9 @@ /* Make sure we can single-step over signal return system calls. */ tdep->step_trap = sparc64_linux_step_trap; + /* Make sure we can single-step over longjmp calls. */ + set_gdbarch_get_longjmp_target (gdbarch, sparc64_linux_get_longjmp_target); + set_gdbarch_write_pc (gdbarch, sparc64_linux_write_pc); /* Functions for 'catch syscall'. */