From patchwork Wed Jun 17 14:23:28 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yao Qi X-Patchwork-Id: 7214 Received: (qmail 27392 invoked by alias); 17 Jun 2015 14:23:40 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 27374 invoked by uid 89); 17 Jun 2015 14:23:38 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-0.9 required=5.0 tests=AWL, BAYES_20, FREEMAIL_FROM, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=ham version=3.3.2 X-HELO: mail-pa0-f46.google.com Received: from mail-pa0-f46.google.com (HELO mail-pa0-f46.google.com) (209.85.220.46) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-GCM-SHA256 encrypted) ESMTPS; Wed, 17 Jun 2015 14:23:36 +0000 Received: by pacyx8 with SMTP id yx8so37260635pac.2 for ; Wed, 17 Jun 2015 07:23:34 -0700 (PDT) X-Received: by 10.70.56.4 with SMTP id w4mr11544601pdp.148.1434551014398; Wed, 17 Jun 2015 07:23:34 -0700 (PDT) Received: from E107787-LIN.cambridge.arm.com (gcc1-power7.osuosl.org. [140.211.15.137]) by mx.google.com with ESMTPSA id g10sm4968072pat.35.2015.06.17.07.23.32 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 17 Jun 2015 07:23:33 -0700 (PDT) From: Yao Qi X-Google-Original-From: Yao Qi To: gdb-patches@sourceware.org Subject: [PATCH] Convert have_ptrace_getregset to a tri-state boolean Date: Wed, 17 Jun 2015 15:23:28 +0100 Message-Id: <1434551008-1013-1-git-send-email-yao.qi@linaro.org> X-IsSubscribed: yes have_ptrace_getregset is a tri-state variable (-1, 0, 1), and we have some conditions like "if (have_ptrace_getregset)", which is not correct. I'll explain why it is not correct in the following example. This fix to this problem to replace the test (have_ptrace_getregset) to test (have_ptrace_getregset == 1) or (have_ptrace_getregset == -1) etc. However Doug thinks it hinders readability https://sourceware.org/ml/gdb-patches/2015-05/msg00692.html so I decide to add a new enum tribool and change have_ptrace_getregset to it, in order to make these tests more readable. have_ptrace_getregset is initialised to -1, and is adjusted to 0 or 1 in $ARCH_linux_read_description according to the capability of the kernel. However, it is possible that have_ptrace_getregset is used before it is set to 0 or 1, which means it is still -1. This is shown below. (gdb) run Starting program: gdb/testsuite/gdb.base/break Breakpoint 2, amd64_linux_fetch_inferior_registers (ops=0xceaa80, regcache=0xe72000, regnum=16) at git/gdb/amd64-linux-nat.c:128 128 { top?p have_ptrace_getregset $1 = TRIBOOL_UNKNOWN top?c Continuing. Breakpoint 2, amd64_linux_fetch_inferior_registers (ops=0xceaa80, regcache=0xe72000, regnum=16) at git/gdb/amd64-linux-nat.c:128 128 { top?c Continuing. Breakpoint 1, x86_linux_read_description (ops=0xceaa80) at git/gdb/x86-linux-nat.c:117 117 { PTRACE_GETREGSET command is used even GDB doesn't know whether PTRACE_GETREGSET is supported or not. It is wrong, but works on x86. However it doesn't work on arm-linux if the kernel doesn't support PTRACE_GETREGSET at all. We'll get: (gdb) run Starting program: gdb/testsuite/gdb.base/break warning: Unable to fetch general register. PC register is not available This patch fixes the error on arm-linux. Also regression tested on x86_64-linux. Is it OK? gdb: 2015-06-17 Yao Qi * amd64-linux-nat.c (amd64_linux_fetch_inferior_registers): Check whether have_ptrace_getregset is TRIBOOL_TRUE explicitly. (amd64_linux_store_inferior_registers): Likewise. * arm-linux-nat.c (fetch_fpregister): Likewise. (fetch_fpregs, store_fpregister): Likewise. (store_fpregister, store_fpregs): Likewise. (fetch_register, fetch_regs): Likewise. (store_register, store_regs): Likewise. (fetch_vfp_regs, store_vfp_regs): Likewise. (arm_linux_read_description): Check have_ptrace_getregset is TRIBOOL_UNKNOWN. Set have_ptrace_getregset to TRIBOOL_TRUE or TRIBOOL_FALSE. * i386-linux-nat.c (fetch_xstateregs): Check have_ptrace_getregset is not TRIBOOL_TRUE. (store_xstateregs): Likewise. * linux-nat.c (have_ptrace_getregset): Change its type to enum tribool. * linux-nat.h (tribool): New enum. * x86-linux-nat.c (x86_linux_read_description): Use enum tribool. Check whether have_ptrace_getregset is TRIBOOL_TRUE. --- gdb/amd64-linux-nat.c | 4 ++-- gdb/arm-linux-nat.c | 36 ++++++++++++++++++------------------ gdb/i386-linux-nat.c | 4 ++-- gdb/linux-nat.c | 2 +- gdb/linux-nat.h | 3 ++- gdb/x86-linux-nat.c | 10 +++++----- 6 files changed, 30 insertions(+), 29 deletions(-) diff --git a/gdb/amd64-linux-nat.c b/gdb/amd64-linux-nat.c index 30892ca..2e1b081 100644 --- a/gdb/amd64-linux-nat.c +++ b/gdb/amd64-linux-nat.c @@ -150,7 +150,7 @@ amd64_linux_fetch_inferior_registers (struct target_ops *ops, { elf_fpregset_t fpregs; - if (have_ptrace_getregset) + if (have_ptrace_getregset == TRIBOOL_TRUE) { char xstateregs[X86_XSTATE_MAX_SIZE]; struct iovec iov; @@ -209,7 +209,7 @@ amd64_linux_store_inferior_registers (struct target_ops *ops, { elf_fpregset_t fpregs; - if (have_ptrace_getregset) + if (have_ptrace_getregset == TRIBOOL_TRUE) { char xstateregs[X86_XSTATE_MAX_SIZE]; struct iovec iov; diff --git a/gdb/arm-linux-nat.c b/gdb/arm-linux-nat.c index 10aea07..c167bce 100644 --- a/gdb/arm-linux-nat.c +++ b/gdb/arm-linux-nat.c @@ -95,7 +95,7 @@ fetch_fpregister (struct regcache *regcache, int regno) tid = GET_THREAD_ID (inferior_ptid); /* Read the floating point state. */ - if (have_ptrace_getregset) + if (have_ptrace_getregset == TRIBOOL_TRUE) { struct iovec iov; @@ -136,7 +136,7 @@ fetch_fpregs (struct regcache *regcache) tid = GET_THREAD_ID (inferior_ptid); /* Read the floating point state. */ - if (have_ptrace_getregset) + if (have_ptrace_getregset == TRIBOOL_TRUE) { struct iovec iov; @@ -176,7 +176,7 @@ store_fpregister (const struct regcache *regcache, int regno) tid = GET_THREAD_ID (inferior_ptid); /* Read the floating point state. */ - if (have_ptrace_getregset) + if (have_ptrace_getregset == TRIBOOL_TRUE) { struct iovec iov; @@ -203,7 +203,7 @@ store_fpregister (const struct regcache *regcache, int regno) if (regno >= ARM_F0_REGNUM && regno <= ARM_F7_REGNUM) collect_nwfpe_register (regcache, regno, fp); - if (have_ptrace_getregset) + if (have_ptrace_getregset == TRIBOOL_TRUE) { struct iovec iov; @@ -235,7 +235,7 @@ store_fpregs (const struct regcache *regcache) tid = GET_THREAD_ID (inferior_ptid); /* Read the floating point state. */ - if (have_ptrace_getregset) + if (have_ptrace_getregset == TRIBOOL_TRUE) { elf_fpregset_t fpregs; struct iovec iov; @@ -263,7 +263,7 @@ store_fpregs (const struct regcache *regcache) if (REG_VALID == regcache_register_status (regcache, regno)) collect_nwfpe_register (regcache, regno, fp); - if (have_ptrace_getregset) + if (have_ptrace_getregset == TRIBOOL_TRUE) { struct iovec iov; @@ -294,7 +294,7 @@ fetch_register (struct regcache *regcache, int regno) /* Get the thread id for the ptrace call. */ tid = GET_THREAD_ID (inferior_ptid); - if (have_ptrace_getregset) + if (have_ptrace_getregset == TRIBOOL_TRUE) { struct iovec iov; @@ -347,7 +347,7 @@ fetch_regs (struct regcache *regcache) /* Get the thread id for the ptrace call. */ tid = GET_THREAD_ID (inferior_ptid); - if (have_ptrace_getregset) + if (have_ptrace_getregset == TRIBOOL_TRUE) { struct iovec iov; @@ -397,7 +397,7 @@ store_register (const struct regcache *regcache, int regno) tid = GET_THREAD_ID (inferior_ptid); /* Get the general registers from the process. */ - if (have_ptrace_getregset) + if (have_ptrace_getregset == TRIBOOL_TRUE) { struct iovec iov; @@ -424,7 +424,7 @@ store_register (const struct regcache *regcache, int regno) regcache_raw_collect (regcache, ARM_PC_REGNUM, (char *) ®s[ARM_PC_REGNUM]); - if (have_ptrace_getregset) + if (have_ptrace_getregset == TRIBOOL_TRUE) { struct iovec iov; @@ -453,7 +453,7 @@ store_regs (const struct regcache *regcache) tid = GET_THREAD_ID (inferior_ptid); /* Fetch the general registers. */ - if (have_ptrace_getregset) + if (have_ptrace_getregset == TRIBOOL_TRUE) { struct iovec iov; @@ -481,7 +481,7 @@ store_regs (const struct regcache *regcache) regcache_raw_collect (regcache, ARM_PS_REGNUM, (char *) ®s[ARM_CPSR_GREGNUM]); - if (have_ptrace_getregset) + if (have_ptrace_getregset == TRIBOOL_TRUE) { struct iovec iov; @@ -593,7 +593,7 @@ fetch_vfp_regs (struct regcache *regcache) /* Get the thread id for the ptrace call. */ tid = GET_THREAD_ID (inferior_ptid); - if (have_ptrace_getregset) + if (have_ptrace_getregset == TRIBOOL_TRUE) { struct iovec iov; @@ -629,7 +629,7 @@ store_vfp_regs (const struct regcache *regcache) /* Get the thread id for the ptrace call. */ tid = GET_THREAD_ID (inferior_ptid); - if (have_ptrace_getregset) + if (have_ptrace_getregset == TRIBOOL_TRUE) { struct iovec iov; @@ -653,7 +653,7 @@ store_vfp_regs (const struct regcache *regcache) regcache_raw_collect (regcache, ARM_FPSCR_REGNUM, (char *) regbuf + 32 * 8); - if (have_ptrace_getregset) + if (have_ptrace_getregset == TRIBOOL_TRUE) { struct iovec iov; @@ -797,7 +797,7 @@ arm_linux_read_description (struct target_ops *ops) { CORE_ADDR arm_hwcap = 0; - if (have_ptrace_getregset == -1) + if (have_ptrace_getregset == TRIBOOL_UNKNOWN) { elf_gregset_t gpregs; struct iovec iov; @@ -808,9 +808,9 @@ arm_linux_read_description (struct target_ops *ops) /* Check if PTRACE_GETREGSET works. */ if (ptrace (PTRACE_GETREGSET, tid, NT_PRSTATUS, &iov) < 0) - have_ptrace_getregset = 0; + have_ptrace_getregset = TRIBOOL_FALSE; else - have_ptrace_getregset = 1; + have_ptrace_getregset = TRIBOOL_TRUE; } if (target_auxv_search (ops, AT_HWCAP, &arm_hwcap) != 1) diff --git a/gdb/i386-linux-nat.c b/gdb/i386-linux-nat.c index 4401a2f..349ce68 100644 --- a/gdb/i386-linux-nat.c +++ b/gdb/i386-linux-nat.c @@ -327,7 +327,7 @@ fetch_xstateregs (struct regcache *regcache, int tid) char xstateregs[X86_XSTATE_MAX_SIZE]; struct iovec iov; - if (!have_ptrace_getregset) + if (have_ptrace_getregset != TRIBOOL_TRUE) return 0; iov.iov_base = xstateregs; @@ -350,7 +350,7 @@ store_xstateregs (const struct regcache *regcache, int tid, int regno) char xstateregs[X86_XSTATE_MAX_SIZE]; struct iovec iov; - if (!have_ptrace_getregset) + if (have_ptrace_getregset != TRIBOOL_TRUE) return 0; iov.iov_base = xstateregs; diff --git a/gdb/linux-nat.c b/gdb/linux-nat.c index 88f4e3e..be429f8 100644 --- a/gdb/linux-nat.c +++ b/gdb/linux-nat.c @@ -166,7 +166,7 @@ blocked. */ #endif /* Does the current host support PTRACE_GETREGSET? */ -int have_ptrace_getregset = -1; +enum tribool have_ptrace_getregset = TRIBOOL_UNKNOWN; /* The single-threaded native GNU/Linux target_ops. We save a pointer for the use of the multi-threaded target. */ diff --git a/gdb/linux-nat.h b/gdb/linux-nat.h index 3d766b5..cae263a 100644 --- a/gdb/linux-nat.h +++ b/gdb/linux-nat.h @@ -116,7 +116,8 @@ struct lwp_info extern struct lwp_info *lwp_list; /* Does the current host support PTRACE_GETREGSET? */ -extern int have_ptrace_getregset; +enum tribool { TRIBOOL_UNKNOWN = -1, TRIBOOL_FALSE = 0, TRIBOOL_TRUE = 1 }; +extern enum tribool have_ptrace_getregset; /* Iterate over each active thread (light-weight process). */ #define ALL_LWPS(LP) \ diff --git a/gdb/x86-linux-nat.c b/gdb/x86-linux-nat.c index 5d8f7c7..04917d0 100644 --- a/gdb/x86-linux-nat.c +++ b/gdb/x86-linux-nat.c @@ -162,13 +162,13 @@ x86_linux_read_description (struct target_ops *ops) if (ptrace (PTRACE_GETFPXREGS, tid, 0, (int) &fpxregs) < 0) { have_ptrace_getfpxregs = 0; - have_ptrace_getregset = 0; + have_ptrace_getregset = TRIBOOL_FALSE; return tdesc_i386_mmx_linux; } } #endif - if (have_ptrace_getregset == -1) + if (have_ptrace_getregset == TRIBOOL_UNKNOWN) { uint64_t xstateregs[(X86_XSTATE_SSE_SIZE / sizeof (uint64_t))]; struct iovec iov; @@ -179,10 +179,10 @@ x86_linux_read_description (struct target_ops *ops) /* Check if PTRACE_GETREGSET works. */ if (ptrace (PTRACE_GETREGSET, tid, (unsigned int) NT_X86_XSTATE, &iov) < 0) - have_ptrace_getregset = 0; + have_ptrace_getregset = TRIBOOL_FALSE; else { - have_ptrace_getregset = 1; + have_ptrace_getregset = TRIBOOL_TRUE; /* Get XCR0 from XSAVE extended state. */ xcr0 = xstateregs[(I386_LINUX_XSAVE_XCR0_OFFSET @@ -194,7 +194,7 @@ x86_linux_read_description (struct target_ops *ops) PTRACE_GETREGSET is not available then set xcr0_features_bits to zero so that the "no-features" descriptions are returned by the switches below. */ - if (have_ptrace_getregset) + if (have_ptrace_getregset == TRIBOOL_TRUE) xcr0_features_bits = xcr0 & X86_XSTATE_ALL_MASK; else xcr0_features_bits = 0;