From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 21558 invoked by alias); 29 Oct 2007 21:21:43 -0000 Received: (qmail 21549 invoked by uid 22791); 29 Oct 2007 21:21:43 -0000 X-Spam-Check-By: sourceware.org Received: from mtagate7.de.ibm.com (HELO mtagate7.de.ibm.com) (195.212.29.156) by sourceware.org (qpsmtpd/0.31) with ESMTP; Mon, 29 Oct 2007 21:21:38 +0000 Received: from d12nrmr1607.megacenter.de.ibm.com (d12nrmr1607.megacenter.de.ibm.com [9.149.167.49]) by mtagate7.de.ibm.com (8.13.8/8.13.8) with ESMTP id l9TLLZB3234288 for ; Mon, 29 Oct 2007 21:21:35 GMT Received: from d12av02.megacenter.de.ibm.com (d12av02.megacenter.de.ibm.com [9.149.165.228]) by d12nrmr1607.megacenter.de.ibm.com (8.13.8/8.13.8/NCO v8.5) with ESMTP id l9TLLZOI2056264 for ; Mon, 29 Oct 2007 22:21:35 +0100 Received: from d12av02.megacenter.de.ibm.com (loopback [127.0.0.1]) by d12av02.megacenter.de.ibm.com (8.12.11.20060308/8.13.3) with ESMTP id l9TLLZf3019816 for ; Mon, 29 Oct 2007 22:21:35 +0100 Received: from tuxmaker.boeblingen.de.ibm.com (tuxmaker.boeblingen.de.ibm.com [9.152.85.9]) by d12av02.megacenter.de.ibm.com (8.12.11.20060308/8.12.11) with SMTP id l9TLLZk7019813; Mon, 29 Oct 2007 22:21:35 +0100 Message-Id: <200710292121.l9TLLZk7019813@d12av02.megacenter.de.ibm.com> Received: by tuxmaker.boeblingen.de.ibm.com (sSMTP sendmail emulation); Mon, 29 Oct 2007 22:21:35 +0100 Subject: Fedora utrace changes break PPC GDB To: roland@redhat.com, gdb@sourceware.org Date: Mon, 29 Oct 2007 21:21:00 -0000 From: "Ulrich Weigand" X-Mailer: ELM [version 2.5 PL2] MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Mailing-List: contact gdb-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-owner@sourceware.org X-SW-Source: 2007-10/txt/msg00291.txt.bz2 Hello, I've been testing GDB on a PowerPC system running a Fedora 7 kernel, and there are some regressions that appear to have been introduced by the ptrace-on-utrace emulation layer that is now included in Fedora. Specifically, there are the following two problems (which also seem to still be present in a current Fedora development kernel): - PTRACE_SET_DEBUGREG ABI change In mainline kernels, PTRACE_SET_DEBUGREG takes an immediate argument (like e.g. PTRACE_POKEUSR). However, the Fedora code has: case PTRACE_GET_DEBUGREG: case PTRACE_SET_DEBUGREG: return ptrace_onereg_access(child, engine, utrace_native_view(current), 3, addr, (unsigned long __user *)data, *request == PTRACE_SET_DEBUGREG); which assumes the "data" argument is a *pointer* to the data, instead of the value itself. This breaks hardware watchpoint support completely. - vrsave register access The mainline kernel uses the following function to implement the PTRACE_GETVRREGS routine: /* copy AltiVec registers VR[0] .. VR[31] */ regsize = 32 * sizeof(vector128); if (copy_to_user(data, task->thread.vr, regsize)) return -EFAULT; data += (regsize / sizeof(unsigned long)); /* copy VSCR */ regsize = 1 * sizeof(vector128); if (copy_to_user(data, &task->thread.vscr, regsize)) return -EFAULT; data += (regsize / sizeof(unsigned long)); /* copy VRSAVE */ if (put_user(task->thread.vrsave, (u32 __user *)data)) return -EFAULT; Note that vscr and vrsave are provided in distinct fields of the thread struct: /* Complete AltiVec register set */ vector128 vr[32] __attribute((aligned(16))); /* AltiVec status */ vector128 vscr __attribute((aligned(16))); unsigned long vrsave; int used_vr; /* set if process has used altivec */ However, the utrace emulation layer in Fedora does case PTRACE_GETVRREGS: return ptrace_whole_regset(child, engine, data, 2, 0); case PTRACE_SETVRREGS: return ptrace_whole_regset(child, engine, data, 2, 1); using the following "regset" and access routines #ifdef CONFIG_ALTIVEC { .n = 33*4+1, .size = sizeof(u32), .align = sizeof(u32), .active = vrregs_active, .get = vrregs_get, .set = vrregs_set }, #endif static int vrregs_get(struct task_struct *target, const struct utrace_regset *regset, unsigned int pos, unsigned int count, void *kbuf, void __user *ubuf) { BUILD_BUG_ON(offsetof(struct thread_struct, vscr) != offsetof(struct thread_struct, vr[32])); BUILD_BUG_ON(offsetof(struct thread_struct, vscr) + sizeof(vector128) != offsetof(struct thread_struct, vrsave)); flush_altivec_to_thread(target); return utrace_regset_copyout(&pos, &count, &kbuf, &ubuf, &target->thread.vr, 0, -1); } This has the effect of simply accessing 33*4+1 "u32" values starting at &target->thread.vr Now, given the declaration above, the vr field is only 32 * 16 bytes long, so this is not really legal C in any case. Even so, access to the vscr field happens to actually work correctly, as it immediately following vr (and there happens to be no padding). However, vrsave is accessed incorrectly on a 64-bit kernel: its value resides in the low 32 bits of the "unsigned long", and the copyout accesses the high 32 bits ... (The BUILD_BUG_ON doesn't help.) This has the effect of GDB always reading vrsave as 0, even after attempting to set it to some other value. (Every restart of the target process will apparently cause the upper 32 bit to be reset.) Any suggestions how to get this fixed? Thanks, Ulrich -- Dr. Ulrich Weigand GNU Toolchain for Linux on System z and Cell BE Ulrich.Weigand@de.ibm.com