From patchwork Mon Jan 30 04:45:11 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thiago Jung Bauermann X-Patchwork-Id: 63899 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id AB4F23858031 for ; Mon, 30 Jan 2023 04:46:04 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org AB4F23858031 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1675053964; bh=T556B1qDxApN1W5PgdX1i1AUoiIe1HwTGpyed7z3xJs=; h=To:Cc:Subject:Date:In-Reply-To:References:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From:Reply-To:From; b=xsBFyZKFnZonXvumOqZkEolW0iLSOdfZvtJuyNRejoJirY8NCmJg0AlPC2ojYIIsn fQRnrUnbOMxO/0cdpB+EuJeEyTdEiQvtjMiQF5giJ/ofnf1Hh7LDNEOQ+VjBmVxSHQ vvqKeQaB4jqmA0kOuzEtgIBGUWvjfcyElUwoQIhM= X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from mail-ot1-x329.google.com (mail-ot1-x329.google.com [IPv6:2607:f8b0:4864:20::329]) by sourceware.org (Postfix) with ESMTPS id 6E3CC3858D38 for ; Mon, 30 Jan 2023 04:45:40 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 6E3CC3858D38 Received: by mail-ot1-x329.google.com with SMTP id 70-20020a9d084c000000b0068bccf754f1so722294oty.7 for ; Sun, 29 Jan 2023 20:45:40 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=T556B1qDxApN1W5PgdX1i1AUoiIe1HwTGpyed7z3xJs=; b=MggqA/9ChqQW2HSIdandLfA8BY358xqxOtKU3xfcISBz7w2q5IglhP/WjipDkggYvg lH37+khhw3fDZ30u6U9SODh+0BiJLyUSud+DhjEpyKBX/V5uI/Vg9qSmXv5W4MCYpZgF 7jUbIh2b72lVccazWe5jRVeUgTlTu1YHvdodSrTHJHp1GqFVGIEt+MY+XTZPX3sLH3gb 8PkXAnAvPk+tpuQR3U40fqJXXj0K9JbiDEtRN7W5u+eYfVfa/m7B1ymc+NWsXzi3Gt7U nDsP8ThtrmOySCA54Ev+3Qiah/Tm5mu9wPJijI7XbVKWhg6JaICV9XqiLTKi0h0pBfTL cvXQ== X-Gm-Message-State: AO0yUKX2l7sF5OMQkaJ0r9bnfM+faTshFP0H0WwB75H3AEVu0zUC038x KHXUgLaAbSk2GkptqCcxXn5ALPVqtngeRAZN X-Google-Smtp-Source: AK7set/XX8snF8Y9m6rL3FIRuSiuTIgscBymbTgms+lPrlvF4s75OZz9DypIAHXx/5OskR0ZbmtDvA== X-Received: by 2002:a9d:7190:0:b0:68b:c44a:b616 with SMTP id o16-20020a9d7190000000b0068bc44ab616mr701544otj.19.1675053939728; Sun, 29 Jan 2023 20:45:39 -0800 (PST) Received: from localhost ([2804:14d:7e39:8470:df99:10bd:7dca:b2e9]) by smtp.gmail.com with ESMTPSA id j9-20020a056830270900b0068b6bcaa037sm4005484otu.40.2023.01.29.20.45.39 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 29 Jan 2023 20:45:39 -0800 (PST) To: gdb-patches@sourceware.org Cc: Thiago Jung Bauermann , Simon Marchi Subject: [PATCH v3 1/8] gdbserver: Add assert in find_register_by_number Date: Mon, 30 Jan 2023 04:45:11 +0000 Message-Id: <20230130044518.3322695-2-thiago.bauermann@linaro.org> X-Mailer: git-send-email 2.39.1 In-Reply-To: <20230130044518.3322695-1-thiago.bauermann@linaro.org> References: <20230130044518.3322695-1-thiago.bauermann@linaro.org> MIME-Version: 1.0 X-Spam-Status: No, score=-11.8 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Thiago Jung Bauermann via Gdb-patches From: Thiago Jung Bauermann Reply-To: Thiago Jung Bauermann Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org Sender: "Gdb-patches" It helped me during development, catching bugs closer to when they actually happened. Also remove the equivalent gdb_assert in regcache_raw_read_unsigned, since it's checking the same condition a few frames above. Suggested-By: Simon Marchi --- gdbserver/regcache.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gdbserver/regcache.cc b/gdbserver/regcache.cc index 3aeefcc79a37..7b896a19767d 100644 --- a/gdbserver/regcache.cc +++ b/gdbserver/regcache.cc @@ -199,6 +199,8 @@ regcache_cpy (struct regcache *dst, struct regcache *src) static const struct gdb::reg & find_register_by_number (const struct target_desc *tdesc, int n) { + gdb_assert (n >= 0 && n < tdesc->reg_defs.size ()); + return tdesc->reg_defs[n]; } @@ -440,8 +442,6 @@ regcache_raw_read_unsigned (struct regcache *regcache, int regnum, int size; gdb_assert (regcache != NULL); - gdb_assert (regnum >= 0 - && regnum < regcache->tdesc->reg_defs.size ()); size = register_size (regcache->tdesc, regnum); From patchwork Mon Jan 30 04:45:12 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thiago Jung Bauermann X-Patchwork-Id: 63900 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id E2459385B521 for ; Mon, 30 Jan 2023 04:46:10 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org E2459385B521 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1675053970; bh=JepbkwFWVJByiZ356UhK3ZNpjNQo502mir4pQ+piYkw=; h=To:Cc:Subject:Date:In-Reply-To:References:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From:Reply-To:From; b=AfZD7CRNBhqTfh/+qsaUeFrZ8B0NqU6Rd1nE/XxyESFChqoZ4bRDqa0NO8sorjGED JwTQEGEZcfE0SYqkFby/gYaZbdBBVj9TZKMIOQrW58X2cJOPv1QkawCJ4MRt3V+MGv +aRuXJu3+dvRrZew199DGfI2dpxGX/b88ivvFdN0= X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from mail-oa1-x36.google.com (mail-oa1-x36.google.com [IPv6:2001:4860:4864:20::36]) by sourceware.org (Postfix) with ESMTPS id A241E3858C60 for ; Mon, 30 Jan 2023 04:45:43 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org A241E3858C60 Received: by mail-oa1-x36.google.com with SMTP id 586e51a60fabf-142b72a728fso13621649fac.9 for ; Sun, 29 Jan 2023 20:45:43 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=JepbkwFWVJByiZ356UhK3ZNpjNQo502mir4pQ+piYkw=; b=rLS4HpZPOBh42wcb2asshX2VBh26sD+kRfRnAODz76ufFR9JL0uY4kU1SVsYRb6NtI XcVMyKjhTJXy3jgvx+Al9JxKxPMpIFyS0zRlZ2fhPeJmB+4vyk75lvvMUIYVUYvJ/7wi W5UYAXbS2WsdCqQh7h66zyG5oWhn/lImIBIRhYi+UFv2/ups0nfQ5MiSb3RYGZnVWH8p YFbwBrmatuqDS81Sh5HoFFxJlJohbT9Nih8eQHLoUrrf5r7gBkNJZJFAbiVp297KECtg CRq8WLmKbelI9u2NaG1h2MURuJrUbQMUHKJigoYewDVsmkTzicTcCyBf7Z3AbOQJEBjG mulw== X-Gm-Message-State: AFqh2koPFPxZTHdB8Q2FkutmgFcekUTRnfbpws28Cp2nszcJwISEhuD0 kDhaz1bIuRutEjpeXGAWSvUwkZ6H0EwYxkkF X-Google-Smtp-Source: AK7set+4FEsIymWIHfvFK+bFfSgCwu3QPvLnFsOB/6nTuQX8E7QvRuBeOgx2ucNke59Q29GGEc7axA== X-Received: by 2002:a05:6871:28f:b0:160:3234:62d9 with SMTP id i15-20020a056871028f00b00160323462d9mr13850223oae.22.1675053942922; Sun, 29 Jan 2023 20:45:42 -0800 (PST) Received: from localhost ([2804:14d:7e39:8470:df99:10bd:7dca:b2e9]) by smtp.gmail.com with ESMTPSA id gr22-20020a056870aa9600b00130d060ce80sm4821720oab.31.2023.01.29.20.45.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 29 Jan 2023 20:45:42 -0800 (PST) To: gdb-patches@sourceware.org Cc: Thiago Jung Bauermann , Simon Marchi Subject: [PATCH v3 2/8] gdbserver: Add PID parameter to linux_get_auxv and linux_get_hwcap Date: Mon, 30 Jan 2023 04:45:12 +0000 Message-Id: <20230130044518.3322695-3-thiago.bauermann@linaro.org> X-Mailer: git-send-email 2.39.1 In-Reply-To: <20230130044518.3322695-1-thiago.bauermann@linaro.org> References: <20230130044518.3322695-1-thiago.bauermann@linaro.org> MIME-Version: 1.0 X-Spam-Status: No, score=-11.4 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Thiago Jung Bauermann via Gdb-patches From: Thiago Jung Bauermann Reply-To: Thiago Jung Bauermann Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org Sender: "Gdb-patches" This patch doesn't change gdbserver behaviour, but after later changes are made it avoids a null pointer dereference when HWCAP needs to be obtained for a specific process while current_thread is nullptr. Fixing linux_read_auxv, linux_get_hwcap and linux_get_hwcap2 to take a PID parameter seems more correct than setting current_thread in one particular code path. Changes are propagated to allow passing the new parameter through the call chain. Approved-By: Simon Marchi --- gdbserver/linux-aarch64-low.cc | 7 ++++--- gdbserver/linux-arm-low.cc | 2 +- gdbserver/linux-low.cc | 18 +++++++++--------- gdbserver/linux-low.h | 9 ++++----- gdbserver/linux-ppc-low.cc | 6 +++--- gdbserver/linux-s390-low.cc | 2 +- gdbserver/netbsd-low.cc | 4 +--- gdbserver/netbsd-low.h | 2 +- gdbserver/server.cc | 3 ++- gdbserver/target.cc | 4 ++-- gdbserver/target.h | 4 ++-- 11 files changed, 30 insertions(+), 31 deletions(-) diff --git a/gdbserver/linux-aarch64-low.cc b/gdbserver/linux-aarch64-low.cc index 3c09e086afee..2ed6e95562c5 100644 --- a/gdbserver/linux-aarch64-low.cc +++ b/gdbserver/linux-aarch64-low.cc @@ -846,12 +846,13 @@ aarch64_target::low_arch_setup () if (is_elf64) { struct aarch64_features features; + int pid = current_thread->id.pid (); features.vq = aarch64_sve_get_vq (tid); /* A-profile PAC is 64-bit only. */ - features.pauth = linux_get_hwcap (8) & AARCH64_HWCAP_PACA; + features.pauth = linux_get_hwcap (pid, 8) & AARCH64_HWCAP_PACA; /* A-profile MTE is 64-bit only. */ - features.mte = linux_get_hwcap2 (8) & HWCAP2_MTE; + features.mte = linux_get_hwcap2 (pid, 8) & HWCAP2_MTE; features.tls = aarch64_tls_register_count (tid); current_process ()->tdesc = aarch64_linux_read_description (features); @@ -3322,7 +3323,7 @@ aarch64_target::supports_memory_tagging () #endif } - return (linux_get_hwcap2 (8) & HWCAP2_MTE) != 0; + return (linux_get_hwcap2 (current_thread->id.pid (), 8) & HWCAP2_MTE) != 0; } bool diff --git a/gdbserver/linux-arm-low.cc b/gdbserver/linux-arm-low.cc index 98ba0e02524b..5975b44af0ae 100644 --- a/gdbserver/linux-arm-low.cc +++ b/gdbserver/linux-arm-low.cc @@ -958,7 +958,7 @@ get_next_pcs_syscall_next_pc (struct arm_get_next_pcs *self) static const struct target_desc * arm_read_description (void) { - unsigned long arm_hwcap = linux_get_hwcap (4); + unsigned long arm_hwcap = linux_get_hwcap (current_thread->id.pid (), 4); if (arm_hwcap & HWCAP_IWMMXT) return arm_linux_read_description (ARM_FP_TYPE_IWMMXT); diff --git a/gdbserver/linux-low.cc b/gdbserver/linux-low.cc index 7e1de3978933..5cd22824e470 100644 --- a/gdbserver/linux-low.cc +++ b/gdbserver/linux-low.cc @@ -5483,12 +5483,11 @@ linux_process_target::supports_read_auxv () to debugger memory starting at MYADDR. */ int -linux_process_target::read_auxv (CORE_ADDR offset, unsigned char *myaddr, - unsigned int len) +linux_process_target::read_auxv (int pid, CORE_ADDR offset, + unsigned char *myaddr, unsigned int len) { char filename[PATH_MAX]; int fd, n; - int pid = lwpid_of (current_thread); xsnprintf (filename, sizeof filename, "/proc/%d/auxv", pid); @@ -6982,14 +6981,15 @@ linux_get_pc_64bit (struct regcache *regcache) /* See linux-low.h. */ int -linux_get_auxv (int wordsize, CORE_ADDR match, CORE_ADDR *valp) +linux_get_auxv (int pid, int wordsize, CORE_ADDR match, CORE_ADDR *valp) { gdb_byte *data = (gdb_byte *) alloca (2 * wordsize); int offset = 0; gdb_assert (wordsize == 4 || wordsize == 8); - while (the_target->read_auxv (offset, data, 2 * wordsize) == 2 * wordsize) + while (the_target->read_auxv (pid, offset, data, 2 * wordsize) + == 2 * wordsize) { if (wordsize == 4) { @@ -7019,20 +7019,20 @@ linux_get_auxv (int wordsize, CORE_ADDR match, CORE_ADDR *valp) /* See linux-low.h. */ CORE_ADDR -linux_get_hwcap (int wordsize) +linux_get_hwcap (int pid, int wordsize) { CORE_ADDR hwcap = 0; - linux_get_auxv (wordsize, AT_HWCAP, &hwcap); + linux_get_auxv (pid, wordsize, AT_HWCAP, &hwcap); return hwcap; } /* See linux-low.h. */ CORE_ADDR -linux_get_hwcap2 (int wordsize) +linux_get_hwcap2 (int pid, int wordsize) { CORE_ADDR hwcap2 = 0; - linux_get_auxv (wordsize, AT_HWCAP2, &hwcap2); + linux_get_auxv (pid, wordsize, AT_HWCAP2, &hwcap2); return hwcap2; } diff --git a/gdbserver/linux-low.h b/gdbserver/linux-low.h index aebfe05707e5..221de85aa2ee 100644 --- a/gdbserver/linux-low.h +++ b/gdbserver/linux-low.h @@ -178,7 +178,7 @@ class linux_process_target : public process_stratum_target bool supports_read_auxv () override; - int read_auxv (CORE_ADDR offset, unsigned char *myaddr, + int read_auxv (int pid, CORE_ADDR offset, unsigned char *myaddr, unsigned int len) override; int insert_point (enum raw_bkpt_type type, CORE_ADDR addr, @@ -946,17 +946,16 @@ extern int have_ptrace_getregset; *VALP and return 1. If not found or if there is an error, return 0. */ -int linux_get_auxv (int wordsize, CORE_ADDR match, - CORE_ADDR *valp); +int linux_get_auxv (int pid, int wordsize, CORE_ADDR match, CORE_ADDR *valp); /* Fetch the AT_HWCAP entry from the auxv vector, where entries are length WORDSIZE. If no entry was found, return zero. */ -CORE_ADDR linux_get_hwcap (int wordsize); +CORE_ADDR linux_get_hwcap (int pid, int wordsize); /* Fetch the AT_HWCAP2 entry from the auxv vector, where entries are length WORDSIZE. If no entry was found, return zero. */ -CORE_ADDR linux_get_hwcap2 (int wordsize); +CORE_ADDR linux_get_hwcap2 (int pid, int wordsize); #endif /* GDBSERVER_LINUX_LOW_H */ diff --git a/gdbserver/linux-ppc-low.cc b/gdbserver/linux-ppc-low.cc index fdf74727e392..f8dd770b8eb3 100644 --- a/gdbserver/linux-ppc-low.cc +++ b/gdbserver/linux-ppc-low.cc @@ -894,8 +894,8 @@ ppc_target::low_arch_setup () /* The value of current_process ()->tdesc needs to be set for this call. */ - ppc_hwcap = linux_get_hwcap (features.wordsize); - ppc_hwcap2 = linux_get_hwcap2 (features.wordsize); + ppc_hwcap = linux_get_hwcap (current_thread->id.pid (), features.wordsize); + ppc_hwcap2 = linux_get_hwcap2 (current_thread->id.pid (), features.wordsize); features.isa205 = ppc_linux_has_isa205 (ppc_hwcap); @@ -1097,7 +1097,7 @@ is_elfv2_inferior (void) const struct target_desc *tdesc = current_process ()->tdesc; int wordsize = register_size (tdesc, 0); - if (!linux_get_auxv (wordsize, AT_PHDR, &phdr)) + if (!linux_get_auxv (current_thread->id.pid (), wordsize, AT_PHDR, &phdr)) return def_res; /* Assume ELF header is at the beginning of the page where program headers diff --git a/gdbserver/linux-s390-low.cc b/gdbserver/linux-s390-low.cc index b3ccdff3e57f..48f64ef7bb3b 100644 --- a/gdbserver/linux-s390-low.cc +++ b/gdbserver/linux-s390-low.cc @@ -592,7 +592,7 @@ s390_target::low_arch_setup () /* Determine word size and HWCAP. */ int pid = pid_of (current_thread); int wordsize = s390_get_wordsize (pid); - unsigned long hwcap = linux_get_hwcap (wordsize); + unsigned long hwcap = linux_get_hwcap (pid, wordsize); /* Check whether the kernel supports extra register sets. */ int have_regset_last_break diff --git a/gdbserver/netbsd-low.cc b/gdbserver/netbsd-low.cc index 15afa36d1152..4defd79eee47 100644 --- a/gdbserver/netbsd-low.cc +++ b/gdbserver/netbsd-low.cc @@ -581,11 +581,9 @@ netbsd_read_auxv(pid_t pid, void *offs, void *addr, size_t len) to debugger memory starting at MYADDR. */ int -netbsd_process_target::read_auxv (CORE_ADDR offset, +netbsd_process_target::read_auxv (int pid, CORE_ADDR offset, unsigned char *myaddr, unsigned int len) { - pid_t pid = pid_of (current_thread); - return netbsd_read_auxv (pid, (void *) (intptr_t) offset, myaddr, len); } diff --git a/gdbserver/netbsd-low.h b/gdbserver/netbsd-low.h index daefc302785e..050b43fc54f4 100644 --- a/gdbserver/netbsd-low.h +++ b/gdbserver/netbsd-low.h @@ -77,7 +77,7 @@ class netbsd_process_target : public process_stratum_target bool supports_read_auxv () override; - int read_auxv (CORE_ADDR offset, unsigned char *myaddr, + int read_auxv (int pid, CORE_ADDR offset, unsigned char *myaddr, unsigned int len) override; bool supports_hardware_single_step () override; diff --git a/gdbserver/server.cc b/gdbserver/server.cc index d802e8b4a341..21fb51a45d16 100644 --- a/gdbserver/server.cc +++ b/gdbserver/server.cc @@ -1443,7 +1443,8 @@ handle_qxfer_auxv (const char *annex, if (annex[0] != '\0' || current_thread == NULL) return -1; - return the_target->read_auxv (offset, readbuf, len); + return the_target->read_auxv (current_thread->id.pid (), offset, readbuf, + len); } /* Handle qXfer:exec-file:read. */ diff --git a/gdbserver/target.cc b/gdbserver/target.cc index 24b8e2160138..b4f8e9f1efb6 100644 --- a/gdbserver/target.cc +++ b/gdbserver/target.cc @@ -344,8 +344,8 @@ process_stratum_target::supports_read_auxv () } int -process_stratum_target::read_auxv (CORE_ADDR offset, unsigned char *myaddr, - unsigned int len) +process_stratum_target::read_auxv (int pid, CORE_ADDR offset, + unsigned char *myaddr, unsigned int len) { gdb_assert_not_reached ("target op read_auxv not supported"); } diff --git a/gdbserver/target.h b/gdbserver/target.h index eea651c30b4b..1b0caa98c56a 100644 --- a/gdbserver/target.h +++ b/gdbserver/target.h @@ -172,10 +172,10 @@ class process_stratum_target /* Return true if the read_auxv target op is supported. */ virtual bool supports_read_auxv (); - /* Read auxiliary vector data from the inferior process. + /* Read auxiliary vector data from the process with pid PID. Read LEN bytes at OFFSET into a buffer at MYADDR. */ - virtual int read_auxv (CORE_ADDR offset, unsigned char *myaddr, + virtual int read_auxv (int pid, CORE_ADDR offset, unsigned char *myaddr, unsigned int len); /* Returns true if GDB Z breakpoint type TYPE is supported, false From patchwork Mon Jan 30 04:45:13 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thiago Jung Bauermann X-Patchwork-Id: 63901 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 146323858024 for ; Mon, 30 Jan 2023 04:46:35 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 146323858024 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1675053995; bh=w9kXP2cLk5NPU9hKtelhqMdBZZQ/tAa4sSU+CQJPUWE=; h=To:Cc:Subject:Date:In-Reply-To:References:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From:Reply-To:From; b=lNQwxERpUHqgtaNgsIA4IEhg7pckdorioQ5luUGDzekamMkBZJxQaev3Ea49y1/wb czYZ6fkGWsQvGQVz8sdyRRgoPrRyGckd29Gqo8cXgASKVBdPP8Bx2C7IZi5IfpvjjK Rus7/tqHGMTRZX13x7NQ70M8VA8yQeArWG0Bg1VU= X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from mail-ot1-x335.google.com (mail-ot1-x335.google.com [IPv6:2607:f8b0:4864:20::335]) by sourceware.org (Postfix) with ESMTPS id 36A943858436 for ; Mon, 30 Jan 2023 04:45:46 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 36A943858436 Received: by mail-ot1-x335.google.com with SMTP id a1-20020a056830008100b006864df3b1f8so4228197oto.3 for ; Sun, 29 Jan 2023 20:45:46 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=w9kXP2cLk5NPU9hKtelhqMdBZZQ/tAa4sSU+CQJPUWE=; b=Acj1Uq1bTJtCzzxffZfFj7dFZLZoLvKSoeJ+X6Cvp8Tu2n/4CvYaKmqNSkWh9CXEEz SEcyVKxEEeqIXNjq37biBbdSq86jo0E4oGus4qyx4MV1VLfg6K2iDXahRolnYFtwV33u bCsitkxjCMCPNgy2EKUqDMKzBpjeG8UyKjSkoYzQwbzcC2MPSdg37ve1OuQOIhkAwHF5 tdu/7+2Pip/E+c8yBOGUmoN6Vt4Lg7gV61kyGmY9/joNhHiOGpmqnOybTCgoiVIAl2cI FbR1hVnZUM19Bq9hQZKWUIzICE6LmfV/Meg4dR3qxYEQKfEt2I4wC0DYY6SQWVeaHNYW mANw== X-Gm-Message-State: AO0yUKW7gYnBY36leYSP+BvSIoUJjXEmi3g6QvzjBOrtfeXnsC2WS+2A X/v7FN9CkrpUPZPiB0J6zDJyVCFVBcrtXfMk X-Google-Smtp-Source: AK7set9kuPxWHddkoJvp2ezrq9RaurZi/hMgwbuROGMW0zqygI43rBv1jMwoy8OthTFpez3MgM4Wng== X-Received: by 2002:a9d:6546:0:b0:68b:cc93:28b with SMTP id q6-20020a9d6546000000b0068bcc93028bmr1647254otl.29.1675053945598; Sun, 29 Jan 2023 20:45:45 -0800 (PST) Received: from localhost ([2804:14d:7e39:8470:df99:10bd:7dca:b2e9]) by smtp.gmail.com with ESMTPSA id v2-20020a0568301bc200b0068bbc9e7cc9sm2510067ota.53.2023.01.29.20.45.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 29 Jan 2023 20:45:45 -0800 (PST) To: gdb-patches@sourceware.org Cc: Thiago Jung Bauermann , Luis Machado , Simon Marchi Subject: [PATCH v3 3/8] gdbserver/linux-aarch64: Factor out function to get aarch64_features Date: Mon, 30 Jan 2023 04:45:13 +0000 Message-Id: <20230130044518.3322695-4-thiago.bauermann@linaro.org> X-Mailer: git-send-email 2.39.1 In-Reply-To: <20230130044518.3322695-1-thiago.bauermann@linaro.org> References: <20230130044518.3322695-1-thiago.bauermann@linaro.org> MIME-Version: 1.0 X-Spam-Status: No, score=-11.5 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Thiago Jung Bauermann via Gdb-patches From: Thiago Jung Bauermann Reply-To: Thiago Jung Bauermann Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org Sender: "Gdb-patches" It will be used in a subsequent commit. There's no functional change. Reviewed-by: Luis Machado Approved-By: Simon Marchi --- gdbserver/linux-aarch64-low.cc | 36 ++++++++++++++++++++++------------ 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/gdbserver/linux-aarch64-low.cc b/gdbserver/linux-aarch64-low.cc index 2ed6e95562c5..92c621e5548c 100644 --- a/gdbserver/linux-aarch64-low.cc +++ b/gdbserver/linux-aarch64-low.cc @@ -675,6 +675,28 @@ aarch64_target::low_delete_process (arch_process_info *info) xfree (info); } +/* Matches HWCAP_PACA in kernel header arch/arm64/include/uapi/asm/hwcap.h. */ +#define AARCH64_HWCAP_PACA (1 << 30) + +/* Obtain the architectural features available in the given THREAD. */ + +static struct aarch64_features +aarch64_get_arch_features (const thread_info *thread) +{ + struct aarch64_features features; + int pid = thread->id.pid (); + int tid = thread->id.lwp (); + + features.vq = aarch64_sve_get_vq (tid); + /* A-profile PAC is 64-bit only. */ + features.pauth = linux_get_hwcap (pid, 8) & AARCH64_HWCAP_PACA; + /* A-profile MTE is 64-bit only. */ + features.mte = linux_get_hwcap2 (pid, 8) & HWCAP2_MTE; + features.tls = aarch64_tls_register_count (tid); + + return features; +} + void aarch64_target::low_new_thread (lwp_info *lwp) { @@ -827,9 +849,6 @@ aarch64_adjust_register_sets (const struct aarch64_features &features) } } -/* Matches HWCAP_PACA in kernel header arch/arm64/include/uapi/asm/hwcap.h. */ -#define AARCH64_HWCAP_PACA (1 << 30) - /* Implementation of linux target ops method "low_arch_setup". */ void @@ -845,15 +864,8 @@ aarch64_target::low_arch_setup () if (is_elf64) { - struct aarch64_features features; - int pid = current_thread->id.pid (); - - features.vq = aarch64_sve_get_vq (tid); - /* A-profile PAC is 64-bit only. */ - features.pauth = linux_get_hwcap (pid, 8) & AARCH64_HWCAP_PACA; - /* A-profile MTE is 64-bit only. */ - features.mte = linux_get_hwcap2 (pid, 8) & HWCAP2_MTE; - features.tls = aarch64_tls_register_count (tid); + struct aarch64_features features + = aarch64_get_arch_features (current_thread); current_process ()->tdesc = aarch64_linux_read_description (features); From patchwork Mon Jan 30 04:45:14 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thiago Jung Bauermann X-Patchwork-Id: 63902 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id B33073858288 for ; Mon, 30 Jan 2023 04:46:38 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org B33073858288 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1675053998; bh=y9V/RcC6gO/K/p4J18q4SdPtNqfxcreCPFqK4dwS/zc=; h=To:Cc:Subject:Date:In-Reply-To:References:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From:Reply-To:From; b=kPTtRH8iHEwxxHipFvRAKi+GpuyCkhpdd5UGQzDHx8aVxKhiDZTjKRmoBgMJml7BO NXDj+UsSn6/7euiO/wgGaD9QiZSGRKTzMSovEZ5rIA653OYmYCXnxY1KY9xDiwIt+p 5SF12IkSetz2C879oLHZNE8XpXlI+ZCXRRQyJJ9E= X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from mail-oa1-x36.google.com (mail-oa1-x36.google.com [IPv6:2001:4860:4864:20::36]) by sourceware.org (Postfix) with ESMTPS id DCC4E385841C for ; Mon, 30 Jan 2023 04:45:48 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org DCC4E385841C Received: by mail-oa1-x36.google.com with SMTP id 586e51a60fabf-1442977d77dso13639182fac.6 for ; Sun, 29 Jan 2023 20:45:48 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=y9V/RcC6gO/K/p4J18q4SdPtNqfxcreCPFqK4dwS/zc=; b=2GKRAy0e9/733gzJn1Pz+WJOdRtC8inoN/wMnwJhwqQgCpOPsLZWr+NQJyrI0hW4ZE SVOTzkJurfTyz6qrCPD8PZklxv9Xoz/8pObjgwpTcg5EzgJ506MtilF5N1sTWVc7Rifo 6vkIWtjLNJE+LhOiDT7FF+rqY14Slxpow02RgEBnNbW49o7KMiZCoALpTIk4w87I0L+8 hsz7COiazlICckJeYaXuQyWakqX1fVOYfwWn+qHanrXVY4Whzd/BClZIuBRkWL+0kcjs SxeSNHWtG7G4SH7P3MxPQaxdyvPsVIwUTeiMqbVCtVEJAAZe6aUwbuFlY2eHu7A7y04j 6C8g== X-Gm-Message-State: AO0yUKWKk1/pUucORieHp1qT9EXoWyz7bhqphrM+YGh1wTQqMs99DGFV U36DKoCTVMcXOeQhf+EiTDG6Vl4lRzflqISH X-Google-Smtp-Source: AK7set/YIPL0LeGIjquQVYiJ81pez5tL5V0qx/us6esPc48EZAoiiJxfpl757LrUTvmhu28ygO7UEA== X-Received: by 2002:a05:6870:a994:b0:163:3231:3f93 with SMTP id ep20-20020a056870a99400b0016332313f93mr10512036oab.39.1675053948240; Sun, 29 Jan 2023 20:45:48 -0800 (PST) Received: from localhost ([2804:14d:7e39:8470:df99:10bd:7dca:b2e9]) by smtp.gmail.com with ESMTPSA id et10-20020a0568705cca00b00163263f84dasm4701940oab.12.2023.01.29.20.45.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 29 Jan 2023 20:45:47 -0800 (PST) To: gdb-patches@sourceware.org Cc: Thiago Jung Bauermann , Luis Machado Subject: [PATCH v3 4/8] gdbserver/linux-aarch64: When thread stops, update its target description Date: Mon, 30 Jan 2023 04:45:14 +0000 Message-Id: <20230130044518.3322695-5-thiago.bauermann@linaro.org> X-Mailer: git-send-email 2.39.1 In-Reply-To: <20230130044518.3322695-1-thiago.bauermann@linaro.org> References: <20230130044518.3322695-1-thiago.bauermann@linaro.org> MIME-Version: 1.0 X-Spam-Status: No, score=-11.6 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Thiago Jung Bauermann via Gdb-patches From: Thiago Jung Bauermann Reply-To: Thiago Jung Bauermann Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org Sender: "Gdb-patches" This change prepares gdbserver to support remotely debugging programs in aarch64-linux where different threads have different SVE vector lengths. It allows gdbserver to support different inferior threads having different target descriptions. To that end, a tdesc field is added to struct thread_info. If it's nullptr (the default) it means that the thread uses the target description stored in struct process_info and thus gdbserver behaviour is unchanged. The get_thread_tdesc method is added to the linux_process_target class to allow aarch64-linux code to probe the inferior's vq register and provide a thread-specific target description reflecting the new vector length. After this change, all targets except SVE-supporting aarch64-linux will still use per-process target descriptions. Reviewed-by: Luis Machado --- gdbserver/gdbthread.h | 4 ++++ gdbserver/linux-aarch64-low.cc | 31 +++++++++++++++++++++++++++++++ gdbserver/linux-low.cc | 17 +++++++++++++++++ gdbserver/linux-low.h | 6 ++++++ gdbserver/regcache.cc | 10 ++++++---- gdbserver/regcache.h | 4 ++++ gdbserver/tdesc.cc | 13 ++++++++++++- gdbserver/tdesc.h | 5 +++++ 8 files changed, 85 insertions(+), 5 deletions(-) diff --git a/gdbserver/gdbthread.h b/gdbserver/gdbthread.h index 493e1dbf6cb6..5b5ba6f8e521 100644 --- a/gdbserver/gdbthread.h +++ b/gdbserver/gdbthread.h @@ -80,6 +80,10 @@ struct thread_info /* Branch trace target information for this thread. */ struct btrace_target_info *btrace = nullptr; + + /* Target description for this thread. Only present if it's different + from the one in process_info. */ + const struct target_desc *tdesc = nullptr; }; extern std::list all_threads; diff --git a/gdbserver/linux-aarch64-low.cc b/gdbserver/linux-aarch64-low.cc index 92c621e5548c..69765ee90db3 100644 --- a/gdbserver/linux-aarch64-low.cc +++ b/gdbserver/linux-aarch64-low.cc @@ -99,6 +99,9 @@ protected: void low_arch_setup () override; + const struct target_desc * + get_thread_tdesc (const thread_info *thread) override; + bool low_cannot_fetch_register (int regno) override; bool low_cannot_store_register (int regno) override; @@ -184,6 +187,9 @@ struct arch_process_info same for each thread, it is reasonable for the data to live here. */ struct aarch64_debug_reg_state debug_reg_state; + + /* Whether this process has the Scalable Vector Extension available. */ + bool has_sve; }; /* Return true if the size of register 0 is 8 byte. */ @@ -869,6 +875,9 @@ aarch64_target::low_arch_setup () current_process ()->tdesc = aarch64_linux_read_description (features); + if (features.vq > 0) + current_process ()->priv->arch_private->has_sve = true; + /* Adjust the register sets we should use for this particular set of features. */ aarch64_adjust_register_sets (features); @@ -879,6 +888,28 @@ aarch64_target::low_arch_setup () aarch64_linux_get_debug_reg_capacity (lwpid_of (current_thread)); } +/* Implementation of linux target ops method "get_thread_tdesc". */ + +const struct target_desc * +aarch64_target::get_thread_tdesc (const thread_info *thread) +{ + const struct process_info *process = get_thread_process (thread); + + /* Only inferiors with SVE need a thread-specific target description. */ + if (!process->priv->arch_private->has_sve) + return nullptr; + + const struct aarch64_features features = aarch64_get_arch_features (thread); + const struct target_desc *tdesc = aarch64_linux_read_description (features); + + /* If the target description we just found is the same as the process-wide + one, there's no need to set a thread-specific one. */ + if (tdesc == process->tdesc) + return nullptr; + + return tdesc; +} + /* Implementation of linux target ops method "get_regs_info". */ const regs_info * diff --git a/gdbserver/linux-low.cc b/gdbserver/linux-low.cc index 5cd22824e470..47916009ebaf 100644 --- a/gdbserver/linux-low.cc +++ b/gdbserver/linux-low.cc @@ -483,6 +483,12 @@ linux_process_target::arch_setup_thread (thread_info *thread) low_arch_setup (); } +const struct target_desc * +linux_process_target::get_thread_tdesc (const thread_info *thread) +{ + return nullptr; +} + int linux_process_target::handle_extended_wait (lwp_info **orig_event_lwp, int wstat) @@ -2348,6 +2354,17 @@ linux_process_target::filter_event (int lwpid, int wstat) return; } } + else + { + /* Give the arch code an opportunity to set the thread's target + description. */ + const struct target_desc *new_tdesc = get_thread_tdesc (thread); + if (new_tdesc != thread->tdesc) + { + free_register_cache_thread (thread); + thread->tdesc = new_tdesc; + } + } } if (WIFSTOPPED (wstat) && child->must_set_ptrace_flags) diff --git a/gdbserver/linux-low.h b/gdbserver/linux-low.h index 221de85aa2ee..b52eb23cc444 100644 --- a/gdbserver/linux-low.h +++ b/gdbserver/linux-low.h @@ -604,6 +604,12 @@ class linux_process_target : public process_stratum_target /* Architecture-specific setup for the current thread. */ virtual void low_arch_setup () = 0; + /* Allows arch-specific code to set the thread's target description when the + inferior stops. Returns nullptr if no thread-specific target description + is necessary. */ + virtual const struct target_desc * + get_thread_tdesc (const thread_info *thread); + /* Return false if we can fetch/store the register, true if we cannot fetch/store the register. */ virtual bool low_cannot_fetch_register (int regno) = 0; diff --git a/gdbserver/regcache.cc b/gdbserver/regcache.cc index 7b896a19767d..fb60e2c9c399 100644 --- a/gdbserver/regcache.cc +++ b/gdbserver/regcache.cc @@ -39,11 +39,11 @@ get_thread_regcache (struct thread_info *thread, int fetch) have. */ if (regcache == NULL) { - struct process_info *proc = get_thread_process (thread); + const target_desc *tdesc = get_thread_target_desc (thread); - gdb_assert (proc->tdesc != NULL); + gdb_assert (tdesc != nullptr); - regcache = new_register_cache (proc->tdesc); + regcache = new_register_cache (tdesc); set_thread_regcache_data (thread, regcache); } @@ -270,7 +270,9 @@ find_regno (const struct target_desc *tdesc, const char *name) internal_error ("Unknown register %s requested", name); } -static void +/* See regcache.h. */ + +void free_register_cache_thread (struct thread_info *thread) { struct regcache *regcache = thread_regcache_data (thread); diff --git a/gdbserver/regcache.h b/gdbserver/regcache.h index 7248bcf5808a..4beea0139cd6 100644 --- a/gdbserver/regcache.h +++ b/gdbserver/regcache.h @@ -79,6 +79,10 @@ void free_register_cache (struct regcache *regcache); void regcache_invalidate_thread (struct thread_info *); +/* Invalidate and release the register cache of the given THREAD. */ + +void free_register_cache_thread (struct thread_info *thread); + /* Invalidate cached registers for all threads of the given process. */ void regcache_invalidate_pid (int pid); diff --git a/gdbserver/tdesc.cc b/gdbserver/tdesc.cc index 2c7257c458f4..e3339dde4d6c 100644 --- a/gdbserver/tdesc.cc +++ b/gdbserver/tdesc.cc @@ -123,13 +123,24 @@ copy_target_description (struct target_desc *dest, dest->xmltarget = src->xmltarget; } +/* See tdesc.h. */ + +const struct target_desc * +get_thread_target_desc (const struct thread_info *thread) +{ + if (thread->tdesc != nullptr) + return thread->tdesc; + + return get_thread_process (thread)->tdesc; +} + const struct target_desc * current_target_desc (void) { if (current_thread == NULL) return &default_description; - return current_process ()->tdesc; + return get_thread_target_desc (current_thread); } /* An empty structure. */ diff --git a/gdbserver/tdesc.h b/gdbserver/tdesc.h index 7fe7d0d8eb30..71cc5b51c84e 100644 --- a/gdbserver/tdesc.h +++ b/gdbserver/tdesc.h @@ -88,6 +88,11 @@ void copy_target_description (struct target_desc *dest, void init_target_desc (struct target_desc *tdesc, const char **expedite_regs); +/* Return the target description corresponding to the given THREAD. */ + +const struct target_desc * + get_thread_target_desc (const struct thread_info *thread); + /* Return the current inferior's target description. Never returns NULL. */ From patchwork Mon Jan 30 04:45:15 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thiago Jung Bauermann X-Patchwork-Id: 63904 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 3948B3858000 for ; Mon, 30 Jan 2023 04:47:07 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 3948B3858000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1675054027; bh=IQ95ekTUCaN+rfTW/X3s2aPzrr9MulFxsjrNtivs69k=; h=To:Cc:Subject:Date:In-Reply-To:References:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From:Reply-To:From; b=AuVPEy2QpeGNR1spgi1wS55RUEahrnkQSprA9LS2fvgOuDgxiS2Z62DHsupLWE/Xm W7F9Ar2lwlcgitxPXNBhmlJk1eJQ62RNqVIsdvrkXwUMOrhWmrE5kDtJxu0d+Bl2EE yaosuts/X23MVeO6Kf9Rtty1Tgvp0bIqXwaVIL5I= X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from mail-oa1-x29.google.com (mail-oa1-x29.google.com [IPv6:2001:4860:4864:20::29]) by sourceware.org (Postfix) with ESMTPS id B625C3858416 for ; Mon, 30 Jan 2023 04:45:51 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org B625C3858416 Received: by mail-oa1-x29.google.com with SMTP id 586e51a60fabf-163adf0cfc4so2398740fac.7 for ; Sun, 29 Jan 2023 20:45:51 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=IQ95ekTUCaN+rfTW/X3s2aPzrr9MulFxsjrNtivs69k=; b=rhDNmKXGFINqGlRH0Hs3vrvQSebfN3Oxq+EAhW+5IY+kjazoPAZUKT5k6d9PepGomN 6+84Ldn3LPsCB85FGIVuLF6leKuMX5PnrivK74ZQGnY/4hf1XOK7uUryfV97aMiivrC9 42M/xUtIfOUEg39D3msl/E2JjHNRJ1/pqcWBq/QWKzaE6h6/LCNE99qwTvbh0jW6w6oq Z5dU28JCcsoVP7lQIGHChhODW67OfZPSJomhpFh/j9Pg9kxhXhc4jJq96CBembBaIRXJ JWu4PAvPdraTQXULAP5emPwMMXVDoNV4UvX3/p25Y53JNhssnofzXoDTqRxw37glpwLF 9/KQ== X-Gm-Message-State: AO0yUKWjzUdbvYGneS5XI1eaJ85i3VQF1ZHVZq6I4gjQoq+HvFpHJp5I 8fFv92tzGur4hww5+XGCuVzjmt/zJH/LiSYI X-Google-Smtp-Source: AK7set9cKyKekYQ/i78yF+Ur2TuaU2ovY1JQs48pqUnSWqxQt7uyKDNeh8xC/Y0MRYJR38LoVlllMg== X-Received: by 2002:a05:6870:ac1e:b0:163:28c9:beef with SMTP id kw30-20020a056870ac1e00b0016328c9beefmr10486233oab.59.1675053951011; Sun, 29 Jan 2023 20:45:51 -0800 (PST) Received: from localhost ([2804:14d:7e39:8470:df99:10bd:7dca:b2e9]) by smtp.gmail.com with ESMTPSA id pa13-20020a0568701d0d00b0015f9cc16ef7sm4734670oab.46.2023.01.29.20.45.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 29 Jan 2023 20:45:50 -0800 (PST) To: gdb-patches@sourceware.org Cc: Thiago Jung Bauermann , Simon Marchi Subject: [PATCH v3 5/8] gdbserver: Transmit target description ID in thread list and stop reply Date: Mon, 30 Jan 2023 04:45:15 +0000 Message-Id: <20230130044518.3322695-6-thiago.bauermann@linaro.org> X-Mailer: git-send-email 2.39.1 In-Reply-To: <20230130044518.3322695-1-thiago.bauermann@linaro.org> References: <20230130044518.3322695-1-thiago.bauermann@linaro.org> MIME-Version: 1.0 X-Spam-Status: No, score=-11.7 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Thiago Jung Bauermann via Gdb-patches From: Thiago Jung Bauermann Reply-To: Thiago Jung Bauermann Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org Sender: "Gdb-patches" Now that an inferior thread can have a different target description than its process, there needs to be a way to communicate this target description to GDB. So add the concept of a target description ID to the remote protocol, which is used to reference them and allows them to be transferred only once over the wire. The ID is an unsigned integer, and is sent in the 'T AA n1:r1;n2:r2;...' stop reply packet as a new 'n:r' pair, where n is "tdesc" and "r" is an unsigned integer containing the ID. It is also sent in the threads list XML in the response of a qXfer:threads:read request. The ID is sent as a new "tdesc" attribute of the node. To request the target description XML of a given ID, GDB sends the qXfer:features:read request with "target-id-%u.xml" as the annex, where %u is the target description ID. Suggested-By: Simon Marchi Reviewed-by: Luis Machado --- gdb/doc/gdb.texinfo | 27 ++++++++++++++++--- gdbserver/remote-utils.cc | 57 +++++++++++++++++++++++++++++++++++++++ gdbserver/remote-utils.h | 9 +++++++ gdbserver/server.cc | 17 ++++++++++-- gdbserver/server.h | 4 +++ 5 files changed, 109 insertions(+), 5 deletions(-) diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index 9c0018ea5c14..fbf7e59853b5 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -42030,6 +42030,10 @@ the stopped thread, as specified in @ref{thread-id syntax}. If @var{n} is @samp{core}, then @var{r} is the hexadecimal number of the core on which the stop event was detected. +@item +If @var{n} is @samp{tdesc}, then @var{r} is the hexadecimal number of +the target description ID (@pxref{Target Description ID}). + @item If @var{n} is a recognized @dfn{stop reason}, it describes a more specific event that stopped the target. The currently defined stop @@ -46546,7 +46550,7 @@ the following structure: @smallexample - + ... description ... @@ -46556,8 +46560,10 @@ Each @samp{thread} element must have the @samp{id} attribute that identifies the thread (@pxref{thread-id syntax}). The @samp{core} attribute, if present, specifies which processor core the thread was last executing on. The @samp{name} attribute, if -present, specifies the human-readable name of the thread. The content -of the of @samp{thread} element is interpreted as human-readable +present, specifies the human-readable name of the thread. The +@samp{tdesc} attribute, if present, specifies the target description +ID of the thread (@pxref{Target Description ID}). The content of +the @samp{thread} element is interpreted as human-readable auxiliary information. The @samp{handle} attribute, if present, is a hex encoded representation of the thread handle. @@ -46767,6 +46773,8 @@ descriptions are accurate, and that @value{GDBN} understands them. target descriptions. @xref{Expat}. @menu +* Target Description ID:: Referencing different descriptions in the + remote protocol. * Retrieving Descriptions:: How descriptions are fetched from a target. * Target Description Format:: The contents of a target description. * Predefined Target Types:: Standard types available for target @@ -46775,6 +46783,14 @@ target descriptions. @xref{Expat}. * Standard Target Features:: Features @value{GDBN} knows about. @end menu +@node Target Description ID +@section Target Description ID + +In cases where a remote target supports threads having different +target descriptions than their parent process, the remote protocol +assigns a non-negative integer to each target description to reference +it in the communication between the host and the target. + @node Retrieving Descriptions @section Retrieving Descriptions @@ -46787,6 +46803,11 @@ qXfer}). The @var{annex} in the @samp{qXfer} packet will be XML document, of the form described in @ref{Target Description Format}. +If target description IDs are being used (@pxref{Target Description ID}), +@value{GDBN} can retrieve a target description with a given ID by using +@samp{target-id-ID.xml} as the @var{annex}, where @var{ID} is the +non-negative integer identifier of the desired target description. + Alternatively, you can specify a file to read for the target description. If a file is set, the target will not be queried. The commands to specify a file are: diff --git a/gdbserver/remote-utils.cc b/gdbserver/remote-utils.cc index 80310bc2c709..baff899307cc 100644 --- a/gdbserver/remote-utils.cc +++ b/gdbserver/remote-utils.cc @@ -1049,6 +1049,53 @@ outreg (struct regcache *regcache, int regno, char *buf) return buf; } +/* See remote-utils.h. */ + +unsigned int +get_tdesc_rsp_id (const target_desc *tdesc) +{ + client_state &cs = get_client_state (); + unsigned int i; + + for (i = 0; i < cs.tdescs.size (); i++) + if (cs.tdescs[i] == tdesc) + return i; + + cs.tdescs.push_back (tdesc); + + return i; +} + +/* See remote-utils.h. */ + +const target_desc * +get_tdesc_from_rsp_id (unsigned int id) +{ + client_state &cs = get_client_state (); + + if (id >= cs.tdescs.size ()) + return nullptr; + + return cs.tdescs[id]; +} + +/* Return the ID as used in the remote protocol for the target descriptor of the + given PTID. */ + +static unsigned int +get_tdesc_rsp_id (ptid_t ptid) +{ + const thread_info *thread = find_thread_ptid (ptid); + const target_desc *tdesc; + + if (thread == nullptr) + tdesc = find_process_pid (ptid.pid ())->tdesc; + else + tdesc = get_thread_target_desc (thread); + + return get_tdesc_rsp_id (tdesc); +} + void prepare_resume_reply (char *buf, ptid_t ptid, const target_waitstatus &status) { @@ -1241,6 +1288,16 @@ prepare_resume_reply (char *buf, ptid_t ptid, const target_waitstatus &status) buf += strlen (buf); current_process ()->dlls_changed = false; } + + if (current_thread->tdesc != nullptr + && current_thread->tdesc != current_process ()->tdesc) + { + sprintf (buf, "tdesc:"); + buf += strlen (buf); + sprintf (buf, "%x", get_tdesc_rsp_id (ptid)); + strcat (buf, ";"); + buf += strlen (buf); + } } break; case TARGET_WAITKIND_EXITED: diff --git a/gdbserver/remote-utils.h b/gdbserver/remote-utils.h index cb2d6c346c99..61ef80b4dad7 100644 --- a/gdbserver/remote-utils.h +++ b/gdbserver/remote-utils.h @@ -75,4 +75,13 @@ int relocate_instruction (CORE_ADDR *to, CORE_ADDR oldloc); void monitor_output (const char *msg); +/* Return the ID as used in the remote protocol for the given target + descriptor. */ + +unsigned int get_tdesc_rsp_id (const target_desc *tdesc); + +/* Return the target description corresponding to the remote protocol ID. */ + +const target_desc *get_tdesc_from_rsp_id (unsigned int id); + #endif /* GDBSERVER_REMOTE_UTILS_H */ diff --git a/gdbserver/server.cc b/gdbserver/server.cc index 21fb51a45d16..2d1062f98468 100644 --- a/gdbserver/server.cc +++ b/gdbserver/server.cc @@ -976,7 +976,15 @@ handle_general_set (char *own_buf) static const char * get_features_xml (const char *annex) { - const struct target_desc *desc = current_target_desc (); + const struct target_desc *desc; + unsigned int id; + + if (strcmp (annex, "target.xml") == 0) + desc = current_target_desc (); + else if (sscanf (annex, "target-id-%u.xml", &id) == 1) + desc = get_tdesc_from_rsp_id (id); + else + desc = nullptr; /* `desc->xmltarget' defines what to return when looking for the "target.xml" file. Its contents can either be verbatim XML code @@ -986,7 +994,7 @@ get_features_xml (const char *annex) This variable is set up from the auto-generated init_registers_... routine for the current target. */ - if (strcmp (annex, "target.xml") == 0) + if (desc != nullptr) { const char *ret = tdesc_get_features_xml (desc); @@ -1664,6 +1672,11 @@ handle_qxfer_threads_worker (thread_info *thread, struct buffer *buffer) if (name != NULL) buffer_xml_printf (buffer, " name=\"%s\"", name); + if (thread->tdesc != nullptr + && thread->tdesc != get_thread_process (thread)->tdesc) + buffer_xml_printf (buffer, " tdesc=\"%u\"", + get_tdesc_rsp_id (thread->tdesc)); + if (handle_status) { char *handle_s = (char *) alloca (handle_len * 2 + 1); diff --git a/gdbserver/server.h b/gdbserver/server.h index 7997d1a32e6e..58be5027795b 100644 --- a/gdbserver/server.h +++ b/gdbserver/server.h @@ -193,6 +193,10 @@ struct client_state /* If true, memory tagging features are supported. */ bool memory_tagging_feature = false; + /* The target descriptions that have been communicated to the client. The + index of a target description in this vector is the ID used to reference it + in the remote protocol. */ + std::vector tdescs; }; client_state &get_client_state (); From patchwork Mon Jan 30 04:45:16 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thiago Jung Bauermann X-Patchwork-Id: 63905 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 82E8E3858D38 for ; Mon, 30 Jan 2023 04:47:34 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 82E8E3858D38 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1675054054; bh=aDmfr8moEGlKeX79D9kihvQnYDRwBCH3CBQz7Qx3euc=; h=To:Cc:Subject:Date:In-Reply-To:References:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From:Reply-To:From; b=ZxFLcJOFVu9vEze4Kt082qnR6T3pRq5pv5XYKzavDX9vRfTu5Dyu70E3xijTaX51a edI3Wtf760vWdmMpka7ACQS2+MLfVAcFPWVFOH2TBdVWYvBZVjJeSkQ14HoHQAyiDE naA0yQm3nZD+n0vsi85NefdvzA3Qw4kQbHJPNWIU= X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from mail-ot1-x335.google.com (mail-ot1-x335.google.com [IPv6:2607:f8b0:4864:20::335]) by sourceware.org (Postfix) with ESMTPS id 7DDC13858C2C for ; Mon, 30 Jan 2023 04:45:54 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 7DDC13858C2C Received: by mail-ot1-x335.google.com with SMTP id a1-20020a056830008100b006864df3b1f8so4228235oto.3 for ; Sun, 29 Jan 2023 20:45:54 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=aDmfr8moEGlKeX79D9kihvQnYDRwBCH3CBQz7Qx3euc=; b=XRAh+SOvfs3f0f8SMJRpPQklP54tfrnJBMhAANaSrgWQVCcSa662aB7tJu+U/7MsF9 /XqW7CxvLtsOoCi4LzLiG5h3eJB5lQ3uVfBTL/sS+/kRegiTxAOyhNnUJJNQb7oqZJlv W12Psw76WdHLBkhgYeGgC/GuEHevm3NfKlA1ORmj7ntpA57GbRbQsN1zCOjptooEzV4W xwGstST2qFHhhHL1n2nPR9BUga/vLHJMFivXDcWppsITTGqzFMpiK+5A+dDCr7C+Y+xV fNXlMIw5nkXnqxz1iVWcTXPhIhYrTN3ljSEmxmZ1vjOeGSnsRsqBycEiaAdhNEknaVcr xYaw== X-Gm-Message-State: AFqh2kqyQkiy/IWw8dcB/huc+KsBfFMOFd+vTQ0slL9KyFjaZfhLnNQQ p85WrTRasJESr9X4FPUy1kmDtW3qOzjMqiyw X-Google-Smtp-Source: AMrXdXskTik8qrHgmbT/+rsyBYqZJ+opXp2z42B1g6B6r3QHPKP6Q1b3jPW0kNpGf79hiaNR9TSUxw== X-Received: by 2002:a05:6830:1457:b0:670:6b50:fde3 with SMTP id w23-20020a056830145700b006706b50fde3mr24811534otp.26.1675053954093; Sun, 29 Jan 2023 20:45:54 -0800 (PST) Received: from localhost ([2804:14d:7e39:8470:df99:10bd:7dca:b2e9]) by smtp.gmail.com with ESMTPSA id g22-20020a9d6496000000b00684bede5359sm5046906otl.42.2023.01.29.20.45.53 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 29 Jan 2023 20:45:53 -0800 (PST) To: gdb-patches@sourceware.org Cc: Thiago Jung Bauermann Subject: [PATCH v3 6/8] gdb/remote: Parse tdesc field in stop reply and threads list XML Date: Mon, 30 Jan 2023 04:45:16 +0000 Message-Id: <20230130044518.3322695-7-thiago.bauermann@linaro.org> X-Mailer: git-send-email 2.39.1 In-Reply-To: <20230130044518.3322695-1-thiago.bauermann@linaro.org> References: <20230130044518.3322695-1-thiago.bauermann@linaro.org> MIME-Version: 1.0 X-Spam-Status: No, score=-11.7 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Thiago Jung Bauermann via Gdb-patches From: Thiago Jung Bauermann Reply-To: Thiago Jung Bauermann Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org Sender: "Gdb-patches" gdbserver added the concept of target description IDs to the remote protocol and uses them in the threads list XML and in the 'T AA' stop reply packet. It also allows fetching a target description with a given ID. This patch is for the GDB-side support. The target descriptions obtained this way aren't yet used but will be in the next patch. In the DTD for the threads list XML, add a "tdesc" attribute to the node. A tdesc_id field is added to the stop_reply and thread_item structs. An m_remote member is added to the threads_listing_context struct, and to simplify its initialisation a constructor is added as well. This is to provide access to the remote state in start_thread. Finally, the remote_state object keeps a map of the target descriptions that have been received from the target, keyed by their ID. There are also methods to get a target description given its ID, and to fetch target descriptions for IDs that were mentioned by gdbserver but not yet retrieved by GDB. The latter gets called after parsing the response of qXfer:threads:read and of the stop reply packet. --- gdb/features/threads.dtd | 1 + gdb/remote.c | 85 +++++++++++++++++++++++++++++++++++++++- gdb/xml-tdesc.c | 27 ++++++++++--- gdb/xml-tdesc.h | 6 +++ 4 files changed, 112 insertions(+), 7 deletions(-) diff --git a/gdb/features/threads.dtd b/gdb/features/threads.dtd index 036b2ce58837..3102d1352978 100644 --- a/gdb/features/threads.dtd +++ b/gdb/features/threads.dtd @@ -11,3 +11,4 @@ + diff --git a/gdb/remote.c b/gdb/remote.c index 218bca30d047..f1d1944414c3 100644 --- a/gdb/remote.c +++ b/gdb/remote.c @@ -80,6 +80,7 @@ #include #include "async-event.h" #include "gdbsupport/selftest.h" +#include "xml-tdesc.h" /* The remote target. */ @@ -238,6 +239,16 @@ class remote_state /* Get the remote arch state for GDBARCH. */ struct remote_arch_state *get_remote_arch_state (struct gdbarch *gdbarch); + /* Add new ID to the target description list. The corresponding XML will be + requested soon. */ + void add_tdesc_id (ULONGEST id); + + /* Get the target description corresponding to remote protocol ID. */ + const target_desc *get_tdesc (ULONGEST id) const; + + /* Get the target descriptions we don't know about from the target. */ + void fetch_unknown_tdescs (remote_target *remote); + public: /* data */ /* A buffer to use for incoming packets, and its current size. The @@ -387,6 +398,10 @@ class remote_state support multi-process. */ std::unordered_map m_arch_states; + + /* The target descriptions that have been received from the target. The key + is the ID used to reference it in the remote protocol. */ + std::unordered_map m_tdescs; }; static const target_info remote_target_info = { @@ -1009,6 +1024,9 @@ struct stop_reply : public notif_event fetch them is avoided). */ std::vector regcache; + /* The target description ID communicated in the stop reply packet. */ + gdb::optional tdesc_id; + enum target_stop_reason stop_reason; CORE_ADDR watch_data_address; @@ -3689,6 +3707,9 @@ struct thread_item /* The thread handle associated with the thread. */ gdb::byte_vector thread_handle; + + /* The ID of the thread's target description, if provided. */ + gdb::optional tdesc_id; }; /* Context passed around to the various methods listing remote @@ -3697,6 +3718,12 @@ struct thread_item struct threads_listing_context { + threads_listing_context (remote_target *remote) + : m_remote (remote) + {} + + DISABLE_COPY_AND_ASSIGN (threads_listing_context); + /* Return true if this object contains an entry for a thread with ptid PTID. */ @@ -3733,6 +3760,9 @@ struct threads_listing_context /* The threads found on the remote target. */ std::vector items; + + /* The remote target associated with this context. */ + remote_target *m_remote; }; static int @@ -3814,6 +3844,13 @@ start_thread (struct gdb_xml_parser *parser, attr = xml_find_attribute (attributes, "handle"); if (attr != NULL) item.thread_handle = hex2bin ((const char *) attr->value.get ()); + + attr = xml_find_attribute (attributes, "tdesc"); + if (attr != NULL) + { + item.tdesc_id = *(ULONGEST *) attr->value.get (); + data->m_remote->get_remote_state ()->add_tdesc_id (*item.tdesc_id); + } } static void @@ -3833,6 +3870,7 @@ const struct gdb_xml_attribute thread_attributes[] = { { "core", GDB_XML_AF_OPTIONAL, gdb_xml_parse_attr_ulongest, NULL }, { "name", GDB_XML_AF_OPTIONAL, NULL, NULL }, { "handle", GDB_XML_AF_OPTIONAL, NULL, NULL }, + { "tdesc", GDB_XML_AF_OPTIONAL, gdb_xml_parse_attr_ulongest, NULL }, { NULL, GDB_XML_AF_NONE, NULL, NULL } }; @@ -3870,6 +3908,7 @@ remote_target::remote_get_threads_with_qxfer (threads_listing_context *context) { gdb_xml_parse_quick (_("threads"), "threads.dtd", threads_elements, xml->data (), context); + get_remote_state ()->fetch_unknown_tdescs (this); } return 1; @@ -3937,7 +3976,7 @@ has_single_non_exited_thread (inferior *inf) void remote_target::update_thread_list () { - struct threads_listing_context context; + struct threads_listing_context context (this); int got_list = 0; /* We have a few different mechanisms to fetch the thread list. Try @@ -7223,7 +7262,11 @@ remote_notif_stop_parse (remote_target *remote, struct notif_client *self, const char *buf, struct notif_event *event) { - remote->remote_parse_stop_reply (buf, (struct stop_reply *) event); + struct stop_reply *stop_reply = (struct stop_reply *) event; + + remote->remote_parse_stop_reply (buf, stop_reply); + + stop_reply->rs->fetch_unknown_tdescs (remote); } static void @@ -7516,6 +7559,36 @@ strprefix (const char *p, const char *pend, const char *prefix) return *prefix == '\0'; } +void +remote_state::add_tdesc_id (ULONGEST id) +{ + /* Check whether the ID was already added. */ + if (m_tdescs.find (id) != m_tdescs.cend ()) + return; + + m_tdescs[id] = nullptr; +} + +const target_desc * +remote_state::get_tdesc (ULONGEST id) const +{ + auto found = m_tdescs.find (id); + + /* Check if the given ID was already provided. */ + if (found == m_tdescs.cend ()) + return nullptr; + + return found->second; +} + +void +remote_state::fetch_unknown_tdescs (remote_target *remote) +{ + for (auto &pair : m_tdescs) + if (pair.second == nullptr) + m_tdescs[pair.first] = target_read_description_xml (remote, pair.first); +} + /* Parse the stop reply in BUF. Either the function succeeds, and the result is stored in EVENT, or throws an error. */ @@ -7674,6 +7747,14 @@ Packet: '%s'\n"), event->ws.set_thread_created (); p = strchrnul (p1 + 1, ';'); } + else if (strprefix (p, p1, "tdesc")) + { + ULONGEST tdesc_id; + + p = unpack_varlen_hex (++p1, &tdesc_id); + event->rs->add_tdesc_id (tdesc_id); + event->tdesc_id = tdesc_id; + } else { ULONGEST pnum; diff --git a/gdb/xml-tdesc.c b/gdb/xml-tdesc.c index ba7154c5d56f..302863e12365 100644 --- a/gdb/xml-tdesc.c +++ b/gdb/xml-tdesc.c @@ -698,14 +698,13 @@ fetch_available_features_from_target (const char *name, target_ops *ops) } -/* Read an XML target description using OPS. Parse it, and return the - parsed description. */ +/* Actual implementation of the target_read_description_xml variants. */ -const struct target_desc * -target_read_description_xml (struct target_ops *ops) +static const struct target_desc * +target_read_description_xml (struct target_ops *ops, const char *desc_name) { gdb::optional tdesc_str - = fetch_available_features_from_target ("target.xml", ops); + = fetch_available_features_from_target (desc_name, ops); if (!tdesc_str) return NULL; @@ -717,6 +716,24 @@ target_read_description_xml (struct target_ops *ops) return tdesc_parse_xml (tdesc_str->data (), fetch_another); } +/* See xml-tdesc.h. */ + +const struct target_desc * +target_read_description_xml (struct target_ops *ops) +{ + return target_read_description_xml (ops, "target.xml"); +} + +/* See xml-tdesc.h. */ + +const struct target_desc * +target_read_description_xml (struct target_ops *ops, ULONGEST id) +{ + std::string desc_name = string_printf ("target-id-%" PRIu64 ".xml", id); + + return target_read_description_xml (ops, desc_name.c_str ()); +} + /* Fetches an XML target description using OPS, processing includes, but not parsing it. Used to dump whole tdesc as a single XML file. */ diff --git a/gdb/xml-tdesc.h b/gdb/xml-tdesc.h index 0fbfc7e043e9..c7cc97c5dfc0 100644 --- a/gdb/xml-tdesc.h +++ b/gdb/xml-tdesc.h @@ -38,6 +38,12 @@ const struct target_desc *file_read_description_xml (const char *filename); const struct target_desc *target_read_description_xml (struct target_ops *); +/* Read an XML target description with the given ID using OPS. Parse it, and + return the parsed description. */ + +const struct target_desc *target_read_description_xml (struct target_ops *ops, + ULONGEST id); + /* Fetches an XML target description using OPS, processing includes, but not parsing it. Used to dump whole tdesc as a single XML file. Returns the description on success, and a disengaged optional From patchwork Mon Jan 30 04:45:17 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thiago Jung Bauermann X-Patchwork-Id: 63906 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 855193858C00 for ; Mon, 30 Jan 2023 04:48:02 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 855193858C00 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1675054082; bh=XLjR37BNOVovrIx3FEqUM4ircjroJyrANS2UB3MsPHQ=; h=To:Cc:Subject:Date:In-Reply-To:References:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From:Reply-To:From; b=OO7rrCEarsEFqCGrX1ndT1ZMWOFmqrD+bOjhF8y0tvxfkb3KVGU1enXjX77qgLG3R 0HRw2s7Hd4+D/usHhPKICFietzVeW5UDmPjYjJz6QkPztWlOeQG5v0gACTCExXXJ9Y i8KXbKWq3qCLWgmC6oZk9J3kN7YSEI3FRSIx9oUw= X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from mail-oo1-xc30.google.com (mail-oo1-xc30.google.com [IPv6:2607:f8b0:4864:20::c30]) by sourceware.org (Postfix) with ESMTPS id 36D2D3858413 for ; Mon, 30 Jan 2023 04:45:58 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 36D2D3858413 Received: by mail-oo1-xc30.google.com with SMTP id z138-20020a4a4990000000b005175b8ae66cso352893ooa.6 for ; Sun, 29 Jan 2023 20:45:58 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=XLjR37BNOVovrIx3FEqUM4ircjroJyrANS2UB3MsPHQ=; b=uYlZ2Bsi7MZWDL7y/Gv89B+tNB0LOtubxvQEs0Lu3oX9neK0mC7Eo0cc50Ul3wlUbr P6wtG4k0xjalLRA/ZUeT7S/tGa8qETO/zS63Bjs7DhpR2xuTZMWfjBn2+CXDIyldnNdq j9ngP/b/DjX+XAK2rkNBiAvz89mXVC01XtpjZUszKJC+5LR9xTeW4KcNAacIiZHUFtOA R3pKbZMrRhRiYtmR14IoGqOwfsFDtJ1amfx6kZuOMAr5/2uKX/Vdx1cY3MYGxthSlBJ0 o/IP1uDknNxEFaGJMe6DbsaUBvpTHRXPagL3cDzSmA+Mua8dZOnVEv5GFHXcVgMa+RQa dz7g== X-Gm-Message-State: AO0yUKUes1+5o481V5ln5f84Ckzhh6zXiU2ZCR/XIe6IBz9egbeMOkg8 z9fyLMe7dQ5gp27neUnK1rxDl09o8ZlVIJdm X-Google-Smtp-Source: AK7set8v8HBnr4I0C4QoTF8NveI4CjDyUWTF8JzqDZlIc9fGYybEKFBldExH6rxHJ+Vj2/AsZ/95vQ== X-Received: by 2002:a4a:52c9:0:b0:4f2:8f8:d2ff with SMTP id d192-20020a4a52c9000000b004f208f8d2ffmr3102478oob.6.1675053957406; Sun, 29 Jan 2023 20:45:57 -0800 (PST) Received: from localhost ([2804:14d:7e39:8470:df99:10bd:7dca:b2e9]) by smtp.gmail.com with ESMTPSA id o20-20020a4ad494000000b004a394578e14sm4524233oos.32.2023.01.29.20.45.56 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 29 Jan 2023 20:45:57 -0800 (PST) To: gdb-patches@sourceware.org Cc: Thiago Jung Bauermann Subject: [PATCH v3 7/8] gdb/aarch64: Detect vector length changes when debugging remotely Date: Mon, 30 Jan 2023 04:45:17 +0000 Message-Id: <20230130044518.3322695-8-thiago.bauermann@linaro.org> X-Mailer: git-send-email 2.39.1 In-Reply-To: <20230130044518.3322695-1-thiago.bauermann@linaro.org> References: <20230130044518.3322695-1-thiago.bauermann@linaro.org> MIME-Version: 1.0 X-Spam-Status: No, score=-11.7 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Thiago Jung Bauermann via Gdb-patches From: Thiago Jung Bauermann Reply-To: Thiago Jung Bauermann Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org Sender: "Gdb-patches" If the remote target provides target description IDs in their threads list and stop reply packets, use them to update the thread's gdbarch. This allows debugging programs remotely that change their SVE vector length during runtime. GDB already supports different vector lengths in native debugging by calling target_ops::thread_architecture, and aarch64_linux_nat_target provides an implementation of that method. So to provide the same feature in remote debugging, implement the thread_architecture method in remote_target, so that the same mechanism can be used for both the native and remote cases. This method returns the gdbarch corresponding to the target description provided by the last threads list or stop reply packet. To allow changing the architecture based on the target description, add a new gdbarch method to allow arch-specific code to make the adjustment. Reviewed-by: Luis Machado --- gdb/aarch64-tdep.c | 20 ++++++++++ gdb/arch-utils.c | 8 ++++ gdb/arch-utils.h | 4 ++ gdb/gdbarch-components.py | 15 +++++++ gdb/gdbarch-gen.h | 10 +++++ gdb/gdbarch.c | 22 ++++++++++ gdb/remote.c | 84 +++++++++++++++++++++++++++++++++++++++ 7 files changed, 163 insertions(+) diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c index b576d3b9d99f..1e6e7116ed8a 100644 --- a/gdb/aarch64-tdep.c +++ b/gdb/aarch64-tdep.c @@ -3502,6 +3502,25 @@ aarch64_cannot_store_register (struct gdbarch *gdbarch, int regnum) || regnum == AARCH64_PAUTH_CMASK_REGNUM (tdep->pauth_reg_base)); } +/* Implement the "update_architecture" gdbarch method. */ + +static struct gdbarch * +aarch64_update_architecture (struct gdbarch *gdbarch, const target_desc *tdesc) +{ + /* If this is a 32-bit architecture, then this is ARM, not AArch64. + There are no SVE registers here, so just return the inferior + architecture. */ + if (gdbarch_bfd_arch_info (gdbarch)->bits_per_word == 32) + return gdbarch; + + struct gdbarch_info info; + + info.bfd_arch_info = bfd_lookup_arch (bfd_arch_aarch64, bfd_mach_aarch64); + info.target_desc = tdesc; + + return gdbarch_find_by_info (info); +} + /* Implement the stack_frame_destroyed_p gdbarch method. */ static int @@ -3748,6 +3767,7 @@ aarch64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) set_tdesc_pseudo_register_reggroup_p (gdbarch, aarch64_pseudo_register_reggroup_p); set_gdbarch_cannot_store_register (gdbarch, aarch64_cannot_store_register); + set_gdbarch_update_architecture (gdbarch, aarch64_update_architecture); /* ABI */ set_gdbarch_short_bit (gdbarch, 16); diff --git a/gdb/arch-utils.c b/gdb/arch-utils.c index 67968126488e..e8ad0aed6eb4 100644 --- a/gdb/arch-utils.c +++ b/gdb/arch-utils.c @@ -1098,6 +1098,14 @@ default_get_return_buf_addr (struct type *val_type, frame_info_ptr cur_frame) return 0; } +/* See arch-utils.h. */ + +struct gdbarch * +default_update_architecture (struct gdbarch *gdbarch, const target_desc *tdesc) +{ + return gdbarch; +} + /* Non-zero if we want to trace architecture code. */ #ifndef GDBARCH_DEBUG diff --git a/gdb/arch-utils.h b/gdb/arch-utils.h index 56690f0fd435..aeee7f51ad49 100644 --- a/gdb/arch-utils.h +++ b/gdb/arch-utils.h @@ -314,4 +314,8 @@ extern enum return_value_convention default_gdbarch_return_value struct regcache *regcache, struct value **read_value, const gdb_byte *writebuf); +/* Default implementation of gdbarch update_architecture method. */ +extern struct gdbarch * +default_update_architecture (struct gdbarch *gdbarch, const target_desc *tdesc); + #endif /* ARCH_UTILS_H */ diff --git a/gdb/gdbarch-components.py b/gdb/gdbarch-components.py index 76ad2832d8a2..68b7521c9966 100644 --- a/gdb/gdbarch-components.py +++ b/gdb/gdbarch-components.py @@ -2744,3 +2744,18 @@ Read core file mappings predefault="default_read_core_file_mappings", invalid=False, ) + +Method( + comment=""" +An architecture may change while the inferior is running. For instance, the +length of the vector registers in AArch64's Scalable Vector Extension is given +by the contents of the VG pseudo-register. + +Return a gdbarch corresponding to the given target description. +""", + type="struct gdbarch *", + name="update_architecture", + params=[("const target_desc *", "tdesc")], + predefault="default_update_architecture", + invalid=False, +) diff --git a/gdb/gdbarch-gen.h b/gdb/gdbarch-gen.h index 32b2d96fbe01..d6068c2bc24f 100644 --- a/gdb/gdbarch-gen.h +++ b/gdb/gdbarch-gen.h @@ -1672,3 +1672,13 @@ extern void set_gdbarch_get_pc_address_flags (struct gdbarch *gdbarch, gdbarch_g typedef void (gdbarch_read_core_file_mappings_ftype) (struct gdbarch *gdbarch, struct bfd *cbfd, read_core_file_mappings_pre_loop_ftype pre_loop_cb, read_core_file_mappings_loop_ftype loop_cb); extern void gdbarch_read_core_file_mappings (struct gdbarch *gdbarch, struct bfd *cbfd, read_core_file_mappings_pre_loop_ftype pre_loop_cb, read_core_file_mappings_loop_ftype loop_cb); extern void set_gdbarch_read_core_file_mappings (struct gdbarch *gdbarch, gdbarch_read_core_file_mappings_ftype *read_core_file_mappings); + +/* An architecture may change while the inferior is running. For instance, the + length of the vector registers in AArch64's Scalable Vector Extension is given + by the contents of the VG pseudo-register. + + Return a gdbarch corresponding to the given target description. */ + +typedef struct gdbarch * (gdbarch_update_architecture_ftype) (struct gdbarch *gdbarch, const target_desc *tdesc); +extern struct gdbarch * gdbarch_update_architecture (struct gdbarch *gdbarch, const target_desc *tdesc); +extern void set_gdbarch_update_architecture (struct gdbarch *gdbarch, gdbarch_update_architecture_ftype *update_architecture); diff --git a/gdb/gdbarch.c b/gdb/gdbarch.c index 46baca9c4793..07d3e060fe1f 100644 --- a/gdb/gdbarch.c +++ b/gdb/gdbarch.c @@ -256,6 +256,7 @@ struct gdbarch gdbarch_type_align_ftype *type_align = default_type_align; gdbarch_get_pc_address_flags_ftype *get_pc_address_flags = default_get_pc_address_flags; gdbarch_read_core_file_mappings_ftype *read_core_file_mappings = default_read_core_file_mappings; + gdbarch_update_architecture_ftype *update_architecture = default_update_architecture; }; /* Create a new ``struct gdbarch'' based on information provided by @@ -517,6 +518,7 @@ verify_gdbarch (struct gdbarch *gdbarch) /* Skip verify of type_align, invalid_p == 0 */ /* Skip verify of get_pc_address_flags, invalid_p == 0 */ /* Skip verify of read_core_file_mappings, invalid_p == 0 */ + /* Skip verify of update_architecture, invalid_p == 0 */ if (!log.empty ()) internal_error (_("verify_gdbarch: the following are invalid ...%s"), log.c_str ()); @@ -1355,6 +1357,9 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file) gdb_printf (file, "gdbarch_dump: read_core_file_mappings = <%s>\n", host_address_to_string (gdbarch->read_core_file_mappings)); + gdb_printf (file, + "gdbarch_dump: update_architecture = <%s>\n", + host_address_to_string (gdbarch->update_architecture)); if (gdbarch->dump_tdep != NULL) gdbarch->dump_tdep (gdbarch, file); } @@ -5317,3 +5322,20 @@ set_gdbarch_read_core_file_mappings (struct gdbarch *gdbarch, { gdbarch->read_core_file_mappings = read_core_file_mappings; } + +struct gdbarch * +gdbarch_update_architecture (struct gdbarch *gdbarch, const target_desc *tdesc) +{ + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->update_architecture != NULL); + if (gdbarch_debug >= 2) + gdb_printf (gdb_stdlog, "gdbarch_update_architecture called\n"); + return gdbarch->update_architecture (gdbarch, tdesc); +} + +void +set_gdbarch_update_architecture (struct gdbarch *gdbarch, + gdbarch_update_architecture_ftype update_architecture) +{ + gdbarch->update_architecture = update_architecture; +} diff --git a/gdb/remote.c b/gdb/remote.c index f1d1944414c3..a17d65220408 100644 --- a/gdb/remote.c +++ b/gdb/remote.c @@ -506,6 +506,8 @@ class remote_target : public process_stratum_target gdb::byte_vector thread_info_to_thread_handle (struct thread_info *tp) override; + struct gdbarch *thread_architecture (ptid_t ptid) override; + void stop (ptid_t) override; void interrupt () override; @@ -1168,6 +1170,10 @@ struct remote_thread_info : public private_thread_info to stop for a watchpoint. */ CORE_ADDR watch_data_address = 0; + /* The architecture corresponding to the target description returned + in the last stop reply or threads list. */ + struct gdbarch *arch = nullptr; + /* Get the thread's resume state. */ enum resume_state get_resume_state () const { @@ -1186,6 +1192,8 @@ struct remote_thread_info : public private_thread_info m_resume_state = resume_state::RESUMED_PENDING_VCONT; m_resumed_pending_vcont_info.step = step; m_resumed_pending_vcont_info.sig = sig; + + arch = nullptr; } /* Get the information this thread's pending vCont-resumption. @@ -1203,6 +1211,8 @@ struct remote_thread_info : public private_thread_info void set_resumed () { m_resume_state = resume_state::RESUMED; + + arch = nullptr; } private: @@ -4046,6 +4056,29 @@ remote_target::update_thread_list () info->extra = std::move (item.extra); info->name = std::move (item.name); info->thread_handle = std::move (item.thread_handle); + + /* If the threads list indicated a target description for this + thread, add it to the thread information. */ + if (item.tdesc_id) + { + const target_desc *tdesc + = get_remote_state ()->get_tdesc (*item.tdesc_id); + + gdb_assert (tdesc != nullptr); + + /* If there's no thread-specific gdbarch, use the one from the + whole inferior. */ + if (info->arch == nullptr) + info->arch = tp->inf->gdbarch; + + gdbarch *new_arch = gdbarch_update_architecture (info->arch, + tdesc); + if (new_arch != info->arch) + { + registers_changed_thread (tp); + info->arch = new_arch; + } + } } } } @@ -8152,6 +8185,36 @@ remote_target::process_stop_reply (struct stop_reply *stop_reply, && status->kind () != TARGET_WAITKIND_SIGNALLED && status->kind () != TARGET_WAITKIND_NO_RESUMED) { + thread_info *thr = find_thread_ptid (this, ptid); + + /* If GDB already knows about this thread, we can give the + architecture-specific code a chance to update the gdbarch based on the + provided target description. */ + if (stop_reply->tdesc_id && thr != nullptr) + { + const target_desc *tdesc + = stop_reply->rs->get_tdesc (*stop_reply->tdesc_id); + + gdb_assert (tdesc != nullptr); + + /* If there's no gdbarch associated with the stop reply, use the one + from the whole inferior. */ + if (stop_reply->arch == nullptr) + stop_reply->arch = thr->inf->gdbarch; + + stop_reply->arch = gdbarch_update_architecture (stop_reply->arch, + tdesc); + + /* Save stop_reply->arch so that it can be returned by the + thread_architecture method. */ + remote_thread_info *remote_thr = get_remote_thread_info (thr); + if (remote_thr->arch != stop_reply->arch) + { + registers_changed_thread (thr); + remote_thr->arch = stop_reply->arch; + } + } + /* Expedited registers. */ if (!stop_reply->regcache.empty ()) { @@ -14469,6 +14532,27 @@ remote_target::thread_info_to_thread_handle (struct thread_info *tp) return priv->thread_handle; } +/* Implementation of the thread_architecture method for the remote target. */ + +struct gdbarch * +remote_target::thread_architecture (ptid_t ptid) +{ + thread_info *thr = find_thread_ptid (this, ptid); + remote_thread_info *remote_thr; + + if (thr == nullptr) + remote_thr = nullptr; + else + remote_thr = get_remote_thread_info (thr); + + if (remote_thr == nullptr || remote_thr->arch == nullptr) + /* The default thread_architecture implementation is the one from + process_stratum_target. */ + return process_stratum_target::thread_architecture (ptid); + + return remote_thr->arch; +} + bool remote_target::can_async_p () { From patchwork Mon Jan 30 04:45:18 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thiago Jung Bauermann X-Patchwork-Id: 63903 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 7ABA938582BE for ; Mon, 30 Jan 2023 04:47:06 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 7ABA938582BE DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1675054026; bh=iWwMV1Gi9uSU9JBvHPYGf2sqQAqYOYs5ehhavy0VFw4=; h=To:Cc:Subject:Date:In-Reply-To:References:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From:Reply-To:From; b=ORc+KSPsDL2VbPNwCCk7G9sRwAYb0En0399l5z+DCFyeMTb3oh2GFE0h0h93GorcD evpOXAVFkI7TZnvysnF2A2ab/oRdcIwrZ5yS3Pyb2RwqmLHoYucsCJji+BXZzrFGG5 H7X5BoMIE/JsFEMPVCFZZDVQVMaS98Grv+9nIl/k= X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from mail-ot1-x330.google.com (mail-ot1-x330.google.com [IPv6:2607:f8b0:4864:20::330]) by sourceware.org (Postfix) with ESMTPS id F0B913858409 for ; Mon, 30 Jan 2023 04:46:00 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org F0B913858409 Received: by mail-ot1-x330.google.com with SMTP id r17-20020a056830449100b0068bb088317aso2406658otv.12 for ; Sun, 29 Jan 2023 20:46:00 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=iWwMV1Gi9uSU9JBvHPYGf2sqQAqYOYs5ehhavy0VFw4=; b=l0IhLnlQQ3OcP6Y5OQ1dFrAXG3gvx7uqB27vRmifrQGFSqmFVkeztKQ43auo9JAZBg fDC6xgdTTG6EgwSAijS8h6MI300FVy1u6d10r4za9xz1AL1GhMLvZ5gaNXGfe8nnvP6Q Xl6Hu9kktkI9oM9d5VVOteoSNB547n6wD/wzZJ5ytvRCQZ0+zmPu2y7TK/Xuq4VN3skD 6gxQyISJmEA9xh8L+bV/OBzHoKoCYkCNFU1ewWQoyY4rqZ0UV5xY7w+KkKc1cFgJTMQ6 TcYJ/YIIYDAticnEEKSa9i1LNG+1UaDTWTOiEXsgmgWGL0ogAaNlzk93moniGhYe6lKW s2dQ== X-Gm-Message-State: AO0yUKUUNHICZIIAV7PIjJruAGrV7K8Vfuf8SU/wl8czC5o5aFk/HBJ/ GeWMog5T0sfIq+HTxbwgPzNzf9PpZYJ+neYO X-Google-Smtp-Source: AK7set+VBjgb3PeNb7DPtN/mmDnByxCF6ylrevnEcS3AIcrNJLW/5wZa4V7EorCZ3H/qxRAPyzTRMQ== X-Received: by 2002:a05:6830:160f:b0:68b:b96b:ec5 with SMTP id g15-20020a056830160f00b0068bb96b0ec5mr5218329otr.9.1675053960234; Sun, 29 Jan 2023 20:46:00 -0800 (PST) Received: from localhost ([2804:14d:7e39:8470:df99:10bd:7dca:b2e9]) by smtp.gmail.com with ESMTPSA id c9-20020a056830000900b0068bd3f19016sm445650otp.66.2023.01.29.20.45.59 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 29 Jan 2023 20:45:59 -0800 (PST) To: gdb-patches@sourceware.org Cc: Thiago Jung Bauermann Subject: [PATCH v3 8/8] gdb/testsuite: Add test to exercise multi-threaded AArch64 SVE inferiors Date: Mon, 30 Jan 2023 04:45:18 +0000 Message-Id: <20230130044518.3322695-9-thiago.bauermann@linaro.org> X-Mailer: git-send-email 2.39.1 In-Reply-To: <20230130044518.3322695-1-thiago.bauermann@linaro.org> References: <20230130044518.3322695-1-thiago.bauermann@linaro.org> MIME-Version: 1.0 X-Spam-Status: No, score=-11.8 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Thiago Jung Bauermann via Gdb-patches From: Thiago Jung Bauermann Reply-To: Thiago Jung Bauermann Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org Sender: "Gdb-patches" This testcase exercises two scenarios with a multi-threaded inferior, one proposed by Luis and another one proposed by Simon. In the first scenario, one of the inferior threads changes its vector length and then hits a breakpoint. In the second one, the main thread hits a breakpoint and then GDB switches to another thread. --- gdb/testsuite/gdb.arch/aarch64-sve-threads.c | 125 ++++++++++++++++++ .../gdb.arch/aarch64-sve-threads.exp | 70 ++++++++++ 2 files changed, 195 insertions(+) create mode 100644 gdb/testsuite/gdb.arch/aarch64-sve-threads.c create mode 100644 gdb/testsuite/gdb.arch/aarch64-sve-threads.exp diff --git a/gdb/testsuite/gdb.arch/aarch64-sve-threads.c b/gdb/testsuite/gdb.arch/aarch64-sve-threads.c new file mode 100644 index 000000000000..7fad77008da3 --- /dev/null +++ b/gdb/testsuite/gdb.arch/aarch64-sve-threads.c @@ -0,0 +1,125 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2023 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/* Exercise AArch64's Scalable Vector Extension in a multi-threaded program. */ + +#include +#include +#include +#include +#include +#include + +/* For one of the tests, the thread needs to sleep after setting the vector + length. This variable is set by GDB. */ +volatile bool should_sleep = false; + +/* Used to signal to the main thread that the additional thread's vector length + was changed. */ +sem_t vl_changed; + +/* Start routine for the additional thread. Sets a new vector length, sleeps if + requested then restores the original vector length. */ + +static void * +thread_function (void *unused) +{ + unsigned int vl; + int rc; + + rc = prctl (PR_SVE_GET_VL, 0, 0, 0, 0); + if (rc < 0) + { + perror ("FAILED to PR_SVE_GET_VL"); + sem_post (&vl_changed); + return NULL; + } + + vl = rc & PR_SVE_VL_LEN_MASK; + + /* Decrease vector length by 16 bytes. */ + vl -= 16; + + rc = prctl (PR_SVE_SET_VL, vl, 0, 0, 0, 0); + if (rc < 0) + { + perror ("FAILED to PR_SVE_SET_VL"); + sem_post (&vl_changed); + return NULL; + } + + /* Let the main thread continue. */ + rc = sem_post (&vl_changed); + if (rc != 0) + { + perror ("sem_post"); + return NULL; + } + + if (should_sleep) + sleep (10); + + /* Restore original vector length. */ + vl += 16; /* break here 1 */ + + rc = prctl (PR_SVE_SET_VL, vl, 0, 0, 0, 0); + if (rc < 0) + { + perror ("FAILED to PR_SVE_SET_VL"); + return NULL; + } + + return NULL; /* break here 2 */ +} + +int +main (int argc, char **argv) +{ + pthread_t thread; + int rc; + + rc = sem_init (&vl_changed, 0, 0); + if (rc != 0) + { + perror ("sem_init"); + return 1; + } + + rc = pthread_create (&thread, NULL, thread_function, NULL); + if (rc != 0) + { + perror ("pthread_create"); + return 1; + } + + /* Wait until the additional thread changes it's vector length. */ + rc = sem_wait (&vl_changed); + if (rc != 0) + { + perror ("sem_wait"); + return 1; + } + + rc = pthread_join (thread, NULL); /* break here 3 */ + if (rc != 0) + { + perror ("pthread_join"); + return 1; + } + + return 0; +} diff --git a/gdb/testsuite/gdb.arch/aarch64-sve-threads.exp b/gdb/testsuite/gdb.arch/aarch64-sve-threads.exp new file mode 100644 index 000000000000..48197650e1de --- /dev/null +++ b/gdb/testsuite/gdb.arch/aarch64-sve-threads.exp @@ -0,0 +1,70 @@ +# Copyright 2023 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# Test a multi-threaded binary that uses SVE and changes the SVE vector length +# in the additional thread. + +if {[skip_aarch64_sve_tests]} { + verbose "Skipping ${gdb_test_file_name}." + return +} + +standard_testfile +if {[prepare_for_testing "failed to prepare" ${testfile} ${srcfile} \ + {debug pthreads}] == -1} { + return -1 +} + +if ![runto_main] { + return -1 +} + +# Stop after the additional thread has changed its vector length. +gdb_breakpoint [gdb_get_line_number "break here 1"] +gdb_continue_to_breakpoint "break here 1" + +# If GDB and gdbserver don't agree on the thread's vector length, this command +# will fail. +gdb_test "print \$z0" " = {q = {u = {.*}}}" "print z0 register" + +# Stop after the additional thread has restored its original vector length. +gdb_breakpoint [gdb_get_line_number "break here 2"] +gdb_continue_to_breakpoint "break here 2" + +# Test that going back to the original vector length doesn't confuse GDB or +# gdbserver. +gdb_test "print \$z0" " = {q = {u = {.*}}}" "print z0 register again" + +# Restart GDB to test a scenario where GDB switches to a thread that changed its +# vector length but hasn't hit any breakpoints yet. +clean_restart ${binfile} + +if ![runto_main] { + return -1 +} + +# Make the thread sleep after changing its vector length. +gdb_test_no_output -nopass "set var should_sleep = 1" "make thread sleep" + +# Stop after the additional thread has been created. +gdb_breakpoint [gdb_get_line_number "break here 3"] +gdb_continue_to_breakpoint "break here 3" + +# The regexp accounts for two lines of output after the "Switching to thread" message. +gdb_test_lines "thread 2" "switch to another thread" \ + {\[Switching to thread 2 \(.*\)\]\r\n#0 [[:print:]]+} + +# Make sure everything is still fine. +gdb_test "print \$z0" " = {q = {u = {.*}}}" "print z0 register in thread 2"