From patchwork Mon Mar 19 15:30:46 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andreas Arnez X-Patchwork-Id: 26375 Received: (qmail 40523 invoked by alias); 19 Mar 2018 15:32:19 -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 40514 invoked by uid 89); 19 Mar 2018 15:32:19 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-24.7 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_LAZY_DOMAIN_SECURITY, RCVD_IN_DNSWL_LOW autolearn=ham version=3.3.2 spammy=tdb0 X-HELO: mx0a-001b2d01.pphosted.com Received: from mx0b-001b2d01.pphosted.com (HELO mx0a-001b2d01.pphosted.com) (148.163.158.5) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Mon, 19 Mar 2018 15:32:17 +0000 Received: from pps.filterd (m0098419.ppops.net [127.0.0.1]) by mx0b-001b2d01.pphosted.com (8.16.0.22/8.16.0.22) with SMTP id w2JFUdc4092335 for ; Mon, 19 Mar 2018 11:32:15 -0400 Received: from e06smtp15.uk.ibm.com (e06smtp15.uk.ibm.com [195.75.94.111]) by mx0b-001b2d01.pphosted.com with ESMTP id 2gtd1k8nkr-1 (version=TLSv1.2 cipher=AES256-SHA256 bits=256 verify=NOT) for ; Mon, 19 Mar 2018 11:32:14 -0400 Received: from localhost by e06smtp15.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Mon, 19 Mar 2018 15:32:13 -0000 Received: from b06cxnps4075.portsmouth.uk.ibm.com (9.149.109.197) by e06smtp15.uk.ibm.com (192.168.101.145) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Mon, 19 Mar 2018 15:32:11 -0000 Received: from d06av22.portsmouth.uk.ibm.com (d06av22.portsmouth.uk.ibm.com [9.149.105.58]) by b06cxnps4075.portsmouth.uk.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id w2JFWBp254591534 for ; Mon, 19 Mar 2018 15:32:11 GMT Received: from d06av22.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id C14B34C058 for ; Mon, 19 Mar 2018 15:25:20 +0000 (GMT) Received: from d06av22.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id A4AD04C04A for ; Mon, 19 Mar 2018 15:25:20 +0000 (GMT) Received: from oc1027705133.ibm.com (unknown [9.152.212.222]) by d06av22.portsmouth.uk.ibm.com (Postfix) with ESMTP for ; Mon, 19 Mar 2018 15:25:20 +0000 (GMT) From: Andreas Arnez To: gdb-patches@sourceware.org Subject: [PATCH 1/3] S390: Enable re-attaching with native-extended-gdbserver Date: Mon, 19 Mar 2018 16:30:46 +0100 In-Reply-To: <1521473488-27210-1-git-send-email-arnez@linux.vnet.ibm.com> References: <1521473488-27210-1-git-send-email-arnez@linux.vnet.ibm.com> X-TM-AS-GCONF: 00 x-cbid: 18031915-0020-0000-0000-00000406E83A X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 18031915-0021-0000-0000-0000429AFDC3 Message-Id: <1521473488-27210-2-git-send-email-arnez@linux.vnet.ibm.com> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:, , definitions=2018-03-19_09:, , signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 malwarescore=0 suspectscore=3 phishscore=0 bulkscore=0 spamscore=0 clxscore=1015 lowpriorityscore=0 impostorscore=0 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1709140000 definitions=main-1803190176 X-IsSubscribed: yes On s390x, when running attach.exp with native-extended-gdbserver, gdbserver crashes in find_regno like this: .../regcache.c:252: A problem internal to GDBserver has been detected. Unknown register tdb0 requested On the GDB side it looks like this: (gdb) attach 31568 Attaching to process 31568 Remote connection closed The test case attempts to attach to a new process via the already running gdbserver. Thus s390_arch_setup is called a second time, and that's where the problem occurs. In order to determine the word width (32 or 64 bits), s390_arch_setup reads the pswm register through the regcache. For that it uses a temporary tdesc which is supposed to work for all s390 targets, since the actual tdesc has not been determined yet. But in this second round this doesn't work, because s390_regsets has been updated already and now contains regsets not described by the temporary tdesc, such as the one containing tdb0. This is fixed by rearranging the logic in s390_arch_setup. gdb/gdbserver/ChangeLog: * linux-s390-low.c (s390_get_hwcap): Replace tdesc parameter by the word size. Add comment. (s390_get_wordsize): New function. (s390_arch_setup): No longer select a temporary tdesc to fetch the pswm with it. Instead, use s390_get_wordsize to determine the word size first and derive the correct tdesc from that directly. --- gdb/gdbserver/linux-s390-low.c | 97 +++++++++++++++++++++++------------------- 1 file changed, 53 insertions(+), 44 deletions(-) diff --git a/gdb/gdbserver/linux-s390-low.c b/gdb/gdbserver/linux-s390-low.c index 451f42c7c9..203accdaaa 100644 --- a/gdb/gdbserver/linux-s390-low.c +++ b/gdb/gdbserver/linux-s390-low.c @@ -486,10 +486,12 @@ s390_set_pc (struct regcache *regcache, CORE_ADDR newpc) } } +/* Get HWCAP from AUXV, using the given WORDSIZE. Return the HWCAP, or + zero if not found. */ + static unsigned long -s390_get_hwcap (const struct target_desc *tdesc) +s390_get_hwcap (int wordsize) { - int wordsize = register_size (tdesc, 0); gdb_byte *data = (gdb_byte *) alloca (2 * wordsize); int offset = 0; @@ -514,6 +516,27 @@ s390_get_hwcap (const struct target_desc *tdesc) return 0; } +/* Determine the word size for the given PID, in bytes. */ + +#ifdef __s390x__ +static int +s390_get_wordsize (int pid) +{ + errno = 0; + PTRACE_XFER_TYPE pswm = ptrace (PTRACE_PEEKUSER, pid, + (PTRACE_TYPE_ARG3) 0, + (PTRACE_TYPE_ARG4) 0); + if (errno != 0) { + warning (_("Couldn't determine word size, assuming 64-bit.\n")); + return 8; + } + /* Derive word size from extended addressing mode (PSW bit 31). */ + return pswm & (1L << 32) ? 8 : 4; +} +#else +#define s390_get_wordsize(pid) 4 +#endif + static int s390_check_regset (int pid, int regset, int regsize) { @@ -540,49 +563,32 @@ s390_arch_setup (void) const struct target_desc *tdesc; struct regset_info *regset; - /* Check whether the kernel supports extra register sets. */ + /* Determine word size and HWCAP. */ int pid = pid_of (current_thread); + int wordsize = s390_get_wordsize (pid); + unsigned long hwcap = s390_get_hwcap (wordsize); + + /* Check whether the kernel supports extra register sets. */ int have_regset_last_break = s390_check_regset (pid, NT_S390_LAST_BREAK, 8); int have_regset_system_call = s390_check_regset (pid, NT_S390_SYSTEM_CALL, 4); - int have_regset_tdb = s390_check_regset (pid, NT_S390_TDB, 256); - int have_regset_vxrs = s390_check_regset (pid, NT_S390_VXRS_LOW, 128) - && s390_check_regset (pid, NT_S390_VXRS_HIGH, 256); - int have_regset_gs = s390_check_regset (pid, NT_S390_GS_CB, 32) - && s390_check_regset (pid, NT_S390_GS_BC, 32); - - /* Assume 31-bit inferior process. */ - if (have_regset_system_call) - tdesc = tdesc_s390_linux32v2; - else if (have_regset_last_break) - tdesc = tdesc_s390_linux32v1; - else - tdesc = tdesc_s390_linux32; + int have_regset_tdb + = (s390_check_regset (pid, NT_S390_TDB, 256) + && (hwcap & HWCAP_S390_TE) != 0); + int have_regset_vxrs + = (s390_check_regset (pid, NT_S390_VXRS_LOW, 128) + && s390_check_regset (pid, NT_S390_VXRS_HIGH, 256) + && (hwcap & HWCAP_S390_VX) != 0); + int have_regset_gs + = (s390_check_regset (pid, NT_S390_GS_CB, 32) + && s390_check_regset (pid, NT_S390_GS_BC, 32) + && (hwcap & HWCAP_S390_GS) != 0); - /* On a 64-bit host, check the low bit of the (31-bit) PSWM - -- if this is one, we actually have a 64-bit inferior. */ { #ifdef __s390x__ - unsigned int pswm; - struct regcache *regcache = new_register_cache (tdesc); - - fetch_inferior_registers (regcache, find_regno (tdesc, "pswm")); - collect_register_by_name (regcache, "pswm", &pswm); - free_register_cache (regcache); - - if (pswm & 1) + if (wordsize == 8) { - if (have_regset_tdb) - have_regset_tdb = - (s390_get_hwcap (tdesc_s390x_linux64v2) & HWCAP_S390_TE) != 0; - if (have_regset_vxrs) - have_regset_vxrs = - (s390_get_hwcap (tdesc_s390x_linux64v2) & HWCAP_S390_VX) != 0; - if (have_regset_gs) - have_regset_gs = - (s390_get_hwcap (tdesc_s390x_linux64v2) & HWCAP_S390_GS) != 0; - if (have_regset_gs) tdesc = tdesc_s390x_gs_linux64; else if (have_regset_vxrs) @@ -602,16 +608,9 @@ s390_arch_setup (void) using the full 64-bit GPRs. */ else #endif - if (s390_get_hwcap (tdesc) & HWCAP_S390_HIGH_GPRS) + if (hwcap & HWCAP_S390_HIGH_GPRS) { have_hwcap_s390_high_gprs = 1; - if (have_regset_tdb) - have_regset_tdb = (s390_get_hwcap (tdesc) & HWCAP_S390_TE) != 0; - if (have_regset_vxrs) - have_regset_vxrs = (s390_get_hwcap (tdesc) & HWCAP_S390_VX) != 0; - if (have_regset_gs) - have_regset_gs = (s390_get_hwcap (tdesc) & HWCAP_S390_GS) != 0; - if (have_regset_gs) tdesc = tdesc_s390_gs_linux64; else if (have_regset_vxrs) @@ -626,6 +625,16 @@ s390_arch_setup (void) else tdesc = tdesc_s390_linux64; } + else + { + /* Assume 31-bit inferior process. */ + if (have_regset_system_call) + tdesc = tdesc_s390_linux32v2; + else if (have_regset_last_break) + tdesc = tdesc_s390_linux32v1; + else + tdesc = tdesc_s390_linux32; + } have_hwcap_s390_vx = have_regset_vxrs; }