From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 20985 invoked by alias); 10 Feb 2015 14:51:06 -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 20969 invoked by uid 89); 10 Feb 2015 14:51:05 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.2 required=5.0 tests=BAYES_00,SPF_HELO_PASS,SPF_SOFTFAIL autolearn=no version=3.3.2 X-HELO: bigwig.baldwin.cx Received: from bigwig.baldwin.cx (HELO bigwig.baldwin.cx) (96.47.65.170) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (CAMELLIA256-SHA encrypted) ESMTPS; Tue, 10 Feb 2015 14:51:03 +0000 Received: from ralph.baldwin.cx (pool-173-54-116-245.nwrknj.fios.verizon.net [173.54.116.245]) by bigwig.baldwin.cx (Postfix) with ESMTPSA id 7E728B91F for ; Tue, 10 Feb 2015 09:50:59 -0500 (EST) From: John Baldwin To: gdb-patches@sourceware.org Subject: [PATCH] Fix signal trampoline detection/unwinding on recent FreeBSD/i386 and FreeBSD/amd64 Date: Tue, 10 Feb 2015 14:51:00 -0000 Message-ID: <1836606.R8FOmMR0ZG@ralph.baldwin.cx> User-Agent: KMail/4.14.2 (FreeBSD/10.1-STABLE; KDE/4.14.2; amd64; ; ) In-Reply-To: <11386216.Yv1qECs4Mc@ralph.baldwin.cx> References: <11386216.Yv1qECs4Mc@ralph.baldwin.cx> MIME-Version: 1.0 Content-Transfer-Encoding: 7Bit Content-Type: text/plain; charset="us-ascii" X-SW-Source: 2015-02/txt/msg00254.txt.bz2 On Wednesday, February 04, 2015 10:47:07 AM John Baldwin wrote: > This patch fixes two issues with signal frame unwinding on recent > FreeBSD/x86: > > First, FreeBSD moved the signal trampoline code into a global shared page > exported by the kernel a few releases ago. To try to make this easier to > detect, FreeBSD added a new per-process sysctl node that exports the > starting and ending address of the signal trampoline code. This sysctl > works on all platforms that FreeBSD supports no matter where the signal > trampoline lives, but I have only updated i386 and amd64 in this patch. > > Second, amd64fbsd_sigcontext_addr was using frame_unwind_register_unsigned > to fetch the stack pointer which resulted in infinite recursion. I've > changed it to use get_frame_register() to match the sigcontext_addr methods > in the i386-bsd and amd64-linux targets instead. Does anyone have any comments on this patch or is there anything I need to fix in it? > Changelog: > > 2015-xx-xx John Baldwin > > * amd64fbsd-nat.c (_initialize_amd64fbsd_nat): Use the KERN_PROC_SIGTRAMP > sysctl to locate the signal trampoline. > * i386fbsd-nat.c (_initialize_i386fbsd_nat): Likewise. > * amd64fbsd-tdep.c (amd64fbsd_sigcontext_addr): Fix infinite recursion. > > diff --git a/gdb/amd64fbsd-nat.c b/gdb/amd64fbsd-nat.c > index 1c396e2..6227681 100644 > --- a/gdb/amd64fbsd-nat.c > +++ b/gdb/amd64fbsd-nat.c > @@ -26,6 +26,7 @@ > #include > #include > #include > +#include > #include > > #include "fbsd-nat.h" > @@ -244,6 +245,29 @@ Please report this to ."), > > SC_RBP_OFFSET = offset; > > +#ifdef KERN_PROC_SIGTRAMP > + /* Newer versions of FreeBSD provide a kern.proc.sigtramp. > + sysctl that returns the location of the signal trampoline. > + Note that this fetches the address for the current (gdb) process. > + This will be correct for other 64-bit processes, but the signal > + trampoline location is not properly set for 32-bit processes. */ > + { > + int mib[4]; > + struct kinfo_sigtramp kst; > + size_t len; > + > + mib[0] = CTL_KERN; > + mib[1] = KERN_PROC; > + mib[2] = KERN_PROC_SIGTRAMP; > + mib[3] = getpid(); > + len = sizeof (kst); > + if (sysctl (mib, 4, &kst, &len, NULL, 0) == 0) > + { > + amd64fbsd_sigtramp_start_addr = (uintptr_t)kst.ksigtramp_start; > + amd64fbsd_sigtramp_end_addr = (uintptr_t)kst.ksigtramp_end; > + } > + } > +#else > /* FreeBSD provides a kern.ps_strings sysctl that we can use to > locate the sigtramp. That way we can still recognize a sigtramp > if its location is changed in a new kernel. Of course this is > @@ -264,4 +288,5 @@ Please report this to ."), > amd64fbsd_sigtramp_end_addr = ps_strings; > } > } > +#endif > } > diff --git a/gdb/amd64fbsd-tdep.c b/gdb/amd64fbsd-tdep.c > index 2d49cdf..abb0cab 100644 > --- a/gdb/amd64fbsd-tdep.c > +++ b/gdb/amd64fbsd-tdep.c > @@ -37,12 +37,16 @@ > static CORE_ADDR > amd64fbsd_sigcontext_addr (struct frame_info *this_frame) > { > + struct gdbarch *gdbarch = get_frame_arch (this_frame); > + enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); > CORE_ADDR sp; > + gdb_byte buf[8]; > > /* The `struct sigcontext' (which really is an `ucontext_t' on > FreeBSD/amd64) lives at a fixed offset in the signal frame. See > . */ > - sp = frame_unwind_register_unsigned (this_frame, AMD64_RSP_REGNUM); > + get_frame_register (this_frame, AMD64_RSP_REGNUM, buf); > + sp = extract_unsigned_integer (buf, 8, byte_order); > return sp + 16; > } > > diff --git a/gdb/i386fbsd-nat.c b/gdb/i386fbsd-nat.c > index f4951d1..5293f0f 100644 > --- a/gdb/i386fbsd-nat.c > +++ b/gdb/i386fbsd-nat.c > @@ -25,6 +25,7 @@ > #include > #include > #include > +#include > > #include "fbsd-nat.h" > #include "i386-tdep.h" > @@ -148,13 +149,34 @@ _initialize_i386fbsd_nat (void) > /* Support debugging kernel virtual memory images. */ > bsd_kvm_add_target (i386fbsd_supply_pcb); > > +#ifdef KERN_PROC_SIGTRAMP > + /* Newer versions of FreeBSD provide a kern.proc.sigtramp. > + sysctl that returns the location of the signal trampoline. > + Note that this fetches the address for the current (gdb) process, > + but should be correct for other processes. */ > + { > + int mib[4]; > + struct kinfo_sigtramp kst; > + size_t len; > + > + mib[0] = CTL_KERN; > + mib[1] = KERN_PROC; > + mib[2] = KERN_PROC_SIGTRAMP; > + mib[3] = getpid(); > + len = sizeof (kst); > + if (sysctl (mib, 4, &kst, &len, NULL, 0) == 0) > + { > + i386fbsd_sigtramp_start_addr = (uintptr_t)kst.ksigtramp_start; > + i386fbsd_sigtramp_end_addr = (uintptr_t)kst.ksigtramp_end; > + } > + } > +#elif defined(KERN_PS_STRINGS) > /* FreeBSD provides a kern.ps_strings sysctl that we can use to > locate the sigtramp. That way we can still recognize a sigtramp > if its location is changed in a new kernel. Of course this is > still based on the assumption that the sigtramp is placed > directly under the location where the program arguments and > environment can be found. */ > -#ifdef KERN_PS_STRINGS > { > int mib[2]; > u_long ps_strings; -- John Baldwin