From patchwork Wed Nov 8 05:00:45 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Marchi X-Patchwork-Id: 79370 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 7A5843858D1E for ; Wed, 8 Nov 2023 05:12:49 +0000 (GMT) X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from smtp.polymtl.ca (smtp.polymtl.ca [132.207.4.11]) by sourceware.org (Postfix) with ESMTPS id D68043858D35 for ; Wed, 8 Nov 2023 05:12:33 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org D68043858D35 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=polymtl.ca Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=polymtl.ca ARC-Filter: OpenARC Filter v1.0.0 sourceware.org D68043858D35 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=132.207.4.11 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1699420355; cv=none; b=EwH/SFmtQRSIqyr2fzGj+IsVOoB7wHxRmaf6jMb8VMugxTFg4E9Emral1bnDXQYtG6JBA+0EVHUJviKuBUhahB7jX/irxCSgTkuPpCMiwVfOzurQ0qNVEov/e5loldVff1n50PccAHKIxYH11KCeHM6+sOlsYhH4EmhktFS5B9g= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1699420355; c=relaxed/simple; bh=SNZhkxD7Zkg6XmHi2mfcNgUINtz0OLTHnzHa8XQqRQg=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=tJrakVH3zf+z4r5Nml8bxfjMGWRxlLd6+GFwnWYakWxrW0X7Q78l/euJUzBozNsEAOoYjD9jN86RtnzrVncZwjLkdd2c914yat01bB0NVipyAx+vnSXBdNDlAjjX5O8w2achsbNfB6d//JDuQ1/vapedJdfaFk/rozb6kO9yJYI= ARC-Authentication-Results: i=1; server2.sourceware.org Received: from simark.ca (simark.ca [158.69.221.121]) (authenticated bits=0) by smtp.polymtl.ca (8.14.7/8.14.7) with ESMTP id 3A85CRnf015315 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 8 Nov 2023 00:12:31 -0500 DKIM-Filter: OpenDKIM Filter v2.11.0 smtp.polymtl.ca 3A85CRnf015315 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=polymtl.ca; s=default; t=1699420351; bh=p4xvFslGI5J+RQVqPiqhHwiPEqccSRbl8NyQZV91aho=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=aEXoSLljxvTHa6mD7euf80IaCjqcXH3XfQBKYzYwbHNz6sI5ShN9JLHzEao4cgx4Z hN1qtMY+3illPESRsKGpyymnQjgnJh/o+KiJMal+cVfgY7sPZGBmGjndXsAagJc0WP pBmPahdYPCCVNdNp20as4OIXhD5sCtjxnUlMcgQo= Received: from simark.localdomain (modemcable238.237-201-24.mc.videotron.ca [24.201.237.238]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) by simark.ca (Postfix) with ESMTPSA id C01381E0BB; Wed, 8 Nov 2023 00:12:26 -0500 (EST) From: Simon Marchi To: gdb-patches@sourceware.org Cc: Simon Marchi Subject: [PATCH 01/24] gdb: don't handle i386 k registers as pseudo registers Date: Wed, 8 Nov 2023 00:00:45 -0500 Message-ID: <20231108051222.1275306-2-simon.marchi@polymtl.ca> X-Mailer: git-send-email 2.42.1 In-Reply-To: <20231108051222.1275306-1-simon.marchi@polymtl.ca> References: <20231108051222.1275306-1-simon.marchi@polymtl.ca> MIME-Version: 1.0 X-Poly-FromMTA: (simark.ca [158.69.221.121]) at Wed, 8 Nov 2023 05:12:27 +0000 X-Spam-Status: No, score=-3188.6 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_PASS, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE 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.30 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org From: Simon Marchi I think that i386 k registers are raw registers, and therefore shouldn't be handled in the various functions handling pseudo registers. What tipped me off is the code in i386_pseudo_register_read_into_value: else if (i386_k_regnum_p (gdbarch, regnum)) { regnum -= tdep->k0_regnum; /* Extract (always little endian). */ status = regcache->raw_read (tdep->k0_regnum + regnum, raw_buf); We take regnum (the pseudo register number we want to read), subtract k0_regnum, add k0_regnum, and pass the result to raw_read. So we would end up calling raw_read with the same regnum as the function received which is supposedly a pseudo register number. Other hints are: - The command `maint print raw-registers` shows the k registers. - Printing $k0 doesn't cause i386_pseudo_register_read_into_value to be called. - There's code in i387-tdep.c to save/restore the k registers. Remove handling of the k registers from: - i386_pseudo_register_read_into_value - i386_pseudo_register_write - i386_ax_pseudo_register_collect Change-Id: Ic97956ed59af6099fef6d36a0b61464172694562 Reviewed-by: John Baldwin --- gdb/i386-tdep.c | 23 ----------------------- 1 file changed, 23 deletions(-) diff --git a/gdb/i386-tdep.c b/gdb/i386-tdep.c index 1ddca2410fdf..2759c1a558c5 100644 --- a/gdb/i386-tdep.c +++ b/gdb/i386-tdep.c @@ -3464,17 +3464,6 @@ i386_pseudo_register_read_into_value (struct gdbarch *gdbarch, memcpy (buf + size, &upper, size); } } - else if (i386_k_regnum_p (gdbarch, regnum)) - { - regnum -= tdep->k0_regnum; - - /* Extract (always little endian). */ - status = regcache->raw_read (tdep->k0_regnum + regnum, raw_buf); - if (status != REG_VALID) - result_value->mark_bytes_unavailable (0, 8); - else - memcpy (buf, raw_buf, 8); - } else if (i386_zmm_regnum_p (gdbarch, regnum)) { regnum -= tdep->zmm0_regnum; @@ -3656,12 +3645,6 @@ i386_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache, regcache->raw_write (I387_BND0R_REGNUM (tdep) + regnum, raw_buf); } - else if (i386_k_regnum_p (gdbarch, regnum)) - { - regnum -= tdep->k0_regnum; - - regcache->raw_write (tdep->k0_regnum + regnum, buf); - } else if (i386_zmm_regnum_p (gdbarch, regnum)) { regnum -= tdep->zmm0_regnum; @@ -3758,12 +3741,6 @@ i386_ax_pseudo_register_collect (struct gdbarch *gdbarch, ax_reg_mask (ax, I387_BND0R_REGNUM (tdep) + regnum); return 0; } - else if (i386_k_regnum_p (gdbarch, regnum)) - { - regnum -= tdep->k0_regnum; - ax_reg_mask (ax, tdep->k0_regnum + regnum); - return 0; - } else if (i386_zmm_regnum_p (gdbarch, regnum)) { regnum -= tdep->zmm0_regnum; From patchwork Wed Nov 8 05:00:46 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Marchi X-Patchwork-Id: 79372 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 A3C3B3858020 for ; Wed, 8 Nov 2023 05:13:21 +0000 (GMT) X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from smtp.polymtl.ca (smtp.polymtl.ca [132.207.4.11]) by sourceware.org (Postfix) with ESMTPS id 9DEAC3858D33 for ; Wed, 8 Nov 2023 05:12:33 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 9DEAC3858D33 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=polymtl.ca Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=polymtl.ca ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 9DEAC3858D33 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=132.207.4.11 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1699420356; cv=none; b=GalW22bNUTgF5c7VGj4kbZs2xznGcqf6BkgZbNdbCNI8mJReD7PyfvjuLpuxWxAASXHQD5tNhdDhnZgtTwoaaQizsxwi/3rnw+cqoQwzKZYvMfu09icTnnPI2AY5N+fWCQT9JiVnmmRiLzBAsDq1CQqda62841jSd7EB84xum1s= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1699420356; c=relaxed/simple; bh=a+Idqp+OTV3XGgtZCty1WBWgcEUoLhpXxxAnDQXxC10=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=IUkQCUZrEJ3r96W0bKrn7oMe0C9z8cwA6j0utD2R5+i52VSTzsNpa/a+mLpJheX0gFAQMNqmbY1zWEu9eqmQ+Jnk0bm98r/flU+5VheafrB56QcjOByseTQwD1pNv3kpTH766WBfHU9zKsuLOON17pz7Kc0SaalF2Pphq0x95q4= ARC-Authentication-Results: i=1; server2.sourceware.org Received: from simark.ca (simark.ca [158.69.221.121]) (authenticated bits=0) by smtp.polymtl.ca (8.14.7/8.14.7) with ESMTP id 3A85CRX6015318 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 8 Nov 2023 00:12:32 -0500 DKIM-Filter: OpenDKIM Filter v2.11.0 smtp.polymtl.ca 3A85CRX6015318 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=polymtl.ca; s=default; t=1699420352; bh=+x1tKGuorHptkQBXeyB5ksDtzekLZ3wD1sCa5Hmhm1A=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Af/6Iz/RC/zUQX5rMVZJPeghjwP3za21uVLkyTTlPwITFprWr4EMpL9msnlLw+Wze y3xhobPYu56DKzH9xCsjUuEeL2YI78/zjubrrO2m8pOrDFrl40B1NmrrOlYSI5wIHX EXocQ+TKcy9z1SvcloOGE/3XijnkdGfh5x5A1wyU= Received: from simark.localdomain (modemcable238.237-201-24.mc.videotron.ca [24.201.237.238]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) by simark.ca (Postfix) with ESMTPSA id 3A5AB1E0C1; Wed, 8 Nov 2023 00:12:27 -0500 (EST) From: Simon Marchi To: gdb-patches@sourceware.org Cc: Simon Marchi Subject: [PATCH 02/24] gdb: use reg_buffer_common throughout gdbsupport/common-regcache.h Date: Wed, 8 Nov 2023 00:00:46 -0500 Message-ID: <20231108051222.1275306-3-simon.marchi@polymtl.ca> X-Mailer: git-send-email 2.42.1 In-Reply-To: <20231108051222.1275306-1-simon.marchi@polymtl.ca> References: <20231108051222.1275306-1-simon.marchi@polymtl.ca> MIME-Version: 1.0 X-Poly-FromMTA: (simark.ca [158.69.221.121]) at Wed, 8 Nov 2023 05:12:27 +0000 X-Spam-Status: No, score=-3188.6 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_PASS, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE 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.30 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org From: Simon Marchi Right now, gdbsupport/common-regcache.h contains two abstractons for a regcache. An opaque type `regcache` (gdb and gdbserver both have their own regcache that is the concrete version of this) and an abstract base class `reg_buffer_common`, that is the base of regcaches on both sides. These abstractions allow code to be written for both gdb and gdbserver, for instance in the gdb/arch sub-directory. However, having two different abstractions is impractical. If some common code has a regcache, and wants to use an operation defined on reg_buffer_common, it can't. It would be better to have just one. Change all instances of `regcache *` in gdbsupport/common-regcache.h to be `reg_buffer_common *`, then fix fallouts. Implementations in gdb and gdbserver now need to down-cast (using gdb::checked_static_cast) from reg_buffer_common to their concrete regcache type. Some of them could be avoided by changing free functions (like regcache_register_size) to be virtual methods on reg_buffer_common. I tried it, it seems to work, but I did not include it in this series to avoid adding unnecessary changes. Change-Id: Ia5503adb6b5509a0f4604bd2a68b4642cc5283fd Reviewed-by: John Baldwin --- gdb/arch/arm-get-next-pcs.c | 6 +++--- gdb/arch/arm-get-next-pcs.h | 5 +++-- gdb/arch/arm.c | 2 +- gdb/arch/arm.h | 4 ++-- gdb/arm-linux-tdep.c | 11 ++++++----- gdb/arm-tdep.c | 5 +++-- gdb/nat/aarch64-hw-point.c | 3 +-- gdb/nat/linux-btrace.c | 3 +-- gdb/regcache.c | 17 ++++++++++------- gdbserver/linux-arm-low.cc | 4 +++- gdbserver/regcache.cc | 19 ++++++++++++------- gdbsupport/common-regcache.cc | 2 +- gdbsupport/common-regcache.h | 17 ++++++++++------- 13 files changed, 56 insertions(+), 42 deletions(-) diff --git a/gdb/arch/arm-get-next-pcs.c b/gdb/arch/arm-get-next-pcs.c index dcbb5a5e2e69..6b033993304b 100644 --- a/gdb/arch/arm-get-next-pcs.c +++ b/gdb/arch/arm-get-next-pcs.c @@ -32,7 +32,7 @@ arm_get_next_pcs_ctor (struct arm_get_next_pcs *self, int byte_order, int byte_order_for_code, int has_thumb2_breakpoint, - struct regcache *regcache) + reg_buffer_common *regcache) { self->ops = ops; self->byte_order = byte_order; @@ -273,7 +273,7 @@ thumb_get_next_pcs_raw (struct arm_get_next_pcs *self) unsigned short inst1; CORE_ADDR nextpc = pc + 2; /* Default is next instruction. */ ULONGEST status, itstate; - struct regcache *regcache = self->regcache; + reg_buffer_common *regcache = self->regcache; std::vector next_pcs; nextpc = MAKE_THUMB_ADDR (nextpc); @@ -653,7 +653,7 @@ arm_get_next_pcs_raw (struct arm_get_next_pcs *self) unsigned long this_instr = 0; unsigned long status; CORE_ADDR nextpc; - struct regcache *regcache = self->regcache; + reg_buffer_common *regcache = self->regcache; CORE_ADDR pc = regcache_read_pc (self->regcache); std::vector next_pcs; diff --git a/gdb/arch/arm-get-next-pcs.h b/gdb/arch/arm-get-next-pcs.h index e6bb8d832286..ec347f01b4fd 100644 --- a/gdb/arch/arm-get-next-pcs.h +++ b/gdb/arch/arm-get-next-pcs.h @@ -24,6 +24,7 @@ /* Forward declaration. */ struct arm_get_next_pcs; +struct reg_buffer_common; /* get_next_pcs operations. */ struct arm_get_next_pcs_ops @@ -50,7 +51,7 @@ struct arm_get_next_pcs not. */ int has_thumb2_breakpoint; /* Registry cache. */ - struct regcache *regcache; + reg_buffer_common *regcache; }; /* Initialize arm_get_next_pcs. */ @@ -59,7 +60,7 @@ void arm_get_next_pcs_ctor (struct arm_get_next_pcs *self, int byte_order, int byte_order_for_code, int has_thumb2_breakpoint, - struct regcache *regcache); + reg_buffer_common *regcache); /* Find the next possible PCs after the current instruction executes. */ std::vector arm_get_next_pcs (struct arm_get_next_pcs *self); diff --git a/gdb/arch/arm.c b/gdb/arch/arm.c index 4720c201c532..88737fc357f8 100644 --- a/gdb/arch/arm.c +++ b/gdb/arch/arm.c @@ -322,7 +322,7 @@ thumb2_instruction_changes_pc (unsigned short inst1, unsigned short inst2) /* See arm.h. */ unsigned long -shifted_reg_val (struct regcache *regcache, unsigned long inst, +shifted_reg_val (reg_buffer_common *regcache, unsigned long inst, int carry, unsigned long pc_val, unsigned long status_reg) { unsigned long res, shift; diff --git a/gdb/arch/arm.h b/gdb/arch/arm.h index c64a15600de3..b6c316191877 100644 --- a/gdb/arch/arm.h +++ b/gdb/arch/arm.h @@ -188,7 +188,7 @@ enum system_register_address : CORE_ADDR ((CORE_ADDR) (((unsigned long) (addr)) + 8 + (sbits (instr, 0, 23) << 2))) /* Forward declaration. */ -struct regcache; +struct reg_buffer_common; /* Return the size in bytes of the complete Thumb instruction whose first halfword is INST1. */ @@ -213,7 +213,7 @@ int thumb_advance_itstate (unsigned int itstate); /* Decode shifted register value. */ -unsigned long shifted_reg_val (struct regcache *regcache, +unsigned long shifted_reg_val (reg_buffer_common *regcache, unsigned long inst, int carry, unsigned long pc_val, diff --git a/gdb/arm-linux-tdep.c b/gdb/arm-linux-tdep.c index dfa816990ff5..909a20324fd5 100644 --- a/gdb/arm-linux-tdep.c +++ b/gdb/arm-linux-tdep.c @@ -869,8 +869,10 @@ static CORE_ADDR arm_linux_get_next_pcs_syscall_next_pc (struct arm_get_next_pcs *self) { CORE_ADDR next_pc = 0; - CORE_ADDR pc = regcache_read_pc (self->regcache); - int is_thumb = arm_is_thumb (self->regcache); + regcache *regcache + = gdb::checked_static_cast (self->regcache); + CORE_ADDR pc = regcache_read_pc (regcache); + int is_thumb = arm_is_thumb (regcache); ULONGEST svc_number = 0; if (is_thumb) @@ -880,7 +882,7 @@ arm_linux_get_next_pcs_syscall_next_pc (struct arm_get_next_pcs *self) } else { - struct gdbarch *gdbarch = self->regcache->arch (); + struct gdbarch *gdbarch = regcache->arch (); enum bfd_endian byte_order_for_code = gdbarch_byte_order_for_code (gdbarch); unsigned long this_instr = @@ -903,8 +905,7 @@ arm_linux_get_next_pcs_syscall_next_pc (struct arm_get_next_pcs *self) { /* SIGRETURN or RT_SIGRETURN may affect the arm thumb mode, so update IS_THUMB. */ - next_pc = arm_linux_sigreturn_next_pc (self->regcache, svc_number, - &is_thumb); + next_pc = arm_linux_sigreturn_next_pc (regcache, svc_number, &is_thumb); } /* Addresses for calling Thumb functions have the bit 0 set. */ diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c index d4047ddbb868..2018f4ed0edd 100644 --- a/gdb/arm-tdep.c +++ b/gdb/arm-tdep.c @@ -7255,7 +7255,8 @@ CORE_ADDR arm_get_next_pcs_addr_bits_remove (struct arm_get_next_pcs *self, CORE_ADDR val) { - return gdbarch_addr_bits_remove (self->regcache->arch (), val); + return gdbarch_addr_bits_remove + (gdb::checked_static_cast (self->regcache)->arch (), val); } /* Wrapper over syscall_next_pc for use in get_next_pcs. */ @@ -7271,7 +7272,7 @@ arm_get_next_pcs_syscall_next_pc (struct arm_get_next_pcs *self) int arm_get_next_pcs_is_thumb (struct arm_get_next_pcs *self) { - return arm_is_thumb (self->regcache); + return arm_is_thumb (gdb::checked_static_cast (self->regcache)); } /* single_step() is called just before we want to resume the inferior, diff --git a/gdb/nat/aarch64-hw-point.c b/gdb/nat/aarch64-hw-point.c index 6747e61e0265..8e9a532cd2a4 100644 --- a/gdb/nat/aarch64-hw-point.c +++ b/gdb/nat/aarch64-hw-point.c @@ -137,8 +137,7 @@ aarch64_point_is_aligned (ptid_t ptid, int is_watchpoint, CORE_ADDR addr, alignment = AARCH64_HWP_ALIGNMENT; else { - struct regcache *regcache - = get_thread_regcache_for_ptid (ptid); + reg_buffer_common *regcache = get_thread_regcache_for_ptid (ptid); /* Set alignment to 2 only if the current process is 32-bit, since thumb instruction can be 2-byte aligned. Otherwise, set diff --git a/gdb/nat/linux-btrace.c b/gdb/nat/linux-btrace.c index 3c217daa4886..7c4b40e40b8a 100644 --- a/gdb/nat/linux-btrace.c +++ b/gdb/nat/linux-btrace.c @@ -284,13 +284,12 @@ perf_event_read_bts (btrace_target_info *tinfo, const uint8_t *begin, struct perf_event_sample sample; size_t read = 0; struct btrace_block block = { 0, 0 }; - struct regcache *regcache; gdb_assert (begin <= start); gdb_assert (start <= end); /* The first block ends at the current pc. */ - regcache = get_thread_regcache_for_ptid (tinfo->ptid); + reg_buffer_common *regcache = get_thread_regcache_for_ptid (tinfo->ptid); block.end = regcache_read_pc (regcache); /* The buffer may contain a partial record as its last entry (i.e. when the diff --git a/gdb/regcache.c b/gdb/regcache.c index 2e48c0258091..11a6ecc3469e 100644 --- a/gdb/regcache.c +++ b/gdb/regcache.c @@ -180,9 +180,10 @@ register_size (struct gdbarch *gdbarch, int regnum) /* See gdbsupport/common-regcache.h. */ int -regcache_register_size (const struct regcache *regcache, int n) +regcache_register_size (const reg_buffer_common *regcache, int n) { - return register_size (regcache->arch (), n); + return register_size + ( gdb::checked_static_cast (regcache)->arch (), n); } reg_buffer::reg_buffer (gdbarch *gdbarch, bool has_pseudo) @@ -435,7 +436,7 @@ get_current_regcache (void) /* See gdbsupport/common-regcache.h. */ -struct regcache * +reg_buffer_common * get_thread_regcache_for_ptid (ptid_t ptid) { /* This function doesn't take a process_stratum_target parameter @@ -648,11 +649,12 @@ readable_regcache::raw_read (int regnum, T *val) } enum register_status -regcache_raw_read_unsigned (struct regcache *regcache, int regnum, +regcache_raw_read_unsigned (reg_buffer_common *regcache, int regnum, ULONGEST *val) { gdb_assert (regcache != NULL); - return regcache->raw_read (regnum, val); + return gdb::checked_static_cast (regcache)->raw_read + (regnum, val); } void @@ -1332,8 +1334,9 @@ reg_buffer::raw_compare (int regnum, const void *buf, int offset) const /* Special handling for register PC. */ CORE_ADDR -regcache_read_pc (struct regcache *regcache) +regcache_read_pc (reg_buffer_common *reg_buf) { + regcache *regcache = gdb::checked_static_cast (reg_buf); struct gdbarch *gdbarch = regcache->arch (); CORE_ADDR pc_val; @@ -1360,7 +1363,7 @@ regcache_read_pc (struct regcache *regcache) /* See gdbsupport/common-regcache.h. */ CORE_ADDR -regcache_read_pc_protected (regcache *regcache) +regcache_read_pc_protected (reg_buffer_common *regcache) { CORE_ADDR pc; try diff --git a/gdbserver/linux-arm-low.cc b/gdbserver/linux-arm-low.cc index 5975b44af0ae..0a6f3622695a 100644 --- a/gdbserver/linux-arm-low.cc +++ b/gdbserver/linux-arm-low.cc @@ -24,6 +24,7 @@ #include "linux-aarch32-low.h" #include "linux-aarch32-tdesc.h" #include "linux-arm-tdesc.h" +#include "gdbsupport/gdb-checked-static-cast.h" #include /* Don't include elf.h if linux/elf.h got included by gdb_proc_service.h. @@ -913,7 +914,8 @@ get_next_pcs_syscall_next_pc (struct arm_get_next_pcs *self) CORE_ADDR pc = regcache_read_pc (self->regcache); int is_thumb = arm_is_thumb_mode (); ULONGEST svc_number = 0; - struct regcache *regcache = self->regcache; + regcache *regcache + = gdb::checked_static_cast (self->regcache); if (is_thumb) { diff --git a/gdbserver/regcache.cc b/gdbserver/regcache.cc index 0b1141662ac6..4ac0fb659c3b 100644 --- a/gdbserver/regcache.cc +++ b/gdbserver/regcache.cc @@ -21,6 +21,8 @@ #include "gdbthread.h" #include "tdesc.h" #include "gdbsupport/rsp-low.h" +#include "gdbsupport/gdb-checked-static-cast.h" + #ifndef IN_PROCESS_AGENT struct regcache * @@ -64,7 +66,7 @@ get_thread_regcache (struct thread_info *thread, int fetch) /* See gdbsupport/common-regcache.h. */ -struct regcache * +reg_buffer_common * get_thread_regcache_for_ptid (ptid_t ptid) { return get_thread_regcache (find_thread_ptid (ptid), 1); @@ -307,9 +309,10 @@ register_size (const struct target_desc *tdesc, int n) /* See gdbsupport/common-regcache.h. */ int -regcache_register_size (const struct regcache *regcache, int n) +regcache_register_size (const reg_buffer_common *regcache, int n) { - return register_size (regcache->tdesc, n); + return register_size + (gdb::checked_static_cast (regcache)->tdesc, n); } static unsigned char * @@ -437,13 +440,14 @@ regcache::raw_collect (int n, void *buf) const } enum register_status -regcache_raw_read_unsigned (struct regcache *regcache, int regnum, +regcache_raw_read_unsigned (reg_buffer_common *reg_buf, int regnum, ULONGEST *val) { int size; + regcache *regcache = gdb::checked_static_cast (reg_buf); gdb_assert (regcache != NULL); - + size = register_size (regcache->tdesc, regnum); if (size > (int) sizeof (ULONGEST)) @@ -486,9 +490,10 @@ collect_register_by_name (struct regcache *regcache, /* Special handling for register PC. */ CORE_ADDR -regcache_read_pc (struct regcache *regcache) +regcache_read_pc (reg_buffer_common *regcache) { - return the_target->read_pc (regcache); + return the_target->read_pc + (gdb::checked_static_cast (regcache)); } void diff --git a/gdbsupport/common-regcache.cc b/gdbsupport/common-regcache.cc index 3515bedb3830..b6f02bac16e2 100644 --- a/gdbsupport/common-regcache.cc +++ b/gdbsupport/common-regcache.cc @@ -23,7 +23,7 @@ /* Return the register's value or throw if it's not available. */ ULONGEST -regcache_raw_get_unsigned (struct regcache *regcache, int regnum) +regcache_raw_get_unsigned (reg_buffer_common *regcache, int regnum) { ULONGEST value; enum register_status status; diff --git a/gdbsupport/common-regcache.h b/gdbsupport/common-regcache.h index e462f532407b..6d98ca8c92ed 100644 --- a/gdbsupport/common-regcache.h +++ b/gdbsupport/common-regcache.h @@ -20,6 +20,8 @@ #ifndef COMMON_COMMON_REGCACHE_H #define COMMON_COMMON_REGCACHE_H +struct reg_buffer_common; + /* This header is a stopgap until we have an independent regcache. */ enum register_status : signed char @@ -44,28 +46,29 @@ enum register_status : signed char thread specified by PTID. This function must be provided by the client. */ -extern struct regcache *get_thread_regcache_for_ptid (ptid_t ptid); +extern reg_buffer_common *get_thread_regcache_for_ptid (ptid_t ptid); /* Return the size of register numbered N in REGCACHE. This function must be provided by the client. */ -extern int regcache_register_size (const struct regcache *regcache, int n); +extern int regcache_register_size (const reg_buffer_common *regcache, int n); /* Read the PC register. This function must be provided by the client. */ -extern CORE_ADDR regcache_read_pc (struct regcache *regcache); +extern CORE_ADDR regcache_read_pc (reg_buffer_common *regcache); /* Read the PC register. If PC cannot be read, return 0. This is a wrapper around 'regcache_read_pc'. */ -extern CORE_ADDR regcache_read_pc_protected (regcache *regcache); +extern CORE_ADDR regcache_read_pc_protected (reg_buffer_common *regcache); /* Read a raw register into a unsigned integer. */ -extern enum register_status regcache_raw_read_unsigned - (struct regcache *regcache, int regnum, ULONGEST *val); +extern enum register_status +regcache_raw_read_unsigned (reg_buffer_common *regcache, int regnum, + ULONGEST *val); -ULONGEST regcache_raw_get_unsigned (struct regcache *regcache, int regnum); +ULONGEST regcache_raw_get_unsigned (reg_buffer_common *regcache, int regnum); struct reg_buffer_common { From patchwork Wed Nov 8 05:00:47 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Marchi X-Patchwork-Id: 79371 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 6B54F3858D33 for ; Wed, 8 Nov 2023 05:13:06 +0000 (GMT) X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from smtp.polymtl.ca (smtp.polymtl.ca [132.207.4.11]) by sourceware.org (Postfix) with ESMTPS id EEF803858D38 for ; Wed, 8 Nov 2023 05:12:33 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org EEF803858D38 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=polymtl.ca Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=polymtl.ca ARC-Filter: OpenARC Filter v1.0.0 sourceware.org EEF803858D38 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=132.207.4.11 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1699420355; cv=none; b=xQ6nrmsQ6oaF5AUXvBGtYmXSPobMOy185/7lTRYm9ZSF6IsAjByRY7TapiQmltiSQ7Sf5dNNSjAvEVBOHbhSCnLy3Lru/d63i0+c0PkbYV/RjIwWIiVnbzUGDqqbEQu9ZZbUs6za1PBGEZj60UPI3rLBQrSIlsagpOja/ASHM0k= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1699420355; c=relaxed/simple; bh=l4Xuu9Rs3oAspptT+JtwgT4eeZns8ZNQj6vbeEo5GVk=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=TUSsRwpnhVzP1kDdqEdFqZWWXeUpO/E5D8MQNNFMtYwzrKv6vEVAmbj6VjhjxsJmWtr18iIjpa7Vha9AVSoluaKzPMSyVGswCeGu3tOtrJ9bg927XT5MJrQoxhOeE1EGKUGqETMv7CryUi9rI3e6hMp+WYjZo5ZLgIEdCENMzmM= ARC-Authentication-Results: i=1; server2.sourceware.org Received: from simark.ca (simark.ca [158.69.221.121]) (authenticated bits=0) by smtp.polymtl.ca (8.14.7/8.14.7) with ESMTP id 3A85CR8k015322 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 8 Nov 2023 00:12:32 -0500 DKIM-Filter: OpenDKIM Filter v2.11.0 smtp.polymtl.ca 3A85CR8k015322 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=polymtl.ca; s=default; t=1699420352; bh=bIquzI6tzyBLSU6Si4tQokvRuXkGgDZUFi/9nBLsvo4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=enb8g0ttpUJhfMGC1hK/IMaYRPgP37COeRiJRvVvJP2NMtb5kJKmArbVoawvAADad ptqZEzaz4MFZUmuSb+ZR3gUPbiP2rQ1SW8CMe8rl3MecWxDO+zLXArqmkG8DbiNfIi o+UHV9rah5xfGh+WMv8kQe4uIBrWwkNT+X6j8Rgs= Received: from simark.localdomain (modemcable238.237-201-24.mc.videotron.ca [24.201.237.238]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) by simark.ca (Postfix) with ESMTPSA id 4E41F1E0D2; Wed, 8 Nov 2023 00:12:27 -0500 (EST) From: Simon Marchi To: gdb-patches@sourceware.org Cc: Simon Marchi Subject: [PATCH 03/24] gdb: make store_integer take an array_view Date: Wed, 8 Nov 2023 00:00:47 -0500 Message-ID: <20231108051222.1275306-4-simon.marchi@polymtl.ca> X-Mailer: git-send-email 2.42.1 In-Reply-To: <20231108051222.1275306-1-simon.marchi@polymtl.ca> References: <20231108051222.1275306-1-simon.marchi@polymtl.ca> MIME-Version: 1.0 X-Poly-FromMTA: (simark.ca [158.69.221.121]) at Wed, 8 Nov 2023 05:12:27 +0000 X-Spam-Status: No, score=-3188.6 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_PASS, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE 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.30 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org From: Simon Marchi Change store_integer, store_signed_integer and store_unsigned_integer to accept an array_view. Add some backwards compatibility overloads to avoid changing all callers at once. Change-Id: Ibb1381228ab1cb65fc7e2e4b92cf9ab1047cdc03 --- gdb/defs.h | 39 +++++++++++++++++++++++++++++++-------- gdb/findvar.c | 16 +++++++--------- 2 files changed, 38 insertions(+), 17 deletions(-) diff --git a/gdb/defs.h b/gdb/defs.h index b8612e1ac6d3..8170ec53c87c 100644 --- a/gdb/defs.h +++ b/gdb/defs.h @@ -501,21 +501,44 @@ extern CORE_ADDR extract_typed_address (const gdb_byte *buf, target-format integer at ADDR which is LEN bytes long. */ template> -extern void store_integer (gdb_byte *addr, int len, enum bfd_endian byte_order, - T val); +extern void store_integer (gdb::array_view dst, + bfd_endian byte_order, T val); + +template +static inline void +store_integer (gdb_byte *addr, int len, bfd_endian byte_order, T val) +{ + return store_integer (gdb::make_array_view (addr, len), byte_order, val); +} + +static inline void +store_signed_integer (gdb::array_view dst, bfd_endian byte_order, + LONGEST val) +{ + return store_integer (dst, byte_order, val); +} + +static inline void +store_signed_integer (gdb_byte *addr, int len, bfd_endian byte_order, + LONGEST val) +{ + return store_signed_integer (gdb::make_array_view (addr, len), byte_order, + val); +} static inline void -store_signed_integer (gdb_byte *addr, int len, - enum bfd_endian byte_order, LONGEST val) +store_unsigned_integer (gdb::array_view dst, bfd_endian byte_order, + ULONGEST val) { - return store_integer (addr, len, byte_order, val); + return store_integer (dst, byte_order, val); } static inline void -store_unsigned_integer (gdb_byte *addr, int len, - enum bfd_endian byte_order, ULONGEST val) +store_unsigned_integer (gdb_byte *addr, int len, bfd_endian byte_order, + LONGEST val) { - return store_integer (addr, len, byte_order, val); + return store_unsigned_integer (gdb::make_array_view (addr, len), byte_order, + val); } extern void store_typed_address (gdb_byte *buf, struct type *type, diff --git a/gdb/findvar.c b/gdb/findvar.c index 4e992ecdcc73..edb61fb27317 100644 --- a/gdb/findvar.c +++ b/gdb/findvar.c @@ -160,12 +160,12 @@ extract_typed_address (const gdb_byte *buf, struct type *type) target-format integer at ADDR which is LEN bytes long. */ template void -store_integer (gdb_byte *addr, int len, enum bfd_endian byte_order, +store_integer (gdb::array_view dst, enum bfd_endian byte_order, T val) { gdb_byte *p; - gdb_byte *startaddr = addr; - gdb_byte *endaddr = startaddr + len; + gdb_byte *startaddr = dst.data (); + gdb_byte *endaddr = startaddr + dst.size (); /* Start at the least significant end of the integer, and work towards the most significant. */ @@ -188,13 +188,11 @@ store_integer (gdb_byte *addr, int len, enum bfd_endian byte_order, } /* Explicit instantiations. */ -template void store_integer (gdb_byte *addr, int len, - enum bfd_endian byte_order, - LONGEST val); +template void store_integer (gdb::array_view dst, + bfd_endian byte_order, LONGEST val); -template void store_integer (gdb_byte *addr, int len, - enum bfd_endian byte_order, - ULONGEST val); +template void store_integer (gdb::array_view dst, + bfd_endian byte_order, ULONGEST val); /* Store the address ADDR as a pointer of type TYPE at BUF, in target form. */ From patchwork Wed Nov 8 05:00:48 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Marchi X-Patchwork-Id: 79391 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 6D5553858413 for ; Wed, 8 Nov 2023 05:32:13 +0000 (GMT) X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from smtp.polymtl.ca (smtp.polymtl.ca [132.207.4.11]) by sourceware.org (Postfix) with ESMTPS id 446783858D3C for ; Wed, 8 Nov 2023 05:31:45 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 446783858D3C Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=polymtl.ca Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=polymtl.ca ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 446783858D3C Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=132.207.4.11 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1699421506; cv=none; b=s/542kctCPJaxjeKckBTz+RCmvsBK01IKcAts13PbwrFps/fRNj9j4nZfrqp3nfPMkf4sNgcp+YHTP/iIDJCDMC22K8Q4vzWTHF3PfgjLZvc1s/aBy6GAOpEt6W6yTavhqFnVFZgfwBRPGaWgs9vJZc7Tsuj0Z8IuadePdDs3+g= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1699421506; c=relaxed/simple; bh=/1Ky7+mqYEDDwR4+lPBIaA0d922iDPDdB/xZgED8Kig=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=e0UYVx9O9tE0Pz2qb0FbFyZcHqKOzXgkLW42oRhnEdG/HbOKHvZ/vvVorKGBYlTdiM1glR9VAjfh+k7PJ8b/bvbXXAMT/9xd7vfyxY9wv+5zbWmGnaT009xxCEokj7SaqqGz6yZ9v8C6ZNDqTxnFSKvBVpp70IhiZBmKg+kwRt4= ARC-Authentication-Results: i=1; server2.sourceware.org Received: from simark.ca (simark.ca [158.69.221.121]) (authenticated bits=0) by smtp.polymtl.ca (8.14.7/8.14.7) with ESMTP id 3A85VceV018761 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 8 Nov 2023 00:31:42 -0500 DKIM-Filter: OpenDKIM Filter v2.11.0 smtp.polymtl.ca 3A85VceV018761 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=polymtl.ca; s=default; t=1699421503; bh=nC6n54NhqTQyYToAiWpAhmMiQzgXCqi/29IqMzOrtEU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=GB8o2etXAcL/RIGjCHN5TDWGvrGyZHT0S7WjD9bXf/KL51gGBc/4eo59qGoaotBV4 Mr4MmMKkO8j9mAsM/rsPy4fjTsLCG4TTnIlx4V3ZXzymR2m9LIoHcwHxgryns5l0ZY 87UGeqp8muupIt8tE2m6NNaxsliPtk8ipD9H+33g= Received: from simark.localdomain (modemcable238.237-201-24.mc.videotron.ca [24.201.237.238]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) by simark.ca (Postfix) with ESMTPSA id 9E6681E11B; Wed, 8 Nov 2023 00:12:27 -0500 (EST) From: Simon Marchi To: gdb-patches@sourceware.org Cc: Simon Marchi Subject: [PATCH 04/24] gdb: simplify conditions in regcache::{read, write, raw_collect, raw_supply}_part Date: Wed, 8 Nov 2023 00:00:48 -0500 Message-ID: <20231108051222.1275306-5-simon.marchi@polymtl.ca> X-Mailer: git-send-email 2.42.1 In-Reply-To: <20231108051222.1275306-1-simon.marchi@polymtl.ca> References: <20231108051222.1275306-1-simon.marchi@polymtl.ca> MIME-Version: 1.0 X-Poly-FromMTA: (simark.ca [158.69.221.121]) at Wed, 8 Nov 2023 05:31:38 +0000 X-Spam-Status: No, score=-3188.6 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_PASS, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE 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.30 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org From: Simon Marchi Make a few simplifications in these functions. 1. When checking if we need to do nothing, if the length is 0, we don't need to do anything, regardless of the value of offset. Remove the offset check. 2. When check if transferring the whole register, if the length is equal to the register size, then we transfer the whole register, no need to check the offset. Remove the offset check. 3. In the gdb_asserts, it is unnecessary to check for: offset <= reg_size given that right after we check for: len >= 0 && offset + len <= reg_size If `offset + len` is <= reg_size and len is >= 0, then necessarily offset is <= reg_size. Remove the `offset <= reg_size` check. Change-Id: I30a73acdc7bf432c45a07f5f177224d1cdc298e8 --- gdb/regcache.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/gdb/regcache.c b/gdb/regcache.c index 11a6ecc3469e..ae5411ba5563 100644 --- a/gdb/regcache.c +++ b/gdb/regcache.c @@ -891,16 +891,16 @@ readable_regcache::read_part (int regnum, int offset, int len, int reg_size = register_size (arch (), regnum); gdb_assert (out != NULL); - gdb_assert (offset >= 0 && offset <= reg_size); + gdb_assert (offset >= 0); gdb_assert (len >= 0 && offset + len <= reg_size); - if (offset == 0 && len == 0) + if (len == 0) { /* Nothing to do. */ return REG_VALID; } - if (offset == 0 && len == reg_size) + if (len == reg_size) { /* Read the full register. */ return (is_raw) ? raw_read (regnum, out) : cooked_read (regnum, out); @@ -928,16 +928,16 @@ reg_buffer::raw_collect_part (int regnum, int offset, int len, int reg_size = register_size (arch (), regnum); gdb_assert (out != nullptr); - gdb_assert (offset >= 0 && offset <= reg_size); + gdb_assert (offset >= 0); gdb_assert (len >= 0 && offset + len <= reg_size); - if (offset == 0 && len == 0) + if (len == 0) { /* Nothing to do. */ return; } - if (offset == 0 && len == reg_size) + if (len == reg_size) { /* Collect the full register. */ return raw_collect (regnum, out); @@ -958,16 +958,16 @@ regcache::write_part (int regnum, int offset, int len, int reg_size = register_size (arch (), regnum); gdb_assert (in != NULL); - gdb_assert (offset >= 0 && offset <= reg_size); + gdb_assert (offset >= 0); gdb_assert (len >= 0 && offset + len <= reg_size); - if (offset == 0 && len == 0) + if (len == 0) { /* Nothing to do. */ return REG_VALID; } - if (offset == 0 && len == reg_size) + if (len == reg_size) { /* Write the full register. */ (is_raw) ? raw_write (regnum, in) : cooked_write (regnum, in); @@ -997,16 +997,16 @@ reg_buffer::raw_supply_part (int regnum, int offset, int len, int reg_size = register_size (arch (), regnum); gdb_assert (in != nullptr); - gdb_assert (offset >= 0 && offset <= reg_size); + gdb_assert (offset >= 0); gdb_assert (len >= 0 && offset + len <= reg_size); - if (offset == 0 && len == 0) + if (len == 0) { /* Nothing to do. */ return; } - if (offset == 0 && len == reg_size) + if (len == reg_size) { /* Supply the full register. */ return raw_supply (regnum, in); From patchwork Wed Nov 8 05:00:49 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Marchi X-Patchwork-Id: 79392 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 0819E385842E for ; Wed, 8 Nov 2023 05:32:28 +0000 (GMT) X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from smtp.polymtl.ca (smtp.polymtl.ca [132.207.4.11]) by sourceware.org (Postfix) with ESMTPS id A8CAB3858D33 for ; Wed, 8 Nov 2023 05:31:44 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org A8CAB3858D33 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=polymtl.ca Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=polymtl.ca ARC-Filter: OpenARC Filter v1.0.0 sourceware.org A8CAB3858D33 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=132.207.4.11 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1699421510; cv=none; b=rmCe1Pv59EWAi/qddchEJXX95ElC6jISixinmMVGVwSKUgS9THsLEo6T4AN2TLZJYQeKoO9vXWlvVE4+sSlBPUHetGf31PfIk0V4Wmhz2UgAe//zGME0+2FfYYqPOYktmj6A69AnKyaULf0g/qB+vBRP9MEOV57VJsiI1u5/esw= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1699421510; c=relaxed/simple; bh=Memg9Tc2b4+GSh5nyx4M6CYU8U4JZvVpJtVSHAkL7MQ=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=ZRg9IA1el/d9LqUG0AZj6mFSgGQ9/PBQYHB0Nf8bGo8ebaf5nzLiYRGLx4Bf+CHSWT2dSiAthXGnxxcvig0JRKwGJoG/OS/QQWvtOl+GbhBq4mi8pPOKzL8elUPGvwBwKdjuoxIFxj7KRpbdhwR03zUXQqj/NGtw9GiqpRI+vQE= ARC-Authentication-Results: i=1; server2.sourceware.org Received: from simark.ca (simark.ca [158.69.221.121]) (authenticated bits=0) by smtp.polymtl.ca (8.14.7/8.14.7) with ESMTP id 3A85VcfG018763 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 8 Nov 2023 00:31:42 -0500 DKIM-Filter: OpenDKIM Filter v2.11.0 smtp.polymtl.ca 3A85VcfG018763 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=polymtl.ca; s=default; t=1699421503; bh=yPSVnu5xf7hkNEzPIvKn1HQv+BFona4GsRuQ/v90dQI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=DJ/uUHZbiTOuXsxJB0f+qLyvVMAs3bLhtvi3su5HSSTGox+ZxANVx+KkbRxoSwp8t cMSCjN70LyvOXh19pUtvbNpDlB+kpoFKhi3A+/KEw54M+VQ3VU6S3e+UZeWhM4D+Wu sji2ytXd/PcVy64ZzjH/42vf/HG7FaCr5TfTJx/w= Received: from simark.localdomain (modemcable238.237-201-24.mc.videotron.ca [24.201.237.238]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) by simark.ca (Postfix) with ESMTPSA id EB6C71E1A7; Wed, 8 Nov 2023 00:12:27 -0500 (EST) From: Simon Marchi To: gdb-patches@sourceware.org Cc: Simon Marchi Subject: [PATCH 05/24] gdb: change regcache interface to use array_view Date: Wed, 8 Nov 2023 00:00:49 -0500 Message-ID: <20231108051222.1275306-6-simon.marchi@polymtl.ca> X-Mailer: git-send-email 2.42.1 In-Reply-To: <20231108051222.1275306-1-simon.marchi@polymtl.ca> References: <20231108051222.1275306-1-simon.marchi@polymtl.ca> MIME-Version: 1.0 X-Poly-FromMTA: (simark.ca [158.69.221.121]) at Wed, 8 Nov 2023 05:31:38 +0000 X-Spam-Status: No, score=-3188.6 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_PASS, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE 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.30 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org From: Simon Marchi Change most of regcache (and base classes) to use array_view when possible, instead of raw pointers. By propagating the use of array_view further, it enables having some runtime checks to make sure the what we read from or write to regcaches has the expected length (such as the one in the `copy(array_view, array_view)` function. It also integrates well when connecting with other APIs already using gdb::array_view. Add some overloads of the methods using raw pointers to avoid having to change all call sites at once (which is both a lot of work and risky). I tried to do this change in small increments, but since many of these functions use each other, it ended up simpler to do it in one shot than having a lot of intermediary / transient changes. This change extends into gdbserver as well, because there is some part of the regcache interface that is shared. Changing the reg_buffer_common interface to use array_view caused some build failures in nat/aarch64-scalable-linux-ptrace.c. That file currently "takes advantage" of the fact that reg_buffer_common::{raw_supply,raw_collect} operates on `void *`, which IMO is dangerous. It uses raw_supply/raw_collect directly on uint64_t's, which I guess is fine because it is expected that native code will have the same endianness as the debugged process. To accomodate that, add some overloads of raw_collect and raw_supply that work on uint64_t. This file also uses raw_collect and raw_supply on `char` pointers. Change it to use `gdb_byte` pointers instead. Add overloads of raw_collect and raw_supply that work on `gdb_byte *` and make an array_view on the fly using the register's size. Those call sites could be converted to use array_view with not much work, in which case these overloads could be removed, but I didn't want to do it in this patch, to avoid starting to dig in arch-specific code. Change-Id: I9005f04114543ddff738949e12d85a31855304c2 --- gdb/frame.c | 4 +- gdb/nat/aarch64-scalable-linux-ptrace.c | 20 +- gdb/regcache.c | 478 ++++++++++++++---------- gdb/regcache.h | 113 ++++-- gdbserver/regcache.cc | 50 +-- gdbserver/regcache.h | 6 +- gdbsupport/common-regcache.h | 41 +- gdbsupport/rsp-low.cc | 8 + gdbsupport/rsp-low.h | 2 + 9 files changed, 451 insertions(+), 271 deletions(-) diff --git a/gdb/frame.c b/gdb/frame.c index 7077016ccba4..afadb8ac4e73 100644 --- a/gdb/frame.c +++ b/gdb/frame.c @@ -1107,9 +1107,9 @@ get_frame_func (frame_info_ptr this_frame) std::unique_ptr frame_save_as_regcache (frame_info_ptr this_frame) { - auto cooked_read = [this_frame] (int regnum, gdb_byte *buf) + auto cooked_read = [this_frame] (int regnum, gdb::array_view buf) { - if (!deprecated_frame_register_read (this_frame, regnum, buf)) + if (!deprecated_frame_register_read (this_frame, regnum, buf.data ())) return REG_UNAVAILABLE; else return REG_VALID; diff --git a/gdb/nat/aarch64-scalable-linux-ptrace.c b/gdb/nat/aarch64-scalable-linux-ptrace.c index dc0e45fa91ee..b8fb317edaca 100644 --- a/gdb/nat/aarch64-scalable-linux-ptrace.c +++ b/gdb/nat/aarch64-scalable-linux-ptrace.c @@ -613,7 +613,7 @@ aarch64_sve_regs_copy_to_reg_buf (int tid, struct reg_buffer_common *reg_buf) { gdb::byte_vector sve_state = aarch64_fetch_sve_regset (tid); - char *base = (char *) sve_state.data (); + gdb_byte *base = sve_state.data (); struct user_sve_header *header = (struct user_sve_header *) sve_state.data (); @@ -684,8 +684,10 @@ aarch64_sve_regs_copy_to_reg_buf (int tid, struct reg_buffer_common *reg_buf) reg_buf->raw_supply (AARCH64_SVE_Z0_REGNUM + i, reg); } - reg_buf->raw_supply (AARCH64_FPSR_REGNUM, &fpsimd->fpsr); - reg_buf->raw_supply (AARCH64_FPCR_REGNUM, &fpsimd->fpcr); + reg_buf->raw_supply (AARCH64_FPSR_REGNUM, + (const gdb_byte *) &fpsimd->fpsr); + reg_buf->raw_supply (AARCH64_FPCR_REGNUM, + (const gdb_byte *) &fpsimd->fpcr); /* Clear the SVE only registers. */ memset (reg, 0, SVE_PT_SVE_ZREG_SIZE (vq)); @@ -720,7 +722,7 @@ aarch64_sve_regs_copy_from_reg_buf (int tid, gdb::byte_vector new_state (SVE_PT_SIZE (32, SVE_PT_REGS_SVE), 0); memcpy (new_state.data (), sve_state.data (), sve_state.size ()); header = (struct user_sve_header *) new_state.data (); - char *base = (char *) new_state.data (); + gdb_byte *base = new_state.data (); /* Sanity check the data in the header. */ if (!sve_vl_valid (header->vl) @@ -805,9 +807,11 @@ aarch64_sve_regs_copy_from_reg_buf (int tid, } if (REG_VALID == reg_buf->get_register_status (AARCH64_FPSR_REGNUM)) - reg_buf->raw_collect (AARCH64_FPSR_REGNUM, &fpsimd->fpsr); + reg_buf->raw_collect (AARCH64_FPSR_REGNUM, + (gdb_byte *) &fpsimd->fpsr); if (REG_VALID == reg_buf->get_register_status (AARCH64_FPCR_REGNUM)) - reg_buf->raw_collect (AARCH64_FPCR_REGNUM, &fpsimd->fpcr); + reg_buf->raw_collect (AARCH64_FPCR_REGNUM, + (gdb_byte *) &fpsimd->fpcr); /* At this point we have collected all the data from the register cache and we are ready to update the FPSIMD register content @@ -894,7 +898,7 @@ aarch64_za_regs_copy_to_reg_buf (int tid, struct reg_buffer_common *reg_buf, /* Sanity check. */ gdb_assert (!za_state.empty ()); - char *base = (char *) za_state.data (); + gdb_byte *base = za_state.data (); struct user_za_header *header = (struct user_za_header *) base; /* If we have ZA state, read it. Otherwise, make the contents of ZA @@ -1027,7 +1031,7 @@ aarch64_za_regs_copy_from_reg_buf (int tid, /* Fetch the current ZA state from the thread. */ gdb::byte_vector za_state = aarch64_fetch_za_regset (tid); - char *base = (char *) za_state.data (); + gdb_byte *base = za_state.data (); struct user_za_header *za_header = (struct user_za_header *) base; uint64_t svq = sve_vq_from_vl (za_header->vl); diff --git a/gdb/regcache.c b/gdb/regcache.c index ae5411ba5563..4f3881386f34 100644 --- a/gdb/regcache.c +++ b/gdb/regcache.c @@ -221,10 +221,9 @@ regcache::regcache (inferior *inf_for_target_calls, gdbarch *gdbarch, readonly_detached_regcache::readonly_detached_regcache (regcache &src) : readonly_detached_regcache (src.arch (), - [&src] (int regnum, gdb_byte *buf) - { - return src.cooked_read (regnum, buf); - }) + [&src] (int regnum, + gdb::array_view buf) + { return src.cooked_read (regnum, buf, 1.0f); }) { } @@ -234,19 +233,36 @@ reg_buffer::arch () const return m_descr->gdbarch; } -/* Return a pointer to register REGNUM's buffer cache. */ +template +gdb::array_view +reg_buffer::register_buffer (int regnum) const +{ + assert_regnum (regnum); + ElemType *start = &m_registers[m_descr->register_offset[regnum]]; + int size = m_descr->sizeof_register[regnum]; + return gdb::array_view (start, size); +} -gdb_byte * +/* See regcache.h. */ + +gdb::array_view reg_buffer::register_buffer (int regnum) const { - return m_registers.get () + m_descr->register_offset[regnum]; + return register_buffer (regnum); +} + +/* See regcache.h. */ + +gdb::array_view +reg_buffer::register_buffer (int regnum) +{ + return register_buffer (regnum); } void reg_buffer::save (register_read_ftype cooked_read) { struct gdbarch *gdbarch = m_descr->gdbarch; - int regnum; /* It should have pseudo registers. */ gdb_assert (m_has_pseudo); @@ -257,17 +273,17 @@ reg_buffer::save (register_read_ftype cooked_read) save_reggroup) and mark them as valid. The full [0 .. gdbarch_num_regs + gdbarch_num_pseudo_regs) range is checked since some architectures need to save/restore `cooked' registers that live in memory. */ - for (regnum = 0; regnum < m_descr->nr_cooked_registers; regnum++) + for (int regnum = 0; regnum < m_descr->nr_cooked_registers; regnum++) { if (gdbarch_register_reggroup_p (gdbarch, regnum, save_reggroup)) { - gdb_byte *dst_buf = register_buffer (regnum); - enum register_status status = cooked_read (regnum, dst_buf); + gdb::array_view dst_buf = register_buffer (regnum); + register_status status = cooked_read (regnum, dst_buf); gdb_assert (status != REG_UNKNOWN); if (status != REG_VALID) - memset (dst_buf, 0, register_size (gdbarch, regnum)); + memset (dst_buf.data (), 0, dst_buf.size ()); m_register_status[regnum] = status; } @@ -294,7 +310,7 @@ regcache::restore (readonly_detached_regcache *src) if (gdbarch_register_reggroup_p (gdbarch, regnum, restore_reggroup)) { if (src->m_register_status[regnum] == REG_VALID) - cooked_write (regnum, src->register_buffer (regnum)); + cooked_write (regnum, src->register_buffer (regnum), 1.0f); } } } @@ -610,21 +626,30 @@ regcache::raw_update (int regnum) } } -enum register_status -readable_regcache::raw_read (int regnum, gdb_byte *buf) +register_status +readable_regcache::raw_read (int regnum, gdb::array_view dst, float) { - gdb_assert (buf != NULL); + assert_regnum (regnum); + gdb_assert (dst.size () == m_descr->sizeof_register[regnum]); + raw_update (regnum); if (m_register_status[regnum] != REG_VALID) - memset (buf, 0, m_descr->sizeof_register[regnum]); + memset (dst.data (), 0, dst.size ()); else - memcpy (buf, register_buffer (regnum), - m_descr->sizeof_register[regnum]); + copy (register_buffer (regnum), dst); return m_register_status[regnum]; } +register_status +readable_regcache::raw_read (int regnum, gdb_byte *dst) +{ + assert_regnum (regnum); + int size = m_descr->sizeof_register[regnum]; + return raw_read (regnum, gdb::make_array_view (dst, size), 1.0f); +} + enum register_status regcache_raw_read_signed (struct regcache *regcache, int regnum, LONGEST *val) { @@ -639,12 +664,14 @@ readable_regcache::raw_read (int regnum, T *val) assert_regnum (regnum); size_t len = m_descr->sizeof_register[regnum]; gdb_byte *buf = (gdb_byte *) alloca (len); - register_status status = raw_read (regnum, buf); + auto view = gdb::make_array_view (buf, len); + register_status status = raw_read (regnum, view, 1.0f); + if (status == REG_VALID) - *val = extract_integer ({buf, len}, - gdbarch_byte_order (m_descr->gdbarch)); + *val = extract_integer (view, gdbarch_byte_order (m_descr->gdbarch)); else *val = 0; + return status; } @@ -668,13 +695,13 @@ template void regcache::raw_write (int regnum, T val) { - gdb_byte *buf; - assert_regnum (regnum); - buf = (gdb_byte *) alloca (m_descr->sizeof_register[regnum]); - store_integer (buf, m_descr->sizeof_register[regnum], - gdbarch_byte_order (m_descr->gdbarch), val); - raw_write (regnum, buf); + + int len = m_descr->sizeof_register[regnum]; + gdb_byte *buf = (gdb_byte *) alloca (m_descr->sizeof_register[regnum]); + auto view = gdb::make_array_view (buf, len); + store_integer (view, gdbarch_byte_order (m_descr->gdbarch), val); + raw_write (regnum, view, 1.0f); } void @@ -698,47 +725,61 @@ regcache_raw_get_signed (struct regcache *regcache, int regnum) return value; } -enum register_status -readable_regcache::cooked_read (int regnum, gdb_byte *buf) +/* See regcache.h. */ + +register_status +readable_regcache::cooked_read (int regnum, gdb::array_view dst, + float) { gdb_assert (regnum >= 0); gdb_assert (regnum < m_descr->nr_cooked_registers); + if (regnum < num_raw_registers ()) - return raw_read (regnum, buf); - else if (m_has_pseudo - && m_register_status[regnum] != REG_UNKNOWN) + return raw_read (regnum, dst, 1.0f); + + gdb_assert (dst.size () == m_descr->sizeof_register[regnum]); + + if (m_has_pseudo && m_register_status[regnum] != REG_UNKNOWN) { if (m_register_status[regnum] == REG_VALID) - memcpy (buf, register_buffer (regnum), - m_descr->sizeof_register[regnum]); + copy (register_buffer (regnum), dst); else - memset (buf, 0, m_descr->sizeof_register[regnum]); + memset (dst.data (), 0, dst.size ()); return m_register_status[regnum]; } else if (gdbarch_pseudo_register_read_value_p (m_descr->gdbarch)) { - struct value *computed; - enum register_status result = REG_VALID; - + register_status result = REG_VALID; scoped_value_mark mark; + value *computed + = gdbarch_pseudo_register_read_value (m_descr->gdbarch, this, regnum); - computed = gdbarch_pseudo_register_read_value (m_descr->gdbarch, - this, regnum); if (computed->entirely_available ()) - memcpy (buf, computed->contents_raw ().data (), - m_descr->sizeof_register[regnum]); + copy (computed->contents_raw (), dst); else { - memset (buf, 0, m_descr->sizeof_register[regnum]); + memset (dst.data (), 0, dst.size ()); result = REG_UNAVAILABLE; } return result; } else - return gdbarch_pseudo_register_read (m_descr->gdbarch, this, - regnum, buf); + return gdbarch_pseudo_register_read (m_descr->gdbarch, this, regnum, + dst.data ()); +} + +/* See regcache.h. */ + +register_status +readable_regcache::cooked_read (int regnum, gdb_byte *dst) +{ + gdb_assert (regnum >= 0); + gdb_assert (regnum < m_descr->nr_cooked_registers); + + int size = m_descr->sizeof_register[regnum]; + return cooked_read (regnum, gdb::make_array_view (dst, size), 1.0f); } struct value * @@ -760,8 +801,8 @@ readable_regcache::cooked_read_value (int regnum) /* It is more efficient in general to do this delegation in this direction than in the other one, even though the value-based API is preferred. */ - if (cooked_read (regnum, - result->contents_raw ().data ()) == REG_UNAVAILABLE) + if (cooked_read (regnum, result->contents_raw (), 1.0f) + == REG_UNAVAILABLE) result->mark_bytes_unavailable (0, result->type ()->length ()); @@ -787,10 +828,10 @@ readable_regcache::cooked_read (int regnum, T *val) gdb_assert (regnum >= 0 && regnum < m_descr->nr_cooked_registers); size_t len = m_descr->sizeof_register[regnum]; gdb_byte *buf = (gdb_byte *) alloca (len); - register_status status = cooked_read (regnum, buf); + auto view = gdb::make_array_view (buf, len); + register_status status = cooked_read (regnum, view, 1.0f); if (status == REG_VALID) - *val = extract_integer ({buf, len}, - gdbarch_byte_order (m_descr->gdbarch)); + *val = extract_integer (view, gdbarch_byte_order (m_descr->gdbarch)); else *val = 0; return status; @@ -816,13 +857,14 @@ template void regcache::cooked_write (int regnum, T val) { - gdb_byte *buf; + gdb_assert (regnum >= 0); + gdb_assert (regnum < m_descr->nr_cooked_registers); - gdb_assert (regnum >=0 && regnum < m_descr->nr_cooked_registers); - buf = (gdb_byte *) alloca (m_descr->sizeof_register[regnum]); - store_integer (buf, m_descr->sizeof_register[regnum], - gdbarch_byte_order (m_descr->gdbarch), val); - cooked_write (regnum, buf); + int size = m_descr->sizeof_register[regnum]; + gdb_byte *buf = (gdb_byte *) alloca (size); + auto view = gdb::make_array_view (buf, size); + store_integer (view, gdbarch_byte_order (m_descr->gdbarch), val); + cooked_write (regnum, view, 1.0f); } void @@ -834,11 +876,10 @@ regcache_cooked_write_unsigned (struct regcache *regcache, int regnum, } void -regcache::raw_write (int regnum, const gdb_byte *buf) +regcache::raw_write (int regnum, gdb::array_view src, float) { - - gdb_assert (buf != NULL); assert_regnum (regnum); + gdb_assert (src.size () == m_descr->sizeof_register[regnum]); /* On the sparc, writing %g0 is a no-op, so we don't even want to change the registers array if something writes to this register. */ @@ -848,15 +889,15 @@ regcache::raw_write (int regnum, const gdb_byte *buf) /* If we have a valid copy of the register, and new value == old value, then don't bother doing the actual store. */ if (get_register_status (regnum) == REG_VALID - && (memcmp (register_buffer (regnum), buf, - m_descr->sizeof_register[regnum]) == 0)) + && (memcmp (register_buffer (regnum).data (), src.data (), src.size ()) + == 0)) return; gdb::optional maybe_restore_thread = maybe_switch_inferior (m_inf_for_target_calls); target_prepare_to_store (this); - raw_supply (regnum, buf); + raw_supply (regnum, src, 1.0f); /* Invalidate the register after it is written, in case of a failure. */ @@ -871,211 +912,248 @@ regcache::raw_write (int regnum, const gdb_byte *buf) } void -regcache::cooked_write (int regnum, const gdb_byte *buf) +regcache::raw_write (int regnum, const gdb_byte *src) +{ + assert_regnum (regnum); + + int size = m_descr->sizeof_register[regnum]; + raw_write (regnum, gdb::make_array_view (src, size), 1.0f); +} + +/* See regcache.h. */ + +void +regcache::cooked_write (int regnum, gdb::array_view src, float) { gdb_assert (regnum >= 0); gdb_assert (regnum < m_descr->nr_cooked_registers); + if (regnum < num_raw_registers ()) - raw_write (regnum, buf); + raw_write (regnum, src, 1.0f); else - gdbarch_pseudo_register_write (m_descr->gdbarch, this, - regnum, buf); + gdbarch_pseudo_register_write (m_descr->gdbarch, this, regnum, + src.data ()); } /* See regcache.h. */ -enum register_status -readable_regcache::read_part (int regnum, int offset, int len, - gdb_byte *out, bool is_raw) +void +regcache::cooked_write (int regnum, const gdb_byte *src) +{ + gdb_assert (regnum >= 0); + gdb_assert (regnum < m_descr->nr_cooked_registers); + + int size = m_descr->sizeof_register[regnum]; + return cooked_write (regnum, gdb::make_array_view (src, size), 1.0f); +} + +/* See regcache.h. */ + +register_status +readable_regcache::read_part (int regnum, int offset, + gdb::array_view dst, bool is_raw) { int reg_size = register_size (arch (), regnum); - gdb_assert (out != NULL); gdb_assert (offset >= 0); - gdb_assert (len >= 0 && offset + len <= reg_size); + gdb_assert (offset + dst.size () <= reg_size); - if (len == 0) + if (dst.size () == 0) { /* Nothing to do. */ return REG_VALID; } - if (len == reg_size) + if (dst.size () == reg_size) { /* Read the full register. */ - return (is_raw) ? raw_read (regnum, out) : cooked_read (regnum, out); + if (is_raw) + return raw_read (regnum, dst, 1.0f); + else + return cooked_read (regnum, dst, 1.0f); } - enum register_status status; - gdb_byte *reg = (gdb_byte *) alloca (reg_size); - /* Read full register to buffer. */ - status = (is_raw) ? raw_read (regnum, reg) : cooked_read (regnum, reg); + register_status status; + gdb_byte *reg_buf = (gdb_byte *) alloca (reg_size); + auto reg = gdb::make_array_view (reg_buf, reg_size); + + if (is_raw) + status = raw_read (regnum, reg, 1.0f); + else + status = cooked_read (regnum, reg, 1.0f); + if (status != REG_VALID) return status; /* Copy out. */ - memcpy (out, reg + offset, len); + copy (reg.slice (offset, dst.size ()), dst); return REG_VALID; } /* See regcache.h. */ void -reg_buffer::raw_collect_part (int regnum, int offset, int len, - gdb_byte *out) const +reg_buffer::raw_collect_part (int regnum, int offset, + gdb::array_view dst) const { int reg_size = register_size (arch (), regnum); - gdb_assert (out != nullptr); gdb_assert (offset >= 0); - gdb_assert (len >= 0 && offset + len <= reg_size); + gdb_assert (offset + dst.size () <= reg_size); - if (len == 0) + if (dst.size () == 0) { /* Nothing to do. */ return; } - if (len == reg_size) + if (dst.size () == reg_size) { /* Collect the full register. */ - return raw_collect (regnum, out); + return raw_collect (regnum, dst, 1.0f); } /* Read to buffer, then write out. */ - gdb_byte *reg = (gdb_byte *) alloca (reg_size); - raw_collect (regnum, reg); - memcpy (out, reg + offset, len); + gdb_byte *reg_buf = (gdb_byte *) alloca (reg_size); + auto reg = gdb::make_array_view (reg_buf, reg_size); + raw_collect (regnum, reg, 1.0f); + copy (reg.slice (offset, dst.size ()), dst); } /* See regcache.h. */ -enum register_status -regcache::write_part (int regnum, int offset, int len, - const gdb_byte *in, bool is_raw) +register_status +regcache::write_part (int regnum, int offset, + gdb::array_view src, bool is_raw) { int reg_size = register_size (arch (), regnum); - gdb_assert (in != NULL); gdb_assert (offset >= 0); - gdb_assert (len >= 0 && offset + len <= reg_size); + gdb_assert (offset + src.size () <= reg_size); - if (len == 0) + if (src.size () == 0) { /* Nothing to do. */ return REG_VALID; } - if (len == reg_size) + if (src.size () == reg_size) { /* Write the full register. */ - (is_raw) ? raw_write (regnum, in) : cooked_write (regnum, in); + if (is_raw) + raw_write (regnum, src, 1.0f); + else + cooked_write (regnum, src, 1.0f); + return REG_VALID; } - enum register_status status; - gdb_byte *reg = (gdb_byte *) alloca (reg_size); - /* Read existing register to buffer. */ - status = (is_raw) ? raw_read (regnum, reg) : cooked_read (regnum, reg); + register_status status; + gdb_byte *reg_buf = (gdb_byte *) alloca (reg_size); + auto reg = gdb::make_array_view (reg_buf, reg_size); + + if (is_raw) + status = raw_read (regnum, reg, 1.0f); + else + status = cooked_read (regnum, reg, 1.0f); + if (status != REG_VALID) return status; /* Update buffer, then write back to regcache. */ - memcpy (reg + offset, in, len); - is_raw ? raw_write (regnum, reg) : cooked_write (regnum, reg); + copy (src, reg.slice (offset, src.size ())); + + if (is_raw) + raw_write (regnum, reg, 1.0f); + else + cooked_write (regnum, reg, 1.0f); + return REG_VALID; } /* See regcache.h. */ void -reg_buffer::raw_supply_part (int regnum, int offset, int len, - const gdb_byte *in) +reg_buffer::raw_supply_part (int regnum, int offset, + gdb::array_view src) { int reg_size = register_size (arch (), regnum); - gdb_assert (in != nullptr); gdb_assert (offset >= 0); - gdb_assert (len >= 0 && offset + len <= reg_size); + gdb_assert (offset + src.size () <= reg_size); - if (len == 0) + if (src.size () == 0) { /* Nothing to do. */ return; } - if (len == reg_size) + if (src.size () == reg_size) { /* Supply the full register. */ - return raw_supply (regnum, in); + return raw_supply (regnum, src, 1.0f); } - gdb_byte *reg = (gdb_byte *) alloca (reg_size); - /* Read existing value to buffer. */ - raw_collect (regnum, reg); + gdb_byte *reg_buf = (gdb_byte *) alloca (reg_size); + auto reg = gdb::make_array_view (reg_buf, reg_size); + raw_collect (regnum, reg, 1.0f); /* Write to buffer, then write out. */ - memcpy (reg + offset, in, len); - raw_supply (regnum, reg); + copy (src, reg.slice (offset, src.size ())); + raw_supply (regnum, reg, 1.0f); } -enum register_status -readable_regcache::raw_read_part (int regnum, int offset, int len, - gdb_byte *buf) +register_status +readable_regcache::raw_read_part (int regnum, int offset, + gdb::array_view dst) { assert_regnum (regnum); - return read_part (regnum, offset, len, buf, true); + return read_part (regnum, offset, dst, true); } /* See regcache.h. */ void -regcache::raw_write_part (int regnum, int offset, int len, - const gdb_byte *buf) +regcache::raw_write_part (int regnum, int offset, + gdb::array_view src) { assert_regnum (regnum); - write_part (regnum, offset, len, buf, true); + write_part (regnum, offset, src, true); } /* See regcache.h. */ -enum register_status -readable_regcache::cooked_read_part (int regnum, int offset, int len, - gdb_byte *buf) +register_status +readable_regcache::cooked_read_part (int regnum, int offset, + gdb::array_view dst) { gdb_assert (regnum >= 0 && regnum < m_descr->nr_cooked_registers); - return read_part (regnum, offset, len, buf, false); + return read_part (regnum, offset, dst, false); } /* See regcache.h. */ void -regcache::cooked_write_part (int regnum, int offset, int len, - const gdb_byte *buf) +regcache::cooked_write_part (int regnum, int offset, + gdb::array_view src) { gdb_assert (regnum >= 0 && regnum < m_descr->nr_cooked_registers); - write_part (regnum, offset, len, buf, false); + write_part (regnum, offset, src, false); } /* See gdbsupport/common-regcache.h. */ void -reg_buffer::raw_supply (int regnum, const void *buf) +reg_buffer::raw_supply (int regnum, gdb::array_view src, float) { - void *regbuf; - size_t size; - - assert_regnum (regnum); - - regbuf = register_buffer (regnum); - size = m_descr->sizeof_register[regnum]; + gdb::array_view dst = register_buffer (regnum); - if (buf) + if (src.data () != nullptr) { - memcpy (regbuf, buf, size); + copy (src, dst); m_register_status[regnum] = REG_VALID; } else @@ -1083,7 +1161,7 @@ reg_buffer::raw_supply (int regnum, const void *buf) /* This memset not strictly necessary, but better than garbage in case the register value manages to escape somewhere (due to a bug, no less). */ - memset (regbuf, 0, size); + memset (dst.data (), 0, dst.size ()); m_register_status[regnum] = REG_UNAVAILABLE; } } @@ -1091,19 +1169,25 @@ reg_buffer::raw_supply (int regnum, const void *buf) /* See regcache.h. */ void -reg_buffer::raw_supply_integer (int regnum, const gdb_byte *addr, - int addr_len, bool is_signed) +reg_buffer::raw_supply (int regnum, const void *src) { - enum bfd_endian byte_order = gdbarch_byte_order (m_descr->gdbarch); - gdb_byte *regbuf; - size_t regsize; - assert_regnum (regnum); - regbuf = register_buffer (regnum); - regsize = m_descr->sizeof_register[regnum]; + int size = m_descr->sizeof_register[regnum]; + raw_supply (regnum, gdb::make_array_view ((const gdb_byte *) src, size), + 1.0f); +} + +/* See regcache.h. */ + +void +reg_buffer::raw_supply_integer (int regnum, const gdb_byte *addr, int addr_len, + bool is_signed) +{ + gdb::array_view dst = register_buffer (regnum); + bfd_endian byte_order = gdbarch_byte_order (m_descr->gdbarch); - copy_integer_to_size (regbuf, regsize, addr, addr_len, is_signed, + copy_integer_to_size (dst.data (), dst.size (), addr, addr_len, is_signed, byte_order); m_register_status[regnum] = REG_VALID; } @@ -1113,32 +1197,31 @@ reg_buffer::raw_supply_integer (int regnum, const gdb_byte *addr, void reg_buffer::raw_supply_zeroed (int regnum) { - void *regbuf; - size_t size; - - assert_regnum (regnum); - - regbuf = register_buffer (regnum); - size = m_descr->sizeof_register[regnum]; - - memset (regbuf, 0, size); + gdb::array_view dst = register_buffer (regnum); + memset (dst.data (), 0, dst.size ()); m_register_status[regnum] = REG_VALID; } /* See gdbsupport/common-regcache.h. */ void -reg_buffer::raw_collect (int regnum, void *buf) const +reg_buffer::raw_collect (int regnum, gdb::array_view dst, + float) const { - const void *regbuf; - size_t size; + gdb::array_view src = register_buffer (regnum); + copy (src, dst); +} - gdb_assert (buf != NULL); +/* See regcache.h. */ + +void +reg_buffer::raw_collect (int regnum, void *dst) const +{ assert_regnum (regnum); - regbuf = register_buffer (regnum); - size = m_descr->sizeof_register[regnum]; - memcpy (buf, regbuf, size); + int size = m_descr->sizeof_register[regnum]; + return raw_collect (regnum, gdb::make_array_view ((gdb_byte *) dst, size), + 1.0f); } /* See regcache.h. */ @@ -1147,16 +1230,9 @@ void reg_buffer::raw_collect_integer (int regnum, gdb_byte *addr, int addr_len, bool is_signed) const { - enum bfd_endian byte_order = gdbarch_byte_order (m_descr->gdbarch); - const gdb_byte *regbuf; - size_t regsize; - - assert_regnum (regnum); - - regbuf = register_buffer (regnum); - regsize = m_descr->sizeof_register[regnum]; - - copy_integer_to_size (addr, addr_len, regbuf, regsize, is_signed, + gdb::array_view dst = register_buffer (regnum); + bfd_endian byte_order = gdbarch_byte_order (m_descr->gdbarch); + copy_integer_to_size (addr, addr_len, dst.data (), dst.size (), is_signed, byte_order); } @@ -1175,7 +1251,8 @@ regcache::transfer_regset_register (struct regcache *out_regcache, int regnum, if (out_buf != nullptr) { - raw_collect_part (regnum, 0, reg_size, out_buf + offs); + raw_collect_part (regnum, 0, + gdb::make_array_view (out_buf + offs, reg_size)); /* Ensure any additional space is cleared. */ if (slot_size > reg_size) @@ -1186,12 +1263,14 @@ regcache::transfer_regset_register (struct regcache *out_regcache, int regnum, /* Zero-extend the register value if the slot is smaller than the register. */ if (slot_size < register_size (gdbarch, regnum)) out_regcache->raw_supply_zeroed (regnum); - out_regcache->raw_supply_part (regnum, 0, reg_size, in_buf + offs); + out_regcache->raw_supply_part (regnum, 0, + gdb::make_array_view (in_buf + offs, + reg_size)); } else { /* Invalidate the register. */ - out_regcache->raw_supply (regnum, nullptr); + out_regcache->raw_supply (regnum, {}); } } @@ -1322,13 +1401,12 @@ bool reg_buffer::raw_compare (int regnum, const void *buf, int offset) const { gdb_assert (buf != NULL); - assert_regnum (regnum); - const char *regbuf = (const char *) register_buffer (regnum); - size_t size = m_descr->sizeof_register[regnum]; - gdb_assert (size >= offset); + gdb::array_view regbuf = register_buffer (regnum); + gdb_assert (offset < regbuf.size ()); + regbuf = regbuf.slice (offset); - return (memcmp (buf, regbuf + offset, size - offset) == 0); + return memcmp (buf, regbuf.data (), regbuf.size ()) == 0; } /* Special handling for register PC. */ @@ -1417,17 +1495,15 @@ regcache::debug_print_register (const char *func, int regno) if (regno >= 0 && regno < gdbarch_num_regs (gdbarch)) { enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); - int size = register_size (gdbarch, regno); - gdb_byte *buf = register_buffer (regno); + gdb::array_view buf = register_buffer (regno); gdb_printf (gdb_stdlog, " = "); - for (int i = 0; i < size; i++) - { - gdb_printf (gdb_stdlog, "%02x", buf[i]); - } - if (size <= sizeof (LONGEST)) + for (gdb_byte byte : buf) + gdb_printf (gdb_stdlog, "%02x", byte); + + if (buf.size () <= sizeof (LONGEST)) { - ULONGEST val = extract_unsigned_integer (buf, size, byte_order); + ULONGEST val = extract_unsigned_integer (buf, byte_order); gdb_printf (gdb_stdlog, " %s %s", core_addr_to_string_nz (val), plongest (val)); @@ -1889,7 +1965,7 @@ cooked_read_test (struct gdbarch *gdbarch) readwrite.set_ptid (mockctx.mock_ptid); gdb::byte_vector buf (register_size (gdbarch, nonzero_regnum)); - readwrite.raw_read (nonzero_regnum, buf.data ()); + readwrite.raw_read (nonzero_regnum, buf, 1.0f); /* raw_read calls target_fetch_registers. */ SELF_CHECK (mockctx.mock_target.fetch_registers_called > 0); @@ -1910,9 +1986,8 @@ cooked_read_test (struct gdbarch *gdbarch) gdb::byte_vector inner_buf (register_size (gdbarch, regnum)); - SELF_CHECK (REG_VALID == readwrite.cooked_read (regnum, - inner_buf.data ())); - + SELF_CHECK (REG_VALID + == readwrite.cooked_read (regnum, inner_buf, 1.0f)); SELF_CHECK (mockctx.mock_target.fetch_registers_called == 0); SELF_CHECK (mockctx.mock_target.store_registers_called == 0); SELF_CHECK (mockctx.mock_target.xfer_partial_called == 0); @@ -1932,8 +2007,7 @@ cooked_read_test (struct gdbarch *gdbarch) continue; gdb::byte_vector inner_buf (register_size (gdbarch, regnum)); - enum register_status status = readonly.cooked_read (regnum, - inner_buf.data ()); + register_status status = readonly.cooked_read (regnum, inner_buf, 1.0f); if (regnum < gdbarch_num_regs (gdbarch)) { @@ -2023,8 +2097,8 @@ cooked_write_test (struct gdbarch *gdbarch) && regnum <= gdbarch_num_regs (gdbarch) + 4)) continue; - std::vector expected (register_size (gdbarch, regnum), 0); - std::vector buf (register_size (gdbarch, regnum), 0); + gdb::byte_vector expected (register_size (gdbarch, regnum), 0); + gdb::byte_vector buf (register_size (gdbarch, regnum), 0); const auto type = register_type (gdbarch, regnum); if (type->code () == TYPE_CODE_FLT @@ -2079,9 +2153,9 @@ cooked_write_test (struct gdbarch *gdbarch) SELF_CHECK (0); } - readwrite.cooked_write (regnum, expected.data ()); + readwrite.cooked_write (regnum, expected, 1.0f); - SELF_CHECK (readwrite.cooked_read (regnum, buf.data ()) == REG_VALID); + SELF_CHECK (readwrite.cooked_read (regnum, buf, 1.0f) == REG_VALID); SELF_CHECK (expected == buf); } } diff --git a/gdb/regcache.h b/gdb/regcache.h index 57ddac465f09..123c9248c345 100644 --- a/gdb/regcache.h +++ b/gdb/regcache.h @@ -20,6 +20,7 @@ #ifndef REGCACHE_H #define REGCACHE_H +#include "gdbsupport/array-view.h" #include "gdbsupport/common-regcache.h" #include "gdbsupport/function-view.h" @@ -172,8 +173,8 @@ extern struct type *register_type (struct gdbarch *gdbarch, int regnum); extern int register_size (struct gdbarch *gdbarch, int regnum); -typedef gdb::function_view - register_read_ftype; +using register_read_ftype + = gdb::function_view)>; /* A (register_number, register_value) pair. */ @@ -199,7 +200,11 @@ class reg_buffer : public reg_buffer_common enum register_status get_register_status (int regnum) const override; /* See gdbsupport/common-regcache.h. */ - void raw_collect (int regnum, void *buf) const override; + void raw_collect (int regnum, gdb::array_view dst, + float) const override; + + /* Deprecated overload of the above. */ + void raw_collect (int regnum, void *dst) const; /* Collect register REGNUM from REGCACHE. Store collected value as an integer at address ADDR, in target endian, with length ADDR_LEN and sign IS_SIGNED. @@ -209,17 +214,24 @@ class reg_buffer : public reg_buffer_common void raw_collect_integer (int regnum, gdb_byte *addr, int addr_len, bool is_signed) const; - /* Collect register REGNUM from REGCACHE, starting at OFFSET in register, - reading only LEN. */ - void raw_collect_part (int regnum, int offset, int len, gdb_byte *out) const; + /* Collect part of register REGNUM from this register buffer. Start at OFFSET + in register. The size is given by the size of DST. */ + void raw_collect_part (int regnum, int offset, + gdb::array_view dst) const; + + /* Deprecated overload of the above. */ + void raw_collect_part (int regnum, int offset, int len, gdb_byte *dst) const + { raw_collect_part (regnum, offset, gdb::make_array_view (dst, len)); } /* See gdbsupport/common-regcache.h. */ - void raw_supply (int regnum, const void *buf) override; + void raw_supply (int regnum, gdb::array_view src, + float) override; + + /* Deprecated overload of the above. */ + void raw_supply (int regnum, const void *src); void raw_supply (int regnum, const reg_buffer &src) - { - raw_supply (regnum, src.register_buffer (regnum)); - } + { raw_supply (regnum, src.register_buffer (regnum), 1.0f); } /* Supply register REGNUM to REGCACHE. Value to supply is an integer stored at address ADDR, in target endian, with length ADDR_LEN and sign IS_SIGNED. @@ -234,9 +246,11 @@ class reg_buffer : public reg_buffer_common unavailable). */ void raw_supply_zeroed (int regnum); - /* Supply register REGNUM to REGCACHE, starting at OFFSET in register, writing - only LEN, without editing the rest of the register. */ - void raw_supply_part (int regnum, int offset, int len, const gdb_byte *in); + /* Supply part of register REGNUM to this register buffer. Start at OFFSET in + the register. The size is given by the size of SRC. The rest of the + register left untouched. */ + void raw_supply_part (int regnum, int offset, + gdb::array_view src); void invalidate (int regnum); @@ -251,7 +265,11 @@ class reg_buffer : public reg_buffer_common int num_raw_registers () const; - gdb_byte *register_buffer (int regnum) const; + /* Return a view on register REGNUM's buffer cache. */ + template + gdb::array_view register_buffer (int regnum) const; + gdb::array_view register_buffer (int regnum) const; + gdb::array_view register_buffer (int regnum); /* Save a register cache. The set of registers saved into the regcache determined by the save_reggroup. COOKED_READ returns @@ -281,27 +299,42 @@ class readable_regcache : public reg_buffer /* Transfer a raw register [0..NUM_REGS) from core-gdb to this regcache, return its value in *BUF and return its availability status. */ + register_status raw_read (int regnum, gdb::array_view dst, float); + + /* Deprecated overload of the above. */ + register_status raw_read (int regnum, gdb_byte *dst); - enum register_status raw_read (int regnum, gdb_byte *buf); template> - enum register_status raw_read (int regnum, T *val); + register_status raw_read (int regnum, T *val); /* Partial transfer of raw registers. Return the status of the register. */ - enum register_status raw_read_part (int regnum, int offset, int len, - gdb_byte *buf); + register_status raw_read_part (int regnum, int offset, + gdb::array_view dst); + + /* Deprecated overload of the above. */ + register_status raw_read_part (int regnum, int offset, int len, + gdb_byte *dst) + { return raw_read_part (regnum, offset, gdb::make_array_view (dst, len)); } /* Make certain that the register REGNUM is up-to-date. */ virtual void raw_update (int regnum) = 0; /* Transfer a raw register [0..NUM_REGS+NUM_PSEUDO_REGS) from core-gdb to - this regcache, return its value in *BUF and return its availability status. */ - enum register_status cooked_read (int regnum, gdb_byte *buf); + this regcache, return its value in DST and return its availability status. */ + register_status cooked_read (int regnum, gdb::array_view dst, + float); + register_status cooked_read (int regnum, gdb_byte *dst); + template> - enum register_status cooked_read (int regnum, T *val); + register_status cooked_read (int regnum, T *val); /* Partial transfer of a cooked register. */ - enum register_status cooked_read_part (int regnum, int offset, int len, - gdb_byte *buf); + register_status cooked_read_part (int regnum, int offset, + gdb::array_view dst); + + /* Deprecated overload of the above. */ + register_status cooked_read_part (int regnum, int offset, int len, gdb_byte *src) + { return cooked_read_part (regnum, offset, gdb::make_array_view (src, len)); } /* Read register REGNUM from the regcache and return a new value. This will call mark_value_bytes_unavailable as appropriate. */ @@ -311,8 +344,8 @@ class readable_regcache : public reg_buffer /* Perform a partial register transfer using a read, modify, write operation. Will fail if register is currently invalid. */ - enum register_status read_part (int regnum, int offset, int len, - gdb_byte *out, bool is_raw); + register_status read_part (int regnum, int offset, + gdb::array_view dst, bool is_raw); }; /* Buffer of registers, can be read and written. */ @@ -354,13 +387,19 @@ class regcache : public detached_regcache /* Update the value of raw register REGNUM (in the range [0..NUM_REGS)) and transfer its value to core-gdb. */ - void raw_write (int regnum, const gdb_byte *buf); + void raw_write (int regnum, gdb::array_view src, float); + + /* Deprecated overload of the above. */ + void raw_write (int regnum, const gdb_byte *src); template> void raw_write (int regnum, T val); /* Transfer of pseudo-registers. */ - void cooked_write (int regnum, const gdb_byte *buf); + void cooked_write (int regnum, gdb::array_view src, float); + + /* Deprecated overload of the above. */ + void cooked_write (int regnum, const gdb_byte *src); template> void cooked_write (int regnum, T val); @@ -369,12 +408,21 @@ class regcache : public detached_regcache /* Partial transfer of raw registers. Perform read, modify, write style operations. */ - void raw_write_part (int regnum, int offset, int len, const gdb_byte *buf); + void raw_write_part (int regnum, int offset, + gdb::array_view src); + + /* Deprecated overload of the above. */ + void raw_write_part (int regnum, int offset, int len, const gdb_byte *src) + { raw_write_part (regnum, offset, gdb::make_array_view (src, len)); } /* Partial transfer of a cooked register. Perform read, modify, write style operations. */ - void cooked_write_part (int regnum, int offset, int len, - const gdb_byte *buf); + void cooked_write_part (int regnum, int offset, + gdb::array_view src); + + /* Deprecated overload of the above. */ + void cooked_write_part (int regnum, int offset, int len, const gdb_byte *src) + { cooked_write_part (regnum, offset, gdb::make_array_view (src, len)); } /* Transfer a set of registers (as described by REGSET) between REGCACHE and BUF. If REGNUM == -1, transfer all registers @@ -442,8 +490,9 @@ class regcache : public detached_regcache /* Perform a partial register transfer using a read, modify, write operation. */ - enum register_status write_part (int regnum, int offset, int len, - const gdb_byte *in, bool is_raw); + register_status write_part (int regnum, int offset, + gdb::array_view src, + bool is_raw); /* The address space of this register cache (for registers where it makes sense, like PC or SP). */ diff --git a/gdbserver/regcache.cc b/gdbserver/regcache.cc index 4ac0fb659c3b..e1c174b56cb6 100644 --- a/gdbserver/regcache.cc +++ b/gdbserver/regcache.cc @@ -315,27 +315,33 @@ regcache_register_size (const reg_buffer_common *regcache, int n) (gdb::checked_static_cast (regcache)->tdesc, n); } -static unsigned char * +static gdb::array_view register_data (const struct regcache *regcache, int n) { - return (regcache->registers - + find_register_by_number (regcache->tdesc, n).offset / 8); + const gdb::reg ® = find_register_by_number (regcache->tdesc, n); + return gdb::make_array_view (regcache->registers + reg.offset / 8, + reg.size / 8); } void -supply_register (struct regcache *regcache, int n, const void *buf) +supply_register (struct regcache *regcache, int n, const void *vbuf) { - return regcache->raw_supply (n, buf); + const gdb::reg ® = find_register_by_number (regcache->tdesc, n); + const gdb_byte *buf = static_cast (vbuf); + return regcache->raw_supply (n, gdb::make_array_view (buf, reg.size / 8), + 1.0f); } /* See gdbsupport/common-regcache.h. */ void -regcache::raw_supply (int n, const void *buf) +regcache::raw_supply (int n, gdb::array_view src, float) { - if (buf) + auto dst = register_data (this, n); + + if (src.data () != nullptr) { - memcpy (register_data (this, n), buf, register_size (tdesc, n)); + copy (src, dst); #ifndef IN_PROCESS_AGENT if (register_status != NULL) register_status[n] = REG_VALID; @@ -343,7 +349,7 @@ regcache::raw_supply (int n, const void *buf) } else { - memset (register_data (this, n), 0, register_size (tdesc, n)); + memset (dst.data (), 0, dst.size ()); #ifndef IN_PROCESS_AGENT if (register_status != NULL) register_status[n] = REG_UNAVAILABLE; @@ -356,8 +362,8 @@ regcache::raw_supply (int n, const void *buf) void supply_register_zeroed (struct regcache *regcache, int n) { - memset (register_data (regcache, n), 0, - register_size (regcache->tdesc, n)); + auto dst = register_data (regcache, n); + memset (dst.data (), 0, dst.size ()); #ifndef IN_PROCESS_AGENT if (regcache->register_status != NULL) regcache->register_status[n] = REG_VALID; @@ -426,17 +432,20 @@ supply_register_by_name (struct regcache *regcache, #endif void -collect_register (struct regcache *regcache, int n, void *buf) +collect_register (struct regcache *regcache, int n, void *vbuf) { - regcache->raw_collect (n, buf); + const gdb::reg ® = find_register_by_number (regcache->tdesc, n); + gdb_byte *buf = static_cast (vbuf); + regcache->raw_collect (n, gdb::make_array_view (buf, reg.size / 8), 1.0f); } /* See gdbsupport/common-regcache.h. */ void -regcache::raw_collect (int n, void *buf) const +regcache::raw_collect (int n, gdb::array_view dst, float) const { - memcpy (buf, register_data (this, n), register_size (tdesc, n)); + auto src = register_data (this, n); + copy (src, dst); } enum register_status @@ -476,8 +485,7 @@ regcache_raw_get_unsigned_by_name (struct regcache *regcache, void collect_register_as_string (struct regcache *regcache, int n, char *buf) { - bin2hex (register_data (regcache, n), buf, - register_size (regcache->tdesc, n)); + bin2hex (register_data (regcache, n), buf); } void @@ -524,9 +532,9 @@ regcache::raw_compare (int regnum, const void *buf, int offset) const { gdb_assert (buf != NULL); - const unsigned char *regbuf = register_data (this, regnum); - int size = register_size (tdesc, regnum); - gdb_assert (size >= offset); + gdb::array_view regbuf = register_data (this, regnum); + gdb_assert (offset < regbuf.size ()); + regbuf = regbuf.slice (offset); - return (memcmp (buf, regbuf + offset, size - offset) == 0); + return memcmp (buf, regbuf.data (), regbuf.size ()) == 0; } diff --git a/gdbserver/regcache.h b/gdbserver/regcache.h index 7248bcf5808a..ba093c97c1f0 100644 --- a/gdbserver/regcache.h +++ b/gdbserver/regcache.h @@ -50,10 +50,12 @@ struct regcache : public reg_buffer_common enum register_status get_register_status (int regnum) const override; /* See gdbsupport/common-regcache.h. */ - void raw_supply (int regnum, const void *buf) override; + void raw_supply (int regnum, gdb::array_view src, + float) override; /* See gdbsupport/common-regcache.h. */ - void raw_collect (int regnum, void *buf) const override; + void raw_collect (int regnum, gdb::array_view dst, + float) const override; /* See gdbsupport/common-regcache.h. */ bool raw_compare (int regnum, const void *buf, int offset) const override; diff --git a/gdbsupport/common-regcache.h b/gdbsupport/common-regcache.h index 6d98ca8c92ed..75d209f7cbc0 100644 --- a/gdbsupport/common-regcache.h +++ b/gdbsupport/common-regcache.h @@ -78,11 +78,44 @@ struct reg_buffer_common buffer. */ virtual register_status get_register_status (int regnum) const = 0; - /* Supply register REGNUM, whose contents are stored in BUF, to REGCACHE. */ - virtual void raw_supply (int regnum, const void *buf) = 0; + /* Supply register REGNUM, whose contents are stored in SRC, to this register + buffer. */ + virtual void raw_supply (int regnum, gdb::array_view src, + float) = 0; + + void raw_supply (int regnum, const uint64_t *src) + { + raw_supply (regnum, + gdb::make_array_view ((const gdb_byte *) src, sizeof (*src)), + 1.0f); + } + + void raw_supply (int regnum, const gdb_byte *src) + { + raw_supply (regnum, + gdb::make_array_view (src, + regcache_register_size (this, regnum)), + 1.0f); + } + + /* Collect register REGNUM from this register buffer and store its contents in + DST. */ + virtual void raw_collect (int regnum, gdb::array_view dst, + float) const = 0; + + void raw_collect (int regnum, uint64_t *dst) const + { + raw_collect (regnum, + gdb::make_array_view ((gdb_byte *) dst, sizeof (*dst)), 1.0f); + }; - /* Collect register REGNUM from REGCACHE and store its contents in BUF. */ - virtual void raw_collect (int regnum, void *buf) const = 0; + void raw_collect (int regnum, gdb_byte *dst) + { + raw_collect (regnum, + gdb::make_array_view (dst, + regcache_register_size (this, regnum)), + 1.0f); + } /* Compare the contents of the register stored in the regcache (ignoring the first OFFSET bytes) to the contents of BUF (without any offset). Returns diff --git a/gdbsupport/rsp-low.cc b/gdbsupport/rsp-low.cc index 3d8c2002956e..632be265c00c 100644 --- a/gdbsupport/rsp-low.cc +++ b/gdbsupport/rsp-low.cc @@ -143,6 +143,14 @@ bin2hex (const gdb_byte *bin, char *hex, int count) /* See rsp-low.h. */ +int +bin2hex (gdb::array_view bin, char *hex) +{ + return bin2hex (bin.data (), hex, bin.size ()); +} + +/* See rsp-low.h. */ + std::string bin2hex (const gdb_byte *bin, int count) { diff --git a/gdbsupport/rsp-low.h b/gdbsupport/rsp-low.h index 327d5f3a0947..1fc2572a7f5c 100644 --- a/gdbsupport/rsp-low.h +++ b/gdbsupport/rsp-low.h @@ -54,6 +54,8 @@ extern std::string hex2str (const char *hex, int count); extern int bin2hex (const gdb_byte *bin, char *hex, int count); +extern int bin2hex (gdb::array_view bin, char *hex); + /* Overloaded version of bin2hex that returns a std::string. */ extern std::string bin2hex (const gdb_byte *bin, int count); From patchwork Wed Nov 8 05:00:50 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Marchi X-Patchwork-Id: 79382 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 7491A3858004 for ; Wed, 8 Nov 2023 05:21:58 +0000 (GMT) X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from smtp.polymtl.ca (smtp.polymtl.ca [132.207.4.11]) by sourceware.org (Postfix) with ESMTPS id 5F73D3858D1E for ; Wed, 8 Nov 2023 05:21:44 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 5F73D3858D1E Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=polymtl.ca Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=polymtl.ca ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 5F73D3858D1E Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=132.207.4.11 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1699420905; cv=none; b=DlQl8Sw9nY6T4l7OnMP9gPGk+LMiP32saHGmwJWO9OgQeT7BsZC7zO5+sUdq+fToin2c86+PGETQ6Ns0pcbvCPhIoYsAMVoW/3BodByutS+9A+3Bs1qnE0xgBTEzrvmH3Tj8BLUff7XDEjzeDRujYSE4ZGXrmMOI3DcpIcIkoCc= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1699420905; c=relaxed/simple; bh=8SX4P9U/z8qCKf4HMZhvtecIes2oJ4TOQcK58MgAFLM=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=T/MYxAipRhbLHVKz3haNiymgOmc7U2HENlABjUSFe5Fhh/o3WU6ZEGKf45qEEATdhKQwA2SqmAlNtTgHznj/koLO+ci8MXsXPVjHoSPd/IlKqWrBYCO4fSejXzyki0ckwWlLtktMx/6OieBTEuDCQE9kzCsmBXCedIi3H5O9Z94= ARC-Authentication-Results: i=1; server2.sourceware.org Received: from simark.ca (simark.ca [158.69.221.121]) (authenticated bits=0) by smtp.polymtl.ca (8.14.7/8.14.7) with ESMTP id 3A85LcHJ016954 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 8 Nov 2023 00:21:42 -0500 DKIM-Filter: OpenDKIM Filter v2.11.0 smtp.polymtl.ca 3A85LcHJ016954 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=polymtl.ca; s=default; t=1699420902; bh=kG2kgDX0uZdraS1+5yRYFvl3G6YP/j4NmjmZrY3oKWY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=H7KUiW36Jln/q2dcI1HImcLg8pEQV8sxhwbo+zF6/3q/DT5YNEver7vbH1cuBNMes zSS2Rc1gs2bw8r0U2oxKS3lUp82sdBESye0bT0Y7e6lZbI9B3d8BZQtbPsPcxRXBtE yRK5F6x0PO7WGZGc0yxhXAY/OFl8l+HXc/Kx3RV0= Received: from simark.localdomain (modemcable238.237-201-24.mc.videotron.ca [24.201.237.238]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) by simark.ca (Postfix) with ESMTPSA id 2F7301E1A8; Wed, 8 Nov 2023 00:12:28 -0500 (EST) From: Simon Marchi To: gdb-patches@sourceware.org Cc: Simon Marchi Subject: [PATCH 06/24] gdb: fix bugs in {get,put}_frame_register_bytes Date: Wed, 8 Nov 2023 00:00:50 -0500 Message-ID: <20231108051222.1275306-7-simon.marchi@polymtl.ca> X-Mailer: git-send-email 2.42.1 In-Reply-To: <20231108051222.1275306-1-simon.marchi@polymtl.ca> References: <20231108051222.1275306-1-simon.marchi@polymtl.ca> MIME-Version: 1.0 X-Poly-FromMTA: (simark.ca [158.69.221.121]) at Wed, 8 Nov 2023 05:21:38 +0000 X-Spam-Status: No, score=-3188.6 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_PASS, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE 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.30 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org From: Simon Marchi I found this only by inspection: the myaddr pointer in {get,put}_frame_register_bytes is reset to `buffer.data ()` at each iteration. This means that we will always use the bytes at the beginning of `buffer` to read or write to the registers, instead of progressing in `buffer`. Fix this by re-writing the functions to chip away the beginning of the buffer array_view as we progress in reading or writing the data. These bugs was introduced almost 3 years ago [1], and yet nobody complained. I'm wondering which architecture relies on that register "overflow" behavior (reading or writing multiple consecutive registers with one {get,put}_frame_register_bytes calls), and in which situation. I find these functions a bit dangerous, if a caller mis-calculates things, it could end up silently reading or writing to the next register, even if it's not the intent. If I could change it, I would prefer to have functions specifically made for that ({get,put}_frame_register_bytes_consecutive or something like that) and make {get,put}_frame_register_bytes only able to write within a single register (which I presume represents most of the use cases of the current {get,put}_frame_register_bytes). If a caller mis-calculates things and an overflow occurs while calling {get,put}_frame_register_bytes, it would hit an assert. The problem is knowing which callers rely on the overflow behavior and which don't. [1] https://gitlab.com/gnutools/binutils-gdb/-/commit/bdec2917b1e94c7198ba39919f45060067952f43 Change-Id: I43bd4a9f7fa8419d388a2b20bdc57d652688ddf8 --- gdb/frame.c | 63 +++++++++++++++++++---------------------------------- 1 file changed, 23 insertions(+), 40 deletions(-) diff --git a/gdb/frame.c b/gdb/frame.c index afadb8ac4e73..b3d99163b4dc 100644 --- a/gdb/frame.c +++ b/gdb/frame.c @@ -1482,9 +1482,6 @@ get_frame_register_bytes (frame_info_ptr frame, int regnum, int *optimizedp, int *unavailablep) { struct gdbarch *gdbarch = get_frame_arch (frame); - int i; - int maxsize; - int numregs; /* Skip registers wholly inside of OFFSET. */ while (offset >= register_size (gdbarch, regnum)) @@ -1495,9 +1492,9 @@ get_frame_register_bytes (frame_info_ptr frame, int regnum, /* Ensure that we will not read beyond the end of the register file. This can only ever happen if the debug information is bad. */ - maxsize = -offset; - numregs = gdbarch_num_cooked_regs (gdbarch); - for (i = regnum; i < numregs; i++) + int maxsize = -offset; + int numregs = gdbarch_num_cooked_regs (gdbarch); + for (int i = regnum; i < numregs; i++) { int thissize = register_size (gdbarch, i); @@ -1506,20 +1503,15 @@ get_frame_register_bytes (frame_info_ptr frame, int regnum, maxsize += thissize; } - int len = buffer.size (); - if (len > maxsize) + if (buffer.size () > maxsize) error (_("Bad debug information detected: " - "Attempt to read %d bytes from registers."), len); + "Attempt to read %zu bytes from registers."), buffer.size ()); /* Copy the data. */ - while (len > 0) + while (!buffer.empty ()) { - int curr_len = register_size (gdbarch, regnum) - offset; - - if (curr_len > len) - curr_len = len; - - gdb_byte *myaddr = buffer.data (); + int curr_len = std::min (register_size (gdbarch, regnum) - offset, + buffer.size ()); if (curr_len == register_size (gdbarch, regnum)) { @@ -1527,8 +1519,8 @@ get_frame_register_bytes (frame_info_ptr frame, int regnum, CORE_ADDR addr; int realnum; - frame_register (frame, regnum, optimizedp, unavailablep, - &lval, &addr, &realnum, myaddr); + frame_register (frame, regnum, optimizedp, unavailablep, &lval, + &addr, &realnum, buffer.data ()); if (*optimizedp || *unavailablep) return false; } @@ -1547,13 +1539,12 @@ get_frame_register_bytes (frame_info_ptr frame, int regnum, return false; } - memcpy (myaddr, value->contents_all ().data () + offset, - curr_len); + copy (value->contents_all ().slice (offset, curr_len), + buffer.slice (0, curr_len)); release_value (value); } - myaddr += curr_len; - len -= curr_len; + buffer = buffer.slice (curr_len); offset = 0; regnum++; } @@ -1578,36 +1569,28 @@ put_frame_register_bytes (frame_info_ptr frame, int regnum, regnum++; } - int len = buffer.size (); /* Copy the data. */ - while (len > 0) + while (!buffer.empty ()) { - int curr_len = register_size (gdbarch, regnum) - offset; + int curr_len = std::min (register_size (gdbarch, regnum) - offset, + buffer.size ()); - if (curr_len > len) - curr_len = len; - - const gdb_byte *myaddr = buffer.data (); if (curr_len == register_size (gdbarch, regnum)) - { - put_frame_register (frame, regnum, myaddr); - } + put_frame_register (frame, regnum, buffer.data ()); else { - struct value *value + value *value = frame_unwind_register_value (frame_info_ptr (frame->next), regnum); - gdb_assert (value != NULL); + gdb_assert (value != nullptr); - memcpy ((char *) value->contents_writeable ().data () + offset, - myaddr, curr_len); - put_frame_register (frame, regnum, - value->contents_raw ().data ()); + copy (buffer.slice (0, curr_len), + value->contents_writeable ().slice (offset, curr_len)); + put_frame_register (frame, regnum, value->contents_raw ().data ()); release_value (value); } - myaddr += curr_len; - len -= curr_len; + buffer = buffer.slice (curr_len); offset = 0; regnum++; } From patchwork Wed Nov 8 05:00:51 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Marchi X-Patchwork-Id: 79384 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 830FA3858C5E for ; Wed, 8 Nov 2023 05:22:03 +0000 (GMT) X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from smtp.polymtl.ca (smtp.polymtl.ca [132.207.4.11]) by sourceware.org (Postfix) with ESMTPS id 6AE293858D33 for ; Wed, 8 Nov 2023 05:21:44 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 6AE293858D33 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=polymtl.ca Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=polymtl.ca ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 6AE293858D33 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=132.207.4.11 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1699420906; cv=none; b=oIw1uXeDMieCvnPUsKMYzQNm4w0HiHSx6yp9ppDOwGNMgM+PcaAL/6hOARjQPP1V2+8cC++EHgRV5mId9rGTsik10YyZp9fkdNFTRIMGYkpSRVQV5s6r4XTJQkhfH8DFbP5FFUSj69+71kPvBFVK9e7pT5T9gPY6AbjGv2ivIcw= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1699420906; c=relaxed/simple; bh=rPGJtb79tvnJTTBPKIwD78wql//vfYHzAqmAqPNHcqc=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=iJs5We90fMl+HaCCAmdJ42x4gPVBcvPR81DflzSZlixSS8Z5D4BBzVBOmsHXXLtymc6lwrFpNK8b8qe3thYrFl73EW0quPqal/JaD1dHFikSgA8TRAXEXmpsy4fQSP5hdHt6Zi+WzzqJWncGEaGDvjsTiMkN0bdnjyIuYF4rPqw= ARC-Authentication-Results: i=1; server2.sourceware.org Received: from simark.ca (simark.ca [158.69.221.121]) (authenticated bits=0) by smtp.polymtl.ca (8.14.7/8.14.7) with ESMTP id 3A85LctJ016956 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 8 Nov 2023 00:21:42 -0500 DKIM-Filter: OpenDKIM Filter v2.11.0 smtp.polymtl.ca 3A85LctJ016956 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=polymtl.ca; s=default; t=1699420903; bh=QwhPYfzLGbOgYhDLM6VtGzikl9903T93zn83Pj1mtNI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=nfjrRD6V1Z167OzPJs2SdU7sf+ay4QUEl1UU+sPzh9s6K9XfbA5P9MCUeBhjo0rpT YMkhShT5ir5VxU/vvIgJOw3pxjKVAl+5afknE1rufUv4lXbIa3TZ5GgjbsXzm8BdmY 5eUU6Uh84jUNQYIJyqwGN+sYc9ARdwF3GyvBE/28= Received: from simark.localdomain (modemcable238.237-201-24.mc.videotron.ca [24.201.237.238]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) by simark.ca (Postfix) with ESMTPSA id 4671F1E1A9; Wed, 8 Nov 2023 00:12:28 -0500 (EST) From: Simon Marchi To: gdb-patches@sourceware.org Cc: Simon Marchi Subject: [PATCH 07/24] gdb: make put_frame_register take an array_view Date: Wed, 8 Nov 2023 00:00:51 -0500 Message-ID: <20231108051222.1275306-8-simon.marchi@polymtl.ca> X-Mailer: git-send-email 2.42.1 In-Reply-To: <20231108051222.1275306-1-simon.marchi@polymtl.ca> References: <20231108051222.1275306-1-simon.marchi@polymtl.ca> MIME-Version: 1.0 X-Poly-FromMTA: (simark.ca [158.69.221.121]) at Wed, 8 Nov 2023 05:21:38 +0000 X-Spam-Status: No, score=-3188.6 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_PASS, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE 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.30 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org From: Simon Marchi Change put_frame_register to take an array_view instead of a raw pointer. Add an assertion to verify that the number of bytes we try to write matches the length of the register. Change-Id: Ib75a9c8a12b47e203097621643eaa2c1830591ae --- gdb/alpha-tdep.c | 12 ++++++------ gdb/frame.c | 13 ++++++++----- gdb/frame.h | 2 +- gdb/i386-tdep.c | 3 ++- gdb/i387-tdep.c | 6 ++++-- gdb/ia64-tdep.c | 6 ++++-- gdb/m68k-tdep.c | 7 ++++--- gdb/mips-tdep.c | 5 +++-- gdb/rs6000-tdep.c | 7 ++++--- 9 files changed, 36 insertions(+), 25 deletions(-) diff --git a/gdb/alpha-tdep.c b/gdb/alpha-tdep.c index 9fb973597fc4..1901b9449e6c 100644 --- a/gdb/alpha-tdep.c +++ b/gdb/alpha-tdep.c @@ -263,14 +263,14 @@ static void alpha_value_to_register (frame_info_ptr frame, int regnum, struct type *valtype, const gdb_byte *in) { - gdb_byte out[ALPHA_REGISTER_SIZE]; - + int reg_size = register_size (get_frame_arch (frame), regnum); gdb_assert (valtype->length () == 4); - gdb_assert (register_size (get_frame_arch (frame), regnum) - <= ALPHA_REGISTER_SIZE); - alpha_lds (get_frame_arch (frame), out, in); + gdb_assert (reg_size <= ALPHA_REGISTER_SIZE); - put_frame_register (frame, regnum, out); + gdb_byte out[ALPHA_REGISTER_SIZE]; + alpha_lds (get_frame_arch (frame), out, in); + auto out_view = gdb::make_array_view (out, reg_size); + put_frame_register (frame, regnum, out_view); } diff --git a/gdb/frame.c b/gdb/frame.c index b3d99163b4dc..84ef8461b835 100644 --- a/gdb/frame.c +++ b/gdb/frame.c @@ -1423,7 +1423,7 @@ read_frame_register_unsigned (frame_info_ptr frame, int regnum, void put_frame_register (frame_info_ptr frame, int regnum, - const gdb_byte *buf) + gdb::array_view buf) { struct gdbarch *gdbarch = get_frame_arch (frame); int realnum; @@ -1431,6 +1431,9 @@ put_frame_register (frame_info_ptr frame, int regnum, int unavail; enum lval_type lval; CORE_ADDR addr; + int size = register_size (gdbarch, regnum); + + gdb_assert (buf.size () == size); frame_register (frame, regnum, &optim, &unavail, &lval, &addr, &realnum, NULL); @@ -1440,11 +1443,11 @@ put_frame_register (frame_info_ptr frame, int regnum, { case lval_memory: { - write_memory (addr, buf, register_size (gdbarch, regnum)); + write_memory (addr, buf.data (), size); break; } case lval_register: - get_current_regcache ()->cooked_write (realnum, buf); + get_current_regcache ()->cooked_write (realnum, buf, 1.0f); break; default: error (_("Attempt to assign to an unmodifiable value.")); @@ -1576,7 +1579,7 @@ put_frame_register_bytes (frame_info_ptr frame, int regnum, buffer.size ()); if (curr_len == register_size (gdbarch, regnum)) - put_frame_register (frame, regnum, buffer.data ()); + put_frame_register (frame, regnum, buffer.slice (0, curr_len)); else { value *value @@ -1586,7 +1589,7 @@ put_frame_register_bytes (frame_info_ptr frame, int regnum, copy (buffer.slice (0, curr_len), value->contents_writeable ().slice (offset, curr_len)); - put_frame_register (frame, regnum, value->contents_raw ().data ()); + put_frame_register (frame, regnum, value->contents_raw ()); release_value (value); } diff --git a/gdb/frame.h b/gdb/frame.h index 1d7422cac32b..e3393cdd972c 100644 --- a/gdb/frame.h +++ b/gdb/frame.h @@ -724,7 +724,7 @@ extern bool read_frame_register_unsigned (frame_info_ptr frame, frame. Note: this call makes the frame's state undefined. The register and frame caches must be flushed. */ extern void put_frame_register (frame_info_ptr frame, int regnum, - const gdb_byte *buf); + gdb::array_view buf); /* Read LEN bytes from one or multiple registers starting with REGNUM in frame FRAME, starting at OFFSET, into BUF. If the register diff --git a/gdb/i386-tdep.c b/gdb/i386-tdep.c index 2759c1a558c5..7f6ea5ba06ec 100644 --- a/gdb/i386-tdep.c +++ b/gdb/i386-tdep.c @@ -3917,7 +3917,8 @@ i386_value_to_register (frame_info_ptr frame, int regnum, gdb_assert (regnum != -1); gdb_assert (register_size (get_frame_arch (frame), regnum) == 4); - put_frame_register (frame, regnum, from); + auto from_view = gdb::make_array_view (from, 4); + put_frame_register (frame, regnum, from_view); regnum = i386_next_regnum (regnum); len -= 4; from += 4; diff --git a/gdb/i387-tdep.c b/gdb/i387-tdep.c index 47667da21c7d..74481f5aeb3c 100644 --- a/gdb/i387-tdep.c +++ b/gdb/i387-tdep.c @@ -397,8 +397,10 @@ i387_value_to_register (frame_info_ptr frame, int regnum, } /* Convert from TYPE. */ - target_float_convert (from, type, to, i387_ext_type (gdbarch)); - put_frame_register (frame, regnum, to); + struct type *to_type = i387_ext_type (gdbarch); + target_float_convert (from, type, to, to_type); + auto to_view = gdb::make_array_view (to, to_type->length ()); + put_frame_register (frame, regnum, to_view); } diff --git a/gdb/ia64-tdep.c b/gdb/ia64-tdep.c index cdd5553cf5d3..113d384e8649 100644 --- a/gdb/ia64-tdep.c +++ b/gdb/ia64-tdep.c @@ -1245,8 +1245,10 @@ ia64_value_to_register (frame_info_ptr frame, int regnum, { struct gdbarch *gdbarch = get_frame_arch (frame); gdb_byte out[IA64_FP_REGISTER_SIZE]; - target_float_convert (in, valtype, out, ia64_ext_type (gdbarch)); - put_frame_register (frame, regnum, out); + type *to_type = ia64_ext_type (gdbarch); + target_float_convert (in, valtype, out, to_type); + auto out_view = gdb::make_array_view (out, to_type->length ()); + put_frame_register (frame, regnum, out_view); } diff --git a/gdb/m68k-tdep.c b/gdb/m68k-tdep.c index 5b2a29a350e5..5a80ecb94390 100644 --- a/gdb/m68k-tdep.c +++ b/gdb/m68k-tdep.c @@ -236,8 +236,8 @@ m68k_value_to_register (frame_info_ptr frame, int regnum, struct type *type, const gdb_byte *from) { gdb_byte to[M68K_MAX_REGISTER_SIZE]; - struct type *fpreg_type = register_type (get_frame_arch (frame), - M68K_FP0_REGNUM); + gdbarch *arch = get_frame_arch (frame); + struct type *fpreg_type = register_type (arch, M68K_FP0_REGNUM); /* We only support floating-point values. */ if (type->code () != TYPE_CODE_FLT) @@ -249,7 +249,8 @@ m68k_value_to_register (frame_info_ptr frame, int regnum, /* Convert from TYPE. */ target_float_convert (from, type, to, fpreg_type); - put_frame_register (frame, regnum, to); + auto to_view = gdb::make_array_view (to, fpreg_type->length ()); + put_frame_register (frame, regnum, to_view); } diff --git a/gdb/mips-tdep.c b/gdb/mips-tdep.c index d40d28e85de5..6bd0a66a6284 100644 --- a/gdb/mips-tdep.c +++ b/gdb/mips-tdep.c @@ -990,8 +990,9 @@ mips_value_to_register (frame_info_ptr frame, int regnum, if (mips_convert_register_float_case_p (gdbarch, regnum, type)) { - put_frame_register (frame, regnum + 0, from + 4); - put_frame_register (frame, regnum + 1, from + 0); + auto from_view = gdb::make_array_view (from, 8); + put_frame_register (frame, regnum, from_view.slice (4)); + put_frame_register (frame, regnum + 1, from_view.slice (0, 4)); } else if (mips_convert_register_gpreg_case_p (gdbarch, regnum, type)) { diff --git a/gdb/rs6000-tdep.c b/gdb/rs6000-tdep.c index bae6737852d8..9fb3f326bd07 100644 --- a/gdb/rs6000-tdep.c +++ b/gdb/rs6000-tdep.c @@ -2715,9 +2715,10 @@ rs6000_value_to_register (frame_info_ptr frame, gdb_assert (type->code () == TYPE_CODE_FLT); - target_float_convert (from, type, - to, builtin_type (gdbarch)->builtin_double); - put_frame_register (frame, regnum, to); + struct type *to_type = builtin_type (gdbarch)->builtin_double; + target_float_convert (from, type, to, to_type); + auto to_view = gdb::make_array_view (to, to_type->length ()); + put_frame_register (frame, regnum, to_view); } /* The type of a function that moves the value of REG between CACHE From patchwork Wed Nov 8 05:00:52 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Marchi X-Patchwork-Id: 79375 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 614F03858407 for ; Wed, 8 Nov 2023 05:15:08 +0000 (GMT) X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from smtp.polymtl.ca (smtp.polymtl.ca [132.207.4.11]) by sourceware.org (Postfix) with ESMTPS id 4F5BB3858D33 for ; Wed, 8 Nov 2023 05:14:38 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 4F5BB3858D33 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=polymtl.ca Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=polymtl.ca ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 4F5BB3858D33 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=132.207.4.11 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1699420480; cv=none; b=R7EDabcdqIDaJSREPeV3/QrHB8Psph5lE8WOexNsAoIwpYccFmRlC0kAvocjvEuRhdHijsyfflsvk1u+cqwlZEM3GVdzHjNtnCVrrPitwKIz3uqsnyjOqAjl0qLrE0bYIiX2oq2Nuw3e5qCfnCNxKMVzPn2og43X2KnQZD4NTZM= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1699420480; c=relaxed/simple; bh=z0Lghi4XafNJ3zWSzhCMNo0kinrRZarBtO5Wko4xOOk=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=KEW/VyQ7LQKdxlinfaatnWucXsW8tYiI3KpOiIhzycVmXnDc6hIsCALXGZE6CUzrBkmN0U/ShwjxU863WEK7oAOaAclT1LY+qsV+1fn/xg+ijGzTCbDANkciq07Odj/i8Z8uyBSx4aSMee+iBIgpSn4bUWgtH5VCG6lLR+XD23Y= ARC-Authentication-Results: i=1; server2.sourceware.org Received: from simark.ca (simark.ca [158.69.221.121]) (authenticated bits=0) by smtp.polymtl.ca (8.14.7/8.14.7) with ESMTP id 3A85EVIj015671 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 8 Nov 2023 00:14:36 -0500 DKIM-Filter: OpenDKIM Filter v2.11.0 smtp.polymtl.ca 3A85EVIj015671 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=polymtl.ca; s=default; t=1699420476; bh=H+rTrRwM5e5smWCkuvehbU6J+4731T5OT4mdA+8o5Vs=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=aY7xkK3L1UGLZm+jn+VibCWPqACys3skFb4lc+c34kVmAzJi+BoFt448Pf2AB6rBX 95KwDKZxfGby0dH82hbiBHFr90MqH2YOvg8UxhHbLmcBx83aArYe9hMlE+4vtcDvAM 1BDB9YXLVb6XCuyZf5vJaMCj07oeCqX5oXuaCCNA= Received: from simark.localdomain (modemcable238.237-201-24.mc.videotron.ca [24.201.237.238]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) by simark.ca (Postfix) with ESMTPSA id A9D3F1E098; Wed, 8 Nov 2023 00:14:31 -0500 (EST) From: Simon Marchi To: gdb-patches@sourceware.org Cc: Simon Marchi Subject: [PATCH 08/24] gdb: change value_of_register and value_of_register_lazy to take the next frame Date: Wed, 8 Nov 2023 00:00:52 -0500 Message-ID: <20231108051222.1275306-9-simon.marchi@polymtl.ca> X-Mailer: git-send-email 2.42.1 In-Reply-To: <20231108051222.1275306-1-simon.marchi@polymtl.ca> References: <20231108051222.1275306-1-simon.marchi@polymtl.ca> MIME-Version: 1.0 X-Poly-FromMTA: (simark.ca [158.69.221.121]) at Wed, 8 Nov 2023 05:14:31 +0000 X-Spam-Status: No, score=-3188.6 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_PASS, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE 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.30 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org From: Simon Marchi Some functions related to the handling of registers in frames accept "this frame", for which we want to read or write the register values, while other functions accept "the next frame", which is the frame next to that. The later is needed because we sometimes need to read register values for a frame that does not exist yet (usually when trying to unwind that frame-to-be). value_of_register and value_of_register_lazy both take "this frame", even if what they ultimately want internally is "the next frame". This is annoying if you are in a spot that currently has "the next frame" and need to call one of these functions (which happens later in this series). You need to get the previous frame only for those functions to get the next frame again. This is more manipulations, more chances of mistake. I propose to change these functions (and a few more functions in the subsequent patches) to operate on "the next frame". Things become a bit less awkward when all these functions agree on which frame they take. So, in this patch, change value_of_register_lazy and value_of_register to take "the next frame" instead of "this frame". This adds a lot of get_next_frame_sentinel_okay, but if we convert the user registers API to also use "the next frame" instead of "this frame", it will get simple again. Change-Id: Iaa24815e648fbe5ae3c214c738758890a91819cd --- gdb/aarch64-tdep.c | 3 +-- gdb/arm-tdep.c | 4 ++-- gdb/eval.c | 3 ++- gdb/findvar.c | 34 ++++++++++++---------------------- gdb/frame-unwind.c | 3 ++- gdb/guile/scm-frame.c | 3 ++- gdb/infcmd.c | 6 +++--- gdb/loongarch-tdep.c | 3 ++- gdb/mi/mi-main.c | 3 ++- gdb/mips-tdep.c | 2 +- gdb/nds32-tdep.c | 5 +++-- gdb/python/py-frame.c | 3 ++- gdb/python/py-unwind.c | 4 ++-- gdb/riscv-tdep.c | 4 ++-- gdb/s12z-tdep.c | 2 +- gdb/std-regs.c | 11 +++++++---- gdb/value.h | 9 +++++++-- 17 files changed, 53 insertions(+), 49 deletions(-) diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c index eaae2d91047b..50bfaa41eee2 100644 --- a/gdb/aarch64-tdep.c +++ b/gdb/aarch64-tdep.c @@ -3449,9 +3449,8 @@ value_of_aarch64_user_reg (frame_info_ptr frame, const void *baton) { const int *reg_p = (const int *) baton; - return value_of_register (*reg_p, frame); + return value_of_register (*reg_p, get_next_frame_sentinel_okay (frame)); } - /* Implement the "software_single_step" gdbarch method, needed to single step through atomic sequences on AArch64. */ diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c index 2018f4ed0edd..5c8c4cd4e94b 100644 --- a/gdb/arm-tdep.c +++ b/gdb/arm-tdep.c @@ -9954,9 +9954,9 @@ static struct value * value_of_arm_user_reg (frame_info_ptr frame, const void *baton) { const int *reg_p = (const int *) baton; - return value_of_register (*reg_p, frame); + return value_of_register (*reg_p, get_next_frame_sentinel_okay (frame)); } - + static enum gdb_osabi arm_elf_osabi_sniffer (bfd *abfd) { diff --git a/gdb/eval.c b/gdb/eval.c index b859e825925b..16206d92702a 100644 --- a/gdb/eval.c +++ b/gdb/eval.c @@ -1134,7 +1134,8 @@ eval_op_register (struct type *expect_type, struct expression *exp, && regno < gdbarch_num_cooked_regs (exp->gdbarch)) val = value::zero (register_type (exp->gdbarch, regno), not_lval); else - val = value_of_register (regno, get_selected_frame (NULL)); + val = value_of_register + (regno, get_next_frame_sentinel_okay (get_selected_frame ())); if (val == NULL) error (_("Value of register %s not available."), name); else diff --git a/gdb/findvar.c b/gdb/findvar.c index edb61fb27317..6ee31e780932 100644 --- a/gdb/findvar.c +++ b/gdb/findvar.c @@ -244,42 +244,32 @@ copy_integer_to_size (gdb_byte *dest, int dest_size, const gdb_byte *source, } } -/* Return a `value' with the contents of (virtual or cooked) register - REGNUM as found in the specified FRAME. The register's type is - determined by register_type (). */ +/* See value.h. */ -struct value * -value_of_register (int regnum, frame_info_ptr frame) +value * +value_of_register (int regnum, frame_info_ptr next_frame) { - struct gdbarch *gdbarch = get_frame_arch (frame); - struct value *reg_val; + gdbarch *gdbarch = frame_unwind_arch (next_frame); /* User registers lie completely outside of the range of normal registers. Catch them early so that the target never sees them. */ if (regnum >= gdbarch_num_cooked_regs (gdbarch)) - return value_of_user_reg (regnum, frame); + return value_of_user_reg (regnum, get_prev_frame_always (next_frame)); - reg_val = value_of_register_lazy (frame, regnum); + value *reg_val = value_of_register_lazy (next_frame, regnum); reg_val->fetch_lazy (); return reg_val; } -/* Return a `value' with the contents of (virtual or cooked) register - REGNUM as found in the specified FRAME. The register's type is - determined by register_type (). The value is not fetched. */ +/* See value.h. */ -struct value * -value_of_register_lazy (frame_info_ptr frame, int regnum) +value * +value_of_register_lazy (frame_info_ptr next_frame, int regnum) { - struct gdbarch *gdbarch = get_frame_arch (frame); - struct value *reg_val; - frame_info_ptr next_frame; + gdbarch *gdbarch = frame_unwind_arch (next_frame); gdb_assert (regnum < gdbarch_num_cooked_regs (gdbarch)); - - gdb_assert (frame != NULL); - - next_frame = get_next_frame_sentinel_okay (frame); + gdb_assert (next_frame != nullptr); /* In some cases NEXT_FRAME may not have a valid frame-id yet. This can happen if we end up trying to unwind a register as part of the frame @@ -292,7 +282,7 @@ value_of_register_lazy (frame_info_ptr frame, int regnum) /* We should have a valid next frame. */ gdb_assert (frame_id_p (get_frame_id (next_frame))); - reg_val = value::allocate_lazy (register_type (gdbarch, regnum)); + value *reg_val = value::allocate_lazy (register_type (gdbarch, regnum)); reg_val->set_lval (lval_register); VALUE_REGNUM (reg_val) = regnum; VALUE_NEXT_FRAME_ID (reg_val) = get_frame_id (next_frame); diff --git a/gdb/frame-unwind.c b/gdb/frame-unwind.c index 927b6256b0b3..89ae3d70b200 100644 --- a/gdb/frame-unwind.c +++ b/gdb/frame-unwind.c @@ -278,7 +278,8 @@ struct value * frame_unwind_got_register (frame_info_ptr frame, int regnum, int new_regnum) { - return value_of_register_lazy (frame, new_regnum); + return value_of_register_lazy (get_next_frame_sentinel_okay (frame), + new_regnum); } /* Return a value which indicates that FRAME saved REGNUM in memory at diff --git a/gdb/guile/scm-frame.c b/gdb/guile/scm-frame.c index 45863c587c1d..830acb8b53ed 100644 --- a/gdb/guile/scm-frame.c +++ b/gdb/guile/scm-frame.c @@ -835,7 +835,8 @@ gdbscm_frame_read_register (SCM self, SCM register_scm) register_str, strlen (register_str)); if (regnum >= 0) - value = value_of_register (regnum, frame); + value = value_of_register (regnum, + get_next_frame_sentinel_okay (frame)); } } catch (const gdb_exception &ex) diff --git a/gdb/infcmd.c b/gdb/infcmd.c index cf8cd5279558..63b700c1e669 100644 --- a/gdb/infcmd.c +++ b/gdb/infcmd.c @@ -2318,9 +2318,9 @@ default_print_registers_info (struct gdbarch *gdbarch, if (*(gdbarch_register_name (gdbarch, i)) == '\0') continue; - default_print_one_register_info (file, - gdbarch_register_name (gdbarch, i), - value_of_register (i, frame)); + default_print_one_register_info + (file, gdbarch_register_name (gdbarch, i), + value_of_register (i, get_next_frame_sentinel_okay (frame))); } } diff --git a/gdb/loongarch-tdep.c b/gdb/loongarch-tdep.c index c65e2414bf8a..6d862dcec044 100644 --- a/gdb/loongarch-tdep.c +++ b/gdb/loongarch-tdep.c @@ -392,7 +392,8 @@ loongarch_software_single_step (struct regcache *regcache) static struct value * value_of_loongarch_user_reg (frame_info_ptr frame, const void *baton) { - return value_of_register ((long long) baton, frame); + return value_of_register ((long long) baton, + get_next_frame_sentinel_okay (frame)); } /* Implement the frame_align gdbarch method. */ diff --git a/gdb/mi/mi-main.c b/gdb/mi/mi-main.c index 944c9116731f..dd5079f87c6c 100644 --- a/gdb/mi/mi-main.c +++ b/gdb/mi/mi-main.c @@ -1101,7 +1101,8 @@ output_register (frame_info_ptr frame, int regnum, int format, int skip_unavailable) { struct ui_out *uiout = current_uiout; - struct value *val = value_of_register (regnum, frame); + value *val + = value_of_register (regnum, get_next_frame_sentinel_okay (frame)); struct value_print_options opts; if (skip_unavailable && !val->entirely_available ()) diff --git a/gdb/mips-tdep.c b/gdb/mips-tdep.c index 6bd0a66a6284..ac90aa1f2c5f 100644 --- a/gdb/mips-tdep.c +++ b/gdb/mips-tdep.c @@ -8074,7 +8074,7 @@ static struct value * value_of_mips_user_reg (frame_info_ptr frame, const void *baton) { const int *reg_p = (const int *) baton; - return value_of_register (*reg_p, frame); + return value_of_register (*reg_p, get_next_frame_sentinel_okay (frame)); } static struct gdbarch * diff --git a/gdb/nds32-tdep.c b/gdb/nds32-tdep.c index a81b5fd1fae1..7618a81fc256 100644 --- a/gdb/nds32-tdep.c +++ b/gdb/nds32-tdep.c @@ -267,9 +267,10 @@ static const struct static struct value * value_of_nds32_reg (frame_info_ptr frame, const void *baton) { - return value_of_register ((int) (intptr_t) baton, frame); + return value_of_register ((int) (intptr_t) baton, + get_next_frame_sentinel_okay (frame)); } - + /* Implement the "frame_align" gdbarch method. */ static CORE_ADDR diff --git a/gdb/python/py-frame.c b/gdb/python/py-frame.c index 1a55e514e396..e6e245520323 100644 --- a/gdb/python/py-frame.c +++ b/gdb/python/py-frame.c @@ -260,7 +260,8 @@ frapy_read_register (PyObject *self, PyObject *args, PyObject *kw) return nullptr; gdb_assert (regnum >= 0); - struct value *val = value_of_register (regnum, frame); + value *val + = value_of_register (regnum, get_next_frame_sentinel_okay (frame)); if (val == NULL) PyErr_SetString (PyExc_ValueError, _("Can't read register.")); diff --git a/gdb/python/py-unwind.c b/gdb/python/py-unwind.c index ee50c51b531d..f1162f22290f 100644 --- a/gdb/python/py-unwind.c +++ b/gdb/python/py-unwind.c @@ -467,8 +467,8 @@ pending_framepy_read_register (PyObject *self, PyObject *args, PyObject *kw) which maps to a real register. In the past, get_frame_register_value() was used here, which did not handle the user register case. */ - struct value *val = value_of_register (regnum, - pending_frame->frame_info); + value *val = value_of_register + (regnum, get_next_frame_sentinel_okay (pending_frame->frame_info)); if (val == NULL) PyErr_Format (PyExc_ValueError, "Cannot read register %d from frame.", diff --git a/gdb/riscv-tdep.c b/gdb/riscv-tdep.c index 3a2891c2c920..48f5a9e35e67 100644 --- a/gdb/riscv-tdep.c +++ b/gdb/riscv-tdep.c @@ -168,7 +168,7 @@ static struct value * value_of_riscv_user_reg (frame_info_ptr frame, const void *baton) { const int *reg_p = (const int *) baton; - return value_of_register (*reg_p, frame); + return value_of_register (*reg_p, get_next_frame_sentinel_okay (frame)); } /* Information about a register alias that needs to be set up for this @@ -1149,7 +1149,7 @@ riscv_print_one_register_info (struct gdbarch *gdbarch, try { - val = value_of_register (regnum, frame); + val = value_of_register (regnum, get_next_frame_sentinel_okay (frame)); regtype = val->type (); } catch (const gdb_exception_error &ex) diff --git a/gdb/s12z-tdep.c b/gdb/s12z-tdep.c index 4781eab083eb..42fd1fb1d6ca 100644 --- a/gdb/s12z-tdep.c +++ b/gdb/s12z-tdep.c @@ -494,7 +494,7 @@ s12z_print_ccw_info (struct gdbarch *gdbarch, frame_info_ptr frame, int reg) { - struct value *v = value_of_register (reg, frame); + value *v = value_of_register (reg, get_next_frame_sentinel_okay (frame)); const char *name = gdbarch_register_name (gdbarch, reg); uint32_t ccw = value_as_long (v); gdb_puts (name, file); diff --git a/gdb/std-regs.c b/gdb/std-regs.c index 54cf9018e426..221b15f1de9f 100644 --- a/gdb/std-regs.c +++ b/gdb/std-regs.c @@ -39,7 +39,7 @@ value_of_builtin_frame_fp_reg (frame_info_ptr frame, const void *baton) register can do so by adding "fp" to register name table (mind you, doing this is probably a dangerous thing). */ return value_of_register (gdbarch_deprecated_fp_regnum (gdbarch), - frame); + get_next_frame_sentinel_okay (frame)); else { struct type *data_ptr_type = builtin_type (gdbarch)->builtin_data_ptr; @@ -58,7 +58,8 @@ value_of_builtin_frame_pc_reg (frame_info_ptr frame, const void *baton) struct gdbarch *gdbarch = get_frame_arch (frame); if (gdbarch_pc_regnum (gdbarch) >= 0) - return value_of_register (gdbarch_pc_regnum (gdbarch), frame); + return value_of_register (gdbarch_pc_regnum (gdbarch), + get_next_frame_sentinel_okay (frame)); else { struct type *func_ptr_type = builtin_type (gdbarch)->builtin_func_ptr; @@ -77,7 +78,8 @@ value_of_builtin_frame_sp_reg (frame_info_ptr frame, const void *baton) struct gdbarch *gdbarch = get_frame_arch (frame); if (gdbarch_sp_regnum (gdbarch) >= 0) - return value_of_register (gdbarch_sp_regnum (gdbarch), frame); + return value_of_register (gdbarch_sp_regnum (gdbarch), + get_next_frame_sentinel_okay (frame)); error (_("Standard register ``$sp'' is not available for this target")); } @@ -87,7 +89,8 @@ value_of_builtin_frame_ps_reg (frame_info_ptr frame, const void *baton) struct gdbarch *gdbarch = get_frame_arch (frame); if (gdbarch_ps_regnum (gdbarch) >= 0) - return value_of_register (gdbarch_ps_regnum (gdbarch), frame); + return value_of_register (gdbarch_ps_regnum (gdbarch), + get_next_frame_sentinel_okay (frame)); error (_("Standard register ``$ps'' is not available for this target")); } diff --git a/gdb/value.h b/gdb/value.h index e4912717684b..37017c9dd9f7 100644 --- a/gdb/value.h +++ b/gdb/value.h @@ -1123,9 +1123,14 @@ extern struct value *value_of_variable (struct symbol *var, extern struct value *address_of_variable (struct symbol *var, const struct block *b); -extern struct value *value_of_register (int regnum, frame_info_ptr frame); +/* Return a value with the contents of register REGNUM as found in the frame + previous to NEXT_FRAME. */ -struct value *value_of_register_lazy (frame_info_ptr frame, int regnum); +extern value *value_of_register (int regnum, frame_info_ptr next_frame); + +/* Same as the above, but the value is not fetched. */ + +extern value *value_of_register_lazy (frame_info_ptr next_frame, int regnum); /* Return the symbol's reading requirement. */ From patchwork Wed Nov 8 05:00:53 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Marchi X-Patchwork-Id: 79373 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 DF73C3858416 for ; Wed, 8 Nov 2023 05:14:51 +0000 (GMT) X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from smtp.polymtl.ca (smtp.polymtl.ca [132.207.4.11]) by sourceware.org (Postfix) with ESMTPS id C6D333858D1E for ; Wed, 8 Nov 2023 05:14:37 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org C6D333858D1E Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=polymtl.ca Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=polymtl.ca ARC-Filter: OpenARC Filter v1.0.0 sourceware.org C6D333858D1E Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=132.207.4.11 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1699420479; cv=none; b=g44b/ghx2uUlfZOsZL9WRrcabZbXXYGwhxLEzCcxYb+tFyeKlAUg8sj1PeVeIlAOaIYi+YEV8Nzv33apDVV5eKecDX3Qh2eVWgygh9AzlNezdG6M1rhOWCgSazXdgD5pKTZ1fSqu/O1ViCIJvZ+2PaeIviEOasOclaI6jCyxzuA= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1699420479; c=relaxed/simple; bh=k+4MBeBdE5d+JLpvby3Lclzf9IkguNcZBTWAZuN7hSU=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=Dfo7nRghyXGacvNvk3rT0tGSJHlGUJIvJAL75aqCIHeuUKh/xIwT4iwREYtNAUFEm5AQd5qsX6XLnH7osi+yQs0c6zXwdm9NC/aszOgZHw/UzMChPUDg+6ZWN0KofKqH3vKtFujyZ4JI+4s59a/uDgWNIyYd4/55ne3XZoxQxX4= ARC-Authentication-Results: i=1; server2.sourceware.org Received: from simark.ca (simark.ca [158.69.221.121]) (authenticated bits=0) by smtp.polymtl.ca (8.14.7/8.14.7) with ESMTP id 3A85EVmR015674 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 8 Nov 2023 00:14:36 -0500 DKIM-Filter: OpenDKIM Filter v2.11.0 smtp.polymtl.ca 3A85EVmR015674 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=polymtl.ca; s=default; t=1699420476; bh=ChUmD4+gIIt6fnRg0W8r9FMPFOI3WwS1ZBz6UBMkNsA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=DFblJHc0PCaUtJklPF71EjldUEqEjQ8i5QWxhfBMDOcyJNrvNvs6F9JyGnsBgM88G xbiffHP3WxnG+ayViZ/Jgj7vKqFQnNt5m3GtMdUUeVcXQH8gtPDy68WtdTeRz/bbbG E2EvrG7bbr+e/9Kqt9bo17/RH/7wml3TEXCYyGII= Received: from simark.localdomain (modemcable238.237-201-24.mc.videotron.ca [24.201.237.238]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) by simark.ca (Postfix) with ESMTPSA id BD6671E0BB; Wed, 8 Nov 2023 00:14:31 -0500 (EST) From: Simon Marchi To: gdb-patches@sourceware.org Cc: Simon Marchi Subject: [PATCH 09/24] gdb: remove frame_register Date: Wed, 8 Nov 2023 00:00:53 -0500 Message-ID: <20231108051222.1275306-10-simon.marchi@polymtl.ca> X-Mailer: git-send-email 2.42.1 In-Reply-To: <20231108051222.1275306-1-simon.marchi@polymtl.ca> References: <20231108051222.1275306-1-simon.marchi@polymtl.ca> MIME-Version: 1.0 X-Poly-FromMTA: (simark.ca [158.69.221.121]) at Wed, 8 Nov 2023 05:14:31 +0000 X-Spam-Status: No, score=-3188.6 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_PASS, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE 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.30 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org From: Simon Marchi I was going to change frame_register to take the "next frame", but I realized that doing so would make it a useless wrapper around frame_register_unwind. So, just remove frame_register and replace uses with frame_register_unwind. Change-Id: I185868bc69f8e098124775d0550d069220a4678a --- gdb/frame.c | 39 ++++++++------------------------------- 1 file changed, 8 insertions(+), 31 deletions(-) diff --git a/gdb/frame.c b/gdb/frame.c index 84ef8461b835..5d8ecb52fe2f 100644 --- a/gdb/frame.c +++ b/gdb/frame.c @@ -1213,31 +1213,6 @@ frame_register_unwind (frame_info_ptr next_frame, int regnum, release_value (value); } -/* Get the value of the register that belongs to this FRAME. This - function is a wrapper to the call sequence ``frame_register_unwind - (get_next_frame (FRAME))''. As per frame_register_unwind(), if - VALUEP is NULL, the registers value is not fetched/computed. */ - -static void -frame_register (frame_info_ptr frame, int regnum, - int *optimizedp, int *unavailablep, enum lval_type *lvalp, - CORE_ADDR *addrp, int *realnump, gdb_byte *bufferp) -{ - /* Require all but BUFFERP to be valid. A NULL BUFFERP indicates - that the value proper does not need to be fetched. */ - gdb_assert (optimizedp != NULL); - gdb_assert (lvalp != NULL); - gdb_assert (addrp != NULL); - gdb_assert (realnump != NULL); - /* gdb_assert (bufferp != NULL); */ - - /* Obtain the register value by unwinding the register from the next - (more inner frame). */ - gdb_assert (frame != NULL && frame->next != NULL); - frame_register_unwind (frame_info_ptr (frame->next), regnum, optimizedp, - unavailablep, lvalp, addrp, realnump, bufferp); -} - void frame_unwind_register (frame_info_ptr next_frame, int regnum, gdb_byte *buf) { @@ -1435,8 +1410,8 @@ put_frame_register (frame_info_ptr frame, int regnum, gdb_assert (buf.size () == size); - frame_register (frame, regnum, &optim, &unavail, - &lval, &addr, &realnum, NULL); + frame_register_unwind (get_next_frame_sentinel_okay (frame), regnum, &optim, + &unavail, &lval, &addr, &realnum, nullptr); if (optim) error (_("Attempt to assign to a register that was not saved.")); switch (lval) @@ -1472,8 +1447,9 @@ deprecated_frame_register_read (frame_info_ptr frame, int regnum, CORE_ADDR addr; int realnum; - frame_register (frame, regnum, &optimized, &unavailable, - &lval, &addr, &realnum, myaddr); + frame_register_unwind (get_next_frame_sentinel_okay (frame), regnum, + &optimized, &unavailable, &lval, &addr, &realnum, + myaddr); return !optimized && !unavailable; } @@ -1522,8 +1498,9 @@ get_frame_register_bytes (frame_info_ptr frame, int regnum, CORE_ADDR addr; int realnum; - frame_register (frame, regnum, optimizedp, unavailablep, &lval, - &addr, &realnum, buffer.data ()); + frame_register_unwind (get_next_frame_sentinel_okay (frame), regnum, + optimizedp, unavailablep, &lval, &addr, + &realnum, buffer.data ()); if (*optimizedp || *unavailablep) return false; } From patchwork Wed Nov 8 05:00:54 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Marchi X-Patchwork-Id: 79374 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 B3BD33858C5E for ; Wed, 8 Nov 2023 05:14:54 +0000 (GMT) X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from smtp.polymtl.ca (smtp.polymtl.ca [132.207.4.11]) by sourceware.org (Postfix) with ESMTPS id 572443858D35 for ; Wed, 8 Nov 2023 05:14:38 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 572443858D35 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=polymtl.ca Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=polymtl.ca ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 572443858D35 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=132.207.4.11 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1699420479; cv=none; b=xMKYdZRH2FzgtULs3z01m54lcyWdJY21F/BoTEKgeJUQ/K1aujNFfZJrZGi4TKYQVfuwHZXRB9RNpq9hC5de4HYZoVhfoax2RV0yRB7X2l44yUiHrZn/wCLbPiCqsh7p3iawQSYv3J/Qzx3uCZ4taxImg9FZLD0+Bj9NAAuI3MU= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1699420479; c=relaxed/simple; bh=BwpIeJXO/BB1oHpo+UDVi14bZVOh4VdwxDCZc3wEUm0=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=LeNFl6rbCAPhKoQyddAENh2GPEhrVo/GTzna7NSjz/NmrkCfkpUW1glitnWy5ut9OmOkjZmkQBbDsm+0KEnJMJKJ07ENQAonD/dnVsulG7TZZiZt+Kd8rgg1V2gxOx4drSVN1jGUvn5y9rCMP/vByM4z5ZBnldw9zovBDNVSlxg= ARC-Authentication-Results: i=1; server2.sourceware.org Received: from simark.ca (simark.ca [158.69.221.121]) (authenticated bits=0) by smtp.polymtl.ca (8.14.7/8.14.7) with ESMTP id 3A85EWPm015678 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 8 Nov 2023 00:14:36 -0500 DKIM-Filter: OpenDKIM Filter v2.11.0 smtp.polymtl.ca 3A85EWPm015678 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=polymtl.ca; s=default; t=1699420477; bh=YbuzO+rAQzosan6XwumBx8dUEKVO+cRJyt2VZY5v8F4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ZJgOR99dnDnmPYa5PrJvhcE7gZhKvEWWdf0dQ4kHkOOHDNxtfzltX72bmayKEIzUA wjP6wefWJHUHsZRivO6NxEh9bJqMTa1x2qZqepkbsimYYNcR4cJBv9Ewi+7etqHQXp 3yPVIqsmUHI+eO1pRVtnmUQmSRfSBxDBGLdnPphQ= Received: from simark.localdomain (modemcable238.237-201-24.mc.videotron.ca [24.201.237.238]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) by simark.ca (Postfix) with ESMTPSA id 13C981E0C1; Wed, 8 Nov 2023 00:14:31 -0500 (EST) From: Simon Marchi To: gdb-patches@sourceware.org Cc: Simon Marchi Subject: [PATCH 10/24] gdb: make put_frame_register take the next frame Date: Wed, 8 Nov 2023 00:00:54 -0500 Message-ID: <20231108051222.1275306-11-simon.marchi@polymtl.ca> X-Mailer: git-send-email 2.42.1 In-Reply-To: <20231108051222.1275306-1-simon.marchi@polymtl.ca> References: <20231108051222.1275306-1-simon.marchi@polymtl.ca> MIME-Version: 1.0 X-Poly-FromMTA: (simark.ca [158.69.221.121]) at Wed, 8 Nov 2023 05:14:32 +0000 X-Spam-Status: No, score=-3188.6 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_PASS, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE 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.30 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org From: Simon Marchi Similar to the previous patches, change put_frame_register to take the "next frame" instead of "this frame". Change-Id: I062fd4663b8f54f0fc7bbf39c860b7341363821b --- gdb/alpha-tdep.c | 3 ++- gdb/frame.c | 16 +++++++++------- gdb/frame.h | 8 ++++---- gdb/i386-tdep.c | 3 ++- gdb/i387-tdep.c | 2 +- gdb/ia64-tdep.c | 2 +- gdb/m68k-tdep.c | 2 +- gdb/mips-tdep.c | 5 +++-- gdb/rs6000-tdep.c | 2 +- 9 files changed, 24 insertions(+), 19 deletions(-) diff --git a/gdb/alpha-tdep.c b/gdb/alpha-tdep.c index 1901b9449e6c..289d6f08782c 100644 --- a/gdb/alpha-tdep.c +++ b/gdb/alpha-tdep.c @@ -269,8 +269,9 @@ alpha_value_to_register (frame_info_ptr frame, int regnum, gdb_byte out[ALPHA_REGISTER_SIZE]; alpha_lds (get_frame_arch (frame), out, in); + auto out_view = gdb::make_array_view (out, reg_size); - put_frame_register (frame, regnum, out_view); + put_frame_register (get_next_frame_sentinel_okay (frame), regnum, out_view); } diff --git a/gdb/frame.c b/gdb/frame.c index 5d8ecb52fe2f..753dde189814 100644 --- a/gdb/frame.c +++ b/gdb/frame.c @@ -1397,10 +1397,10 @@ read_frame_register_unsigned (frame_info_ptr frame, int regnum, } void -put_frame_register (frame_info_ptr frame, int regnum, - gdb::array_view buf) +put_frame_register (frame_info_ptr next_frame, int regnum, + gdb::array_view buf) { - struct gdbarch *gdbarch = get_frame_arch (frame); + gdbarch *gdbarch = frame_unwind_arch (next_frame); int realnum; int optim; int unavail; @@ -1410,8 +1410,8 @@ put_frame_register (frame_info_ptr frame, int regnum, gdb_assert (buf.size () == size); - frame_register_unwind (get_next_frame_sentinel_okay (frame), regnum, &optim, - &unavail, &lval, &addr, &realnum, nullptr); + frame_register_unwind (next_frame, regnum, &optim, &unavail, &lval, &addr, + &realnum, nullptr); if (optim) error (_("Attempt to assign to a register that was not saved.")); switch (lval) @@ -1556,7 +1556,8 @@ put_frame_register_bytes (frame_info_ptr frame, int regnum, buffer.size ()); if (curr_len == register_size (gdbarch, regnum)) - put_frame_register (frame, regnum, buffer.slice (0, curr_len)); + put_frame_register (get_next_frame_sentinel_okay (frame), regnum, + buffer.slice (0, curr_len)); else { value *value @@ -1566,7 +1567,8 @@ put_frame_register_bytes (frame_info_ptr frame, int regnum, copy (buffer.slice (0, curr_len), value->contents_writeable ().slice (offset, curr_len)); - put_frame_register (frame, regnum, value->contents_raw ()); + put_frame_register (get_next_frame_sentinel_okay (frame), regnum, + value->contents_raw ()); release_value (value); } diff --git a/gdb/frame.h b/gdb/frame.h index e3393cdd972c..7d3b8da0243d 100644 --- a/gdb/frame.h +++ b/gdb/frame.h @@ -720,10 +720,10 @@ extern ULONGEST get_frame_register_unsigned (frame_info_ptr frame, extern bool read_frame_register_unsigned (frame_info_ptr frame, int regnum, ULONGEST *val); -/* The reverse. Store a register value relative to the specified - frame. Note: this call makes the frame's state undefined. The - register and frame caches must be flushed. */ -extern void put_frame_register (frame_info_ptr frame, int regnum, +/* The reverse. Store a register value relative to NEXT_FRAME's previous frame. + Note: this call makes the frame's state undefined. The register and frame + caches must be flushed. */ +extern void put_frame_register (frame_info_ptr next_frame, int regnum, gdb::array_view buf); /* Read LEN bytes from one or multiple registers starting with REGNUM diff --git a/gdb/i386-tdep.c b/gdb/i386-tdep.c index 7f6ea5ba06ec..9666e1dba890 100644 --- a/gdb/i386-tdep.c +++ b/gdb/i386-tdep.c @@ -3918,7 +3918,8 @@ i386_value_to_register (frame_info_ptr frame, int regnum, gdb_assert (register_size (get_frame_arch (frame), regnum) == 4); auto from_view = gdb::make_array_view (from, 4); - put_frame_register (frame, regnum, from_view); + put_frame_register (get_next_frame_sentinel_okay (frame), regnum, + from_view); regnum = i386_next_regnum (regnum); len -= 4; from += 4; diff --git a/gdb/i387-tdep.c b/gdb/i387-tdep.c index 74481f5aeb3c..cfa2a1e297ff 100644 --- a/gdb/i387-tdep.c +++ b/gdb/i387-tdep.c @@ -400,7 +400,7 @@ i387_value_to_register (frame_info_ptr frame, int regnum, struct type *to_type = i387_ext_type (gdbarch); target_float_convert (from, type, to, to_type); auto to_view = gdb::make_array_view (to, to_type->length ()); - put_frame_register (frame, regnum, to_view); + put_frame_register (get_next_frame_sentinel_okay (frame), regnum, to_view); } diff --git a/gdb/ia64-tdep.c b/gdb/ia64-tdep.c index 113d384e8649..facb1bbac19c 100644 --- a/gdb/ia64-tdep.c +++ b/gdb/ia64-tdep.c @@ -1248,7 +1248,7 @@ ia64_value_to_register (frame_info_ptr frame, int regnum, type *to_type = ia64_ext_type (gdbarch); target_float_convert (in, valtype, out, to_type); auto out_view = gdb::make_array_view (out, to_type->length ()); - put_frame_register (frame, regnum, out_view); + put_frame_register (get_next_frame_sentinel_okay (frame), regnum, out_view); } diff --git a/gdb/m68k-tdep.c b/gdb/m68k-tdep.c index 5a80ecb94390..bee411f6e61f 100644 --- a/gdb/m68k-tdep.c +++ b/gdb/m68k-tdep.c @@ -250,7 +250,7 @@ m68k_value_to_register (frame_info_ptr frame, int regnum, /* Convert from TYPE. */ target_float_convert (from, type, to, fpreg_type); auto to_view = gdb::make_array_view (to, fpreg_type->length ()); - put_frame_register (frame, regnum, to_view); + put_frame_register (get_next_frame_sentinel_okay (frame), regnum, to_view); } diff --git a/gdb/mips-tdep.c b/gdb/mips-tdep.c index ac90aa1f2c5f..941397b7ccdc 100644 --- a/gdb/mips-tdep.c +++ b/gdb/mips-tdep.c @@ -991,8 +991,9 @@ mips_value_to_register (frame_info_ptr frame, int regnum, if (mips_convert_register_float_case_p (gdbarch, regnum, type)) { auto from_view = gdb::make_array_view (from, 8); - put_frame_register (frame, regnum, from_view.slice (4)); - put_frame_register (frame, regnum + 1, from_view.slice (0, 4)); + frame_info_ptr next_frame = get_next_frame_sentinel_okay (frame); + put_frame_register (next_frame, regnum, from_view.slice (4)); + put_frame_register (next_frame, regnum + 1, from_view.slice (0, 4)); } else if (mips_convert_register_gpreg_case_p (gdbarch, regnum, type)) { diff --git a/gdb/rs6000-tdep.c b/gdb/rs6000-tdep.c index 9fb3f326bd07..a8626c32c2c1 100644 --- a/gdb/rs6000-tdep.c +++ b/gdb/rs6000-tdep.c @@ -2718,7 +2718,7 @@ rs6000_value_to_register (frame_info_ptr frame, struct type *to_type = builtin_type (gdbarch)->builtin_double; target_float_convert (from, type, to, to_type); auto to_view = gdb::make_array_view (to, to_type->length ()); - put_frame_register (frame, regnum, to_view); + put_frame_register (get_next_frame_sentinel_okay (frame), regnum, to_view); } /* The type of a function that moves the value of REG between CACHE From patchwork Wed Nov 8 05:00:55 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Marchi X-Patchwork-Id: 79376 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 A4D0E3858C74 for ; Wed, 8 Nov 2023 05:15:22 +0000 (GMT) X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from smtp.polymtl.ca (smtp.polymtl.ca [132.207.4.11]) by sourceware.org (Postfix) with ESMTPS id CF6AC3858D38 for ; Wed, 8 Nov 2023 05:14:38 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org CF6AC3858D38 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=polymtl.ca Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=polymtl.ca ARC-Filter: OpenARC Filter v1.0.0 sourceware.org CF6AC3858D38 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=132.207.4.11 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1699420480; cv=none; b=dCteNOokCnq9cqXlU4GXDeyuwuBzwfBWqh8EQLWxxuKS5vFKUzHUvCjZR+mbNLJj05oKyELBcVv66+FNuDHZ45pm4y5JYeCbkiUhMGJzPMjVmPEIbs+kJ/yv5TIqTgJQUQqB1xg5W5R4Qt6v4bdowGqY9VVJ04U1zrZ3foct//o= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1699420480; c=relaxed/simple; bh=eEjr8P0Qb3Jqj2Y8FmyROJin8A/InNLw7QRomYmvFAc=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=I0jsqeG1BOc1IzQZ07dc2+QdL6RaWZ/ozlyDzBHelqrr2x0ssy1G51PtA+vss4NPNuop2wbtRx5KiF+Tia12q4aFGytBmJmU7o6rqqsLKRBJq/gsV1b8FrwYP+vYAT5Qb3rxIrVhN9+pksX6J3xkx6ag2Pkgzyzpl0EF6wQwMCs= ARC-Authentication-Results: i=1; server2.sourceware.org Received: from simark.ca (simark.ca [158.69.221.121]) (authenticated bits=0) by smtp.polymtl.ca (8.14.7/8.14.7) with ESMTP id 3A85EWJf015681 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 8 Nov 2023 00:14:36 -0500 DKIM-Filter: OpenDKIM Filter v2.11.0 smtp.polymtl.ca 3A85EWJf015681 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=polymtl.ca; s=default; t=1699420477; bh=/uzACaHjgfSNkQB5xf/YE1NN0LcEQSWq2ztQIr9NqDU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=U0iHUTEy5UJhfpYg1O/3Or/IVsiYIA735/tjH4RM6hNXTZx8wEEvvh7UA9To0lOy8 Mc2jG6CEjVtpEFjdHPQjhiOvc6L/IKfnMrSTbuHqXV0lh1ms+rIgHYqgjlpVx1Ypq4 ZEnYwdIBNhEmCbM59WEi6XkwgnIVdm1HNCT5wIVk= Received: from simark.localdomain (modemcable238.237-201-24.mc.videotron.ca [24.201.237.238]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) by simark.ca (Postfix) with ESMTPSA id 2DB9B1E0D2; Wed, 8 Nov 2023 00:14:32 -0500 (EST) From: Simon Marchi To: gdb-patches@sourceware.org Cc: Simon Marchi Subject: [PATCH 11/24] gdb: make put_frame_register_bytes take the next frame Date: Wed, 8 Nov 2023 00:00:55 -0500 Message-ID: <20231108051222.1275306-12-simon.marchi@polymtl.ca> X-Mailer: git-send-email 2.42.1 In-Reply-To: <20231108051222.1275306-1-simon.marchi@polymtl.ca> References: <20231108051222.1275306-1-simon.marchi@polymtl.ca> MIME-Version: 1.0 X-Poly-FromMTA: (simark.ca [158.69.221.121]) at Wed, 8 Nov 2023 05:14:32 +0000 X-Spam-Status: No, score=-3188.6 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_PASS, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE 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.30 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org From: Simon Marchi Similar to the previous patches, change put_frame_register_bytes to take the "next frame" instead of "this frame". Change-Id: I27bcb26573686d99b231230823cff8db6405a788 --- gdb/dwarf2/expr.c | 6 +++--- gdb/frame.c | 14 +++++--------- gdb/frame.h | 4 ++-- gdb/mips-tdep.c | 11 ++++++----- gdb/valops.c | 32 +++++++++++++++----------------- 5 files changed, 31 insertions(+), 36 deletions(-) diff --git a/gdb/dwarf2/expr.c b/gdb/dwarf2/expr.c index b21016eb38bb..7fc7b3abf5ca 100644 --- a/gdb/dwarf2/expr.c +++ b/gdb/dwarf2/expr.c @@ -272,9 +272,9 @@ rw_pieced_value (value *v, value *from, bool check_optimized) copy_bitwise (buffer.data (), bits_to_skip % 8, from_contents, offset, this_size_bits, bits_big_endian); - put_frame_register_bytes (frame, gdb_regnum, - bits_to_skip / 8, - buffer); + put_frame_register_bytes + (get_next_frame_sentinel_okay (frame), gdb_regnum, + bits_to_skip / 8, buffer); } } break; diff --git a/gdb/frame.c b/gdb/frame.c index 753dde189814..d4e2155fdb29 100644 --- a/gdb/frame.c +++ b/gdb/frame.c @@ -1536,11 +1536,11 @@ get_frame_register_bytes (frame_info_ptr frame, int regnum, } void -put_frame_register_bytes (frame_info_ptr frame, int regnum, +put_frame_register_bytes (frame_info_ptr next_frame, int regnum, CORE_ADDR offset, gdb::array_view buffer) { - struct gdbarch *gdbarch = get_frame_arch (frame); + gdbarch *gdbarch = frame_unwind_arch (next_frame); /* Skip registers wholly inside of OFFSET. */ while (offset >= register_size (gdbarch, regnum)) @@ -1556,19 +1556,15 @@ put_frame_register_bytes (frame_info_ptr frame, int regnum, buffer.size ()); if (curr_len == register_size (gdbarch, regnum)) - put_frame_register (get_next_frame_sentinel_okay (frame), regnum, - buffer.slice (0, curr_len)); + put_frame_register (next_frame, regnum, buffer.slice (0, curr_len)); else { - value *value - = frame_unwind_register_value (frame_info_ptr (frame->next), - regnum); + value *value = frame_unwind_register_value (next_frame, regnum); gdb_assert (value != nullptr); copy (buffer.slice (0, curr_len), value->contents_writeable ().slice (offset, curr_len)); - put_frame_register (get_next_frame_sentinel_okay (frame), regnum, - value->contents_raw ()); + put_frame_register (next_frame, regnum, value->contents_raw ()); release_value (value); } diff --git a/gdb/frame.h b/gdb/frame.h index 7d3b8da0243d..a25f6de35f0d 100644 --- a/gdb/frame.h +++ b/gdb/frame.h @@ -736,8 +736,8 @@ extern bool get_frame_register_bytes (frame_info_ptr frame, int regnum, int *optimizedp, int *unavailablep); /* Write bytes from BUFFER to one or multiple registers starting with REGNUM - in frame FRAME, starting at OFFSET. */ -extern void put_frame_register_bytes (frame_info_ptr frame, int regnum, + in NEXT_FRAME's previous frame, starting at OFFSET. */ +extern void put_frame_register_bytes (frame_info_ptr next_frame, int regnum, CORE_ADDR offset, gdb::array_view buffer); diff --git a/gdb/mips-tdep.c b/gdb/mips-tdep.c index 941397b7ccdc..ce3eed3eb70d 100644 --- a/gdb/mips-tdep.c +++ b/gdb/mips-tdep.c @@ -999,7 +999,8 @@ mips_value_to_register (frame_info_ptr frame, int regnum, { gdb_byte fill[8]; size_t len = type->length (); - + frame_info_ptr next_frame = get_next_frame_sentinel_okay (frame); + /* Sign extend values, irrespective of type, that are stored to a 64-bit general purpose register. (32-bit unsigned values are stored as signed quantities within a 64-bit register. @@ -1012,8 +1013,8 @@ mips_value_to_register (frame_info_ptr frame, int regnum, store_signed_integer (fill, 8, BFD_ENDIAN_BIG, -1); else store_signed_integer (fill, 8, BFD_ENDIAN_BIG, 0); - put_frame_register_bytes (frame, regnum, 0, {fill, 8 - len}); - put_frame_register_bytes (frame, regnum, 8 - len, {from, len}); + put_frame_register_bytes (next_frame, regnum, 0, {fill, 8 - len}); + put_frame_register_bytes (next_frame, regnum, 8 - len, {from, len}); } else { @@ -1021,8 +1022,8 @@ mips_value_to_register (frame_info_ptr frame, int regnum, store_signed_integer (fill, 8, BFD_ENDIAN_LITTLE, -1); else store_signed_integer (fill, 8, BFD_ENDIAN_LITTLE, 0); - put_frame_register_bytes (frame, regnum, 0, {from, len}); - put_frame_register_bytes (frame, regnum, len, {fill, 8 - len}); + put_frame_register_bytes (next_frame, regnum, 0, {from, len}); + put_frame_register_bytes (next_frame, regnum, len, {fill, 8 - len}); } } else diff --git a/gdb/valops.c b/gdb/valops.c index 70851cd40b4f..2530c1d6412c 100644 --- a/gdb/valops.c +++ b/gdb/valops.c @@ -1191,10 +1191,6 @@ value_assign (struct value *toval, struct value *fromval) case lval_register: { - frame_info_ptr frame; - struct gdbarch *gdbarch; - int value_reg; - /* Figure out which frame this register value is in. The value holds the frame_id for the next frame, that is the frame this register value was unwound from. @@ -1202,15 +1198,14 @@ value_assign (struct value *toval, struct value *fromval) Below we will call put_frame_register_bytes which requires that we pass it the actual frame in which the register value is valid, i.e. not the next frame. */ - frame = frame_find_by_id (VALUE_NEXT_FRAME_ID (toval)); - frame = get_prev_frame_always (frame); + frame_info_ptr next_frame = frame_find_by_id (VALUE_NEXT_FRAME_ID (toval)); - value_reg = VALUE_REGNUM (toval); + int value_reg = VALUE_REGNUM (toval); - if (!frame) + if (next_frame == nullptr) error (_("Value being assigned to is no longer active.")); - gdbarch = get_frame_arch (frame); + gdbarch *gdbarch = frame_unwind_arch (next_frame); if (toval->bitsize ()) { @@ -1230,9 +1225,10 @@ value_assign (struct value *toval, struct value *fromval) "don't fit in a %d bit word."), (int) sizeof (LONGEST) * HOST_CHAR_BIT); - if (!get_frame_register_bytes (frame, value_reg, offset, - {buffer, changed_len}, - &optim, &unavail)) + if (!get_frame_register_bytes (get_prev_frame_always (next_frame), + value_reg, offset, + { buffer, changed_len }, &optim, + &unavail)) { if (optim) throw_error (OPTIMIZED_OUT_ERROR, @@ -1245,8 +1241,8 @@ value_assign (struct value *toval, struct value *fromval) modify_field (type, buffer, value_as_long (fromval), toval->bitpos (), toval->bitsize ()); - put_frame_register_bytes (frame, value_reg, offset, - {buffer, changed_len}); + put_frame_register_bytes (next_frame, value_reg, offset, + { buffer, changed_len }); } else { @@ -1256,17 +1252,19 @@ value_assign (struct value *toval, struct value *fromval) /* If TOVAL is a special machine register requiring conversion of program values to a special raw format. */ - gdbarch_value_to_register (gdbarch, frame, + gdbarch_value_to_register (gdbarch, + get_prev_frame_always (next_frame), VALUE_REGNUM (toval), type, fromval->contents ().data ()); } else - put_frame_register_bytes (frame, value_reg, + put_frame_register_bytes (next_frame, value_reg, toval->offset (), fromval->contents ()); } - gdb::observers::register_changed.notify (frame, value_reg); + gdb::observers::register_changed.notify + (get_prev_frame_always (next_frame), value_reg); break; } From patchwork Wed Nov 8 05:00:56 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Marchi X-Patchwork-Id: 79385 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 1E04C3858416 for ; Wed, 8 Nov 2023 05:22:14 +0000 (GMT) X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from smtp.polymtl.ca (smtp.polymtl.ca [132.207.4.11]) by sourceware.org (Postfix) with ESMTPS id E836D3858D38 for ; Wed, 8 Nov 2023 05:21:44 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org E836D3858D38 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=polymtl.ca Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=polymtl.ca ARC-Filter: OpenARC Filter v1.0.0 sourceware.org E836D3858D38 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=132.207.4.11 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1699420906; cv=none; b=nX8qTBmhkEovbaPcTn8n9EJzj9zNDkwrlLbD/MvbZhJY7HaoqSHtCgR8DQQoDwI32LZOMLH0DG7ZOiqw5o6VzdNd3psBQZHakdq/TVLN8/ILlxoRWmfpJ2WjmdisDUqnCRYThiltpdmYAHEmyLgwCfVqGo8zdsZunKRlFSR7PX0= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1699420906; c=relaxed/simple; bh=JW52APMGBGgDVoJ5N0yyT6L8+0fcJsime2+8cR2NCRs=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=FHnRCr3EYmwdmszdfpugkYJ18YInpjRpOJU7XEf4yhLZsw1L62AYv08/H/6z5NacyMNpE4P+br2Ir87fjE8O4JW3C43HpxmScGaiygUj4uQC4c/gf9MxWuAhxzPJzUU91Qv917BWpqqdXFgguAka8gVi9EX+4f9bC+PZ22LkWfs= ARC-Authentication-Results: i=1; server2.sourceware.org Received: from simark.ca (simark.ca [158.69.221.121]) (authenticated bits=0) by smtp.polymtl.ca (8.14.7/8.14.7) with ESMTP id 3A85LcNx016955 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 8 Nov 2023 00:21:42 -0500 DKIM-Filter: OpenDKIM Filter v2.11.0 smtp.polymtl.ca 3A85LcNx016955 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=polymtl.ca; s=default; t=1699420903; bh=1w5a/rnT2wrufy9XO/ndDVcMD9wO/QJjyDKpW6KxcxI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=qbhCEfU0SlEBqjbffjCqjDBvfss0HkMI2IH/Y0XjJ+1Le1pq28aLDSqppJKDk55K5 /+mMiL5qC/dDib82/4KmqMhk4GwlrNnpBbf5/dvps1Ray27kVNSzGA5aIHw5P7qQUT gAdu2HshcYBcm7Ea3NIPJIKj34QTKapPZp77lAbw= Received: from simark.localdomain (modemcable238.237-201-24.mc.videotron.ca [24.201.237.238]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) by simark.ca (Postfix) with ESMTPSA id 448CF1E1AA; Wed, 8 Nov 2023 00:14:32 -0500 (EST) From: Simon Marchi To: gdb-patches@sourceware.org Cc: Simon Marchi Subject: [PATCH 12/24] gdb: make get_frame_register_bytes take the next frame Date: Wed, 8 Nov 2023 00:00:56 -0500 Message-ID: <20231108051222.1275306-13-simon.marchi@polymtl.ca> X-Mailer: git-send-email 2.42.1 In-Reply-To: <20231108051222.1275306-1-simon.marchi@polymtl.ca> References: <20231108051222.1275306-1-simon.marchi@polymtl.ca> MIME-Version: 1.0 X-Poly-FromMTA: (simark.ca [158.69.221.121]) at Wed, 8 Nov 2023 05:21:38 +0000 X-Spam-Status: No, score=-3188.6 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_PASS, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE 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.30 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org From: Simon Marchi Similar to the previous patches, change get_frame_register_bytes to take the "next frame" instead of "this frame". Change-Id: Ie8f35042bfa6e93565fcefaee71b6b3903f0fe9f --- gdb/dwarf2/expr.c | 22 +++++++++++----------- gdb/frame.c | 16 ++++++---------- gdb/frame.h | 10 +++++----- gdb/i386-tdep.c | 8 ++++---- gdb/i387-tdep.c | 10 +++++----- gdb/ia64-tdep.c | 9 ++++----- gdb/m68k-tdep.c | 10 +++++----- gdb/mips-tdep.c | 7 ++++--- gdb/rs6000-tdep.c | 10 +++++----- gdb/valops.c | 3 +-- 10 files changed, 50 insertions(+), 55 deletions(-) diff --git a/gdb/dwarf2/expr.c b/gdb/dwarf2/expr.c index 7fc7b3abf5ca..c71bbb594131 100644 --- a/gdb/dwarf2/expr.c +++ b/gdb/dwarf2/expr.c @@ -204,8 +204,9 @@ rw_pieced_value (value *v, value *from, bool check_optimized) { case DWARF_VALUE_REGISTER: { - frame_info_ptr frame = frame_find_by_id (c->frame_id); - gdbarch *arch = get_frame_arch (frame); + frame_info_ptr next_frame + = get_next_frame_sentinel_okay (frame_find_by_id (c->frame_id)); + gdbarch *arch = frame_unwind_arch (next_frame); int gdb_regnum = dwarf_reg_to_regnum_or_error (arch, p->v.regno); ULONGEST reg_bits = 8 * register_size (arch, gdb_regnum); int optim, unavail; @@ -225,9 +226,9 @@ rw_pieced_value (value *v, value *from, bool check_optimized) if (from == nullptr) { /* Read mode. */ - if (!get_frame_register_bytes (frame, gdb_regnum, - bits_to_skip / 8, - buffer, &optim, &unavail)) + if (!get_frame_register_bytes (next_frame, gdb_regnum, + bits_to_skip / 8, buffer, + &optim, &unavail)) { if (optim) { @@ -254,9 +255,9 @@ rw_pieced_value (value *v, value *from, bool check_optimized) { /* Data is copied non-byte-aligned into the register. Need some bits from original register value. */ - get_frame_register_bytes (frame, gdb_regnum, - bits_to_skip / 8, - buffer, &optim, &unavail); + get_frame_register_bytes (next_frame, gdb_regnum, + bits_to_skip / 8, buffer, &optim, + &unavail); if (optim) throw_error (OPTIMIZED_OUT_ERROR, _("Can't do read-modify-write to " @@ -272,9 +273,8 @@ rw_pieced_value (value *v, value *from, bool check_optimized) copy_bitwise (buffer.data (), bits_to_skip % 8, from_contents, offset, this_size_bits, bits_big_endian); - put_frame_register_bytes - (get_next_frame_sentinel_okay (frame), gdb_regnum, - bits_to_skip / 8, buffer); + put_frame_register_bytes (next_frame, gdb_regnum, + bits_to_skip / 8, buffer); } } break; diff --git a/gdb/frame.c b/gdb/frame.c index d4e2155fdb29..341bd26ee0df 100644 --- a/gdb/frame.c +++ b/gdb/frame.c @@ -1455,12 +1455,11 @@ deprecated_frame_register_read (frame_info_ptr frame, int regnum, } bool -get_frame_register_bytes (frame_info_ptr frame, int regnum, - CORE_ADDR offset, - gdb::array_view buffer, +get_frame_register_bytes (frame_info_ptr next_frame, int regnum, + CORE_ADDR offset, gdb::array_view buffer, int *optimizedp, int *unavailablep) { - struct gdbarch *gdbarch = get_frame_arch (frame); + gdbarch *gdbarch = frame_unwind_arch (next_frame); /* Skip registers wholly inside of OFFSET. */ while (offset >= register_size (gdbarch, regnum)) @@ -1498,17 +1497,14 @@ get_frame_register_bytes (frame_info_ptr frame, int regnum, CORE_ADDR addr; int realnum; - frame_register_unwind (get_next_frame_sentinel_okay (frame), regnum, - optimizedp, unavailablep, &lval, &addr, - &realnum, buffer.data ()); + frame_register_unwind (next_frame, regnum, optimizedp, unavailablep, + &lval, &addr, &realnum, buffer.data ()); if (*optimizedp || *unavailablep) return false; } else { - struct value *value - = frame_unwind_register_value (frame_info_ptr (frame->next), - regnum); + value *value = frame_unwind_register_value (next_frame, regnum); gdb_assert (value != NULL); *optimizedp = value->optimized_out (); *unavailablep = !value->entirely_available (); diff --git a/gdb/frame.h b/gdb/frame.h index a25f6de35f0d..3b26da817cd8 100644 --- a/gdb/frame.h +++ b/gdb/frame.h @@ -726,11 +726,11 @@ extern bool read_frame_register_unsigned (frame_info_ptr frame, extern void put_frame_register (frame_info_ptr next_frame, int regnum, gdb::array_view buf); -/* Read LEN bytes from one or multiple registers starting with REGNUM - in frame FRAME, starting at OFFSET, into BUF. If the register - contents are optimized out or unavailable, set *OPTIMIZEDP, - *UNAVAILABLEP accordingly. */ -extern bool get_frame_register_bytes (frame_info_ptr frame, int regnum, +/* Read LEN bytes from one or multiple registers starting with REGNUM in + NEXT_FRAME's previous frame, starting at OFFSET, into BUF. If the register + contents are optimized out or unavailable, set *OPTIMIZEDP, *UNAVAILABLEP + accordingly. */ +extern bool get_frame_register_bytes (frame_info_ptr next_frame, int regnum, CORE_ADDR offset, gdb::array_view buffer, int *optimizedp, int *unavailablep); diff --git a/gdb/i386-tdep.c b/gdb/i386-tdep.c index 9666e1dba890..152529834eea 100644 --- a/gdb/i386-tdep.c +++ b/gdb/i386-tdep.c @@ -3877,10 +3877,10 @@ i386_register_to_value (frame_info_ptr frame, int regnum, gdb_assert (regnum != -1); gdb_assert (register_size (gdbarch, regnum) == 4); - if (!get_frame_register_bytes (frame, regnum, 0, - gdb::make_array_view (to, - register_size (gdbarch, - regnum)), + auto to_view + = gdb::make_array_view (to, register_size (gdbarch, regnum)); + frame_info_ptr next_frame = get_next_frame_sentinel_okay (frame); + if (!get_frame_register_bytes (next_frame, regnum, 0, to_view, optimizedp, unavailablep)) return 0; diff --git a/gdb/i387-tdep.c b/gdb/i387-tdep.c index cfa2a1e297ff..9085386172d5 100644 --- a/gdb/i387-tdep.c +++ b/gdb/i387-tdep.c @@ -364,11 +364,11 @@ i387_register_to_value (frame_info_ptr frame, int regnum, } /* Convert to TYPE. */ - if (!get_frame_register_bytes (frame, regnum, 0, - gdb::make_array_view (from, - register_size (gdbarch, - regnum)), - optimizedp, unavailablep)) + auto from_view + = gdb::make_array_view (from, register_size (gdbarch, regnum)); + frame_info_ptr next_frame = get_next_frame_sentinel_okay (frame); + if (!get_frame_register_bytes (next_frame, regnum, 0, from_view, optimizedp, + unavailablep)) return 0; target_float_convert (from, i387_ext_type (gdbarch), to, type); diff --git a/gdb/ia64-tdep.c b/gdb/ia64-tdep.c index facb1bbac19c..d4c1736f0e7f 100644 --- a/gdb/ia64-tdep.c +++ b/gdb/ia64-tdep.c @@ -1227,11 +1227,10 @@ ia64_register_to_value (frame_info_ptr frame, int regnum, gdb_byte in[IA64_FP_REGISTER_SIZE]; /* Convert to TYPE. */ - if (!get_frame_register_bytes (frame, regnum, 0, - gdb::make_array_view (in, - register_size (gdbarch, - regnum)), - optimizedp, unavailablep)) + auto in_view = gdb::make_array_view (in, register_size (gdbarch, regnum)); + frame_info_ptr next_frame = get_next_frame_sentinel_okay (frame); + if (!get_frame_register_bytes (next_frame, regnum, 0, in_view, optimizedp, + unavailablep)) return 0; target_float_convert (in, ia64_ext_type (gdbarch), out, valtype); diff --git a/gdb/m68k-tdep.c b/gdb/m68k-tdep.c index bee411f6e61f..3cdf23682646 100644 --- a/gdb/m68k-tdep.c +++ b/gdb/m68k-tdep.c @@ -216,11 +216,11 @@ m68k_register_to_value (frame_info_ptr frame, int regnum, gdb_assert (type->code () == TYPE_CODE_FLT); /* Convert to TYPE. */ - if (!get_frame_register_bytes (frame, regnum, 0, - gdb::make_array_view (from, - register_size (gdbarch, - regnum)), - optimizedp, unavailablep)) + auto from_view + = gdb::make_array_view (from, register_size (gdbarch, regnum)); + frame_info_ptr next_frame = get_next_frame_sentinel_okay (frame); + if (!get_frame_register_bytes (next_frame, regnum, 0, from_view, optimizedp, + unavailablep)) return 0; target_float_convert (from, fpreg_type, to, type); diff --git a/gdb/mips-tdep.c b/gdb/mips-tdep.c index ce3eed3eb70d..8e25c45dd297 100644 --- a/gdb/mips-tdep.c +++ b/gdb/mips-tdep.c @@ -947,17 +947,18 @@ mips_register_to_value (frame_info_ptr frame, int regnum, int *optimizedp, int *unavailablep) { struct gdbarch *gdbarch = get_frame_arch (frame); + frame_info_ptr next_frame = get_next_frame_sentinel_okay (frame); if (mips_convert_register_float_case_p (gdbarch, regnum, type)) { get_frame_register (frame, regnum + 0, to + 4); get_frame_register (frame, regnum + 1, to + 0); - if (!get_frame_register_bytes (frame, regnum + 0, 0, {to + 4, 4}, + if (!get_frame_register_bytes (next_frame, regnum + 0, 0, { to + 4, 4 }, optimizedp, unavailablep)) return 0; - if (!get_frame_register_bytes (frame, regnum + 1, 0, {to + 0, 4}, + if (!get_frame_register_bytes (next_frame, regnum + 1, 0, { to + 0, 4 }, optimizedp, unavailablep)) return 0; *optimizedp = *unavailablep = 0; @@ -969,7 +970,7 @@ mips_register_to_value (frame_info_ptr frame, int regnum, CORE_ADDR offset; offset = gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG ? 8 - len : 0; - if (!get_frame_register_bytes (frame, regnum, offset, {to, len}, + if (!get_frame_register_bytes (next_frame, regnum, offset, { to, len }, optimizedp, unavailablep)) return 0; diff --git a/gdb/rs6000-tdep.c b/gdb/rs6000-tdep.c index a8626c32c2c1..819f07b47c0a 100644 --- a/gdb/rs6000-tdep.c +++ b/gdb/rs6000-tdep.c @@ -2691,11 +2691,11 @@ rs6000_register_to_value (frame_info_ptr frame, gdb_assert (type->code () == TYPE_CODE_FLT); - if (!get_frame_register_bytes (frame, regnum, 0, - gdb::make_array_view (from, - register_size (gdbarch, - regnum)), - optimizedp, unavailablep)) + auto from_view + = gdb::make_array_view (from, register_size (gdbarch, regnum)); + frame_info_ptr next_frame = get_next_frame_sentinel_okay (frame); + if (!get_frame_register_bytes (next_frame, regnum, 0, from_view, optimizedp, + unavailablep)) return 0; target_float_convert (from, builtin_type (gdbarch)->builtin_double, diff --git a/gdb/valops.c b/gdb/valops.c index 2530c1d6412c..35bf8be788f0 100644 --- a/gdb/valops.c +++ b/gdb/valops.c @@ -1225,8 +1225,7 @@ value_assign (struct value *toval, struct value *fromval) "don't fit in a %d bit word."), (int) sizeof (LONGEST) * HOST_CHAR_BIT); - if (!get_frame_register_bytes (get_prev_frame_always (next_frame), - value_reg, offset, + if (!get_frame_register_bytes (next_frame, value_reg, offset, { buffer, changed_len }, &optim, &unavail)) { From patchwork Wed Nov 8 05:00:57 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Marchi X-Patchwork-Id: 79393 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 A6175385B512 for ; Wed, 8 Nov 2023 05:51:57 +0000 (GMT) X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from smtp.polymtl.ca (smtp.polymtl.ca [132.207.4.11]) by sourceware.org (Postfix) with ESMTPS id E04E23858039 for ; Wed, 8 Nov 2023 05:51:44 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org E04E23858039 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=polymtl.ca Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=polymtl.ca ARC-Filter: OpenARC Filter v1.0.0 sourceware.org E04E23858039 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=132.207.4.11 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1699422706; cv=none; b=YdvFdAA2JSHLBYrVZ0ZDrYJSkzNarQ1AG3djaG+wT5XMqgxIbjBLAQtskboXoSazdJ6/Uxv2R4TD7j34thRWCPhTKvq4/sk5ZniLLzJJH879cMYld71MCpC8TAjGbz1SiO6H/1QElb9UecHqKgURlensb1vQ3X6D6Jkte89aY4Y= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1699422706; c=relaxed/simple; bh=klY8ROuh0omHi3MYYlsV9jiKfb0kjToKEDIUnnaKjvU=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=FaOG+IdgxiXVbaFfZh9JClSwctgXLTJQltknhKn/yUGoewcbGWSTXdXsuIgg7nRkSSKC+fA29M5X2Y5QcfosUHRuKIOhSCWiBz956nZfHfQ6kJHgyOf9A729I4SYaMZovMkZPU8Y74qyTXQ9eO/xE+O5aXqIJrARj1VAyOdgnWE= ARC-Authentication-Results: i=1; server2.sourceware.org Received: from simark.ca (simark.ca [158.69.221.121]) (authenticated bits=0) by smtp.polymtl.ca (8.14.7/8.14.7) with ESMTP id 3A85pcew022283 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 8 Nov 2023 00:51:43 -0500 DKIM-Filter: OpenDKIM Filter v2.11.0 smtp.polymtl.ca 3A85pcew022283 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=polymtl.ca; s=default; t=1699422703; bh=VFXA9q0eDnRudiMx2f7/Z6PT2RL7tu5F20ojZDnfyPQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=N+aGtdzkiARG2Ararhb6eTvwKoha1o3LyEVHpAeht83zf9LUpbID20kqs6oHZ/FRg jRLc2KncdQoW0vj1wS0+7R+Y4ml1cFGPtOMmeTqHrtFzpujlWsQ0AzEI+JZfHFNhKg zBiXKPAaZj7xrIyoVA5XGYnEWXyFovyHCHwoWAEg= Received: from simark.localdomain (modemcable238.237-201-24.mc.videotron.ca [24.201.237.238]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) by simark.ca (Postfix) with ESMTPSA id 5EE861E1AB; Wed, 8 Nov 2023 00:14:32 -0500 (EST) From: Simon Marchi To: gdb-patches@sourceware.org Cc: Simon Marchi Subject: [PATCH 13/24] gdb: add value::allocate_register Date: Wed, 8 Nov 2023 00:00:57 -0500 Message-ID: <20231108051222.1275306-14-simon.marchi@polymtl.ca> X-Mailer: git-send-email 2.42.1 In-Reply-To: <20231108051222.1275306-1-simon.marchi@polymtl.ca> References: <20231108051222.1275306-1-simon.marchi@polymtl.ca> MIME-Version: 1.0 X-Poly-FromMTA: (simark.ca [158.69.221.121]) at Wed, 8 Nov 2023 05:51:38 +0000 X-Spam-Status: No, score=-3188.6 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_PASS, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE 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.30 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org From: Simon Marchi Add value::allocate_register, to facilitate allocating a value representing a register in a given frame (or rather, in the given frame's previous frame). It will be used in a subsequent patch. I changed one relatively obvious spot that could use it, to at least exercise the code path. Change-Id: Icd4960f5e471a74b657bb3596c88d89679ef3772 --- gdb/regcache.c | 7 ++----- gdb/value.c | 15 +++++++++++++++ gdb/value.h | 7 +++++++ 3 files changed, 24 insertions(+), 5 deletions(-) diff --git a/gdb/regcache.c b/gdb/regcache.c index 4f3881386f34..4256b82da19a 100644 --- a/gdb/regcache.c +++ b/gdb/regcache.c @@ -792,11 +792,8 @@ readable_regcache::cooked_read_value (int regnum) || (m_has_pseudo && m_register_status[regnum] != REG_UNKNOWN) || !gdbarch_pseudo_register_read_value_p (m_descr->gdbarch)) { - struct value *result; - - result = value::allocate (register_type (m_descr->gdbarch, regnum)); - result->set_lval (lval_register); - VALUE_REGNUM (result) = regnum; + value *result = value::allocate_register + (get_next_frame_sentinel_okay (get_current_frame ()), regnum); /* It is more efficient in general to do this delegation in this direction than in the other one, even though the value-based diff --git a/gdb/value.c b/gdb/value.c index 17b7c53d0522..a1b18087416f 100644 --- a/gdb/value.c +++ b/gdb/value.c @@ -959,6 +959,21 @@ value::allocate (struct type *type) return allocate (type, true); } +/* See value.h */ + +struct value * +value::allocate_register (frame_info_ptr next_frame, int regnum) +{ + value *result + = value::allocate (register_type (frame_unwind_arch (next_frame), regnum)); + + result->set_lval (lval_register); + VALUE_REGNUM (result) = regnum; + VALUE_NEXT_FRAME_ID (result) = get_frame_id (next_frame); + + return result; +} + /* Allocate a value that has the correct length for COUNT repetitions of type TYPE. */ diff --git a/gdb/value.h b/gdb/value.h index 37017c9dd9f7..511bde8bbd46 100644 --- a/gdb/value.h +++ b/gdb/value.h @@ -159,6 +159,13 @@ struct value /* Allocate a value and its contents for type TYPE. */ static struct value *allocate (struct type *type); + /* Allocate a non-lazy value representing register RENUM in the frame previous + to NEXT_FRAME. The type of the value is found using `register_type`. + + The caller is responsible for filling the value's contents. */ + static struct value *allocate_register (frame_info_ptr next_frame, + int regnum); + /* Create a computed lvalue, with type TYPE, function pointers FUNCS, and closure CLOSURE. */ static struct value *allocate_computed (struct type *type, From patchwork Wed Nov 8 05:00:58 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Marchi X-Patchwork-Id: 79390 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 92851385828E for ; Wed, 8 Nov 2023 05:32:02 +0000 (GMT) X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from smtp.polymtl.ca (smtp.polymtl.ca [132.207.4.11]) by sourceware.org (Postfix) with ESMTPS id 0BD893858D38 for ; Wed, 8 Nov 2023 05:31:45 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 0BD893858D38 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=polymtl.ca Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=polymtl.ca ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 0BD893858D38 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=132.207.4.11 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1699421509; cv=none; b=gLPLoMhG/15OylTdlxf3Y01hY9U3YbJOIrkXjCTVxp1HqYH89W/BfcV59ONEU3vDHxANzg9y3z03/8hBTBAB/zDe9C09d5ShsEQg489UPg/iUVF6wddODRmSHKPCQGEhPX82e+sOtH0DS9huewwp7QdH56WWd+J0Lh6vzxl5OMQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1699421509; c=relaxed/simple; bh=4cffZ4QmnkkBHI8lUeRihi16e7xqcv57DJnHTpy+BSU=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=Fuc5QRlC+pdXVaj78BKqKvc5rewQX8780SdcEl6V1ne8QET0M6uNfmYUpt+ggLS0q/ob2hxS3XAFYITgzuDp2xurz626pL3DrWKW72AQCHnNJCzAIgO6AYcDUeGph36R0XLzjBq4aLXjSXNuAT+ODF/ox2Sow/oeovD4kgWxXlc= ARC-Authentication-Results: i=1; server2.sourceware.org Received: from simark.ca (simark.ca [158.69.221.121]) (authenticated bits=0) by smtp.polymtl.ca (8.14.7/8.14.7) with ESMTP id 3A85VcaW018762 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 8 Nov 2023 00:31:43 -0500 DKIM-Filter: OpenDKIM Filter v2.11.0 smtp.polymtl.ca 3A85VcaW018762 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=polymtl.ca; s=default; t=1699421503; bh=50jP5xfVidB2w3pzJjfMsQpqNBYohqNXuoaQrNDO9Yg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=q5brKMe3+osQa8UmhiR9p5JuteRAySTuwlrYWRtwqJfr0jwN3ER8m2Qyp5Y5itp1d 1XcppZ9M3Nb2dFt94Om8ndrJuoW3NhymSlgqUThaYMXI0JqBy3uLPjZR/wVT4rfw5H cVgvnA8VxTX5fjGMCMyFFJ2OZpDPS+k7EDzoDVmg= Received: from simark.localdomain (modemcable238.237-201-24.mc.videotron.ca [24.201.237.238]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) by simark.ca (Postfix) with ESMTPSA id 9533E1E1AC; Wed, 8 Nov 2023 00:14:32 -0500 (EST) From: Simon Marchi To: gdb-patches@sourceware.org Cc: Simon Marchi Subject: [PATCH 14/24] gdb: read pseudo register through frame Date: Wed, 8 Nov 2023 00:00:58 -0500 Message-ID: <20231108051222.1275306-15-simon.marchi@polymtl.ca> X-Mailer: git-send-email 2.42.1 In-Reply-To: <20231108051222.1275306-1-simon.marchi@polymtl.ca> References: <20231108051222.1275306-1-simon.marchi@polymtl.ca> MIME-Version: 1.0 X-Poly-FromMTA: (simark.ca [158.69.221.121]) at Wed, 8 Nov 2023 05:31:38 +0000 X-Spam-Status: No, score=-3188.6 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_PASS, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE 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.30 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org From: Simon Marchi Change gdbarch_pseudo_register_read_value to take a frame instead of a regcache. The frame (and formerly the regcache) is used to read raw registers needed to make up the pseudo register value. The problem with using the regcache is that it always provides raw register values for the current frame (frame 0). Let's say the user wants to read the ebx register on amd64. ebx is a pseudo register, obtained by reading the bottom half (bottom 4 bytes) of the rbx register, which is a raw register. If the currently selected frame is frame 0, it works fine: (gdb) frame 0 #0 break_here_asm () at /home/smarchi/src/binutils-gdb/gdb/testsuite/gdb.arch/amd64-pseudo-unwind-asm.S:36 36 in /home/smarchi/src/binutils-gdb/gdb/testsuite/gdb.arch/amd64-pseudo-unwind-asm.S (gdb) p/x $ebx $1 = 0x24252627 (gdb) p/x $rbx $2 = 0x2021222324252627 But if the user is looking at another frame, and the raw register behind the pseudo register has been saved at some point in the call stack, then we get a wrong answer: (gdb) frame 1 #1 0x000055555555517d in caller () at /home/smarchi/src/binutils-gdb/gdb/testsuite/gdb.arch/amd64-pseudo-unwind-asm.S:56 56 in /home/smarchi/src/binutils-gdb/gdb/testsuite/gdb.arch/amd64-pseudo-unwind-asm.S (gdb) p/x $ebx $3 = 0x24252627 (gdb) p/x $rbx $4 = 0x1011121314151617 Here, the value of ebx was computed using the value of rbx in frame 0 (through the regcache), it should have been computed using the value of rbx in frame 1. In other to make this work properly, make the following changes: - Make dwarf2_frame_prev_register return nullptr if it doesn't know how to unwind a register and that register is a pseudo register. Previously, it returned `frame_unwind_got_register`, meaning, in our example, "the value of ebx in frame 1 is the same as the value of ebx in frame 0", which is obviously false. Return nullptr as a way to say "I don't know". - In frame_unwind_register_value, when prev_register (for instance dwarf2_frame_prev_register) returns nullptr, and we are trying to read a pseudo register, try to get the register value through gdbarch_pseudo_register_read_value or gdbarch_pseudo_register_read. If using gdbarch_pseudo_register_read, the behavior is known to be broken. Implementations should be migrated to use gdbarch_pseudo_register_read_value to fix that. - Change gdbarch_pseudo_register_read_value to take a frame_info instead of a regcache, update implementations (aarch64, amd64, i386). In i386-tdep.c, I made a copy of i386_mmx_regnum_to_fp_regnum that uses a frame instead of a regcache. The version using the regcache is still used by i386_pseudo_register_write. It will get removed in a subsequent patch. - Add some helpers in value.{c,h} to implement the common cases of pseudo registers: taking part of a raw register and concatenating multiple raw registers. - Update readable_regcache::{cooked_read,cooked_read_value} to pass the current frame to gdbarch_pseudo_register_read_value. Passing the current frame will give the same behavior as before: for frame 0, raw registers will be read from the current thread's regcache. Notes: - I do not plan on changing gdbarch_pseudo_register_read to receive a frame instead of a regcache. That method is considered deprecated. Instead, we should be working on migrating implementations to use gdbarch_pseudo_register_read_value instead. - In frame_unwind_register_value, we still ask the unwinder to try to unwind pseudo register values. It's apparently possible for the debug info to provide information about [1] pseudo registers, so we want to try that first, before falling back to computing them ourselves. [1] https://inbox.sourceware.org/gdb-patches/20180528174715.A954AD804AD@oc3748833570.ibm.com/ Change-Id: Id6ef1c64e19090a183dec050e4034d8c2394e7ca Reviewed-by: John Baldwin --- gdb/aarch64-tdep.c | 148 +++++++++++-------------- gdb/amd64-tdep.c | 43 ++------ gdb/dwarf2/frame.c | 5 +- gdb/frame.c | 36 +++++- gdb/gdbarch-gen.h | 4 +- gdb/gdbarch.c | 4 +- gdb/gdbarch_components.py | 2 +- gdb/i386-tdep.c | 224 ++++++++++++++------------------------ gdb/i386-tdep.h | 7 +- gdb/regcache.c | 38 +++++-- gdb/value.c | 70 ++++++++++++ gdb/value.h | 26 +++++ 12 files changed, 322 insertions(+), 285 deletions(-) diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c index 50bfaa41eee2..341a6a19de5f 100644 --- a/gdb/aarch64-tdep.c +++ b/gdb/aarch64-tdep.c @@ -3104,25 +3104,14 @@ aarch64_pseudo_register_reggroup_p (struct gdbarch *gdbarch, int regnum, /* Helper for aarch64_pseudo_read_value. */ -static struct value * -aarch64_pseudo_read_value_1 (struct gdbarch *gdbarch, - readable_regcache *regcache, int regnum_offset, - int regsize, struct value *result_value) +static value * +aarch64_pseudo_read_value_1 (frame_info_ptr next_frame, + const int pseudo_reg_num, int raw_regnum_offset) { - unsigned v_regnum = AARCH64_V0_REGNUM + regnum_offset; - - /* Enough space for a full vector register. */ - gdb_byte reg_buf[register_size (gdbarch, AARCH64_V0_REGNUM)]; - gdb_static_assert (AARCH64_V0_REGNUM == AARCH64_SVE_Z0_REGNUM); + unsigned v_regnum = AARCH64_V0_REGNUM + raw_regnum_offset; - if (regcache->raw_read (v_regnum, reg_buf) != REG_VALID) - result_value->mark_bytes_unavailable (0, - result_value->type ()->length ()); - else - memcpy (result_value->contents_raw ().data (), reg_buf, regsize); - - return result_value; - } + return pseudo_from_raw_part (next_frame, pseudo_reg_num, v_regnum, 0); +} /* Helper function for reading/writing ZA pseudo-registers. Given REGNUM, a ZA pseudo-register number, return, in OFFSETS, the information on positioning @@ -3205,54 +3194,47 @@ aarch64_za_offsets_from_regnum (struct gdbarch *gdbarch, int regnum, /* Given REGNUM, a SME pseudo-register number, return its value in RESULT. */ -static struct value * -aarch64_sme_pseudo_register_read (struct gdbarch *gdbarch, - readable_regcache *regcache, int regnum, - struct value *result) +static value * +aarch64_sme_pseudo_register_read (gdbarch *gdbarch, frame_info_ptr next_frame, + const int pseudo_reg_num) { aarch64_gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); gdb_assert (tdep->has_sme ()); gdb_assert (tdep->sme_svq > 0); - gdb_assert (tdep->sme_pseudo_base <= regnum); - gdb_assert (regnum < tdep->sme_pseudo_base + tdep->sme_pseudo_count); + gdb_assert (tdep->sme_pseudo_base <= pseudo_reg_num); + gdb_assert (pseudo_reg_num < tdep->sme_pseudo_base + tdep->sme_pseudo_count); /* Fetch the offsets that we need in order to read from the correct blocks of ZA. */ struct za_offsets offsets; - aarch64_za_offsets_from_regnum (gdbarch, regnum, offsets); + aarch64_za_offsets_from_regnum (gdbarch, pseudo_reg_num, offsets); /* Fetch the contents of ZA. */ - size_t svl = sve_vl_from_vq (tdep->sme_svq); - gdb::byte_vector za (std::pow (svl, 2)); - regcache->raw_read (tdep->sme_za_regnum, za.data ()); + value *za_value = value_of_register (tdep->sme_za_regnum, next_frame); + value *result = value::allocate_register (next_frame, pseudo_reg_num); /* Copy the requested data. */ for (int chunks = 0; chunks < offsets.chunks; chunks++) { - const gdb_byte *source - = za.data () + offsets.starting_offset + chunks * offsets.stride_size; - gdb_byte *destination - = result->contents_raw ().data () + chunks * offsets.chunk_size; - - memcpy (destination, source, offsets.chunk_size); + int src_offset = offsets.starting_offset + chunks * offsets.stride_size; + int dst_offset = chunks * offsets.chunk_size; + za_value->contents_copy (result, dst_offset, src_offset, + offsets.chunk_size); } + return result; } /* Implement the "pseudo_register_read_value" gdbarch method. */ -static struct value * -aarch64_pseudo_read_value (struct gdbarch *gdbarch, readable_regcache *regcache, - int regnum) +static value * +aarch64_pseudo_read_value (gdbarch *gdbarch, frame_info_ptr next_frame, + const int pseudo_reg_num) { aarch64_gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); - struct value *result_value = value::allocate (register_type (gdbarch, regnum)); - result_value->set_lval (lval_register); - VALUE_REGNUM (result_value) = regnum; - - if (is_w_pseudo_register (gdbarch, regnum)) + if (is_w_pseudo_register (gdbarch, pseudo_reg_num)) { enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); /* Default offset for little endian. */ @@ -3262,53 +3244,49 @@ aarch64_pseudo_read_value (struct gdbarch *gdbarch, readable_regcache *regcache, offset = 4; /* Find the correct X register to extract the data from. */ - int x_regnum = AARCH64_X0_REGNUM + (regnum - tdep->w_pseudo_base); - gdb_byte data[4]; + int x_regnum + = AARCH64_X0_REGNUM + (pseudo_reg_num - tdep->w_pseudo_base); /* Read the bottom 4 bytes of X. */ - if (regcache->raw_read_part (x_regnum, offset, 4, data) != REG_VALID) - result_value->mark_bytes_unavailable (0, 4); - else - memcpy (result_value->contents_raw ().data (), data, 4); - - return result_value; + return pseudo_from_raw_part (next_frame, pseudo_reg_num, x_regnum, + offset); } - else if (is_sme_pseudo_register (gdbarch, regnum)) - return aarch64_sme_pseudo_register_read (gdbarch, regcache, regnum, - result_value); - - regnum -= gdbarch_num_regs (gdbarch); - - if (regnum >= AARCH64_Q0_REGNUM && regnum < AARCH64_Q0_REGNUM + 32) - return aarch64_pseudo_read_value_1 (gdbarch, regcache, - regnum - AARCH64_Q0_REGNUM, - Q_REGISTER_SIZE, result_value); - - if (regnum >= AARCH64_D0_REGNUM && regnum < AARCH64_D0_REGNUM + 32) - return aarch64_pseudo_read_value_1 (gdbarch, regcache, - regnum - AARCH64_D0_REGNUM, - D_REGISTER_SIZE, result_value); - - if (regnum >= AARCH64_S0_REGNUM && regnum < AARCH64_S0_REGNUM + 32) - return aarch64_pseudo_read_value_1 (gdbarch, regcache, - regnum - AARCH64_S0_REGNUM, - S_REGISTER_SIZE, result_value); - - if (regnum >= AARCH64_H0_REGNUM && regnum < AARCH64_H0_REGNUM + 32) - return aarch64_pseudo_read_value_1 (gdbarch, regcache, - regnum - AARCH64_H0_REGNUM, - H_REGISTER_SIZE, result_value); - - if (regnum >= AARCH64_B0_REGNUM && regnum < AARCH64_B0_REGNUM + 32) - return aarch64_pseudo_read_value_1 (gdbarch, regcache, - regnum - AARCH64_B0_REGNUM, - B_REGISTER_SIZE, result_value); - - if (tdep->has_sve () && regnum >= AARCH64_SVE_V0_REGNUM - && regnum < AARCH64_SVE_V0_REGNUM + 32) - return aarch64_pseudo_read_value_1 (gdbarch, regcache, - regnum - AARCH64_SVE_V0_REGNUM, - V_REGISTER_SIZE, result_value); + else if (is_sme_pseudo_register (gdbarch, pseudo_reg_num)) + return aarch64_sme_pseudo_register_read (gdbarch, next_frame, + pseudo_reg_num); + + /* Offset in the "pseudo-register space". */ + int pseudo_offset = pseudo_reg_num - gdbarch_num_regs (gdbarch); + + if (pseudo_offset >= AARCH64_Q0_REGNUM + && pseudo_offset < AARCH64_Q0_REGNUM + 32) + return aarch64_pseudo_read_value_1 (next_frame, pseudo_reg_num, + pseudo_offset - AARCH64_Q0_REGNUM); + + if (pseudo_offset >= AARCH64_D0_REGNUM + && pseudo_offset < AARCH64_D0_REGNUM + 32) + return aarch64_pseudo_read_value_1 (next_frame, pseudo_reg_num, + pseudo_offset - AARCH64_D0_REGNUM); + + if (pseudo_offset >= AARCH64_S0_REGNUM + && pseudo_offset < AARCH64_S0_REGNUM + 32) + return aarch64_pseudo_read_value_1 (next_frame, pseudo_reg_num, + pseudo_offset - AARCH64_S0_REGNUM); + + if (pseudo_offset >= AARCH64_H0_REGNUM + && pseudo_offset < AARCH64_H0_REGNUM + 32) + return aarch64_pseudo_read_value_1 (next_frame, pseudo_reg_num, + pseudo_offset - AARCH64_H0_REGNUM); + + if (pseudo_offset >= AARCH64_B0_REGNUM + && pseudo_offset < AARCH64_B0_REGNUM + 32) + return aarch64_pseudo_read_value_1 (next_frame, pseudo_reg_num, + pseudo_offset - AARCH64_B0_REGNUM); + + if (tdep->has_sve () && pseudo_offset >= AARCH64_SVE_V0_REGNUM + && pseudo_offset < AARCH64_SVE_V0_REGNUM + 32) + return aarch64_pseudo_read_value_1 (next_frame, pseudo_reg_num, + pseudo_offset - AARCH64_SVE_V0_REGNUM); gdb_assert_not_reached ("regnum out of bound"); } diff --git a/gdb/amd64-tdep.c b/gdb/amd64-tdep.c index e6feee677b3d..955a6860631d 100644 --- a/gdb/amd64-tdep.c +++ b/gdb/amd64-tdep.c @@ -348,18 +348,12 @@ amd64_pseudo_register_name (struct gdbarch *gdbarch, int regnum) return i386_pseudo_register_name (gdbarch, regnum); } -static struct value * -amd64_pseudo_register_read_value (struct gdbarch *gdbarch, - readable_regcache *regcache, +static value * +amd64_pseudo_register_read_value (gdbarch *gdbarch, frame_info_ptr next_frame, int regnum) { i386_gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); - value *result_value = value::allocate (register_type (gdbarch, regnum)); - result_value->set_lval (lval_register); - VALUE_REGNUM (result_value) = regnum; - gdb_byte *buf = result_value->contents_raw ().data (); - if (i386_byte_regnum_p (gdbarch, regnum)) { int gpnum = regnum - tdep->al_regnum; @@ -368,44 +362,21 @@ amd64_pseudo_register_read_value (struct gdbarch *gdbarch, if (gpnum >= AMD64_NUM_LOWER_BYTE_REGS) { gpnum -= AMD64_NUM_LOWER_BYTE_REGS; - gdb_byte raw_buf[register_size (gdbarch, gpnum)]; /* Special handling for AH, BH, CH, DH. */ - register_status status = regcache->raw_read (gpnum, raw_buf); - if (status == REG_VALID) - memcpy (buf, raw_buf + 1, 1); - else - result_value->mark_bytes_unavailable (0, - result_value->type ()->length ()); + return pseudo_from_raw_part (next_frame, regnum, gpnum, 1); } else - { - gdb_byte raw_buf[register_size (gdbarch, gpnum)]; - register_status status = regcache->raw_read (gpnum, raw_buf); - if (status == REG_VALID) - memcpy (buf, raw_buf, 1); - else - result_value->mark_bytes_unavailable (0, - result_value->type ()->length ()); - } + return pseudo_from_raw_part (next_frame, regnum, gpnum, 0); } else if (i386_dword_regnum_p (gdbarch, regnum)) { int gpnum = regnum - tdep->eax_regnum; - gdb_byte raw_buf[register_size (gdbarch, gpnum)]; - /* Extract (always little endian). */ - register_status status = regcache->raw_read (gpnum, raw_buf); - if (status == REG_VALID) - memcpy (buf, raw_buf, 4); - else - result_value->mark_bytes_unavailable (0, - result_value->type ()->length ()); + + return pseudo_from_raw_part (next_frame, regnum, gpnum, 0); } else - i386_pseudo_register_read_into_value (gdbarch, regcache, regnum, - result_value); - - return result_value; + return i386_pseudo_register_read_value (gdbarch, next_frame, regnum); } static void diff --git a/gdb/dwarf2/frame.c b/gdb/dwarf2/frame.c index abc8d6134824..7f8ed2bc9eec 100644 --- a/gdb/dwarf2/frame.c +++ b/gdb/dwarf2/frame.c @@ -1220,7 +1220,10 @@ dwarf2_frame_prev_register (frame_info_ptr this_frame, void **this_cache, "undefined"). Code above issues a complaint about this. Here just fudge the books, assume GCC, and that the value is more inner on the stack. */ - return frame_unwind_got_register (this_frame, regnum, regnum); + if (regnum < gdbarch_num_regs (gdbarch)) + return frame_unwind_got_register (this_frame, regnum, regnum); + else + return nullptr; case DWARF2_FRAME_REG_SAME_VALUE: return frame_unwind_got_register (this_frame, regnum, regnum); diff --git a/gdb/frame.c b/gdb/frame.c index 341bd26ee0df..3035f87369ca 100644 --- a/gdb/frame.c +++ b/gdb/frame.c @@ -1256,9 +1256,39 @@ frame_unwind_register_value (frame_info_ptr next_frame, int regnum) frame_unwind_find_by_frame (next_frame, &next_frame->prologue_cache); /* Ask this frame to unwind its register. */ - value *value = next_frame->unwind->prev_register (next_frame, - &next_frame->prologue_cache, - regnum); + value *value + = next_frame->unwind->prev_register (next_frame, + &next_frame->prologue_cache, regnum); + if (value == nullptr) + { + if (gdbarch_pseudo_register_read_value_p (gdbarch)) + { + /* This is a pseudo register, we don't know how how what raw registers + this pseudo register is made of. Ask the gdbarch to read the + value, it will itself ask the next frame to unwind the values of + the raw registers it needs to compose the value of the pseudo + register. */ + value = gdbarch_pseudo_register_read_value + (gdbarch, next_frame, regnum); + } + else if (gdbarch_pseudo_register_read_p (gdbarch)) + { + value = value::allocate_register (next_frame, regnum); + + /* Passing the current regcache is known to be broken, the pseudo + register value will be constructed using the current raw registers, + rather than reading them using NEXT_FRAME. Architectures should be + migrated to gdbarch_pseudo_register_read_value. */ + register_status status = gdbarch_pseudo_register_read + (gdbarch, get_current_regcache (), regnum, + value->contents_writeable ().data ()); + if (status == REG_UNAVAILABLE) + value->mark_bytes_unavailable (0, value->type ()->length ()); + } + else + error (_("Can't unwind value of register %d (%s)"), regnum, + user_reg_map_regnum_to_name (gdbarch, regnum)); + } if (frame_debug) { diff --git a/gdb/gdbarch-gen.h b/gdb/gdbarch-gen.h index 1d169c6e4f46..c2de274ed2a9 100644 --- a/gdb/gdbarch-gen.h +++ b/gdb/gdbarch-gen.h @@ -196,8 +196,8 @@ extern void set_gdbarch_pseudo_register_read (struct gdbarch *gdbarch, gdbarch_p extern bool gdbarch_pseudo_register_read_value_p (struct gdbarch *gdbarch); -typedef struct value * (gdbarch_pseudo_register_read_value_ftype) (struct gdbarch *gdbarch, readable_regcache *regcache, int cookednum); -extern struct value * gdbarch_pseudo_register_read_value (struct gdbarch *gdbarch, readable_regcache *regcache, int cookednum); +typedef struct value * (gdbarch_pseudo_register_read_value_ftype) (struct gdbarch *gdbarch, frame_info_ptr next_frame, int cookednum); +extern struct value * gdbarch_pseudo_register_read_value (struct gdbarch *gdbarch, frame_info_ptr next_frame, int cookednum); extern void set_gdbarch_pseudo_register_read_value (struct gdbarch *gdbarch, gdbarch_pseudo_register_read_value_ftype *pseudo_register_read_value); extern bool gdbarch_pseudo_register_write_p (struct gdbarch *gdbarch); diff --git a/gdb/gdbarch.c b/gdb/gdbarch.c index ea6e4c647b10..06ff52576bdf 100644 --- a/gdb/gdbarch.c +++ b/gdb/gdbarch.c @@ -1886,13 +1886,13 @@ gdbarch_pseudo_register_read_value_p (struct gdbarch *gdbarch) } struct value * -gdbarch_pseudo_register_read_value (struct gdbarch *gdbarch, readable_regcache *regcache, int cookednum) +gdbarch_pseudo_register_read_value (struct gdbarch *gdbarch, frame_info_ptr next_frame, int cookednum) { gdb_assert (gdbarch != NULL); gdb_assert (gdbarch->pseudo_register_read_value != NULL); if (gdbarch_debug >= 2) gdb_printf (gdb_stdlog, "gdbarch_pseudo_register_read_value called\n"); - return gdbarch->pseudo_register_read_value (gdbarch, regcache, cookednum); + return gdbarch->pseudo_register_read_value (gdbarch, next_frame, cookednum); } void diff --git a/gdb/gdbarch_components.py b/gdb/gdbarch_components.py index 592d301ed353..86754af17cc3 100644 --- a/gdb/gdbarch_components.py +++ b/gdb/gdbarch_components.py @@ -414,7 +414,7 @@ never be called. """, type="struct value *", name="pseudo_register_read_value", - params=[("readable_regcache *", "regcache"), ("int", "cookednum")], + params=[("frame_info_ptr", "next_frame"), ("int", "cookednum")], predicate=True, ) diff --git a/gdb/i386-tdep.c b/gdb/i386-tdep.c index 152529834eea..7f849bac6cd3 100644 --- a/gdb/i386-tdep.c +++ b/gdb/i386-tdep.c @@ -3411,195 +3411,131 @@ i386_mmx_regnum_to_fp_regnum (readable_regcache *regcache, int regnum) return (I387_ST0_REGNUM (tdep) + fpreg); } +/* Map a cooked register onto a raw register or memory. For the i386, + the MMX registers need to be mapped onto floating point registers. */ + +static int +i386_mmx_regnum_to_fp_regnum (frame_info_ptr next_frame, int regnum) +{ + gdbarch *arch = frame_unwind_arch (next_frame); + i386_gdbarch_tdep *tdep = gdbarch_tdep (arch); + ULONGEST fstat + = frame_unwind_register_unsigned (next_frame, I387_FSTAT_REGNUM (tdep)); + int tos = (fstat >> 11) & 0x7; + int mmxreg = regnum - tdep->mm0_regnum; + int fpreg = (mmxreg + tos) % 8; + + return (I387_ST0_REGNUM (tdep) + fpreg); +} + /* A helper function for us by i386_pseudo_register_read_value and amd64_pseudo_register_read_value. It does all the work but reads the data into an already-allocated value. */ -void -i386_pseudo_register_read_into_value (struct gdbarch *gdbarch, - readable_regcache *regcache, - int regnum, - struct value *result_value) +value * +i386_pseudo_register_read_value (gdbarch *gdbarch, frame_info_ptr next_frame, + const int pseudo_reg_num) { - gdb_byte raw_buf[I386_MAX_REGISTER_SIZE]; - enum register_status status; - gdb_byte *buf = result_value->contents_raw ().data (); - - if (i386_mmx_regnum_p (gdbarch, regnum)) + if (i386_mmx_regnum_p (gdbarch, pseudo_reg_num)) { - int fpnum = i386_mmx_regnum_to_fp_regnum (regcache, regnum); + int fpnum = i386_mmx_regnum_to_fp_regnum (next_frame, pseudo_reg_num); /* Extract (always little endian). */ - status = regcache->raw_read (fpnum, raw_buf); - if (status != REG_VALID) - result_value->mark_bytes_unavailable (0, - result_value->type ()->length ()); - else - memcpy (buf, raw_buf, register_size (gdbarch, regnum)); + return pseudo_from_raw_part (next_frame, pseudo_reg_num, fpnum, 0); } else { i386_gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); - if (i386_bnd_regnum_p (gdbarch, regnum)) + if (i386_bnd_regnum_p (gdbarch, pseudo_reg_num)) { - regnum -= tdep->bnd0_regnum; + int i = pseudo_reg_num - tdep->bnd0_regnum; /* Extract (always little endian). Read lower 128bits. */ - status = regcache->raw_read (I387_BND0R_REGNUM (tdep) + regnum, - raw_buf); - if (status != REG_VALID) - result_value->mark_bytes_unavailable (0, 16); - else + value *bndr_value + = value_of_register (I387_BND0R_REGNUM (tdep) + i, next_frame); + int size = builtin_type (gdbarch)->builtin_data_ptr->length (); + value *result + = value::allocate_register (next_frame, pseudo_reg_num); + + /* Copy the lower. */ + bndr_value->contents_copy (result, 0, 0, size); + + /* Copy the upper. */ + bndr_value->contents_copy (result, size, 8, size); + + /* If upper bytes are available, compute ones' complement. */ + if (result->bytes_available (size, size)) { bfd_endian byte_order - = gdbarch_byte_order (current_inferior ()->arch ()); - LONGEST upper, lower; - int size = builtin_type (gdbarch)->builtin_data_ptr->length (); - - lower = extract_unsigned_integer (raw_buf, 8, byte_order); - upper = extract_unsigned_integer (raw_buf + 8, 8, byte_order); + = gdbarch_byte_order (frame_unwind_arch (next_frame)); + gdb::array_view upper_bytes + = result->contents_raw ().slice (size, size); + ULONGEST upper + = extract_unsigned_integer (upper_bytes, byte_order); upper = ~upper; - - memcpy (buf, &lower, size); - memcpy (buf + size, &upper, size); + store_unsigned_integer (upper_bytes, byte_order, upper); } + + return result; } - else if (i386_zmm_regnum_p (gdbarch, regnum)) + else if (i386_zmm_regnum_p (gdbarch, pseudo_reg_num)) { - regnum -= tdep->zmm0_regnum; - - if (regnum < num_lower_zmm_regs) - { - /* Extract (always little endian). Read lower 128bits. */ - status = regcache->raw_read (I387_XMM0_REGNUM (tdep) + regnum, - raw_buf); - if (status != REG_VALID) - result_value->mark_bytes_unavailable (0, 16); - else - memcpy (buf, raw_buf, 16); + /* Which register is it, relative to zmm0. */ + int i_0 = pseudo_reg_num - tdep->zmm0_regnum; - /* Extract (always little endian). Read upper 128bits. */ - status = regcache->raw_read (tdep->ymm0h_regnum + regnum, - raw_buf); - if (status != REG_VALID) - result_value->mark_bytes_unavailable (16, 16); - else - memcpy (buf + 16, raw_buf, 16); - } + if (i_0 < num_lower_zmm_regs) + return pseudo_from_concat_raw (next_frame, pseudo_reg_num, + I387_XMM0_REGNUM (tdep) + i_0, + tdep->ymm0h_regnum + i_0, + tdep->zmm0h_regnum + i_0); else { - /* Extract (always little endian). Read lower 128bits. */ - status = regcache->raw_read (I387_XMM16_REGNUM (tdep) + regnum - - num_lower_zmm_regs, - raw_buf); - if (status != REG_VALID) - result_value->mark_bytes_unavailable (0, 16); - else - memcpy (buf, raw_buf, 16); - - /* Extract (always little endian). Read upper 128bits. */ - status = regcache->raw_read (I387_YMM16H_REGNUM (tdep) + regnum - - num_lower_zmm_regs, - raw_buf); - if (status != REG_VALID) - result_value->mark_bytes_unavailable (16, 16); - else - memcpy (buf + 16, raw_buf, 16); - } + /* Which register is it, relative to zmm16. */ + int i_16 = i_0 - num_lower_zmm_regs; - /* Read upper 256bits. */ - status = regcache->raw_read (tdep->zmm0h_regnum + regnum, - raw_buf); - if (status != REG_VALID) - result_value->mark_bytes_unavailable (32, 32); - else - memcpy (buf + 32, raw_buf, 32); + return pseudo_from_concat_raw (next_frame, pseudo_reg_num, + I387_XMM16_REGNUM (tdep) + i_16, + I387_YMM16H_REGNUM (tdep) + i_16, + tdep->zmm0h_regnum + i_0); + } } - else if (i386_ymm_regnum_p (gdbarch, regnum)) + else if (i386_ymm_regnum_p (gdbarch, pseudo_reg_num)) { - regnum -= tdep->ymm0_regnum; + int i = pseudo_reg_num - tdep->ymm0_regnum; - /* Extract (always little endian). Read lower 128bits. */ - status = regcache->raw_read (I387_XMM0_REGNUM (tdep) + regnum, - raw_buf); - if (status != REG_VALID) - result_value->mark_bytes_unavailable (0, 16); - else - memcpy (buf, raw_buf, 16); - /* Read upper 128bits. */ - status = regcache->raw_read (tdep->ymm0h_regnum + regnum, - raw_buf); - if (status != REG_VALID) - result_value->mark_bytes_unavailable (16, 32); - else - memcpy (buf + 16, raw_buf, 16); + return pseudo_from_concat_raw (next_frame, pseudo_reg_num, + I387_XMM0_REGNUM (tdep) + i, + tdep->ymm0h_regnum + i); } - else if (i386_ymm_avx512_regnum_p (gdbarch, regnum)) + else if (i386_ymm_avx512_regnum_p (gdbarch, pseudo_reg_num)) { - regnum -= tdep->ymm16_regnum; - /* Extract (always little endian). Read lower 128bits. */ - status = regcache->raw_read (I387_XMM16_REGNUM (tdep) + regnum, - raw_buf); - if (status != REG_VALID) - result_value->mark_bytes_unavailable (0, 16); - else - memcpy (buf, raw_buf, 16); - /* Read upper 128bits. */ - status = regcache->raw_read (tdep->ymm16h_regnum + regnum, - raw_buf); - if (status != REG_VALID) - result_value->mark_bytes_unavailable (16, 16); - else - memcpy (buf + 16, raw_buf, 16); + int i = pseudo_reg_num - tdep->ymm16_regnum; + + return pseudo_from_concat_raw (next_frame, pseudo_reg_num, + I387_XMM16_REGNUM (tdep) + i, + tdep->ymm16h_regnum + i); } - else if (i386_word_regnum_p (gdbarch, regnum)) + else if (i386_word_regnum_p (gdbarch, pseudo_reg_num)) { - int gpnum = regnum - tdep->ax_regnum; + int gpnum = pseudo_reg_num - tdep->ax_regnum; /* Extract (always little endian). */ - status = regcache->raw_read (gpnum, raw_buf); - if (status != REG_VALID) - result_value->mark_bytes_unavailable (0, - result_value->type ()->length ()); - else - memcpy (buf, raw_buf, 2); + return pseudo_from_raw_part (next_frame, pseudo_reg_num, gpnum, 0); } - else if (i386_byte_regnum_p (gdbarch, regnum)) + else if (i386_byte_regnum_p (gdbarch, pseudo_reg_num)) { - int gpnum = regnum - tdep->al_regnum; + int gpnum = pseudo_reg_num - tdep->al_regnum; /* Extract (always little endian). We read both lower and upper registers. */ - status = regcache->raw_read (gpnum % 4, raw_buf); - if (status != REG_VALID) - result_value->mark_bytes_unavailable (0, - result_value->type ()->length ()); - else if (gpnum >= 4) - memcpy (buf, raw_buf + 1, 1); - else - memcpy (buf, raw_buf, 1); + return pseudo_from_raw_part (next_frame, pseudo_reg_num, gpnum % 4, + gpnum >= 4 ? 1 : 0); } else internal_error (_("invalid regnum")); } } -static struct value * -i386_pseudo_register_read_value (struct gdbarch *gdbarch, - readable_regcache *regcache, - int regnum) -{ - struct value *result; - - result = value::allocate (register_type (gdbarch, regnum)); - result->set_lval (lval_register); - VALUE_REGNUM (result) = regnum; - - i386_pseudo_register_read_into_value (gdbarch, regcache, regnum, result); - - return result; -} - void i386_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache, int regnum, const gdb_byte *buf) diff --git a/gdb/i386-tdep.h b/gdb/i386-tdep.h index 4283a52c9292..970dc8904f2a 100644 --- a/gdb/i386-tdep.h +++ b/gdb/i386-tdep.h @@ -376,10 +376,9 @@ extern const char *i386_pseudo_register_name (struct gdbarch *gdbarch, extern struct type *i386_pseudo_register_type (struct gdbarch *gdbarch, int regnum); -extern void i386_pseudo_register_read_into_value (struct gdbarch *gdbarch, - readable_regcache *regcache, - int regnum, - struct value *result); +extern value *i386_pseudo_register_read_value (gdbarch *gdbarch, + frame_info_ptr next_frame, + int regnum); extern void i386_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache, diff --git a/gdb/regcache.c b/gdb/regcache.c index 4256b82da19a..ff5f5b70433e 100644 --- a/gdb/regcache.c +++ b/gdb/regcache.c @@ -752,8 +752,9 @@ readable_regcache::cooked_read (int regnum, gdb::array_view dst, { register_status result = REG_VALID; scoped_value_mark mark; - value *computed - = gdbarch_pseudo_register_read_value (m_descr->gdbarch, this, regnum); + value *computed = gdbarch_pseudo_register_read_value + (m_descr->gdbarch, get_next_frame_sentinel_okay (get_current_frame ()), + regnum); if (computed->entirely_available ()) copy (computed->contents_raw (), dst); @@ -806,8 +807,9 @@ readable_regcache::cooked_read_value (int regnum) return result; } else - return gdbarch_pseudo_register_read_value (m_descr->gdbarch, - this, regnum); + return gdbarch_pseudo_register_read_value + (m_descr->gdbarch, get_next_frame_sentinel_okay (get_current_frame ()), + regnum); } enum register_status @@ -1958,10 +1960,18 @@ cooked_read_test (struct gdbarch *gdbarch) break; } - readwrite_regcache readwrite (&mockctx.mock_inferior, gdbarch); + /* Install this regcache in the regcaches global structure, so that. */ + pid_ptid_regcache_map &x = regcaches[&mockctx.mock_target]; + ptid_regcache_map &y = x[mockctx.mock_ptid.pid ()]; + regcache &readwrite + = *y.emplace (std::make_pair (mockctx.mock_ptid, + gdb::make_unique ( + &mockctx.mock_inferior, gdbarch))) + ->second; + readwrite.set_ptid (mockctx.mock_ptid); - gdb::byte_vector buf (register_size (gdbarch, nonzero_regnum)); + gdb::byte_vector buf (register_size (gdbarch, nonzero_regnum)); readwrite.raw_read (nonzero_regnum, buf, 1.0f); /* raw_read calls target_fetch_registers. */ @@ -2060,6 +2070,8 @@ cooked_read_test (struct gdbarch *gdbarch) mockctx.mock_target.reset (); } + + regcaches.erase (&mockctx.mock_target); } /* Test regcache::cooked_write by writing some expected contents to @@ -2074,7 +2086,17 @@ cooked_write_test (struct gdbarch *gdbarch) /* Create a mock environment. A process_stratum target pushed. */ scoped_mock_context ctx (gdbarch); - readwrite_regcache readwrite (&ctx.mock_inferior, gdbarch); + + + /* Install this regcache in the regcaches global structure, so that. */ + pid_ptid_regcache_map &x = regcaches[&ctx.mock_target]; + ptid_regcache_map &y = x[ctx.mock_ptid.pid ()]; + regcache &readwrite + = *y.emplace (std::make_pair (ctx.mock_ptid, + gdb::make_unique ( + &ctx.mock_inferior, gdbarch))) + ->second; + readwrite.set_ptid (ctx.mock_ptid); const int num_regs = gdbarch_num_cooked_regs (gdbarch); @@ -2155,6 +2177,8 @@ cooked_write_test (struct gdbarch *gdbarch) SELF_CHECK (readwrite.cooked_read (regnum, buf, 1.0f) == REG_VALID); SELF_CHECK (expected == buf); } + + regcaches.erase (&ctx.mock_target); } /* Verify that when two threads with the same ptid exist (from two different diff --git a/gdb/value.c b/gdb/value.c index a1b18087416f..27a79dc62fc1 100644 --- a/gdb/value.c +++ b/gdb/value.c @@ -4041,6 +4041,76 @@ value::fetch_lazy () set_lazy (false); } +/* See value.h. */ + +value * +pseudo_from_raw_part (frame_info_ptr next_frame, int pseudo_reg_num, + int raw_reg_num, int raw_offset) +{ + value *pseudo_reg_val + = value::allocate_register (next_frame, pseudo_reg_num); + value *raw_reg_val = value_of_register (raw_reg_num, next_frame); + raw_reg_val->contents_copy (pseudo_reg_val, 0, raw_offset, + pseudo_reg_val->type ()->length ()); + return pseudo_reg_val; +} + +/* See value.h. */ + +value * +pseudo_from_concat_raw (frame_info_ptr next_frame, int pseudo_reg_num, + int raw_reg_1_num, int raw_reg_2_num) +{ + value *pseudo_reg_val + = value::allocate_register (next_frame, pseudo_reg_num); + int dst_offset = 0; + + value *raw_reg_1_val = value_of_register (raw_reg_1_num, next_frame); + raw_reg_1_val->contents_copy (pseudo_reg_val, dst_offset, 0, + raw_reg_1_val->type ()->length ()); + dst_offset += raw_reg_1_val->type ()->length (); + + value *raw_reg_2_val = value_of_register (raw_reg_2_num, next_frame); + raw_reg_2_val->contents_copy (pseudo_reg_val, dst_offset, 0, + raw_reg_2_val->type ()->length ()); + dst_offset += raw_reg_2_val->type ()->length (); + + gdb_assert (dst_offset == pseudo_reg_val->type ()->length ()); + + return pseudo_reg_val; +} + +/* See value.h. */ + +value * +pseudo_from_concat_raw (frame_info_ptr next_frame, int pseudo_reg_num, + int raw_reg_1_num, int raw_reg_2_num, + int raw_reg_3_num) +{ + value *pseudo_reg_val + = value::allocate_register (next_frame, pseudo_reg_num); + int dst_offset = 0; + + value *raw_reg_1_val = value_of_register (raw_reg_1_num, next_frame); + raw_reg_1_val->contents_copy (pseudo_reg_val, dst_offset, 0, + raw_reg_1_val->type ()->length ()); + dst_offset += raw_reg_1_val->type ()->length (); + + value *raw_reg_2_val = value_of_register (raw_reg_2_num, next_frame); + raw_reg_2_val->contents_copy (pseudo_reg_val, dst_offset, 0, + raw_reg_2_val->type ()->length ()); + dst_offset += raw_reg_2_val->type ()->length (); + + value *raw_reg_3_val = value_of_register (raw_reg_3_num, next_frame); + raw_reg_3_val->contents_copy (pseudo_reg_val, dst_offset, 0, + raw_reg_3_val->type ()->length ()); + dst_offset += raw_reg_3_val->type ()->length (); + + gdb_assert (dst_offset == pseudo_reg_val->type ()->length ()); + + return pseudo_reg_val; +} + /* Implementation of the convenience function $_isvoid. */ static struct value * diff --git a/gdb/value.h b/gdb/value.h index 511bde8bbd46..b5c097ad58bf 100644 --- a/gdb/value.h +++ b/gdb/value.h @@ -1650,4 +1650,30 @@ struct scoped_array_length_limiting gdb::optional m_old_value; }; +/* Helpers for building pseudo register values from raw registers. */ + +/* Create a value for pseudo register PSEUDO_REG_NUM by using bytes from + raw register RAW_REG_NUM starting at RAW_OFFSET. + + The size of the pseudo register specifies how many bytes to use. The + offset plus the size must not overflow the raw register's size. */ + +value *pseudo_from_raw_part (frame_info_ptr next_frame, int pseudo_reg_num, + int raw_reg_num, int raw_offset); + +/* Create a value for pseudo register PSEUDO_REG_NUM by concatenating raw + registers RAW_REG_1_NUM and RAW_REG_2_NUM. + + The sum of the sizes of raw registers must be equal to the size of the + pseudo register. */ + +value *pseudo_from_concat_raw (frame_info_ptr next_frame, int pseudo_reg_num, + int raw_reg_1_num, int raw_reg_2_num); + +/* Same as the above, but with three raw registers. */ + +value *pseudo_from_concat_raw (frame_info_ptr next_frame, int pseudo_reg_num, + int raw_reg_1_num, int raw_reg_2_num, + int raw_reg_3_num); + #endif /* !defined (VALUE_H) */ From patchwork Wed Nov 8 05:00:59 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Marchi X-Patchwork-Id: 79389 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 C9788385841B for ; Wed, 8 Nov 2023 05:31:57 +0000 (GMT) X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from smtp.polymtl.ca (smtp.polymtl.ca [132.207.4.11]) by sourceware.org (Postfix) with ESMTPS id C4F343858D35 for ; Wed, 8 Nov 2023 05:31:44 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org C4F343858D35 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=polymtl.ca Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=polymtl.ca ARC-Filter: OpenARC Filter v1.0.0 sourceware.org C4F343858D35 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=132.207.4.11 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1699421505; cv=none; b=Dx2IbH8ZQFMyZTZxjIBEzE8lNV+csPjefRrd4q/uLCPOeX640PLDE9QLppdTF0WAPxyMSSwamHgDzW9qxQtV6DcWyhcN3ZTOewGUZxT/hQ5HKuJtOV0ruWI91B5KqGOFUIlRu22epTLipe8VCAM82+gVDWgtqQazjji+bu330lc= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1699421505; c=relaxed/simple; bh=6Z86Szk//Mnb5Fjvl/ZhrS5QeKCMYSYAbjiG30uf3OQ=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=aS43TZa4rDmtCGqb0wE/vLJ+Zc73Hha8mRjoiL5RQz5af2/iWrCtv4+tVtIA+IwFohXdaRsnLLuz1gI5z0gOQNhdSeVRrGQFra5n1eYRMuj+almzih9TLb8fXUl8GyMkxku1Mw6t07MSJ//D4Lg81vGcs3NrXWRkTsN8HDHShSc= ARC-Authentication-Results: i=1; server2.sourceware.org Received: from simark.ca (simark.ca [158.69.221.121]) (authenticated bits=0) by smtp.polymtl.ca (8.14.7/8.14.7) with ESMTP id 3A85Vc3u018764 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 8 Nov 2023 00:31:42 -0500 DKIM-Filter: OpenDKIM Filter v2.11.0 smtp.polymtl.ca 3A85Vc3u018764 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=polymtl.ca; s=default; t=1699421503; bh=oYr9b2shyqn3xQMhb1jv9rFPhQqNLLFYFp58YK30aJ0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=VKcwxgZCJN4ZFjXJK4WcjcUqfYlUe1XghkVHO8D+ur+wSAsdJXJqRicOmfVHHp+RI OOESZOywUUiBCs3KPzmqn3zEMkhWzOAVG9bW2nanjB0ChBPdlLlMRiBlG5zBz9KVGB Bost3gYGCdh0nF3v6BbNUNrgAH0/g0gBK5X8q7xc= Received: from simark.localdomain (modemcable238.237-201-24.mc.videotron.ca [24.201.237.238]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) by simark.ca (Postfix) with ESMTPSA id E44721E1BC; Wed, 8 Nov 2023 00:14:32 -0500 (EST) From: Simon Marchi To: gdb-patches@sourceware.org Cc: Simon Marchi Subject: [PATCH 15/24] gdb: change parameter name in frame_unwind_register_unsigned declaration Date: Wed, 8 Nov 2023 00:00:59 -0500 Message-ID: <20231108051222.1275306-16-simon.marchi@polymtl.ca> X-Mailer: git-send-email 2.42.1 In-Reply-To: <20231108051222.1275306-1-simon.marchi@polymtl.ca> References: <20231108051222.1275306-1-simon.marchi@polymtl.ca> MIME-Version: 1.0 X-Poly-FromMTA: (simark.ca [158.69.221.121]) at Wed, 8 Nov 2023 05:31:38 +0000 X-Spam-Status: No, score=-3188.6 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_PASS, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE 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.30 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org From: Simon Marchi For consistency with the declarations around. Change-Id: I398266a61eae6e93fb7e306923009da9dd7f8fc4 --- gdb/frame.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gdb/frame.h b/gdb/frame.h index 3b26da817cd8..a2921674782c 100644 --- a/gdb/frame.h +++ b/gdb/frame.h @@ -707,7 +707,7 @@ extern LONGEST frame_unwind_register_signed (frame_info_ptr next_frame, int regnum); extern LONGEST get_frame_register_signed (frame_info_ptr frame, int regnum); -extern ULONGEST frame_unwind_register_unsigned (frame_info_ptr frame, +extern ULONGEST frame_unwind_register_unsigned (frame_info_ptr next_frame, int regnum); extern ULONGEST get_frame_register_unsigned (frame_info_ptr frame, int regnum); From patchwork Wed Nov 8 05:01:00 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Marchi X-Patchwork-Id: 79380 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 816AD3858C41 for ; Wed, 8 Nov 2023 05:17:10 +0000 (GMT) X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from smtp.polymtl.ca (smtp.polymtl.ca [132.207.4.11]) by sourceware.org (Postfix) with ESMTPS id 9A3003858D3C for ; Wed, 8 Nov 2023 05:16:43 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 9A3003858D3C Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=polymtl.ca Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=polymtl.ca ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 9A3003858D3C Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=132.207.4.11 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1699420606; cv=none; b=ZRSi0EgSzhtHfzWuq9MXCh4ZWb+SLQSGBc3tmTfBSjRKqlNLy2oqPFgAtetl3mxhwbqN8YOTCzqnzBNlBUhodvZFVxPNco6hJfswzspD1Ez6IkZiVzZNrqV/s2NhBIZPl+vQp63ZrtGA8ieCEcO+9QXmK1BEnM+JfyD6/UbFNJs= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1699420606; c=relaxed/simple; bh=GP8Whz6s691BFPJMFOvjKtR3GRC/b2Ovk4a7qZMN0/0=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=AmpiAhf4eOldgGhDwhlO524WYLwXkTDxUupYwyLYRHWWz2xSqrc3+OT2WZRzLECSL95RiVTPGb8PvcjnoXAdXV2VJit8FO1af3OdDtvNYGyeFPiWMIpAOe8/tklqhU/8U3aTqJRNlMQP/KVXLBlhIHFiDk+XoHOSHjBz0RC4kEU= ARC-Authentication-Results: i=1; server2.sourceware.org Received: from simark.ca (simark.ca [158.69.221.121]) (authenticated bits=0) by smtp.polymtl.ca (8.14.7/8.14.7) with ESMTP id 3A85GbuR016028 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 8 Nov 2023 00:16:41 -0500 DKIM-Filter: OpenDKIM Filter v2.11.0 smtp.polymtl.ca 3A85GbuR016028 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=polymtl.ca; s=default; t=1699420601; bh=71i2GZh1HBfBz1HJ4DYxRL6X4Adxu/KVntgSwnTOykg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ET3pgixmF3//ibIvUWYFz5+sSGHVJRsXQfwZlkaotpjHy8KRykkqVDRn9o/SVSBEa DF739OU2qt9HOKIfyjum8zCVHG57xeWO2HJ2mb1TqszMIljFE3tFc86leWBJvAuuSg ey4mAtaOnCBscehd2YViULk1CDdLIQ+iXcXQWhK8= Received: from simark.localdomain (modemcable238.237-201-24.mc.videotron.ca [24.201.237.238]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) by simark.ca (Postfix) with ESMTPSA id F319E1E098; Wed, 8 Nov 2023 00:16:36 -0500 (EST) From: Simon Marchi To: gdb-patches@sourceware.org Cc: Simon Marchi Subject: [PATCH 16/24] gdb: rename gdbarch_pseudo_register_write to gdbarch_deprecated_pseudo_register_write Date: Wed, 8 Nov 2023 00:01:00 -0500 Message-ID: <20231108051222.1275306-17-simon.marchi@polymtl.ca> X-Mailer: git-send-email 2.42.1 In-Reply-To: <20231108051222.1275306-1-simon.marchi@polymtl.ca> References: <20231108051222.1275306-1-simon.marchi@polymtl.ca> MIME-Version: 1.0 X-Poly-FromMTA: (simark.ca [158.69.221.121]) at Wed, 8 Nov 2023 05:16:37 +0000 X-Spam-Status: No, score=-3188.6 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_PASS, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE 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.30 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org From: Simon Marchi The next patch introduces a new variant of gdbarch_pseudo_register_write that takes a frame instead of a regcache for implementations to write raw registers. Rename to old one to make it clear it's deprecated. Change-Id: If8872c89c6f8a1edfcab983eb064248fd5ff3115 --- gdb/aarch64-tdep.c | 2 +- gdb/amd64-tdep.c | 4 ++-- gdb/arm-tdep.c | 2 +- gdb/avr-tdep.c | 3 ++- gdb/bfin-tdep.c | 3 ++- gdb/csky-tdep.c | 4 ++-- gdb/frv-tdep.c | 3 ++- gdb/gdbarch-gen.h | 15 +++++++++++---- gdb/gdbarch.c | 30 +++++++++++++++--------------- gdb/gdbarch_components.py | 10 +++++++++- gdb/h8300-tdep.c | 3 ++- gdb/i386-tdep.c | 3 ++- gdb/ia64-tdep.c | 3 ++- gdb/m32c-tdep.c | 3 ++- gdb/m68hc11-tdep.c | 3 ++- gdb/mep-tdep.c | 3 ++- gdb/mips-tdep.c | 3 ++- gdb/msp430-tdep.c | 3 ++- gdb/nds32-tdep.c | 3 ++- gdb/regcache.c | 4 ++-- gdb/riscv-tdep.c | 9 +++++---- gdb/rl78-tdep.c | 3 ++- gdb/rs6000-tdep.c | 4 ++-- gdb/s390-tdep.c | 3 ++- gdb/sh-tdep.c | 9 ++++++--- gdb/sparc-tdep.c | 3 ++- gdb/sparc64-tdep.c | 3 ++- gdb/xtensa-tdep.c | 3 ++- 28 files changed, 90 insertions(+), 54 deletions(-) diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c index 341a6a19de5f..d1a6d46fb1f2 100644 --- a/gdb/aarch64-tdep.c +++ b/gdb/aarch64-tdep.c @@ -4481,7 +4481,7 @@ aarch64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) set_gdbarch_num_pseudo_regs (gdbarch, num_pseudo_regs); set_gdbarch_pseudo_register_read_value (gdbarch, aarch64_pseudo_read_value); - set_gdbarch_pseudo_register_write (gdbarch, aarch64_pseudo_write); + set_gdbarch_deprecated_pseudo_register_write (gdbarch, aarch64_pseudo_write); set_tdesc_pseudo_register_name (gdbarch, aarch64_pseudo_register_name); set_tdesc_pseudo_register_type (gdbarch, aarch64_pseudo_register_type); set_tdesc_pseudo_register_reggroup_p (gdbarch, diff --git a/gdb/amd64-tdep.c b/gdb/amd64-tdep.c index 955a6860631d..a0b4986d5b6c 100644 --- a/gdb/amd64-tdep.c +++ b/gdb/amd64-tdep.c @@ -3205,8 +3205,8 @@ amd64_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch, set_gdbarch_pseudo_register_read_value (gdbarch, amd64_pseudo_register_read_value); - set_gdbarch_pseudo_register_write (gdbarch, - amd64_pseudo_register_write); + set_gdbarch_deprecated_pseudo_register_write (gdbarch, + amd64_pseudo_register_write); set_gdbarch_ax_pseudo_register_collect (gdbarch, amd64_ax_pseudo_register_collect); diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c index 5c8c4cd4e94b..cd4c760c2ff4 100644 --- a/gdb/arm-tdep.c +++ b/gdb/arm-tdep.c @@ -10906,7 +10906,7 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) { set_gdbarch_num_pseudo_regs (gdbarch, num_pseudos); set_gdbarch_pseudo_register_read (gdbarch, arm_pseudo_read); - set_gdbarch_pseudo_register_write (gdbarch, arm_pseudo_write); + set_gdbarch_deprecated_pseudo_register_write (gdbarch, arm_pseudo_write); } /* Add standard register aliases. We add aliases even for those diff --git a/gdb/avr-tdep.c b/gdb/avr-tdep.c index 92aec3b510f5..5690f6f65c74 100644 --- a/gdb/avr-tdep.c +++ b/gdb/avr-tdep.c @@ -1510,7 +1510,8 @@ avr_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) set_gdbarch_num_pseudo_regs (gdbarch, AVR_NUM_PSEUDO_REGS); set_gdbarch_pseudo_register_read (gdbarch, avr_pseudo_register_read); - set_gdbarch_pseudo_register_write (gdbarch, avr_pseudo_register_write); + set_gdbarch_deprecated_pseudo_register_write (gdbarch, + avr_pseudo_register_write); set_gdbarch_return_value (gdbarch, avr_return_value); diff --git a/gdb/bfin-tdep.c b/gdb/bfin-tdep.c index 4b9067a2d0f7..0ff4355f573e 100644 --- a/gdb/bfin-tdep.c +++ b/gdb/bfin-tdep.c @@ -805,7 +805,8 @@ bfin_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) set_gdbarch_num_regs (gdbarch, BFIN_NUM_REGS); set_gdbarch_pseudo_register_read (gdbarch, bfin_pseudo_register_read); - set_gdbarch_pseudo_register_write (gdbarch, bfin_pseudo_register_write); + set_gdbarch_deprecated_pseudo_register_write (gdbarch, + bfin_pseudo_register_write); set_gdbarch_num_pseudo_regs (gdbarch, BFIN_NUM_PSEUDO_REGS); set_gdbarch_sp_regnum (gdbarch, BFIN_SP_REGNUM); set_gdbarch_pc_regnum (gdbarch, BFIN_PC_REGNUM); diff --git a/gdb/csky-tdep.c b/gdb/csky-tdep.c index e82b8dff546e..6cca72041a73 100644 --- a/gdb/csky-tdep.c +++ b/gdb/csky-tdep.c @@ -2872,8 +2872,8 @@ csky_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) tdep->fv_pseudo_registers_count); set_gdbarch_pseudo_register_read (gdbarch, csky_pseudo_register_read); - set_gdbarch_pseudo_register_write (gdbarch, - csky_pseudo_register_write); + set_gdbarch_deprecated_pseudo_register_write + (gdbarch, csky_pseudo_register_write); set_tdesc_pseudo_register_name (gdbarch, csky_pseudo_register_name); } diff --git a/gdb/frv-tdep.c b/gdb/frv-tdep.c index 3656f6fcb663..e4c10dfb4347 100644 --- a/gdb/frv-tdep.c +++ b/gdb/frv-tdep.c @@ -1499,7 +1499,8 @@ frv_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) set_gdbarch_register_sim_regno (gdbarch, frv_register_sim_regno); set_gdbarch_pseudo_register_read (gdbarch, frv_pseudo_register_read); - set_gdbarch_pseudo_register_write (gdbarch, frv_pseudo_register_write); + set_gdbarch_deprecated_pseudo_register_write (gdbarch, + frv_pseudo_register_write); set_gdbarch_skip_prologue (gdbarch, frv_skip_prologue); set_gdbarch_skip_main_prologue (gdbarch, frv_skip_main_prologue); diff --git a/gdb/gdbarch-gen.h b/gdb/gdbarch-gen.h index c2de274ed2a9..3160aa8a9613 100644 --- a/gdb/gdbarch-gen.h +++ b/gdb/gdbarch-gen.h @@ -200,11 +200,18 @@ typedef struct value * (gdbarch_pseudo_register_read_value_ftype) (struct gdbarc extern struct value * gdbarch_pseudo_register_read_value (struct gdbarch *gdbarch, frame_info_ptr next_frame, int cookednum); extern void set_gdbarch_pseudo_register_read_value (struct gdbarch *gdbarch, gdbarch_pseudo_register_read_value_ftype *pseudo_register_read_value); -extern bool gdbarch_pseudo_register_write_p (struct gdbarch *gdbarch); +/* Write bytes to a pseudo register. -typedef void (gdbarch_pseudo_register_write_ftype) (struct gdbarch *gdbarch, struct regcache *regcache, int cookednum, const gdb_byte *buf); -extern void gdbarch_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache, int cookednum, const gdb_byte *buf); -extern void set_gdbarch_pseudo_register_write (struct gdbarch *gdbarch, gdbarch_pseudo_register_write_ftype *pseudo_register_write); + This is marked as deprecated because it gets passed a regcache for + implementations to write raw registers in. This doesn't work for unwound + frames, where the raw registers backing the pseudo registers may have been + saved elsewhere. */ + +extern bool gdbarch_deprecated_pseudo_register_write_p (struct gdbarch *gdbarch); + +typedef void (gdbarch_deprecated_pseudo_register_write_ftype) (struct gdbarch *gdbarch, struct regcache *regcache, int cookednum, const gdb_byte *buf); +extern void gdbarch_deprecated_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache, int cookednum, const gdb_byte *buf); +extern void set_gdbarch_deprecated_pseudo_register_write (struct gdbarch *gdbarch, gdbarch_deprecated_pseudo_register_write_ftype *deprecated_pseudo_register_write); extern int gdbarch_num_regs (struct gdbarch *gdbarch); extern void set_gdbarch_num_regs (struct gdbarch *gdbarch, int num_regs); diff --git a/gdb/gdbarch.c b/gdb/gdbarch.c index 06ff52576bdf..e198d339f6ba 100644 --- a/gdb/gdbarch.c +++ b/gdb/gdbarch.c @@ -74,7 +74,7 @@ struct gdbarch gdbarch_virtual_frame_pointer_ftype *virtual_frame_pointer = legacy_virtual_frame_pointer; gdbarch_pseudo_register_read_ftype *pseudo_register_read = nullptr; gdbarch_pseudo_register_read_value_ftype *pseudo_register_read_value = nullptr; - gdbarch_pseudo_register_write_ftype *pseudo_register_write = nullptr; + gdbarch_deprecated_pseudo_register_write_ftype *deprecated_pseudo_register_write = nullptr; int num_regs = -1; int num_pseudo_regs = 0; gdbarch_ax_pseudo_register_collect_ftype *ax_pseudo_register_collect = nullptr; @@ -330,7 +330,7 @@ verify_gdbarch (struct gdbarch *gdbarch) /* Skip verify of virtual_frame_pointer, invalid_p == 0 */ /* Skip verify of pseudo_register_read, has predicate. */ /* Skip verify of pseudo_register_read_value, has predicate. */ - /* Skip verify of pseudo_register_write, has predicate. */ + /* Skip verify of deprecated_pseudo_register_write, has predicate. */ if (gdbarch->num_regs == -1) log.puts ("\n\tnum_regs"); /* Skip verify of num_pseudo_regs, invalid_p == 0 */ @@ -650,11 +650,11 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file) "gdbarch_dump: pseudo_register_read_value = <%s>\n", host_address_to_string (gdbarch->pseudo_register_read_value)); gdb_printf (file, - "gdbarch_dump: gdbarch_pseudo_register_write_p() = %d\n", - gdbarch_pseudo_register_write_p (gdbarch)); + "gdbarch_dump: gdbarch_deprecated_pseudo_register_write_p() = %d\n", + gdbarch_deprecated_pseudo_register_write_p (gdbarch)); gdb_printf (file, - "gdbarch_dump: pseudo_register_write = <%s>\n", - host_address_to_string (gdbarch->pseudo_register_write)); + "gdbarch_dump: deprecated_pseudo_register_write = <%s>\n", + host_address_to_string (gdbarch->deprecated_pseudo_register_write)); gdb_printf (file, "gdbarch_dump: num_regs = %s\n", plongest (gdbarch->num_regs)); @@ -1903,27 +1903,27 @@ set_gdbarch_pseudo_register_read_value (struct gdbarch *gdbarch, } bool -gdbarch_pseudo_register_write_p (struct gdbarch *gdbarch) +gdbarch_deprecated_pseudo_register_write_p (struct gdbarch *gdbarch) { gdb_assert (gdbarch != NULL); - return gdbarch->pseudo_register_write != NULL; + return gdbarch->deprecated_pseudo_register_write != NULL; } void -gdbarch_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache, int cookednum, const gdb_byte *buf) +gdbarch_deprecated_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache, int cookednum, const gdb_byte *buf) { gdb_assert (gdbarch != NULL); - gdb_assert (gdbarch->pseudo_register_write != NULL); + gdb_assert (gdbarch->deprecated_pseudo_register_write != NULL); if (gdbarch_debug >= 2) - gdb_printf (gdb_stdlog, "gdbarch_pseudo_register_write called\n"); - gdbarch->pseudo_register_write (gdbarch, regcache, cookednum, buf); + gdb_printf (gdb_stdlog, "gdbarch_deprecated_pseudo_register_write called\n"); + gdbarch->deprecated_pseudo_register_write (gdbarch, regcache, cookednum, buf); } void -set_gdbarch_pseudo_register_write (struct gdbarch *gdbarch, - gdbarch_pseudo_register_write_ftype pseudo_register_write) +set_gdbarch_deprecated_pseudo_register_write (struct gdbarch *gdbarch, + gdbarch_deprecated_pseudo_register_write_ftype deprecated_pseudo_register_write) { - gdbarch->pseudo_register_write = pseudo_register_write; + gdbarch->deprecated_pseudo_register_write = deprecated_pseudo_register_write; } int diff --git a/gdb/gdbarch_components.py b/gdb/gdbarch_components.py index 86754af17cc3..1100da160550 100644 --- a/gdb/gdbarch_components.py +++ b/gdb/gdbarch_components.py @@ -419,8 +419,16 @@ never be called. ) Method( + comment=""" +Write bytes to a pseudo register. + +This is marked as deprecated because it gets passed a regcache for +implementations to write raw registers in. This doesn't work for unwound +frames, where the raw registers backing the pseudo registers may have been +saved elsewhere. +""", type="void", - name="pseudo_register_write", + name="deprecated_pseudo_register_write", params=[ ("struct regcache *", "regcache"), ("int", "cookednum"), diff --git a/gdb/h8300-tdep.c b/gdb/h8300-tdep.c index d1494916f594..20f503c209bf 100644 --- a/gdb/h8300-tdep.c +++ b/gdb/h8300-tdep.c @@ -1318,7 +1318,8 @@ h8300_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) } set_gdbarch_pseudo_register_read (gdbarch, h8300_pseudo_register_read); - set_gdbarch_pseudo_register_write (gdbarch, h8300_pseudo_register_write); + set_gdbarch_deprecated_pseudo_register_write (gdbarch, + h8300_pseudo_register_write); /* * Basic register fields and methods. diff --git a/gdb/i386-tdep.c b/gdb/i386-tdep.c index 7f849bac6cd3..5f12f17bc5eb 100644 --- a/gdb/i386-tdep.c +++ b/gdb/i386-tdep.c @@ -8603,7 +8603,8 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) /* Pseudo registers may be changed by amd64_init_abi. */ set_gdbarch_pseudo_register_read_value (gdbarch, i386_pseudo_register_read_value); - set_gdbarch_pseudo_register_write (gdbarch, i386_pseudo_register_write); + set_gdbarch_deprecated_pseudo_register_write (gdbarch, + i386_pseudo_register_write); set_gdbarch_ax_pseudo_register_collect (gdbarch, i386_ax_pseudo_register_collect); diff --git a/gdb/ia64-tdep.c b/gdb/ia64-tdep.c index d4c1736f0e7f..34b7fa09d5d3 100644 --- a/gdb/ia64-tdep.c +++ b/gdb/ia64-tdep.c @@ -3959,7 +3959,8 @@ ia64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) set_gdbarch_register_type (gdbarch, ia64_register_type); set_gdbarch_pseudo_register_read (gdbarch, ia64_pseudo_register_read); - set_gdbarch_pseudo_register_write (gdbarch, ia64_pseudo_register_write); + set_gdbarch_deprecated_pseudo_register_write (gdbarch, + ia64_pseudo_register_write); set_gdbarch_dwarf2_reg_to_regnum (gdbarch, ia64_dwarf_reg_to_regnum); set_gdbarch_register_reggroup_p (gdbarch, ia64_register_reggroup_p); set_gdbarch_convert_register_p (gdbarch, ia64_convert_register_p); diff --git a/gdb/m32c-tdep.c b/gdb/m32c-tdep.c index e06dbbe12bff..d053135e592d 100644 --- a/gdb/m32c-tdep.c +++ b/gdb/m32c-tdep.c @@ -977,7 +977,8 @@ make_regs (struct gdbarch *arch) set_gdbarch_register_name (arch, m32c_register_name); set_gdbarch_register_type (arch, m32c_register_type); set_gdbarch_pseudo_register_read (arch, m32c_pseudo_register_read); - set_gdbarch_pseudo_register_write (arch, m32c_pseudo_register_write); + set_gdbarch_deprecated_pseudo_register_write (arch, + m32c_pseudo_register_write); set_gdbarch_register_sim_regno (arch, m32c_register_sim_regno); set_gdbarch_stab_reg_to_regnum (arch, m32c_debug_info_reg_to_regnum); set_gdbarch_dwarf2_reg_to_regnum (arch, m32c_debug_info_reg_to_regnum); diff --git a/gdb/m68hc11-tdep.c b/gdb/m68hc11-tdep.c index 1257c55ce667..668158f15a09 100644 --- a/gdb/m68hc11-tdep.c +++ b/gdb/m68hc11-tdep.c @@ -1491,7 +1491,8 @@ m68hc11_gdbarch_init (struct gdbarch_info info, set_gdbarch_register_name (gdbarch, m68hc11_register_name); set_gdbarch_register_type (gdbarch, m68hc11_register_type); set_gdbarch_pseudo_register_read (gdbarch, m68hc11_pseudo_register_read); - set_gdbarch_pseudo_register_write (gdbarch, m68hc11_pseudo_register_write); + set_gdbarch_deprecated_pseudo_register_write (gdbarch, + m68hc11_pseudo_register_write); set_gdbarch_push_dummy_call (gdbarch, m68hc11_push_dummy_call); diff --git a/gdb/mep-tdep.c b/gdb/mep-tdep.c index a84df4e1f53c..94d1ddf2a147 100644 --- a/gdb/mep-tdep.c +++ b/gdb/mep-tdep.c @@ -2424,7 +2424,8 @@ mep_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) set_gdbarch_register_type (gdbarch, mep_register_type); set_gdbarch_num_pseudo_regs (gdbarch, MEP_NUM_PSEUDO_REGS); set_gdbarch_pseudo_register_read (gdbarch, mep_pseudo_register_read); - set_gdbarch_pseudo_register_write (gdbarch, mep_pseudo_register_write); + set_gdbarch_deprecated_pseudo_register_write (gdbarch, + mep_pseudo_register_write); set_gdbarch_dwarf2_reg_to_regnum (gdbarch, mep_debug_reg_to_regnum); set_gdbarch_stab_reg_to_regnum (gdbarch, mep_debug_reg_to_regnum); diff --git a/gdb/mips-tdep.c b/gdb/mips-tdep.c index 8e25c45dd297..a4ba68748b9c 100644 --- a/gdb/mips-tdep.c +++ b/gdb/mips-tdep.c @@ -8518,7 +8518,8 @@ mips_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) set_gdbarch_long_double_bit (gdbarch, 64); set_gdbarch_register_reggroup_p (gdbarch, mips_register_reggroup_p); set_gdbarch_pseudo_register_read (gdbarch, mips_pseudo_register_read); - set_gdbarch_pseudo_register_write (gdbarch, mips_pseudo_register_write); + set_gdbarch_deprecated_pseudo_register_write (gdbarch, + mips_pseudo_register_write); set_gdbarch_ax_pseudo_register_collect (gdbarch, mips_ax_pseudo_register_collect); diff --git a/gdb/msp430-tdep.c b/gdb/msp430-tdep.c index 97d9073efbbe..92404045497c 100644 --- a/gdb/msp430-tdep.c +++ b/gdb/msp430-tdep.c @@ -937,7 +937,8 @@ msp430_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) set_gdbarch_sp_regnum (gdbarch, MSP430_SP_REGNUM); set_gdbarch_register_reggroup_p (gdbarch, msp430_register_reggroup_p); set_gdbarch_pseudo_register_read (gdbarch, msp430_pseudo_register_read); - set_gdbarch_pseudo_register_write (gdbarch, msp430_pseudo_register_write); + set_gdbarch_deprecated_pseudo_register_write (gdbarch, + msp430_pseudo_register_write); set_gdbarch_dwarf2_reg_to_regnum (gdbarch, msp430_dwarf2_reg_to_regnum); set_gdbarch_register_sim_regno (gdbarch, msp430_register_sim_regno); diff --git a/gdb/nds32-tdep.c b/gdb/nds32-tdep.c index 7618a81fc256..83685d06f3ee 100644 --- a/gdb/nds32-tdep.c +++ b/gdb/nds32-tdep.c @@ -2001,7 +2001,8 @@ nds32_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) else if (use_pseudo_fsrs == 1) { set_gdbarch_pseudo_register_read (gdbarch, nds32_pseudo_register_read); - set_gdbarch_pseudo_register_write (gdbarch, nds32_pseudo_register_write); + set_gdbarch_deprecated_pseudo_register_write + (gdbarch, nds32_pseudo_register_write); set_tdesc_pseudo_register_name (gdbarch, nds32_pseudo_register_name); set_tdesc_pseudo_register_type (gdbarch, nds32_pseudo_register_type); set_gdbarch_num_pseudo_regs (gdbarch, num_fsr_map[fpu_freg]); diff --git a/gdb/regcache.c b/gdb/regcache.c index ff5f5b70433e..dadc949434ee 100644 --- a/gdb/regcache.c +++ b/gdb/regcache.c @@ -930,8 +930,8 @@ regcache::cooked_write (int regnum, gdb::array_view src, float) if (regnum < num_raw_registers ()) raw_write (regnum, src, 1.0f); else - gdbarch_pseudo_register_write (m_descr->gdbarch, this, regnum, - src.data ()); + gdbarch_deprecated_pseudo_register_write (m_descr->gdbarch, this, regnum, + src.data ()); } /* See regcache.h. */ diff --git a/gdb/riscv-tdep.c b/gdb/riscv-tdep.c index 48f5a9e35e67..c1b9c8d435e5 100644 --- a/gdb/riscv-tdep.c +++ b/gdb/riscv-tdep.c @@ -1002,9 +1002,9 @@ riscv_pseudo_register_read (struct gdbarch *gdbarch, return REG_UNKNOWN; } -/* Implement gdbarch_pseudo_register_write. Write the contents of BUF into - pseudo-register REGNUM in REGCACHE. BUF is sized based on the type of - register REGNUM. */ +/* Implement gdbarch_deprecated_pseudo_register_write. Write the contents of + BUF into pseudo-register REGNUM in REGCACHE. BUF is sized based on the type + of register REGNUM. */ static void riscv_pseudo_register_write (struct gdbarch *gdbarch, @@ -4229,7 +4229,8 @@ riscv_gdbarch_init (struct gdbarch_info info, set_tdesc_pseudo_register_reggroup_p (gdbarch, riscv_pseudo_register_reggroup_p); set_gdbarch_pseudo_register_read (gdbarch, riscv_pseudo_register_read); - set_gdbarch_pseudo_register_write (gdbarch, riscv_pseudo_register_write); + set_gdbarch_deprecated_pseudo_register_write (gdbarch, + riscv_pseudo_register_write); /* Finalise the target description registers. */ tdesc_use_registers (gdbarch, tdesc, std::move (tdesc_data), diff --git a/gdb/rl78-tdep.c b/gdb/rl78-tdep.c index 2f40fbddaa1e..19298063186f 100644 --- a/gdb/rl78-tdep.c +++ b/gdb/rl78-tdep.c @@ -1436,7 +1436,8 @@ rl78_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) set_gdbarch_pc_regnum (gdbarch, RL78_PC_REGNUM); set_gdbarch_sp_regnum (gdbarch, RL78_SP_REGNUM); set_gdbarch_pseudo_register_read (gdbarch, rl78_pseudo_register_read); - set_gdbarch_pseudo_register_write (gdbarch, rl78_pseudo_register_write); + set_gdbarch_deprecated_pseudo_register_write (gdbarch, + rl78_pseudo_register_write); set_gdbarch_dwarf2_reg_to_regnum (gdbarch, rl78_dwarf_reg_to_regnum); set_gdbarch_register_reggroup_p (gdbarch, rl78_register_reggroup_p); set_gdbarch_register_sim_regno (gdbarch, rl78_register_sim_regno); diff --git a/gdb/rs6000-tdep.c b/gdb/rs6000-tdep.c index 819f07b47c0a..78016eb8fccd 100644 --- a/gdb/rs6000-tdep.c +++ b/gdb/rs6000-tdep.c @@ -8291,8 +8291,8 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) || have_vsx || have_htm_fpu || have_htm_vsx) { set_gdbarch_pseudo_register_read (gdbarch, rs6000_pseudo_register_read); - set_gdbarch_pseudo_register_write (gdbarch, - rs6000_pseudo_register_write); + set_gdbarch_deprecated_pseudo_register_write + (gdbarch, rs6000_pseudo_register_write); set_gdbarch_ax_pseudo_register_collect (gdbarch, rs6000_ax_pseudo_register_collect); } diff --git a/gdb/s390-tdep.c b/gdb/s390-tdep.c index 54b5c89e5e3c..52faae971ee6 100644 --- a/gdb/s390-tdep.c +++ b/gdb/s390-tdep.c @@ -7081,7 +7081,8 @@ s390_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) /* Pseudo registers. */ set_gdbarch_pseudo_register_read (gdbarch, s390_pseudo_register_read); - set_gdbarch_pseudo_register_write (gdbarch, s390_pseudo_register_write); + set_gdbarch_deprecated_pseudo_register_write (gdbarch, + s390_pseudo_register_write); set_tdesc_pseudo_register_name (gdbarch, s390_pseudo_register_name); set_tdesc_pseudo_register_type (gdbarch, s390_pseudo_register_type); set_tdesc_pseudo_register_reggroup_p (gdbarch, diff --git a/gdb/sh-tdep.c b/gdb/sh-tdep.c index babf85eeb906..ae1ce1e44713 100644 --- a/gdb/sh-tdep.c +++ b/gdb/sh-tdep.c @@ -2286,7 +2286,8 @@ sh_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) set_gdbarch_fp0_regnum (gdbarch, 25); set_gdbarch_num_pseudo_regs (gdbarch, 9); set_gdbarch_pseudo_register_read (gdbarch, sh_pseudo_register_read); - set_gdbarch_pseudo_register_write (gdbarch, sh_pseudo_register_write); + set_gdbarch_deprecated_pseudo_register_write (gdbarch, + sh_pseudo_register_write); set_gdbarch_return_value (gdbarch, sh_return_value_fpu); set_gdbarch_push_dummy_call (gdbarch, sh_push_dummy_call_fpu); break; @@ -2297,7 +2298,8 @@ sh_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) set_gdbarch_num_pseudo_regs (gdbarch, 1); set_gdbarch_pseudo_register_read (gdbarch, sh_pseudo_register_read); - set_gdbarch_pseudo_register_write (gdbarch, sh_pseudo_register_write); + set_gdbarch_deprecated_pseudo_register_write (gdbarch, + sh_pseudo_register_write); break; case bfd_mach_sh_dsp: @@ -2337,7 +2339,8 @@ sh_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) set_gdbarch_fp0_regnum (gdbarch, 25); set_gdbarch_num_pseudo_regs (gdbarch, 13); set_gdbarch_pseudo_register_read (gdbarch, sh_pseudo_register_read); - set_gdbarch_pseudo_register_write (gdbarch, sh_pseudo_register_write); + set_gdbarch_deprecated_pseudo_register_write (gdbarch, + sh_pseudo_register_write); set_gdbarch_return_value (gdbarch, sh_return_value_fpu); set_gdbarch_push_dummy_call (gdbarch, sh_push_dummy_call_fpu); break; diff --git a/gdb/sparc-tdep.c b/gdb/sparc-tdep.c index 78f240db04e7..3a053a99e351 100644 --- a/gdb/sparc-tdep.c +++ b/gdb/sparc-tdep.c @@ -1844,7 +1844,8 @@ sparc32_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) set_tdesc_pseudo_register_name (gdbarch, sparc32_pseudo_register_name); set_tdesc_pseudo_register_type (gdbarch, sparc32_pseudo_register_type); set_gdbarch_pseudo_register_read (gdbarch, sparc32_pseudo_register_read); - set_gdbarch_pseudo_register_write (gdbarch, sparc32_pseudo_register_write); + set_gdbarch_deprecated_pseudo_register_write (gdbarch, + sparc32_pseudo_register_write); /* Register numbers of various important registers. */ set_gdbarch_sp_regnum (gdbarch, SPARC_SP_REGNUM); /* %sp */ diff --git a/gdb/sparc64-tdep.c b/gdb/sparc64-tdep.c index abbbb73d1db9..61f486689f15 100644 --- a/gdb/sparc64-tdep.c +++ b/gdb/sparc64-tdep.c @@ -1825,7 +1825,8 @@ sparc64_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) set_tdesc_pseudo_register_name (gdbarch, sparc64_pseudo_register_name); set_tdesc_pseudo_register_type (gdbarch, sparc64_pseudo_register_type); set_gdbarch_pseudo_register_read (gdbarch, sparc64_pseudo_register_read); - set_gdbarch_pseudo_register_write (gdbarch, sparc64_pseudo_register_write); + set_gdbarch_deprecated_pseudo_register_write (gdbarch, + sparc64_pseudo_register_write); /* Register numbers of various important registers. */ set_gdbarch_pc_regnum (gdbarch, SPARC64_PC_REGNUM); /* %pc */ diff --git a/gdb/xtensa-tdep.c b/gdb/xtensa-tdep.c index c9935d152641..8f313f0feabd 100644 --- a/gdb/xtensa-tdep.c +++ b/gdb/xtensa-tdep.c @@ -3174,7 +3174,8 @@ xtensa_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) /* Pseudo-Register read/write. */ set_gdbarch_pseudo_register_read (gdbarch, xtensa_pseudo_register_read); - set_gdbarch_pseudo_register_write (gdbarch, xtensa_pseudo_register_write); + set_gdbarch_deprecated_pseudo_register_write (gdbarch, + xtensa_pseudo_register_write); /* Set target information. */ set_gdbarch_num_regs (gdbarch, tdep->num_regs); From patchwork Wed Nov 8 05:01:01 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Marchi X-Patchwork-Id: 79379 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 C7CCA385841B for ; Wed, 8 Nov 2023 05:17:02 +0000 (GMT) X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from smtp.polymtl.ca (smtp.polymtl.ca [132.207.4.11]) by sourceware.org (Postfix) with ESMTPS id 7510E3858D38 for ; Wed, 8 Nov 2023 05:16:43 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 7510E3858D38 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=polymtl.ca Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=polymtl.ca ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 7510E3858D38 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=132.207.4.11 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1699420605; cv=none; b=U3wqT2Q45ictZaCvI8USnlXRT3mbp27BmmkRMRd3YbcYynzymq4QEU07NPzraxp6+Csk7ffwWjoYxF7MPFj+QDEYZrIFsr8Wk/Q6fjiIgB+bQ+klsBG9uzakExzg+tRRcmBSbtu++dyqVsxs/Ubpb+RQ9SB7F9u4TO94XndhbpY= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1699420605; c=relaxed/simple; bh=zv+OMBpXYpnjABwPhc+L2sJftNUtH7YmW8rXsBsor2Q=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=nzPVJ+h7na3IeMRPOEcP29CjAIRviE2M0Q7MXcVovHcpxs9cTk+7mVSiP87RLd99ZBFjyDV7roCeU+83NoAzvq5xsNc8aOfNmo08qp0CFgcfWdQup1kgTBqlSwiv6E8MFR6jd9BY2XpaL9I4cKriPanyphB//M4KFBS3QFhumb4= ARC-Authentication-Results: i=1; server2.sourceware.org Received: from simark.ca (simark.ca [158.69.221.121]) (authenticated bits=0) by smtp.polymtl.ca (8.14.7/8.14.7) with ESMTP id 3A85Gbxo016031 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 8 Nov 2023 00:16:41 -0500 DKIM-Filter: OpenDKIM Filter v2.11.0 smtp.polymtl.ca 3A85Gbxo016031 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=polymtl.ca; s=default; t=1699420601; bh=QSuZcm5VrwPux1cNP0hKqfN2+nA4l5p3RCRn21xgf1I=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=m+RTymLBQCWmAF6RFK+Bw8XTMvlMkOB48Pw9ma+45sHAo00nqI+yFEJWcWiPXinLe ePR+EFtBPjwCU6IeS0R38Mw/DhRdYXJL3iGZ36dXeiijuc5ShF7UNK9xNMWogK0dzY m60OMqANld44zH7k42rccMloG8+GJcei0PZaJvbg= Received: from simark.localdomain (modemcable238.237-201-24.mc.videotron.ca [24.201.237.238]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) by simark.ca (Postfix) with ESMTPSA id 13ECE1E0BB; Wed, 8 Nov 2023 00:16:37 -0500 (EST) From: Simon Marchi To: gdb-patches@sourceware.org Cc: Simon Marchi Subject: [PATCH 17/24] gdb: add gdbarch_pseudo_register_write that takes a frame Date: Wed, 8 Nov 2023 00:01:01 -0500 Message-ID: <20231108051222.1275306-18-simon.marchi@polymtl.ca> X-Mailer: git-send-email 2.42.1 In-Reply-To: <20231108051222.1275306-1-simon.marchi@polymtl.ca> References: <20231108051222.1275306-1-simon.marchi@polymtl.ca> MIME-Version: 1.0 X-Poly-FromMTA: (simark.ca [158.69.221.121]) at Wed, 8 Nov 2023 05:16:37 +0000 X-Spam-Status: No, score=-3188.6 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_PASS, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE 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.30 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org From: Simon Marchi Add a new variant of gdbarch_pseudo_register_write that takes a frame_info in order to write raw registers. Use this new method when available: - in put_frame_register, when trying to write a pseudo register to a given frame - in regcache::cooked_write No implementation is migrated to use this new method (that will come in subsequent patches), so no behavior change is expected here. The objective is to fix writing pseudo registers to non-current frames. See previous commit "gdb: read pseudo register through frame" for a more detailed explanation. Change-Id: Ie7fe364a15a4d86c2ecb09de2b4baa08c45555ac --- gdb/frame.c | 9 +++++- gdb/gdbarch-gen.h | 15 +++++++++- gdb/gdbarch.c | 32 ++++++++++++++++++++ gdb/gdbarch_components.py | 19 ++++++++++++ gdb/regcache.c | 4 +++ gdb/value.c | 63 +++++++++++++++++++++++++++++++++++++++ gdb/value.h | 22 ++++++++++++++ 7 files changed, 162 insertions(+), 2 deletions(-) diff --git a/gdb/frame.c b/gdb/frame.c index 3035f87369ca..81836d6d5357 100644 --- a/gdb/frame.c +++ b/gdb/frame.c @@ -1452,7 +1452,14 @@ put_frame_register (frame_info_ptr next_frame, int regnum, break; } case lval_register: - get_current_regcache ()->cooked_write (realnum, buf, 1.0f); + /* Not sure if that's always true... but we have a problem if not. */ + gdb_assert (size == register_size (gdbarch, realnum)); + + if (realnum < gdbarch_num_regs (gdbarch) + || !gdbarch_pseudo_register_write_p (gdbarch)) + get_current_regcache ()->cooked_write (realnum, buf, 1.0f); + else + gdbarch_pseudo_register_write (gdbarch, next_frame, realnum, buf); break; default: error (_("Attempt to assign to an unmodifiable value.")); diff --git a/gdb/gdbarch-gen.h b/gdb/gdbarch-gen.h index 3160aa8a9613..9cf58490d0b6 100644 --- a/gdb/gdbarch-gen.h +++ b/gdb/gdbarch-gen.h @@ -200,12 +200,25 @@ typedef struct value * (gdbarch_pseudo_register_read_value_ftype) (struct gdbarc extern struct value * gdbarch_pseudo_register_read_value (struct gdbarch *gdbarch, frame_info_ptr next_frame, int cookednum); extern void set_gdbarch_pseudo_register_read_value (struct gdbarch *gdbarch, gdbarch_pseudo_register_read_value_ftype *pseudo_register_read_value); +/* Write bytes in BUF to pseudo register with number PSEUDO_REG_NUM. + + Raw registers backing the pseudo register should be written to using + NEXT_FRAME. */ + +extern bool gdbarch_pseudo_register_write_p (struct gdbarch *gdbarch); + +typedef void (gdbarch_pseudo_register_write_ftype) (struct gdbarch *gdbarch, frame_info_ptr next_frame, int pseudo_reg_num, gdb::array_view buf); +extern void gdbarch_pseudo_register_write (struct gdbarch *gdbarch, frame_info_ptr next_frame, int pseudo_reg_num, gdb::array_view buf); +extern void set_gdbarch_pseudo_register_write (struct gdbarch *gdbarch, gdbarch_pseudo_register_write_ftype *pseudo_register_write); + /* Write bytes to a pseudo register. This is marked as deprecated because it gets passed a regcache for implementations to write raw registers in. This doesn't work for unwound frames, where the raw registers backing the pseudo registers may have been - saved elsewhere. */ + saved elsewhere. + + Implementations should be migrated to implement pseudo_register_write instead. */ extern bool gdbarch_deprecated_pseudo_register_write_p (struct gdbarch *gdbarch); diff --git a/gdb/gdbarch.c b/gdb/gdbarch.c index e198d339f6ba..d584305fefb2 100644 --- a/gdb/gdbarch.c +++ b/gdb/gdbarch.c @@ -74,6 +74,7 @@ struct gdbarch gdbarch_virtual_frame_pointer_ftype *virtual_frame_pointer = legacy_virtual_frame_pointer; gdbarch_pseudo_register_read_ftype *pseudo_register_read = nullptr; gdbarch_pseudo_register_read_value_ftype *pseudo_register_read_value = nullptr; + gdbarch_pseudo_register_write_ftype *pseudo_register_write = nullptr; gdbarch_deprecated_pseudo_register_write_ftype *deprecated_pseudo_register_write = nullptr; int num_regs = -1; int num_pseudo_regs = 0; @@ -330,6 +331,7 @@ verify_gdbarch (struct gdbarch *gdbarch) /* Skip verify of virtual_frame_pointer, invalid_p == 0 */ /* Skip verify of pseudo_register_read, has predicate. */ /* Skip verify of pseudo_register_read_value, has predicate. */ + /* Skip verify of pseudo_register_write, has predicate. */ /* Skip verify of deprecated_pseudo_register_write, has predicate. */ if (gdbarch->num_regs == -1) log.puts ("\n\tnum_regs"); @@ -649,6 +651,12 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file) gdb_printf (file, "gdbarch_dump: pseudo_register_read_value = <%s>\n", host_address_to_string (gdbarch->pseudo_register_read_value)); + gdb_printf (file, + "gdbarch_dump: gdbarch_pseudo_register_write_p() = %d\n", + gdbarch_pseudo_register_write_p (gdbarch)); + gdb_printf (file, + "gdbarch_dump: pseudo_register_write = <%s>\n", + host_address_to_string (gdbarch->pseudo_register_write)); gdb_printf (file, "gdbarch_dump: gdbarch_deprecated_pseudo_register_write_p() = %d\n", gdbarch_deprecated_pseudo_register_write_p (gdbarch)); @@ -1902,6 +1910,30 @@ set_gdbarch_pseudo_register_read_value (struct gdbarch *gdbarch, gdbarch->pseudo_register_read_value = pseudo_register_read_value; } +bool +gdbarch_pseudo_register_write_p (struct gdbarch *gdbarch) +{ + gdb_assert (gdbarch != NULL); + return gdbarch->pseudo_register_write != NULL; +} + +void +gdbarch_pseudo_register_write (struct gdbarch *gdbarch, frame_info_ptr next_frame, int pseudo_reg_num, gdb::array_view buf) +{ + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->pseudo_register_write != NULL); + if (gdbarch_debug >= 2) + gdb_printf (gdb_stdlog, "gdbarch_pseudo_register_write called\n"); + gdbarch->pseudo_register_write (gdbarch, next_frame, pseudo_reg_num, buf); +} + +void +set_gdbarch_pseudo_register_write (struct gdbarch *gdbarch, + gdbarch_pseudo_register_write_ftype pseudo_register_write) +{ + gdbarch->pseudo_register_write = pseudo_register_write; +} + bool gdbarch_deprecated_pseudo_register_write_p (struct gdbarch *gdbarch) { diff --git a/gdb/gdbarch_components.py b/gdb/gdbarch_components.py index 1100da160550..ce8169b19a57 100644 --- a/gdb/gdbarch_components.py +++ b/gdb/gdbarch_components.py @@ -418,6 +418,23 @@ never be called. predicate=True, ) +Method( + comment=""" +Write bytes in BUF to pseudo register with number PSEUDO_REG_NUM. + +Raw registers backing the pseudo register should be written to using +NEXT_FRAME. +""", + type="void", + name="pseudo_register_write", + params=[ + ("frame_info_ptr", "next_frame"), + ("int", "pseudo_reg_num"), + ("gdb::array_view", "buf"), + ], + predicate=True, +) + Method( comment=""" Write bytes to a pseudo register. @@ -426,6 +443,8 @@ This is marked as deprecated because it gets passed a regcache for implementations to write raw registers in. This doesn't work for unwound frames, where the raw registers backing the pseudo registers may have been saved elsewhere. + +Implementations should be migrated to implement pseudo_register_write instead. """, type="void", name="deprecated_pseudo_register_write", diff --git a/gdb/regcache.c b/gdb/regcache.c index dadc949434ee..16b117e767be 100644 --- a/gdb/regcache.c +++ b/gdb/regcache.c @@ -929,6 +929,10 @@ regcache::cooked_write (int regnum, gdb::array_view src, float) if (regnum < num_raw_registers ()) raw_write (regnum, src, 1.0f); + else if (gdbarch_pseudo_register_write_p (m_descr->gdbarch)) + gdbarch_pseudo_register_write + (m_descr->gdbarch, get_next_frame_sentinel_okay (get_current_frame ()), + regnum, src); else gdbarch_deprecated_pseudo_register_write (m_descr->gdbarch, this, regnum, src.data ()); diff --git a/gdb/value.c b/gdb/value.c index 27a79dc62fc1..51dca972a587 100644 --- a/gdb/value.c +++ b/gdb/value.c @@ -4057,6 +4057,22 @@ pseudo_from_raw_part (frame_info_ptr next_frame, int pseudo_reg_num, /* See value.h. */ +void +pseudo_to_raw_part (frame_info_ptr next_frame, + gdb::array_view pseudo_buf, + int raw_reg_num, int raw_offset) +{ + int raw_reg_size = register_size (get_frame_arch (next_frame), raw_reg_num); + + /* When overflowing a register, put_frame_register_bytes writes to the + subsequent registers. We don't want that behavior here, so make sure + the write is wholly within register RAW_REG_NUM. */ + gdb_assert (raw_offset + pseudo_buf.size () <= raw_reg_size); + put_frame_register_bytes (next_frame, raw_reg_num, raw_offset, pseudo_buf); +} + +/* See value.h. */ + value * pseudo_from_concat_raw (frame_info_ptr next_frame, int pseudo_reg_num, int raw_reg_1_num, int raw_reg_2_num) @@ -4080,6 +4096,27 @@ pseudo_from_concat_raw (frame_info_ptr next_frame, int pseudo_reg_num, return pseudo_reg_val; } +void +pseudo_to_concat_raw (frame_info_ptr next_frame, + gdb::array_view pseudo_buf, + int raw_reg_1_num, int raw_reg_2_num) +{ + int src_offset = 0; + gdbarch *arch = frame_unwind_arch (next_frame); + + int raw_reg_1_size = register_size (arch, raw_reg_1_num); + put_frame_register_bytes (next_frame, raw_reg_1_num, 0, + pseudo_buf.slice (src_offset, raw_reg_1_size)); + src_offset += raw_reg_1_size; + + int raw_reg_2_size = register_size (arch, raw_reg_2_num); + put_frame_register_bytes (next_frame, raw_reg_2_num, 0, + pseudo_buf.slice (src_offset, raw_reg_2_size)); + src_offset += raw_reg_2_size; + + gdb_assert (src_offset == pseudo_buf.size ()); +} + /* See value.h. */ value * @@ -4111,6 +4148,32 @@ pseudo_from_concat_raw (frame_info_ptr next_frame, int pseudo_reg_num, return pseudo_reg_val; } +void +pseudo_to_concat_raw (frame_info_ptr next_frame, + gdb::array_view pseudo_buf, + int raw_reg_1_num, int raw_reg_2_num, int raw_reg_3_num) +{ + int src_offset = 0; + gdbarch *arch = frame_unwind_arch (next_frame); + + int raw_reg_1_size = register_size (arch, raw_reg_1_num); + put_frame_register_bytes (next_frame, raw_reg_1_num, 0, + pseudo_buf.slice (src_offset, raw_reg_1_size)); + src_offset += raw_reg_1_size; + + int raw_reg_2_size = register_size (arch, raw_reg_2_num); + put_frame_register_bytes (next_frame, raw_reg_2_num, 0, + pseudo_buf.slice (src_offset, raw_reg_2_size)); + src_offset += raw_reg_2_size; + + int raw_reg_3_size = register_size (arch, raw_reg_3_num); + put_frame_register_bytes (next_frame, raw_reg_3_num, 0, + pseudo_buf.slice (src_offset, raw_reg_3_size)); + src_offset += raw_reg_3_size; + + gdb_assert (src_offset == pseudo_buf.size ()); +} + /* Implementation of the convenience function $_isvoid. */ static struct value * diff --git a/gdb/value.h b/gdb/value.h index b5c097ad58bf..6a74d4e2c2ee 100644 --- a/gdb/value.h +++ b/gdb/value.h @@ -1661,6 +1661,13 @@ struct scoped_array_length_limiting value *pseudo_from_raw_part (frame_info_ptr next_frame, int pseudo_reg_num, int raw_reg_num, int raw_offset); +/* Write PSEUDO_BUF, the contents of a pseudo register, to part of raw register + RAW_REG_NUM starting at RAW_OFFSET. */ + +void pseudo_to_raw_part (frame_info_ptr this_frame, + gdb::array_view pseudo_buf, + int raw_reg_num, int raw_offset); + /* Create a value for pseudo register PSEUDO_REG_NUM by concatenating raw registers RAW_REG_1_NUM and RAW_REG_2_NUM. @@ -1670,10 +1677,25 @@ value *pseudo_from_raw_part (frame_info_ptr next_frame, int pseudo_reg_num, value *pseudo_from_concat_raw (frame_info_ptr next_frame, int pseudo_reg_num, int raw_reg_1_num, int raw_reg_2_num); +/* Write PSEUDO_BUF, the contents of a pseudo register, to the two raw registers + RAW_REG_1_NUM and RAW_REG_2_NUM. */ + +void pseudo_to_concat_raw (frame_info_ptr this_frame, + gdb::array_view pseudo_buf, + int raw_reg_1_num, int raw_reg_2_num); + /* Same as the above, but with three raw registers. */ value *pseudo_from_concat_raw (frame_info_ptr next_frame, int pseudo_reg_num, int raw_reg_1_num, int raw_reg_2_num, int raw_reg_3_num); +/* Write PSEUDO_BUF, the contents of a pseudo register, to the tthreewo raw + registers RAW_REG_1_NUM, RAW_REG_2_NUM and RAW_REG_3_NUM. */ + +void pseudo_to_concat_raw (frame_info_ptr this_frame, + gdb::array_view pseudo_buf, + int raw_reg_1_num, int raw_reg_2_num, + int raw_reg_3_num); + #endif /* !defined (VALUE_H) */ From patchwork Wed Nov 8 05:01:02 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Marchi X-Patchwork-Id: 79378 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 6B57B3857711 for ; Wed, 8 Nov 2023 05:16:58 +0000 (GMT) X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from smtp.polymtl.ca (smtp.polymtl.ca [132.207.4.11]) by sourceware.org (Postfix) with ESMTPS id 6F1253858D35 for ; Wed, 8 Nov 2023 05:16:43 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 6F1253858D35 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=polymtl.ca Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=polymtl.ca ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 6F1253858D35 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=132.207.4.11 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1699420605; cv=none; b=IXpSQUNSbruLU6TGgtUFWyAYr6N8YZ084NmJmjEzMoK8LJua+MDnzGOm12kd7kaRHMTIm5OhWprBt9Z7/v4lArD3IK9ed18tHxujCPjzruMzyaAj/JKsrj0Ba8E1gZ82cEWzJVY2rHaknc7SYoKJ1yVJbTBE7UvVMrQIuvSlgp4= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1699420605; c=relaxed/simple; bh=dlMhe8D//pR//3ci76un7RimpkSmdRmo0AlScpayTGA=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=n9PKKdJ3Rbbq0KDrCXZMhURqfoiZF/+WODT49YZSKrvS3nP/Z7WShE9TBvxB+gtLRH1Q4/OgC9wRSm3hTAOK3bRMtoiW4SQsPzOcS+rBRtnKJK1wV754Zr7DMFH1SxG+hsvvC6TdSLXgR+S4KAypJt19IA/dNLTfgigW47xeCWQ= ARC-Authentication-Results: i=1; server2.sourceware.org Received: from simark.ca (simark.ca [158.69.221.121]) (authenticated bits=0) by smtp.polymtl.ca (8.14.7/8.14.7) with ESMTP id 3A85Gb4s016034 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 8 Nov 2023 00:16:41 -0500 DKIM-Filter: OpenDKIM Filter v2.11.0 smtp.polymtl.ca 3A85Gb4s016034 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=polymtl.ca; s=default; t=1699420602; bh=ihSUn9eZZxfkxgTSvZZcxCQ4pI1/LaRW099T3B2PXCg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=QlR8DeQ4437Ks1l3WMnpq8JHfsSpz/Q1TZkZL2fKubLnXxRiPpfcZgTtiWgeLBaLg Gt8uFjKPSQ3CUiW6lMwwgilegxV+rks1U8ez/9VoEkg/GMXg7PhVKy7EVLQMwBrXxq mI4dLFE62D190FIfg551wpFIcne7mF9+lRB8PzZo= Received: from simark.localdomain (modemcable238.237-201-24.mc.videotron.ca [24.201.237.238]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) by simark.ca (Postfix) with ESMTPSA id 2B36E1E0C1; Wed, 8 Nov 2023 00:16:37 -0500 (EST) From: Simon Marchi To: gdb-patches@sourceware.org Cc: Simon Marchi Subject: [PATCH 18/24] gdb: migrate i386 and amd64 to the new gdbarch_pseudo_register_write Date: Wed, 8 Nov 2023 00:01:02 -0500 Message-ID: <20231108051222.1275306-19-simon.marchi@polymtl.ca> X-Mailer: git-send-email 2.42.1 In-Reply-To: <20231108051222.1275306-1-simon.marchi@polymtl.ca> References: <20231108051222.1275306-1-simon.marchi@polymtl.ca> MIME-Version: 1.0 X-Poly-FromMTA: (simark.ca [158.69.221.121]) at Wed, 8 Nov 2023 05:16:37 +0000 X-Spam-Status: No, score=-3188.6 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_PASS, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE 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.30 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org From: Simon Marchi Make i386 and amd64 use the new gdbarch_pseudo_register_write. This fixes writing to pseudo registers in non-current frames for those architectures. Change-Id: I4977e8fe12d2cef116f8834c34cdf6fec618554f --- gdb/amd64-tdep.c | 39 +++---------- gdb/i386-tdep.c | 146 +++++++++++++++++------------------------------ gdb/i386-tdep.h | 6 +- gdb/value.c | 3 +- gdb/value.h | 6 +- 5 files changed, 66 insertions(+), 134 deletions(-) diff --git a/gdb/amd64-tdep.c b/gdb/amd64-tdep.c index a0b4986d5b6c..4b9dbbab66e8 100644 --- a/gdb/amd64-tdep.c +++ b/gdb/amd64-tdep.c @@ -380,9 +380,8 @@ amd64_pseudo_register_read_value (gdbarch *gdbarch, frame_info_ptr next_frame, } static void -amd64_pseudo_register_write (struct gdbarch *gdbarch, - struct regcache *regcache, - int regnum, const gdb_byte *buf) +amd64_pseudo_register_write (gdbarch *gdbarch, frame_info_ptr next_frame, + int regnum, gdb::array_view buf) { i386_gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); @@ -393,41 +392,18 @@ amd64_pseudo_register_write (struct gdbarch *gdbarch, if (gpnum >= AMD64_NUM_LOWER_BYTE_REGS) { gpnum -= AMD64_NUM_LOWER_BYTE_REGS; - gdb_byte raw_buf[register_size (gdbarch, gpnum)]; - - /* Read ... AH, BH, CH, DH. */ - regcache->raw_read (gpnum, raw_buf); - /* ... Modify ... (always little endian). */ - memcpy (raw_buf + 1, buf, 1); - /* ... Write. */ - regcache->raw_write (gpnum, raw_buf); + pseudo_to_raw_part (next_frame, buf, gpnum, 1); } else - { - gdb_byte raw_buf[register_size (gdbarch, gpnum)]; - - /* Read ... */ - regcache->raw_read (gpnum, raw_buf); - /* ... Modify ... (always little endian). */ - memcpy (raw_buf, buf, 1); - /* ... Write. */ - regcache->raw_write (gpnum, raw_buf); - } + pseudo_to_raw_part (next_frame, buf, gpnum, 0); } else if (i386_dword_regnum_p (gdbarch, regnum)) { int gpnum = regnum - tdep->eax_regnum; - gdb_byte raw_buf[register_size (gdbarch, gpnum)]; - - /* Read ... */ - regcache->raw_read (gpnum, raw_buf); - /* ... Modify ... (always little endian). */ - memcpy (raw_buf, buf, 4); - /* ... Write. */ - regcache->raw_write (gpnum, raw_buf); + pseudo_to_raw_part (next_frame, buf, gpnum, 0); } else - i386_pseudo_register_write (gdbarch, regcache, regnum, buf); + i386_pseudo_register_write (gdbarch, next_frame, regnum, buf); } /* Implement the 'ax_pseudo_register_collect' gdbarch method. */ @@ -3205,8 +3181,7 @@ amd64_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch, set_gdbarch_pseudo_register_read_value (gdbarch, amd64_pseudo_register_read_value); - set_gdbarch_deprecated_pseudo_register_write (gdbarch, - amd64_pseudo_register_write); + set_gdbarch_pseudo_register_write (gdbarch, amd64_pseudo_register_write); set_gdbarch_ax_pseudo_register_collect (gdbarch, amd64_ax_pseudo_register_collect); diff --git a/gdb/i386-tdep.c b/gdb/i386-tdep.c index 5f12f17bc5eb..6b4e16155fee 100644 --- a/gdb/i386-tdep.c +++ b/gdb/i386-tdep.c @@ -3391,26 +3391,6 @@ i386_pseudo_register_type (struct gdbarch *gdbarch, int regnum) internal_error (_("invalid regnum")); } -/* Map a cooked register onto a raw register or memory. For the i386, - the MMX registers need to be mapped onto floating point registers. */ - -static int -i386_mmx_regnum_to_fp_regnum (readable_regcache *regcache, int regnum) -{ - gdbarch *arch = regcache->arch (); - i386_gdbarch_tdep *tdep = gdbarch_tdep (arch); - int mmxreg, fpreg; - ULONGEST fstat; - int tos; - - mmxreg = regnum - tdep->mm0_regnum; - regcache->raw_read (I387_FSTAT_REGNUM (tdep), &fstat); - tos = (fstat >> 11) & 0x7; - fpreg = (mmxreg + tos) % 8; - - return (I387_ST0_REGNUM (tdep) + fpreg); -} - /* Map a cooked register onto a raw register or memory. For the i386, the MMX registers need to be mapped onto floating point registers. */ @@ -3537,115 +3517,92 @@ i386_pseudo_register_read_value (gdbarch *gdbarch, frame_info_ptr next_frame, } void -i386_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache, - int regnum, const gdb_byte *buf) +i386_pseudo_register_write (gdbarch *gdbarch, frame_info_ptr next_frame, + const int pseudo_reg_num, + gdb::array_view buf) { - gdb_byte raw_buf[I386_MAX_REGISTER_SIZE]; - - if (i386_mmx_regnum_p (gdbarch, regnum)) + if (i386_mmx_regnum_p (gdbarch, pseudo_reg_num)) { - int fpnum = i386_mmx_regnum_to_fp_regnum (regcache, regnum); + int fpnum = i386_mmx_regnum_to_fp_regnum (next_frame, pseudo_reg_num); - /* Read ... */ - regcache->raw_read (fpnum, raw_buf); - /* ... Modify ... (always little endian). */ - memcpy (raw_buf, buf, register_size (gdbarch, regnum)); - /* ... Write. */ - regcache->raw_write (fpnum, raw_buf); + pseudo_to_raw_part (next_frame, buf, fpnum, 0); } else { i386_gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); - if (i386_bnd_regnum_p (gdbarch, regnum)) + if (i386_bnd_regnum_p (gdbarch, pseudo_reg_num)) { - ULONGEST upper, lower; int size = builtin_type (gdbarch)->builtin_data_ptr->length (); bfd_endian byte_order = gdbarch_byte_order (current_inferior ()->arch ()); /* New values from input value. */ - regnum -= tdep->bnd0_regnum; - lower = extract_unsigned_integer (buf, size, byte_order); - upper = extract_unsigned_integer (buf + size, size, byte_order); + int reg_index = pseudo_reg_num - tdep->bnd0_regnum; + int raw_regnum = I387_BND0R_REGNUM (tdep) + reg_index; - /* Fetching register buffer. */ - regcache->raw_read (I387_BND0R_REGNUM (tdep) + regnum, - raw_buf); + value *bndr_value = value_of_register (raw_regnum, next_frame); + gdb::array_view bndr_view + = bndr_value->contents_writeable (); - upper = ~upper; + /* Copy lower bytes directly. */ + copy (buf.slice (0, size), bndr_view.slice (0, size)); - /* Set register bits. */ - memcpy (raw_buf, &lower, 8); - memcpy (raw_buf + 8, &upper, 8); + /* Convert and then copy upper bytes. */ + ULONGEST upper + = extract_unsigned_integer (buf.slice (size, size), byte_order); + upper = ~upper; + store_unsigned_integer (bndr_view.slice (8, size), byte_order, + upper); - regcache->raw_write (I387_BND0R_REGNUM (tdep) + regnum, raw_buf); + put_frame_register (next_frame, raw_regnum, bndr_view); } - else if (i386_zmm_regnum_p (gdbarch, regnum)) + else if (i386_zmm_regnum_p (gdbarch, pseudo_reg_num)) { - regnum -= tdep->zmm0_regnum; + /* Which register is it, relative to zmm0. */ + int reg_index_0 = pseudo_reg_num - tdep->zmm0_regnum; - if (regnum < num_lower_zmm_regs) - { - /* Write lower 128bits. */ - regcache->raw_write (I387_XMM0_REGNUM (tdep) + regnum, buf); - /* Write upper 128bits. */ - regcache->raw_write (I387_YMM0_REGNUM (tdep) + regnum, buf + 16); - } + if (reg_index_0 < num_lower_zmm_regs) + pseudo_to_concat_raw (next_frame, buf, + I387_XMM0_REGNUM (tdep) + reg_index_0, + I387_YMM0_REGNUM (tdep) + reg_index_0, + tdep->zmm0h_regnum + reg_index_0); else { - /* Write lower 128bits. */ - regcache->raw_write (I387_XMM16_REGNUM (tdep) + regnum - - num_lower_zmm_regs, buf); - /* Write upper 128bits. */ - regcache->raw_write (I387_YMM16H_REGNUM (tdep) + regnum - - num_lower_zmm_regs, buf + 16); + /* Which register is it, relative to zmm16. */ + int reg_index_16 = reg_index_0 - num_lower_zmm_regs; + + pseudo_to_concat_raw (next_frame, buf, + I387_XMM16_REGNUM (tdep) + reg_index_16, + I387_YMM16H_REGNUM (tdep) + reg_index_16, + tdep->zmm0h_regnum + +reg_index_0); } - /* Write upper 256bits. */ - regcache->raw_write (tdep->zmm0h_regnum + regnum, buf + 32); } - else if (i386_ymm_regnum_p (gdbarch, regnum)) + else if (i386_ymm_regnum_p (gdbarch, pseudo_reg_num)) { - regnum -= tdep->ymm0_regnum; + int i = pseudo_reg_num - tdep->ymm0_regnum; - /* ... Write lower 128bits. */ - regcache->raw_write (I387_XMM0_REGNUM (tdep) + regnum, buf); - /* ... Write upper 128bits. */ - regcache->raw_write (tdep->ymm0h_regnum + regnum, buf + 16); + pseudo_to_concat_raw (next_frame, buf, I387_XMM0_REGNUM (tdep) + i, + tdep->ymm0h_regnum + i); } - else if (i386_ymm_avx512_regnum_p (gdbarch, regnum)) + else if (i386_ymm_avx512_regnum_p (gdbarch, pseudo_reg_num)) { - regnum -= tdep->ymm16_regnum; + int i = pseudo_reg_num - tdep->ymm16_regnum; - /* ... Write lower 128bits. */ - regcache->raw_write (I387_XMM16_REGNUM (tdep) + regnum, buf); - /* ... Write upper 128bits. */ - regcache->raw_write (tdep->ymm16h_regnum + regnum, buf + 16); + pseudo_to_concat_raw (next_frame, buf, I387_XMM16_REGNUM (tdep) + i, + tdep->ymm16h_regnum + i); } - else if (i386_word_regnum_p (gdbarch, regnum)) + else if (i386_word_regnum_p (gdbarch, pseudo_reg_num)) { - int gpnum = regnum - tdep->ax_regnum; + int gpnum = pseudo_reg_num - tdep->ax_regnum; - /* Read ... */ - regcache->raw_read (gpnum, raw_buf); - /* ... Modify ... (always little endian). */ - memcpy (raw_buf, buf, 2); - /* ... Write. */ - regcache->raw_write (gpnum, raw_buf); + pseudo_to_raw_part (next_frame, buf, gpnum, 0); } - else if (i386_byte_regnum_p (gdbarch, regnum)) + else if (i386_byte_regnum_p (gdbarch, pseudo_reg_num)) { - int gpnum = regnum - tdep->al_regnum; + int gpnum = pseudo_reg_num - tdep->al_regnum; - /* Read ... We read both lower and upper registers. */ - regcache->raw_read (gpnum % 4, raw_buf); - /* ... Modify ... (always little endian). */ - if (gpnum >= 4) - memcpy (raw_buf + 1, buf, 1); - else - memcpy (raw_buf, buf, 1); - /* ... Write. */ - regcache->raw_write (gpnum % 4, raw_buf); + pseudo_to_raw_part (next_frame, buf, gpnum % 4, gpnum >= 4 ? 1 : 0); } else internal_error (_("invalid regnum")); @@ -8603,8 +8560,7 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) /* Pseudo registers may be changed by amd64_init_abi. */ set_gdbarch_pseudo_register_read_value (gdbarch, i386_pseudo_register_read_value); - set_gdbarch_deprecated_pseudo_register_write (gdbarch, - i386_pseudo_register_write); + set_gdbarch_pseudo_register_write (gdbarch, i386_pseudo_register_write); set_gdbarch_ax_pseudo_register_collect (gdbarch, i386_ax_pseudo_register_collect); diff --git a/gdb/i386-tdep.h b/gdb/i386-tdep.h index 970dc8904f2a..b132da23a104 100644 --- a/gdb/i386-tdep.h +++ b/gdb/i386-tdep.h @@ -380,9 +380,9 @@ extern value *i386_pseudo_register_read_value (gdbarch *gdbarch, frame_info_ptr next_frame, int regnum); -extern void i386_pseudo_register_write (struct gdbarch *gdbarch, - struct regcache *regcache, - int regnum, const gdb_byte *buf); +extern void i386_pseudo_register_write (gdbarch *gdbarch, + frame_info_ptr next_frame, int regnum, + gdb::array_view buf); extern int i386_ax_pseudo_register_collect (struct gdbarch *gdbarch, struct agent_expr *ax, diff --git a/gdb/value.c b/gdb/value.c index 51dca972a587..5c18bb17a781 100644 --- a/gdb/value.c +++ b/gdb/value.c @@ -4062,7 +4062,8 @@ pseudo_to_raw_part (frame_info_ptr next_frame, gdb::array_view pseudo_buf, int raw_reg_num, int raw_offset) { - int raw_reg_size = register_size (get_frame_arch (next_frame), raw_reg_num); + int raw_reg_size + = register_size (frame_unwind_arch (next_frame), raw_reg_num); /* When overflowing a register, put_frame_register_bytes writes to the subsequent registers. We don't want that behavior here, so make sure diff --git a/gdb/value.h b/gdb/value.h index 6a74d4e2c2ee..3b3cb9c00982 100644 --- a/gdb/value.h +++ b/gdb/value.h @@ -1664,7 +1664,7 @@ value *pseudo_from_raw_part (frame_info_ptr next_frame, int pseudo_reg_num, /* Write PSEUDO_BUF, the contents of a pseudo register, to part of raw register RAW_REG_NUM starting at RAW_OFFSET. */ -void pseudo_to_raw_part (frame_info_ptr this_frame, +void pseudo_to_raw_part (frame_info_ptr next_frame, gdb::array_view pseudo_buf, int raw_reg_num, int raw_offset); @@ -1680,7 +1680,7 @@ value *pseudo_from_concat_raw (frame_info_ptr next_frame, int pseudo_reg_num, /* Write PSEUDO_BUF, the contents of a pseudo register, to the two raw registers RAW_REG_1_NUM and RAW_REG_2_NUM. */ -void pseudo_to_concat_raw (frame_info_ptr this_frame, +void pseudo_to_concat_raw (frame_info_ptr next_frame, gdb::array_view pseudo_buf, int raw_reg_1_num, int raw_reg_2_num); @@ -1693,7 +1693,7 @@ value *pseudo_from_concat_raw (frame_info_ptr next_frame, int pseudo_reg_num, /* Write PSEUDO_BUF, the contents of a pseudo register, to the tthreewo raw registers RAW_REG_1_NUM, RAW_REG_2_NUM and RAW_REG_3_NUM. */ -void pseudo_to_concat_raw (frame_info_ptr this_frame, +void pseudo_to_concat_raw (frame_info_ptr next_frame, gdb::array_view pseudo_buf, int raw_reg_1_num, int raw_reg_2_num, int raw_reg_3_num); From patchwork Wed Nov 8 05:01:03 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Marchi X-Patchwork-Id: 79377 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 697DA3857BB3 for ; Wed, 8 Nov 2023 05:16:57 +0000 (GMT) X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from smtp.polymtl.ca (smtp.polymtl.ca [132.207.4.11]) by sourceware.org (Postfix) with ESMTPS id D21CE3858CDB for ; Wed, 8 Nov 2023 05:16:43 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org D21CE3858CDB Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=polymtl.ca Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=polymtl.ca ARC-Filter: OpenARC Filter v1.0.0 sourceware.org D21CE3858CDB Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=132.207.4.11 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1699420605; cv=none; b=LjIjBLzqAJvv7HTla6taWUbj4yykLXUZmcYjTZMxY6P5F4xgLxSBayjrlKzGw3bT3CY/KcrDcOrNRED3GsXuOH8qHWPCCMGozTuB9lUQfmBMdUw/vh7MfF4oa4ocjGVeff9jyFtoNjOAbgF29Sn0LAf/PT3/mmv3Vlat8//2vgY= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1699420605; c=relaxed/simple; bh=xFcWAcPzPHJDAjWkI8rqTXeY8Bvita3qbWVuxKchPV8=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=Qht0MKpDgLmZZ16TV+IsACyziOArB3rhtGxS/5EcED4iaWkf2eSajdcO5PSlAzhoyCvu9Zy7uw6lNXIDjqAiHtKYuXTVmQZy8AYqn6gjP+Ilx7Lce04HxdMKZnj+yvmHsrZ90pn4Zo2pw7gnVG7QSLgpGXTDsrTaNwGaLt8Z+Ok= ARC-Authentication-Results: i=1; server2.sourceware.org Received: from simark.ca (simark.ca [158.69.221.121]) (authenticated bits=0) by smtp.polymtl.ca (8.14.7/8.14.7) with ESMTP id 3A85Gb72016038 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 8 Nov 2023 00:16:41 -0500 DKIM-Filter: OpenDKIM Filter v2.11.0 smtp.polymtl.ca 3A85Gb72016038 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=polymtl.ca; s=default; t=1699420602; bh=UNiZm6G4i9B2w4tZaviCOYMyMMtHS9+EkakDP+0y9JI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=uqu43OoU+07FCNGUH0u7LrnJLT5p05q7tu1+Dn2h4E+r9sI3gWL5KeNtqxFQEEWhI O0OTRaQ3Npy2k4PeOClW5CtJjK/WYVUaueKsc9fRQcBLwYgc/Nbsc1caLlATcra9xX /dxqpL+ugIyhqegz+beP6waJIdS+yca6d8rFP+/I= Received: from simark.localdomain (modemcable238.237-201-24.mc.videotron.ca [24.201.237.238]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) by simark.ca (Postfix) with ESMTPSA id 4415B1E0D2; Wed, 8 Nov 2023 00:16:37 -0500 (EST) From: Simon Marchi To: gdb-patches@sourceware.org Cc: Simon Marchi Subject: [PATCH 19/24] gdb: make aarch64_za_offsets_from_regnum return za_offsets Date: Wed, 8 Nov 2023 00:01:03 -0500 Message-ID: <20231108051222.1275306-20-simon.marchi@polymtl.ca> X-Mailer: git-send-email 2.42.1 In-Reply-To: <20231108051222.1275306-1-simon.marchi@polymtl.ca> References: <20231108051222.1275306-1-simon.marchi@polymtl.ca> MIME-Version: 1.0 X-Poly-FromMTA: (simark.ca [158.69.221.121]) at Wed, 8 Nov 2023 05:16:37 +0000 X-Spam-Status: No, score=-3188.6 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_PASS, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE 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.30 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org From: Simon Marchi This is not necessary, but it seems more natural to me to make aarch64_za_offsets_from_regnum return a za_offsets object, rather than fill an instance passed by parameter. Change-Id: I40a185f055727da887ce7774be193eef1f4b9147 --- gdb/aarch64-tdep.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c index d1a6d46fb1f2..e9f5bdd141c8 100644 --- a/gdb/aarch64-tdep.c +++ b/gdb/aarch64-tdep.c @@ -3114,12 +3114,11 @@ aarch64_pseudo_read_value_1 (frame_info_ptr next_frame, } /* Helper function for reading/writing ZA pseudo-registers. Given REGNUM, - a ZA pseudo-register number, return, in OFFSETS, the information on positioning - of the bytes that must be read from/written to. */ + a ZA pseudo-register number, return the information on positioning of the + bytes that must be read from/written to. */ -static void -aarch64_za_offsets_from_regnum (struct gdbarch *gdbarch, int regnum, - struct za_offsets &offsets) +static za_offsets +aarch64_za_offsets_from_regnum (struct gdbarch *gdbarch, int regnum) { aarch64_gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); @@ -3135,6 +3134,7 @@ aarch64_za_offsets_from_regnum (struct gdbarch *gdbarch, int regnum, /* Fetch the streaming vector length. */ size_t svl = sve_vl_from_vq (tdep->sme_svq); + za_offsets offsets; if (is_sme_tile_slice_pseudo_register (gdbarch, regnum)) { @@ -3190,6 +3190,8 @@ aarch64_za_offsets_from_regnum (struct gdbarch *gdbarch, int regnum, /* The chunk size is always svl bytes. */ offsets.chunk_size = svl; } + + return offsets; } /* Given REGNUM, a SME pseudo-register number, return its value in RESULT. */ @@ -3207,8 +3209,8 @@ aarch64_sme_pseudo_register_read (gdbarch *gdbarch, frame_info_ptr next_frame, /* Fetch the offsets that we need in order to read from the correct blocks of ZA. */ - struct za_offsets offsets; - aarch64_za_offsets_from_regnum (gdbarch, pseudo_reg_num, offsets); + za_offsets offsets + = aarch64_za_offsets_from_regnum (gdbarch, pseudo_reg_num); /* Fetch the contents of ZA. */ value *za_value = value_of_register (tdep->sme_za_regnum, next_frame); @@ -3330,8 +3332,7 @@ aarch64_sme_pseudo_register_write (struct gdbarch *gdbarch, /* Fetch the offsets that we need in order to write to the correct blocks of ZA. */ - struct za_offsets offsets; - aarch64_za_offsets_from_regnum (gdbarch, regnum, offsets); + za_offsets offsets = aarch64_za_offsets_from_regnum (gdbarch, regnum); /* Fetch the contents of ZA. */ size_t svl = sve_vl_from_vq (tdep->sme_svq); From patchwork Wed Nov 8 05:01:04 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Marchi X-Patchwork-Id: 79386 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 5E92C3858428 for ; Wed, 8 Nov 2023 05:26:58 +0000 (GMT) X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from smtp.polymtl.ca (smtp.polymtl.ca [132.207.4.11]) by sourceware.org (Postfix) with ESMTPS id CCF233858D1E for ; Wed, 8 Nov 2023 05:26:44 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org CCF233858D1E Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=polymtl.ca Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=polymtl.ca ARC-Filter: OpenARC Filter v1.0.0 sourceware.org CCF233858D1E Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=132.207.4.11 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1699421205; cv=none; b=Da3idqOVw1RvdtGDUre4m0OHV/jA/ZScR76h8FgVOCXleX/DkbXiII392ffeB/Iw9kVR0QkMhZOA9Z0Hu1sJDEIWCfOIONiHMKNeNR4RGDVa3McTTXTaWJ88BvpFXkzcH5y6XxuwmKQy8q3k3XVZ6yxblkGW8OF+BJ2+YTxjkJo= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1699421205; c=relaxed/simple; bh=DU9DM9nfYtlLQ3rbsGkja66Y3p6dmMo0O2qVAF1nDJg=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=DfcRtqAC3QCLLNmtWWc4yCxdjScK0YcMEcZ2DDGYikWeNYWyWKT9AqykLY+RjMblI7wKumkxGSxbTs1/WPyGcUYhPitifWvrrFMkAFb1xpHwN9KFt4Eemn3r0O5boMzHeEuu8dSNWdkjNBt0KqyDZX3gWNSZU0iq6PZhgHKb/b0= ARC-Authentication-Results: i=1; server2.sourceware.org Received: from simark.ca (simark.ca [158.69.221.121]) (authenticated bits=0) by smtp.polymtl.ca (8.14.7/8.14.7) with ESMTP id 3A85Qc58017727 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 8 Nov 2023 00:26:43 -0500 DKIM-Filter: OpenDKIM Filter v2.11.0 smtp.polymtl.ca 3A85Qc58017727 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=polymtl.ca; s=default; t=1699421203; bh=lLfomCDvGm5FOJktWeNLkJX2YbJot4f1CcNuq9iHuos=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=NOsGffboSzamZf7NQqFhbD4G+Cg8HusvU6mAdF8vhGIKlA+hvsABpCb9kXD6HTNUk vaz6FJZKVUMMNw3OQxt1LhRKp3VEH9+RuO80yqzu/8xhPmjrb+SNKnMgiypQtOdUO5 wMGiBz6b2aukgQM5OIjRgiovOCrn6MsXj1pfUZa8= Received: from simark.localdomain (modemcable238.237-201-24.mc.videotron.ca [24.201.237.238]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) by simark.ca (Postfix) with ESMTPSA id 580DE1E1C3; Wed, 8 Nov 2023 00:16:37 -0500 (EST) From: Simon Marchi To: gdb-patches@sourceware.org Cc: Simon Marchi Subject: [PATCH 20/24] gdb: add missing raw register read in aarch64_sme_pseudo_register_write Date: Wed, 8 Nov 2023 00:01:04 -0500 Message-ID: <20231108051222.1275306-21-simon.marchi@polymtl.ca> X-Mailer: git-send-email 2.42.1 In-Reply-To: <20231108051222.1275306-1-simon.marchi@polymtl.ca> References: <20231108051222.1275306-1-simon.marchi@polymtl.ca> MIME-Version: 1.0 X-Poly-FromMTA: (simark.ca [158.69.221.121]) at Wed, 8 Nov 2023 05:26:38 +0000 X-Spam-Status: No, score=-3188.6 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_PASS, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE 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.30 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org From: Simon Marchi It seems like the intention here is to read the contents of the ZA register and only write part of it. However, there's no actual read of the ZA register, so it looks like we'll write uninitialized bytes to the target, for the portion of the raw register where we don't write the pseudo register. Add a call to raw_read to fix this. I don't know how to test this though. Change-Id: I7548240bd4324f6a3b729a1ebf7502fae5a46e9e --- gdb/aarch64-tdep.c | 1 + 1 file changed, 1 insertion(+) diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c index e9f5bdd141c8..ff159c412ced 100644 --- a/gdb/aarch64-tdep.c +++ b/gdb/aarch64-tdep.c @@ -3337,6 +3337,7 @@ aarch64_sme_pseudo_register_write (struct gdbarch *gdbarch, /* Fetch the contents of ZA. */ size_t svl = sve_vl_from_vq (tdep->sme_svq); gdb::byte_vector za (std::pow (svl, 2)); + regcache->raw_read (tdep->sme_za_regnum, za, 1.0f); /* Copy the requested data. */ for (int chunks = 0; chunks < offsets.chunks; chunks++) From patchwork Wed Nov 8 05:01:05 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Marchi X-Patchwork-Id: 79388 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 DC655385841F for ; Wed, 8 Nov 2023 05:26:59 +0000 (GMT) X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from smtp.polymtl.ca (smtp.polymtl.ca [132.207.4.11]) by sourceware.org (Postfix) with ESMTPS id 3B4E53858D35 for ; Wed, 8 Nov 2023 05:26:45 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 3B4E53858D35 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=polymtl.ca Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=polymtl.ca ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 3B4E53858D35 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=132.207.4.11 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1699421206; cv=none; b=a8/DKDKs620frYuRWmK0uapfFIn4MZ2qiBaWVXuiz+0UGK143y9cOynE8CzdSuo2Wv/KibaYFzE4Xo+Si1WX5pKsIjez1Az3up5T5ci+MnXFL7BowhyXnYsH7z8HCFJqAe84x7PfBUOLhK0hJuQpJNQAy7wcZS8bA9iNZ9MSfLs= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1699421206; c=relaxed/simple; bh=okuhgng3Ilv/9pXVRg1eCvjhWmp36COqiI0DMvFPZkA=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=XfeaP5gY1b8hnfrwo+VQiMbfz6go6vgN0Zao8EriNvputFgrQrcI/Nsft0FXgs/vAGHE5zoj5p9RlL4BQni8D+E7sT9Qdzx+SH79EoII/P6cmcmDF8+S7ZBCDKujk1ANmrEO17imKbFUZLpu91gZsIo/RiBWsCuOJs0+wsjEPb8= ARC-Authentication-Results: i=1; server2.sourceware.org Received: from simark.ca (simark.ca [158.69.221.121]) (authenticated bits=0) by smtp.polymtl.ca (8.14.7/8.14.7) with ESMTP id 3A85Qc5h017728 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 8 Nov 2023 00:26:43 -0500 DKIM-Filter: OpenDKIM Filter v2.11.0 smtp.polymtl.ca 3A85Qc5h017728 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=polymtl.ca; s=default; t=1699421203; bh=e7puLOSqeRruA28YQD51aLztPb+jdqYEt4NCfOJL3Hg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=rekBs2gjlEjy9s0OcUSBiLymaJ3EdRqszc0rH7YYIhfsO7wjGUUHbRWGF61et5yUd atPeEzNZvY2NiHqnw2rd/JguM2ymkEbs7bhBzcjeb3rjf3WdVurt5IXHmreMv4aysL FRAgCowKvVpr65/rXZbu/QkdEVKvyAIcvA8eseg0= Received: from simark.localdomain (modemcable238.237-201-24.mc.videotron.ca [24.201.237.238]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) by simark.ca (Postfix) with ESMTPSA id A4B0B1E1C8; Wed, 8 Nov 2023 00:16:37 -0500 (EST) From: Simon Marchi To: gdb-patches@sourceware.org Cc: Simon Marchi Subject: [PATCH 21/24] gdb: migrate aarch64 to new gdbarch_pseudo_register_write Date: Wed, 8 Nov 2023 00:01:05 -0500 Message-ID: <20231108051222.1275306-22-simon.marchi@polymtl.ca> X-Mailer: git-send-email 2.42.1 In-Reply-To: <20231108051222.1275306-1-simon.marchi@polymtl.ca> References: <20231108051222.1275306-1-simon.marchi@polymtl.ca> MIME-Version: 1.0 X-Poly-FromMTA: (simark.ca [158.69.221.121]) at Wed, 8 Nov 2023 05:26:38 +0000 X-Spam-Status: No, score=-3188.6 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_PASS, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE 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.30 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org From: Simon Marchi Make aarch64 use the new gdbarch_pseudo_register_write. This fixes writing pseudo registers to non-current frames on this architecture. Change-Id: Ic012a0b95ae728d45a7121f77a79d604c23a849e --- gdb/aarch64-tdep.c | 132 ++++++++++++++++++++++++--------------------- 1 file changed, 71 insertions(+), 61 deletions(-) diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c index ff159c412ced..1815d78dec40 100644 --- a/gdb/aarch64-tdep.c +++ b/gdb/aarch64-tdep.c @@ -3296,32 +3296,33 @@ aarch64_pseudo_read_value (gdbarch *gdbarch, frame_info_ptr next_frame, /* Helper for aarch64_pseudo_write. */ static void -aarch64_pseudo_write_1 (struct gdbarch *gdbarch, struct regcache *regcache, - int regnum_offset, int regsize, const gdb_byte *buf) +aarch64_pseudo_write_1 (gdbarch *gdbarch, frame_info_ptr next_frame, + int regnum_offset, + gdb::array_view buf) { unsigned v_regnum = AARCH64_V0_REGNUM + regnum_offset; - - /* Enough space for a full vector register. */ - gdb_byte reg_buf[register_size (gdbarch, AARCH64_V0_REGNUM)]; gdb_static_assert (AARCH64_V0_REGNUM == AARCH64_SVE_Z0_REGNUM); - /* Ensure the register buffer is zero, we want gdb writes of the + /* Enough space for a full vector register. + + Ensure the register buffer is zero-ed, we want gdb writes of the various 'scalar' pseudo registers to behavior like architectural writes, register width bytes are written the remainder are set to zero. */ - memset (reg_buf, 0, register_size (gdbarch, AARCH64_V0_REGNUM)); - - memcpy (reg_buf, buf, regsize); - regcache->raw_write (v_regnum, reg_buf); + constexpr int raw_reg_size = 16; + gdb_byte raw_buf[raw_reg_size] {}; + gdb::array_view raw_view (raw_buf); + copy (buf, raw_view.slice (0, buf.size ())); + put_frame_register (next_frame, v_regnum, raw_view); } /* Given REGNUM, a SME pseudo-register number, store the bytes from DATA to the pseudo-register. */ static void -aarch64_sme_pseudo_register_write (struct gdbarch *gdbarch, - struct regcache *regcache, - int regnum, const gdb_byte *data) +aarch64_sme_pseudo_register_write (gdbarch *gdbarch, frame_info_ptr next_frame, + const int regnum, + gdb::array_view data) { aarch64_gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); @@ -3335,33 +3336,39 @@ aarch64_sme_pseudo_register_write (struct gdbarch *gdbarch, za_offsets offsets = aarch64_za_offsets_from_regnum (gdbarch, regnum); /* Fetch the contents of ZA. */ - size_t svl = sve_vl_from_vq (tdep->sme_svq); - gdb::byte_vector za (std::pow (svl, 2)); - regcache->raw_read (tdep->sme_za_regnum, za, 1.0f); + value *za_value = value_of_register (tdep->sme_za_regnum, next_frame); - /* Copy the requested data. */ - for (int chunks = 0; chunks < offsets.chunks; chunks++) - { - const gdb_byte *source = data + chunks * offsets.chunk_size; - gdb_byte *destination - = za.data () + offsets.starting_offset + chunks * offsets.stride_size; + { + /* Create a view only on the portion of za we want to write. */ + gdb::array_view za_view + = za_value->contents_writeable ().slice (offsets.starting_offset); - memcpy (destination, source, offsets.chunk_size); - } + /* Copy the requested data. */ + for (int chunks = 0; chunks < offsets.chunks; chunks++) + { + gdb::array_view src + = data.slice (chunks * offsets.chunk_size, offsets.chunk_size); + gdb::array_view dst + = za_view.slice (chunks * offsets.stride_size, offsets.chunk_size); + copy (src, dst); + } + } /* Write back to ZA. */ - regcache->raw_write (tdep->sme_za_regnum, za.data ()); + put_frame_register (next_frame, tdep->sme_za_regnum, + za_value->contents_raw ()); } /* Implement the "pseudo_register_write" gdbarch method. */ static void -aarch64_pseudo_write (struct gdbarch *gdbarch, struct regcache *regcache, - int regnum, const gdb_byte *buf) +aarch64_pseudo_write (gdbarch *gdbarch, frame_info_ptr next_frame, + const int pseudo_reg_num, + gdb::array_view buf) { aarch64_gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); - if (is_w_pseudo_register (gdbarch, regnum)) + if (is_w_pseudo_register (gdbarch, pseudo_reg_num)) { enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); /* Default offset for little endian. */ @@ -3371,53 +3378,56 @@ aarch64_pseudo_write (struct gdbarch *gdbarch, struct regcache *regcache, offset = 4; /* Find the correct X register to extract the data from. */ - int x_regnum = AARCH64_X0_REGNUM + (regnum - tdep->w_pseudo_base); + int x_regnum = AARCH64_X0_REGNUM + (pseudo_reg_num - tdep->w_pseudo_base); /* First zero-out the contents of X. */ - ULONGEST zero = 0; - regcache->raw_write (x_regnum, zero); + gdb_byte bytes[8] {}; + gdb::array_view bytes_view (bytes); + copy (buf, bytes_view.slice (offset, 4)); + /* Write to the bottom 4 bytes of X. */ - regcache->raw_write_part (x_regnum, offset, 4, buf); + put_frame_register (next_frame, x_regnum, bytes_view); return; } - else if (is_sme_pseudo_register (gdbarch, regnum)) + else if (is_sme_pseudo_register (gdbarch, pseudo_reg_num)) { - aarch64_sme_pseudo_register_write (gdbarch, regcache, regnum, buf); + aarch64_sme_pseudo_register_write (gdbarch, next_frame, pseudo_reg_num, + buf); return; } - regnum -= gdbarch_num_regs (gdbarch); + /* Offset in the "pseudo-register space". */ + int pseudo_offset = pseudo_reg_num - gdbarch_num_regs (gdbarch); - if (regnum >= AARCH64_Q0_REGNUM && regnum < AARCH64_Q0_REGNUM + 32) - return aarch64_pseudo_write_1 (gdbarch, regcache, - regnum - AARCH64_Q0_REGNUM, Q_REGISTER_SIZE, - buf); + if (pseudo_offset >= AARCH64_Q0_REGNUM + && pseudo_offset < AARCH64_Q0_REGNUM + 32) + return aarch64_pseudo_write_1 (gdbarch, next_frame, + pseudo_offset - AARCH64_Q0_REGNUM, buf); - if (regnum >= AARCH64_D0_REGNUM && regnum < AARCH64_D0_REGNUM + 32) - return aarch64_pseudo_write_1 (gdbarch, regcache, - regnum - AARCH64_D0_REGNUM, D_REGISTER_SIZE, - buf); + if (pseudo_offset >= AARCH64_D0_REGNUM + && pseudo_offset < AARCH64_D0_REGNUM + 32) + return aarch64_pseudo_write_1 (gdbarch, next_frame, + pseudo_offset - AARCH64_D0_REGNUM, buf); - if (regnum >= AARCH64_S0_REGNUM && regnum < AARCH64_S0_REGNUM + 32) - return aarch64_pseudo_write_1 (gdbarch, regcache, - regnum - AARCH64_S0_REGNUM, S_REGISTER_SIZE, - buf); + if (pseudo_offset >= AARCH64_S0_REGNUM + && pseudo_offset < AARCH64_S0_REGNUM + 32) + return aarch64_pseudo_write_1 (gdbarch, next_frame, + pseudo_offset - AARCH64_S0_REGNUM, buf); - if (regnum >= AARCH64_H0_REGNUM && regnum < AARCH64_H0_REGNUM + 32) - return aarch64_pseudo_write_1 (gdbarch, regcache, - regnum - AARCH64_H0_REGNUM, H_REGISTER_SIZE, - buf); + if (pseudo_offset >= AARCH64_H0_REGNUM + && pseudo_offset < AARCH64_H0_REGNUM + 32) + return aarch64_pseudo_write_1 (gdbarch, next_frame, + pseudo_offset - AARCH64_H0_REGNUM, buf); - if (regnum >= AARCH64_B0_REGNUM && regnum < AARCH64_B0_REGNUM + 32) - return aarch64_pseudo_write_1 (gdbarch, regcache, - regnum - AARCH64_B0_REGNUM, B_REGISTER_SIZE, - buf); + if (pseudo_offset >= AARCH64_B0_REGNUM + && pseudo_offset < AARCH64_B0_REGNUM + 32) + return aarch64_pseudo_write_1 (gdbarch, next_frame, + pseudo_offset - AARCH64_B0_REGNUM, buf); - if (tdep->has_sve () && regnum >= AARCH64_SVE_V0_REGNUM - && regnum < AARCH64_SVE_V0_REGNUM + 32) - return aarch64_pseudo_write_1 (gdbarch, regcache, - regnum - AARCH64_SVE_V0_REGNUM, - V_REGISTER_SIZE, buf); + if (tdep->has_sve () && pseudo_offset >= AARCH64_SVE_V0_REGNUM + && pseudo_offset < AARCH64_SVE_V0_REGNUM + 32) + return aarch64_pseudo_write_1 (gdbarch, next_frame, + pseudo_offset - AARCH64_SVE_V0_REGNUM, buf); gdb_assert_not_reached ("regnum out of bound"); } @@ -4483,7 +4493,7 @@ aarch64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) set_gdbarch_num_pseudo_regs (gdbarch, num_pseudo_regs); set_gdbarch_pseudo_register_read_value (gdbarch, aarch64_pseudo_read_value); - set_gdbarch_deprecated_pseudo_register_write (gdbarch, aarch64_pseudo_write); + set_gdbarch_pseudo_register_write (gdbarch, aarch64_pseudo_write); set_tdesc_pseudo_register_name (gdbarch, aarch64_pseudo_register_name); set_tdesc_pseudo_register_type (gdbarch, aarch64_pseudo_register_type); set_tdesc_pseudo_register_reggroup_p (gdbarch, From patchwork Wed Nov 8 05:01:06 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Marchi X-Patchwork-Id: 79387 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 5E9E43858433 for ; Wed, 8 Nov 2023 05:26:58 +0000 (GMT) X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from smtp.polymtl.ca (smtp.polymtl.ca [132.207.4.11]) by sourceware.org (Postfix) with ESMTPS id D45533858D33 for ; Wed, 8 Nov 2023 05:26:44 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org D45533858D33 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=polymtl.ca Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=polymtl.ca ARC-Filter: OpenARC Filter v1.0.0 sourceware.org D45533858D33 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=132.207.4.11 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1699421206; cv=none; b=omgcO22uQr/c+W+fOtHKMq9m5Jt2KXRZ9O1asLlatfCjxnheJAyOMFoWP+2Aw6omyMoFVN4UNOvmzc30oT9crXvQKakX36OVy+m8H+oB0eTyAZ4pqKUrimPNTuuwAiUjt6qzB6dh+sZpzH+IGjAKhMj0HEvF1PexgS1nxDDun/Q= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1699421206; c=relaxed/simple; bh=bNjSvbZ1g7v3uXqd+zGI/UyL6/w2XUnPXLe4IgbjiBs=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=reLg07PE33/ZNMxGR70tYcAqCWaxtdqnPe8ie3d9IMl1nAHCbsKU/EVHyU9CKb7kgqdrKQPhbc3EnvWXQ4EbbMYHaew1A18a9dKqWldIhqoJ39nd2/chAGz81za6Rcox454B5Bski9bV7b0RBPQoveiTCBFPO+l9u09Ao1EMarI= ARC-Authentication-Results: i=1; server2.sourceware.org Received: from simark.ca (simark.ca [158.69.221.121]) (authenticated bits=0) by smtp.polymtl.ca (8.14.7/8.14.7) with ESMTP id 3A85Qcu4017726 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 8 Nov 2023 00:26:43 -0500 DKIM-Filter: OpenDKIM Filter v2.11.0 smtp.polymtl.ca 3A85Qcu4017726 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=polymtl.ca; s=default; t=1699421203; bh=iCiofSkApvc2ZUyWXLK1ax4W2yBRWi2ac7OSpq2aUKw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=SveITCUxBJiGZ0P6QsMkXAW1cgluKlhTEjRHbLqpQykVZt1P8fVLk1Aqw2JETYPJz 5NczG/TRXnes/cLsX4ufHLw5uh54OaI9+Z4MBlC7xF50hwxSTdWKT+ldXCZYQO3yeo AtZV06y+9PoE9WHHlaHhizbjgjbnxeC1s43XWA3M= Received: from simark.localdomain (modemcable238.237-201-24.mc.videotron.ca [24.201.237.238]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) by simark.ca (Postfix) with ESMTPSA id BA4E91E1CA; Wed, 8 Nov 2023 00:16:37 -0500 (EST) From: Simon Marchi To: gdb-patches@sourceware.org Cc: Simon Marchi Subject: [PATCH 22/24] gdb: migrate arm to gdbarch_pseudo_register_read_value Date: Wed, 8 Nov 2023 00:01:06 -0500 Message-ID: <20231108051222.1275306-23-simon.marchi@polymtl.ca> X-Mailer: git-send-email 2.42.1 In-Reply-To: <20231108051222.1275306-1-simon.marchi@polymtl.ca> References: <20231108051222.1275306-1-simon.marchi@polymtl.ca> MIME-Version: 1.0 X-Poly-FromMTA: (simark.ca [158.69.221.121]) at Wed, 8 Nov 2023 05:26:38 +0000 X-Spam-Status: No, score=-3188.6 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_PASS, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE 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.30 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org From: Simon Marchi Make arm use the "newer" gdbarch_pseudo_register_read_value. This fixes reading pseudo registers in non-current frames on that architecture. Change-Id: Ic4d3d5d96957a4addfa3443c7b567dc4a31794a9 --- gdb/arm-tdep.c | 76 +++++++++++++++++++++++++++++--------------------- 1 file changed, 44 insertions(+), 32 deletions(-) diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c index cd4c760c2ff4..9bf51485b800 100644 --- a/gdb/arm-tdep.c +++ b/gdb/arm-tdep.c @@ -9816,61 +9816,73 @@ arm_neon_quad_read (struct gdbarch *gdbarch, readable_regcache *regcache, return REG_VALID; } -/* Read the contents of the MVE pseudo register REGNUM and store it - in BUF. */ +/* Read the contents of a NEON quad register, by reading from two double + registers, and return it as a value. QUAD_REG_INDEX is the index of the quad + register, in [0, 15]. */ -static enum register_status -arm_mve_pseudo_read (struct gdbarch *gdbarch, readable_regcache *regcache, - int regnum, gdb_byte *buf) +static value * +arm_neon_quad_read_value (gdbarch *gdbarch, frame_info_ptr next_frame, + int pseudo_reg_num, int quad_reg_index) +{ + std::string raw_reg_name = string_printf ("d%d", quad_reg_index << 1); + int double_regnum + = user_reg_map_name_to_regnum (gdbarch, raw_reg_name.c_str (), + raw_reg_name.length ()); + + return pseudo_from_concat_raw (next_frame, pseudo_reg_num, double_regnum, + double_regnum + 1); +} + +/* Read the contents of the MVE pseudo register REGNUM and return it as a + value. */ +static value * +arm_mve_pseudo_read_value (gdbarch *gdbarch, frame_info_ptr next_frame, + int pseudo_reg_num) { arm_gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); /* P0 is the first 16 bits of VPR. */ - return regcache->raw_read_part (tdep->mve_vpr_regnum, 0, 2, buf); + return pseudo_from_raw_part (next_frame, pseudo_reg_num, + tdep->mve_vpr_regnum, 0); } -static enum register_status -arm_pseudo_read (struct gdbarch *gdbarch, readable_regcache *regcache, - int regnum, gdb_byte *buf) +static value * +arm_pseudo_read_value (gdbarch *gdbarch, frame_info_ptr next_frame, + const int pseudo_reg_num) { - const int num_regs = gdbarch_num_regs (gdbarch); - char name_buf[4]; - gdb_byte reg_buf[8]; - int offset, double_regnum; arm_gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); - gdb_assert (regnum >= num_regs); + gdb_assert (pseudo_reg_num >= gdbarch_num_regs (gdbarch)); - if (is_q_pseudo (gdbarch, regnum)) + if (is_q_pseudo (gdbarch, pseudo_reg_num)) { /* Quad-precision register. */ - return arm_neon_quad_read (gdbarch, regcache, - regnum - tdep->q_pseudo_base, buf); + return arm_neon_quad_read_value (gdbarch, next_frame, pseudo_reg_num, + pseudo_reg_num - tdep->q_pseudo_base); } - else if (is_mve_pseudo (gdbarch, regnum)) - return arm_mve_pseudo_read (gdbarch, regcache, regnum, buf); + else if (is_mve_pseudo (gdbarch, pseudo_reg_num)) + return arm_mve_pseudo_read_value (gdbarch, next_frame, pseudo_reg_num); else { - enum register_status status; + int s_reg_index = pseudo_reg_num - tdep->s_pseudo_base; - regnum -= tdep->s_pseudo_base; /* Single-precision register. */ - gdb_assert (regnum < 32); + gdb_assert (s_reg_index < 32); /* s0 is always the least significant half of d0. */ + int offset; if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG) - offset = (regnum & 1) ? 0 : 4; + offset = (s_reg_index & 1) ? 0 : 4; else - offset = (regnum & 1) ? 4 : 0; + offset = (s_reg_index & 1) ? 4 : 0; - xsnprintf (name_buf, sizeof (name_buf), "d%d", regnum >> 1); - double_regnum = user_reg_map_name_to_regnum (gdbarch, name_buf, - strlen (name_buf)); + std::string raw_reg_name = string_printf ("d%d", s_reg_index >> 1); + int double_regnum + = user_reg_map_name_to_regnum (gdbarch, raw_reg_name.c_str (), + raw_reg_name.length ()); - status = regcache->raw_read (double_regnum, reg_buf); - if (status == REG_VALID) - memcpy (buf, reg_buf + offset, 4); - return status; + return pseudo_from_raw_part (next_frame, pseudo_reg_num, double_regnum, + offset); } } @@ -10905,7 +10917,7 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) if (tdep->have_s_pseudos || have_mve || have_pacbti) { set_gdbarch_num_pseudo_regs (gdbarch, num_pseudos); - set_gdbarch_pseudo_register_read (gdbarch, arm_pseudo_read); + set_gdbarch_pseudo_register_read_value (gdbarch, arm_pseudo_read_value); set_gdbarch_deprecated_pseudo_register_write (gdbarch, arm_pseudo_write); } From patchwork Wed Nov 8 05:01:07 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Marchi X-Patchwork-Id: 79383 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 D31073857B9B for ; Wed, 8 Nov 2023 05:21:58 +0000 (GMT) X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from smtp.polymtl.ca (smtp.polymtl.ca [132.207.4.11]) by sourceware.org (Postfix) with ESMTPS id 996A23858D35 for ; Wed, 8 Nov 2023 05:21:44 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 996A23858D35 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=polymtl.ca Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=polymtl.ca ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 996A23858D35 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=132.207.4.11 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1699420905; cv=none; b=TljjcLE67hLL+tuWEtM8ZmpLFvWI5ViA/XMWTJJhhXetBCcsd7Sm6/b6EL0zDPfDtg8vKHs+R8hlxMW0Xz89VbzK9FuVZpZcnMghYg08K19uCwOXGZfZCH0X85GhS8L0zej7dURD9eR3QB3VO7mxDqOoF54dUBRUt370jY7DlaA= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1699420905; c=relaxed/simple; bh=9ZClA6t2fPylEB8dcoTaSLcsxfMh+JFjoriLOWtfiLo=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=DmRhtEAGt8lktZVBCD+whd0Egocj0Y13pBQJVSJTrOUmams3VF16YIE7rNi5rWWmB3x6uS/FvzEURoYIQJrFHJQcIFNeZ2wSzgxuiinf0kRZTLGQSXf5cAwAnczm8cgjoXupvookfwBllMRjzl9l5DOSKrLNTxssdt92F5sS/30= ARC-Authentication-Results: i=1; server2.sourceware.org Received: from simark.ca (simark.ca [158.69.221.121]) (authenticated bits=0) by smtp.polymtl.ca (8.14.7/8.14.7) with ESMTP id 3A85LcNi016953 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 8 Nov 2023 00:21:42 -0500 DKIM-Filter: OpenDKIM Filter v2.11.0 smtp.polymtl.ca 3A85LcNi016953 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=polymtl.ca; s=default; t=1699420903; bh=Bj8PgNZ47TjErJBqt5ZZa6hphVyigICLEVIYo+VXbKI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=WElyXWQddubiweoNm5y2Alm93zGneEqt8E+QNKJd9QystwfvnWNd6+qwwvptHp8+S dWQhhE5FWzPPvsAlRt7K27JZ1/Hyg68yFQjMWY8mJxpA/Pjqafty+msMmfVPs5dNch QXESQMGEnNAUHXzEtmpkXu/FNc/TnYuSIPu1J9yY= Received: from simark.localdomain (modemcable238.237-201-24.mc.videotron.ca [24.201.237.238]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) by simark.ca (Postfix) with ESMTPSA id CCBF51E1CC; Wed, 8 Nov 2023 00:16:37 -0500 (EST) From: Simon Marchi To: gdb-patches@sourceware.org Cc: Simon Marchi Subject: [PATCH 23/24] gdb: migrate arm to new gdbarch_pseudo_register_write Date: Wed, 8 Nov 2023 00:01:07 -0500 Message-ID: <20231108051222.1275306-24-simon.marchi@polymtl.ca> X-Mailer: git-send-email 2.42.1 In-Reply-To: <20231108051222.1275306-1-simon.marchi@polymtl.ca> References: <20231108051222.1275306-1-simon.marchi@polymtl.ca> MIME-Version: 1.0 X-Poly-FromMTA: (simark.ca [158.69.221.121]) at Wed, 8 Nov 2023 05:21:38 +0000 X-Spam-Status: No, score=-3188.6 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_PASS, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE 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.30 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org From: Simon Marchi Make arm use the new gdbarch_pseudo_register_write. This fixes writing pseudo registers to non-current frames for that architecture. Change-Id: Icb2a649ab6394817844230e9e94c3d0564d2f765 --- gdb/arm-tdep.c | 62 +++++++++++++++++++++++++++++--------------------- 1 file changed, 36 insertions(+), 26 deletions(-) diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c index 9bf51485b800..a0d019b564bf 100644 --- a/gdb/arm-tdep.c +++ b/gdb/arm-tdep.c @@ -9908,57 +9908,67 @@ arm_neon_quad_write (struct gdbarch *gdbarch, struct regcache *regcache, regcache->raw_write (double_regnum + 1, buf + 8); } +static void +arm_neon_quad_write (gdbarch *gdbarch, frame_info_ptr next_frame, + int quad_reg_index, gdb::array_view buf) +{ + std::string raw_reg_name = string_printf ("d%d", quad_reg_index << 1); + int double_regnum + = user_reg_map_name_to_regnum (gdbarch, raw_reg_name.data (), + raw_reg_name.length ()); + + pseudo_to_concat_raw (next_frame, buf, double_regnum, double_regnum + 1); +} + /* Store the contents of BUF to the MVE pseudo register REGNUM. */ static void -arm_mve_pseudo_write (struct gdbarch *gdbarch, struct regcache *regcache, - int regnum, const gdb_byte *buf) +arm_mve_pseudo_write (gdbarch *gdbarch, frame_info_ptr next_frame, + int pseudo_reg_num, gdb::array_view buf) { arm_gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); /* P0 is the first 16 bits of VPR. */ - regcache->raw_write_part (tdep->mve_vpr_regnum, 0, 2, buf); + pseudo_to_raw_part(next_frame, buf, tdep->mve_vpr_regnum, 0); } static void -arm_pseudo_write (struct gdbarch *gdbarch, struct regcache *regcache, - int regnum, const gdb_byte *buf) +arm_pseudo_write (gdbarch *gdbarch, frame_info_ptr next_frame, + const int pseudo_reg_num, + gdb::array_view buf) { - const int num_regs = gdbarch_num_regs (gdbarch); - char name_buf[4]; - gdb_byte reg_buf[8]; - int offset, double_regnum; arm_gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); - gdb_assert (regnum >= num_regs); + gdb_assert (pseudo_reg_num >= gdbarch_num_regs (gdbarch)); - if (is_q_pseudo (gdbarch, regnum)) + if (is_q_pseudo (gdbarch, pseudo_reg_num)) { /* Quad-precision register. */ - arm_neon_quad_write (gdbarch, regcache, - regnum - tdep->q_pseudo_base, buf); + arm_neon_quad_write (gdbarch, next_frame, + pseudo_reg_num - tdep->q_pseudo_base, buf); } - else if (is_mve_pseudo (gdbarch, regnum)) - arm_mve_pseudo_write (gdbarch, regcache, regnum, buf); + else if (is_mve_pseudo (gdbarch, pseudo_reg_num)) + arm_mve_pseudo_write (gdbarch, next_frame, pseudo_reg_num, buf); else { - regnum -= tdep->s_pseudo_base; + int s_reg_index = pseudo_reg_num - tdep->s_pseudo_base; + /* Single-precision register. */ - gdb_assert (regnum < 32); + gdb_assert (s_reg_index < 32); /* s0 is always the least significant half of d0. */ + int offset; if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG) - offset = (regnum & 1) ? 0 : 4; + offset = (s_reg_index & 1) ? 0 : 4; else - offset = (regnum & 1) ? 4 : 0; + offset = (s_reg_index & 1) ? 4 : 0; - xsnprintf (name_buf, sizeof (name_buf), "d%d", regnum >> 1); - double_regnum = user_reg_map_name_to_regnum (gdbarch, name_buf, - strlen (name_buf)); + std::string raw_reg_name = string_printf ("d%d", s_reg_index >> 1); + int double_regnum + = user_reg_map_name_to_regnum (gdbarch, raw_reg_name.c_str (), + raw_reg_name.length ()); - regcache->raw_read (double_regnum, reg_buf); - memcpy (reg_buf + offset, buf, 4); - regcache->raw_write (double_regnum, reg_buf); + pseudo_to_raw_part (next_frame, buf, double_regnum, offset); } } @@ -10918,7 +10928,7 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) { set_gdbarch_num_pseudo_regs (gdbarch, num_pseudos); set_gdbarch_pseudo_register_read_value (gdbarch, arm_pseudo_read_value); - set_gdbarch_deprecated_pseudo_register_write (gdbarch, arm_pseudo_write); + set_gdbarch_pseudo_register_write (gdbarch, arm_pseudo_write); } /* Add standard register aliases. We add aliases even for those From patchwork Wed Nov 8 05:01:08 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Marchi X-Patchwork-Id: 79381 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 C82953858416 for ; Wed, 8 Nov 2023 05:19:03 +0000 (GMT) X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from smtp.polymtl.ca (smtp.polymtl.ca [132.207.4.11]) by sourceware.org (Postfix) with ESMTPS id 030763858D1E for ; Wed, 8 Nov 2023 05:18:46 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 030763858D1E Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=polymtl.ca Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=polymtl.ca ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 030763858D1E Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=132.207.4.11 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1699420730; cv=none; b=EOHTm74cXz7xno/OXuPW6VOz49YR7eWUqXNllcgEbahSeBFrRrUXdN9Yms3NMC6nQ0AUhKlPGpTbMs5Fpv1TFzDEQkWuXUiFr8bxohdSdfdCiOuBJmpJ0PL6n/4QZ7VXdE3RiB0Z0lfXjgcUSuUY/DKyIAhIiWxS6ZGg6n3BDMw= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1699420730; c=relaxed/simple; bh=PEgTJMWarRkcrwY0IkrvsdX0Odv5/Lr/e23ibUYQ/e0=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=XW+dAT66gPcrhq+jTcN3V1T4wCqAStsWHQsl8wFzMdZ+rJVXOt8q3XtB+KGhgsQ/DNLhddDJJhz5ioKgAsePiFXAHEG+F24cOcUK7TIJmgNJDR9yI3Y0iN7fw7SzxdnX3/wWWPXr93F5otRVvK05UHhS+4uDk3JKMXDPzCBu5ys= ARC-Authentication-Results: i=1; server2.sourceware.org Received: from simark.ca (simark.ca [158.69.221.121]) (authenticated bits=0) by smtp.polymtl.ca (8.14.7/8.14.7) with ESMTP id 3A85IfIM016407 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 8 Nov 2023 00:18:45 -0500 DKIM-Filter: OpenDKIM Filter v2.11.0 smtp.polymtl.ca 3A85IfIM016407 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=polymtl.ca; s=default; t=1699420726; bh=WioefiLTgybxG7zkp8OYOwPbcB3a8iWBphWJnq9S4Z0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=dA8IBDU6uQGeqqIcFHcIsJJwGL799xNycm0l3NDyRUznSUZpNl3jkiuxvE6WHvdEv 8vAx7fpw9LcNc+Gktk7LJr+QQxHVZDAdB/9xF5fS7feiineY69wJVZQSxLGebnoVRz 0pwRBMdPYEhm5EP19hBbT2SldplRlDa4MsJBoMEI= Received: from simark.localdomain (modemcable238.237-201-24.mc.videotron.ca [24.201.237.238]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) by simark.ca (Postfix) with ESMTPSA id 2A2B61E098; Wed, 8 Nov 2023 00:18:41 -0500 (EST) From: Simon Marchi To: gdb-patches@sourceware.org Cc: Simon Marchi Subject: [PATCH 24/24] gdb/testsuite: add tests for unwinding of pseudo registers Date: Wed, 8 Nov 2023 00:01:08 -0500 Message-ID: <20231108051222.1275306-25-simon.marchi@polymtl.ca> X-Mailer: git-send-email 2.42.1 In-Reply-To: <20231108051222.1275306-1-simon.marchi@polymtl.ca> References: <20231108051222.1275306-1-simon.marchi@polymtl.ca> MIME-Version: 1.0 X-Poly-FromMTA: (simark.ca [158.69.221.121]) at Wed, 8 Nov 2023 05:18:41 +0000 X-Spam-Status: No, score=-3188.6 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_PASS, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE 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.30 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org This patch adds tests to exercise the previous patches' changes. All three tests: - aarch64-pseudo-unwind - amd64-pseudo-unwind - arm-pseudo-unwind follow the same pattern, just with different registers. The other test, arm-pseudo-unwind-legacy, tests the special case where the unwind information contains an entry for a register considered a pseudo-register by GDB. Change-Id: Ic29ac040c5eb087b4a0d79f9d02f65b7979df30f --- .../gdb.arch/aarch64-pseudo-unwind-asm.S | 82 +++++++++++++++++ .../gdb.arch/aarch64-pseudo-unwind.c | 33 +++++++ .../gdb.arch/aarch64-pseudo-unwind.exp | 90 ++++++++++++++++++ .../gdb.arch/amd64-pseudo-unwind-asm.S | 66 ++++++++++++++ gdb/testsuite/gdb.arch/amd64-pseudo-unwind.c | 33 +++++++ .../gdb.arch/amd64-pseudo-unwind.exp | 91 +++++++++++++++++++ .../gdb.arch/arm-pseudo-unwind-asm.S | 81 +++++++++++++++++ .../gdb.arch/arm-pseudo-unwind-legacy-asm.S | 84 +++++++++++++++++ .../gdb.arch/arm-pseudo-unwind-legacy.c | 33 +++++++ .../gdb.arch/arm-pseudo-unwind-legacy.exp | 86 ++++++++++++++++++ gdb/testsuite/gdb.arch/arm-pseudo-unwind.c | 33 +++++++ gdb/testsuite/gdb.arch/arm-pseudo-unwind.exp | 88 ++++++++++++++++++ 12 files changed, 800 insertions(+) create mode 100644 gdb/testsuite/gdb.arch/aarch64-pseudo-unwind-asm.S create mode 100644 gdb/testsuite/gdb.arch/aarch64-pseudo-unwind.c create mode 100644 gdb/testsuite/gdb.arch/aarch64-pseudo-unwind.exp create mode 100644 gdb/testsuite/gdb.arch/amd64-pseudo-unwind-asm.S create mode 100644 gdb/testsuite/gdb.arch/amd64-pseudo-unwind.c create mode 100644 gdb/testsuite/gdb.arch/amd64-pseudo-unwind.exp create mode 100644 gdb/testsuite/gdb.arch/arm-pseudo-unwind-asm.S create mode 100644 gdb/testsuite/gdb.arch/arm-pseudo-unwind-legacy-asm.S create mode 100644 gdb/testsuite/gdb.arch/arm-pseudo-unwind-legacy.c create mode 100644 gdb/testsuite/gdb.arch/arm-pseudo-unwind-legacy.exp create mode 100644 gdb/testsuite/gdb.arch/arm-pseudo-unwind.c create mode 100644 gdb/testsuite/gdb.arch/arm-pseudo-unwind.exp diff --git a/gdb/testsuite/gdb.arch/aarch64-pseudo-unwind-asm.S b/gdb/testsuite/gdb.arch/aarch64-pseudo-unwind-asm.S new file mode 100644 index 000000000000..586642656296 --- /dev/null +++ b/gdb/testsuite/gdb.arch/aarch64-pseudo-unwind-asm.S @@ -0,0 +1,82 @@ +/* Copyright 2018-2023 Free Software Foundation, Inc. + + This file is part of GDB. + + 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 . */ + +.section .note.GNU-stack,"",%progbits + +.data +value_callee: +.quad 0x2021222324252627 +value_caller: +.quad 0x1011121314151617 + +.text +.global callee +callee: + /* Standard prologue: + - push fp (x29) and lr (x30) to the stack. + - mov sp to fp */ +.cfi_startproc + stp x29, x30, [sp, -16]! +.cfi_def_cfa 29, 16 +.cfi_offset 29, -16 +.cfi_offset 30, -8 + mov x29, sp + + /* Save caller's q8 value on the stack. */ +.cfi_offset 72, -32 + str q8, [sp, -16]! + + /* Put our own q8 value. */ + adr x0, value_callee + ld1 { v8.1d }, [x0] +break_here_asm: + + /* Restore caller's q8 value. */ + ldr q8, [sp], 16 + + /* Standard epilogue: + - pop fo (x29) and lr (x30) from the stack */ + ldp x29, x30, [sp], 16 + ret +.cfi_endproc + + +.global caller +caller: + /* Standard prologue. */ +.cfi_startproc + stp x29, x30, [sp, -16]! +.cfi_def_cfa 29, 16 +.cfi_offset x29, -16 +.cfi_offset x30, -8 + add x29, sp, 0 + + /* Put our own q8 value. */ + adr x0, value_caller + ld1 { v8.1d }, [x0] + + /* Call callee. */ + bl callee + + /* Store our q8 value in x0 to return it. */ + str q8, [sp, -16]! + ldr x0, [sp], 16 + + /* Standard epilogue. */ + ldp x29, x30, [sp], 16 + ret +.cfi_endproc diff --git a/gdb/testsuite/gdb.arch/aarch64-pseudo-unwind.c b/gdb/testsuite/gdb.arch/aarch64-pseudo-unwind.c new file mode 100644 index 000000000000..d18876fe3be3 --- /dev/null +++ b/gdb/testsuite/gdb.arch/aarch64-pseudo-unwind.c @@ -0,0 +1,33 @@ +/* Copyright 2018-2023 Free Software Foundation, Inc. + + This file is part of GDB. + + 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 . */ + +#include + +uint64_t caller (void); + +static void +break_here_c (uint64_t value) +{ +} + +int +main (void) +{ + uint64_t value = caller (); + break_here_c (value); + return 0; +} diff --git a/gdb/testsuite/gdb.arch/aarch64-pseudo-unwind.exp b/gdb/testsuite/gdb.arch/aarch64-pseudo-unwind.exp new file mode 100644 index 000000000000..685bebc9df1f --- /dev/null +++ b/gdb/testsuite/gdb.arch/aarch64-pseudo-unwind.exp @@ -0,0 +1,90 @@ +# Copyright 2018-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 . + +# This test is equivalent to amd64-pseudo-unwind, but specific to AArch64. We +# use the raw register v8/q8 (it's the same register, but referred to differently +# depending on the instruction) which is 128 bits long (although we only load +# a 64-bits value, it's enough for the test). We use pseudo register s8, which +# is the low 32-bits of v8/q8. + +if { ![istarget aarch64-*-* ] } { + verbose "Skipping aarch64 pseudo register unwind." + return +} + +standard_testfile aarch64-pseudo-unwind.c aarch64-pseudo-unwind-asm.S + +if { [prepare_for_testing "failed to prepare" ${testfile} \ + "${srcfile} ${srcfile2}" {debug}] } { + return -1 +} + +clean_restart ${binfile} + +if ![runto_main] then { + fail "could not run to main" +} + +gdb_breakpoint break_here_asm temporary +gdb_continue_to_breakpoint "continue to callee" + +# Verify the value of v8/s8 in the inner frame (callee). +with_test_prefix "callee, before change" { + gdb_test "p/x \$v8.q.u" " = \\{0x2021222324252627\\}" + gdb_test "p/x \$s8.u" " = 0x24252627" +} + +# Verify that we can change the value of the pseudo register (s8) in the inner +# frame (callee). +gdb_test_no_output "set \$s8.u = 0x34353637" + +# Verify the value of v8/s8 in the inner frame (callee) after the change. +with_test_prefix "callee, after change" { + gdb_test "p/x \$v8.q.u" " = \\{0x34353637\\}" + gdb_test "p/x \$s8.u" " = 0x34353637" +} + +# Go up one frame (to caller) and do the same. +gdb_test "up" + +# Verify the value of v8/s8 in the outer frame (caller). +with_test_prefix "caller, before change" { + gdb_test "p/x \$v8.q.u" " = \\{0x1011121314151617\\}" + gdb_test "p/x \$s8.u" " = 0x14151617" +} + +# Verify that we can change the value of the pseudo register (s8) in the outer +# frame (caller). +gdb_test_no_output "set \$s8.u = 0x44454647" + +# Verify the value of v8/s8 in the outer frame (caller) after the change. +with_test_prefix "caller, after change" { + gdb_test "p/x \$v8.q.u" " = \\{0x44454647\\}" + gdb_test "p/x \$s8.u" " = 0x44454647" +} + +# Go back to frame 0 (callee), check that the change to the outer frame didn't +# mess up anything there. +gdb_test "down" +with_test_prefix "callee, after change in caller" { + gdb_test "p/x \$v8.q.u" " = \\{0x34353637\\}" + gdb_test "p/x \$s8.u" " = 0x34353637" +} + +# Verify that the value of the saved v8 we changed is correctly seen by the +# inferior. +gdb_breakpoint break_here_c temporary +gdb_continue_to_breakpoint "continue to break_here_c" +gdb_test "p/x value" " = 0x44454647" diff --git a/gdb/testsuite/gdb.arch/amd64-pseudo-unwind-asm.S b/gdb/testsuite/gdb.arch/amd64-pseudo-unwind-asm.S new file mode 100644 index 000000000000..c306b82e4864 --- /dev/null +++ b/gdb/testsuite/gdb.arch/amd64-pseudo-unwind-asm.S @@ -0,0 +1,66 @@ +/* Copyright 2018-2023 Free Software Foundation, Inc. + + This file is part of GDB. + + 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 . */ + +.section .note.GNU-stack,"",%progbits + +.text +.global callee +callee: + /* Standard prologue. */ +.cfi_startproc + push %rbp +.cfi_def_cfa rbp, 16 + mov %rsp, %rbp + + /* Save caller's rbx value on the stack. */ +.cfi_offset rbx, -24 + push %rbx + + /* Put our own rbx value. */ + mov $0x2021222324252627, %rbx +break_here_asm: + + /* Restore caller's rbx value. */ + pop %rbx + + /* Standard epilogue. */ + pop %rbp + ret +.cfi_endproc + + +.global caller +caller: +.cfi_startproc + /* Standard prologue. */ + push %rbp +.cfi_def_cfa_offset 16 + mov %rsp, %rbp + + /* Put our own rbx value. */ + mov $0x1011121314151617, %rbx + + /* Call callee. */ + call callee + + /* Store our rbx value in rax to return it. */ + mov %rbx, %rax + + /* Standard epilogue. */ + pop %rbp + ret +.cfi_endproc diff --git a/gdb/testsuite/gdb.arch/amd64-pseudo-unwind.c b/gdb/testsuite/gdb.arch/amd64-pseudo-unwind.c new file mode 100644 index 000000000000..d18876fe3be3 --- /dev/null +++ b/gdb/testsuite/gdb.arch/amd64-pseudo-unwind.c @@ -0,0 +1,33 @@ +/* Copyright 2018-2023 Free Software Foundation, Inc. + + This file is part of GDB. + + 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 . */ + +#include + +uint64_t caller (void); + +static void +break_here_c (uint64_t value) +{ +} + +int +main (void) +{ + uint64_t value = caller (); + break_here_c (value); + return 0; +} diff --git a/gdb/testsuite/gdb.arch/amd64-pseudo-unwind.exp b/gdb/testsuite/gdb.arch/amd64-pseudo-unwind.exp new file mode 100644 index 000000000000..45e9a3c96224 --- /dev/null +++ b/gdb/testsuite/gdb.arch/amd64-pseudo-unwind.exp @@ -0,0 +1,91 @@ +# Copyright 2018-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 . + +# This test verifies that we can read and write the value of a pseudo register +# in unwound frames. For the test, we choose one raw register, rbx, and one +# pseudo register that is backed by rbx, ebx. We have two frames (the inner one, +# #0 and the outer one, #1) that each set a value for rbx. We verify that we +# can read both rbx and ebx correctly for each frame, and that when we write to +# ebx, rbx for that frame is correctly updated. + +if { ![istarget x86_64-*-* ] || ![is_lp64_target] } { + verbose "Skipping amd64 pseudo register unwind." + return +} + +standard_testfile amd64-pseudo-unwind.c amd64-pseudo-unwind-asm.S + +if { [prepare_for_testing "failed to prepare" ${testfile} \ + "${srcfile} ${srcfile2}" {debug}] } { + return -1 +} + +clean_restart ${binfile} + +if ![runto_main] then { + fail "could not run to main" +} + +gdb_breakpoint break_here_asm temporary +gdb_continue_to_breakpoint "continue to callee" + +# Verify the value of rbx/ebx in the inner frame (callee). +with_test_prefix "callee, before change" { + gdb_test "p/x \$rbx" " = 0x2021222324252627" + gdb_test "p/x \$ebx" " = 0x24252627" +} + +# Verify that we can change the value of the pseudo register (ebx) in the inner +# frame (callee). +gdb_test_no_output "set \$ebx = 0x34353637" + +# Verify the value of rbx/ebx in the inner frame (callee) after the change. +with_test_prefix "callee, after change" { + gdb_test "p/x \$rbx" " = 0x2021222334353637" + gdb_test "p/x \$ebx" " = 0x34353637" +} + +# Go up one frame, and do the same. +gdb_test "up" + +# Verify the value of rbx/ebx in the outer frame (caller). +with_test_prefix "caller, before change" { + gdb_test "p/x \$rbx" " = 0x1011121314151617" + gdb_test "p/x \$ebx" " = 0x14151617" +} + +# Verify that we can change the value of the pseudo register (ebx) in the outer +# frame (caller). +gdb_test_no_output "set \$ebx = 0x44454647" + +# Verify the value of rbx/ebx in the outer frame (caller) after the change. +with_test_prefix "caller, after change" { + gdb_test "p/x \$rbx" " = 0x1011121344454647" + gdb_test "p/x \$ebx" " = 0x44454647" +} + +# Go back to frame 0 (callee), check that the change to the outer frame didn't +# mess up anything there. +gdb_test "down" +with_test_prefix "callee, after change in caller" { + gdb_test "p/x \$rbx" " = 0x2021222334353637" + gdb_test "p/x \$ebx" " = 0x34353637" +} + +# Verify that the value of the saved rbx we changed is correctly seen by the +# inferior. +gdb_breakpoint break_here_c temporary +gdb_continue_to_breakpoint "continue to break_here_c" +gdb_test "p/x value" " = 0x1011121344454647" diff --git a/gdb/testsuite/gdb.arch/arm-pseudo-unwind-asm.S b/gdb/testsuite/gdb.arch/arm-pseudo-unwind-asm.S new file mode 100644 index 000000000000..8d78573cefe4 --- /dev/null +++ b/gdb/testsuite/gdb.arch/arm-pseudo-unwind-asm.S @@ -0,0 +1,81 @@ +/* Copyright 2018-2023 Free Software Foundation, Inc. + + This file is part of GDB. + + 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 . */ + +.section .note.GNU-stack,"",%progbits + +.data +value_callee: +.quad 0x2021222324252627 +value_caller: +.quad 0x1011121314151617 + +.text +.arm +.global callee +callee: + /* Standard prologue. */ +.cfi_startproc + push {fp, lr} +.cfi_def_cfa fp, 4 +.cfi_offset fp, -8 +.cfi_offset lr, -4 + add fp, sp, #4 + + /* Save caller's d8 value on the stack. */ +.cfi_offset d8, -16 + vpush {d8} + + /* Put our own d8 value. */ + ldr r0, =value_callee + vldr d8, [r0] +break_here_asm: + + /* Restore caller's d8 value. */ + vpop {d8} + + /* Standard epilogue. */ + pop {fp, pc} +.cfi_endproc + + +.global caller +caller: + /* Standard prologue. */ +.cfi_startproc + push {fp, lr} +.cfi_def_cfa fp, 4 +.cfi_offset fp, -8 +.cfi_offset lr, -4 + add fp, sp, #4 + + /* Put our own d8 value. */ + ldr r0, =value_caller + vldr d8, [r0] + + /* Call callee. */ + bl callee + + /* Store our d8 value in r0-r1 to return it. */ + vpush {d8} + pop {r0} + pop {r1} + + /* Standard epilogue. */ + pop {fp, pc} +.cfi_endproc + + diff --git a/gdb/testsuite/gdb.arch/arm-pseudo-unwind-legacy-asm.S b/gdb/testsuite/gdb.arch/arm-pseudo-unwind-legacy-asm.S new file mode 100644 index 000000000000..786e79a0543e --- /dev/null +++ b/gdb/testsuite/gdb.arch/arm-pseudo-unwind-legacy-asm.S @@ -0,0 +1,84 @@ +/* Copyright 2018-2023 Free Software Foundation, Inc. + + This file is part of GDB. + + 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 . */ + +/* The difference between this and arm-pseudo-unwind is that here, the CFI + directives use the obsolete DWARF number for the s16 register (a + pseudo-register in GDB), whereas arm-pseudo-unwind uses the number for the d8 + register (the underlying raw register for s16). */ + +.section .note.GNU-stack,"",%progbits + +.data +value_callee: +.quad 0x20212223 +value_caller: +.quad 0x10111213 + +.text +.arm +.global callee +callee: +.cfi_startproc + /* Standard prologue. */ + push {fp, lr} +.cfi_def_cfa fp, 4 +.cfi_offset fp, -8 +.cfi_offset lr, -4 + add fp, sp, #4 + + /* Save caller's s16 value on the stack. */ +.cfi_offset 80, -12 + vpush {s16} + + /* Put our own s16 value. */ + ldr r0, =value_callee + vldr s16, [r0] +break_here_asm: + + /* Restore caller's s16 value. */ + vpop {s16} + + /* Standard epilogue. */ + pop {fp, pc} +.cfi_endproc + + +.global caller +caller: +.cfi_startproc + /* Standard prologue. */ + push {fp, lr} +.cfi_def_cfa fp, 4 +.cfi_offset fp, -8 +.cfi_offset lr, -4 + add fp, sp, #4 + + /* Put our own s16 value. */ + ldr r0, =value_caller + vldr s16, [r0] + + /* Call callee. */ + bl callee + + /* Store our s16 value in r0-r1 to return it. */ + vpush {s16} + pop {r0} + mov r1, #0 + + /* Standard epilogue. */ + pop {fp, pc} +.cfi_endproc diff --git a/gdb/testsuite/gdb.arch/arm-pseudo-unwind-legacy.c b/gdb/testsuite/gdb.arch/arm-pseudo-unwind-legacy.c new file mode 100644 index 000000000000..d18876fe3be3 --- /dev/null +++ b/gdb/testsuite/gdb.arch/arm-pseudo-unwind-legacy.c @@ -0,0 +1,33 @@ +/* Copyright 2018-2023 Free Software Foundation, Inc. + + This file is part of GDB. + + 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 . */ + +#include + +uint64_t caller (void); + +static void +break_here_c (uint64_t value) +{ +} + +int +main (void) +{ + uint64_t value = caller (); + break_here_c (value); + return 0; +} diff --git a/gdb/testsuite/gdb.arch/arm-pseudo-unwind-legacy.exp b/gdb/testsuite/gdb.arch/arm-pseudo-unwind-legacy.exp new file mode 100644 index 000000000000..c3d0979799dc --- /dev/null +++ b/gdb/testsuite/gdb.arch/arm-pseudo-unwind-legacy.exp @@ -0,0 +1,86 @@ +# Copyright 2018-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 . + +# This test is in the same vein as amd64-pseudo-unwind, making sure we can +# read write pseudo registers in outer frames. However, it tests a special +# case where the debug info includes unwind information for a pseudo register +# but not the underlying raw register. This can happen for the pseudo register +# s16, which is the bottom half of the raw register d8. +# +# See "DWARF for the ARM architecture": +# https://github.com/ARM-software/abi-aa/releases/download/2023Q3/aadwarf32.pdf + +if { ![istarget arm*-*-* ] } { + verbose "Skipping arm pseudo register unwind." + return +} + +standard_testfile arm-pseudo-unwind-legacy.c arm-pseudo-unwind-legacy-asm.S + +if { [prepare_for_testing "failed to prepare" ${testfile} \ + "${srcfile} ${srcfile2}" {debug additional_flags=-marm}] } { + return -1 +} + +clean_restart ${binfile} + +if ![runto_main] then { + fail "could not run to main" +} + +gdb_breakpoint break_here_asm temporary +gdb_continue_to_breakpoint "continue to callee" + +# Verify the value of s16 in the inner frame (callee). +with_test_prefix "callee, before change" { + gdb_test "p/x \$s16" " = 0x20212223" +} + +# Verify that we can change the value of s16 in the inner frame (callee). +gdb_test_no_output "set \$s16 = 1.0" + +# Verify the value of s16 in the inner frame (callee) after the change. +with_test_prefix "callee, after change" { + gdb_test "p/x \$s16" " = 0x3f800000" +} + +# Go up one frame, and do the same. +gdb_test "up" + +# Verify the value of s16 in the outer frame (caller). +with_test_prefix "caller, before change" { + gdb_test "p/x \$s16" " = 0x10111213" +} + +# Verify that we can change the value of s16 in the outer frame (caller). +gdb_test_no_output "set \$s16 = 2.0" + +# Verify the value of s16 in the outer frame (caller) after the change. +with_test_prefix "caller, after change" { + gdb_test "p/x \$s16" " = 0x40000000" +} + +# Go back to frame 0 (callee), check that the change to the outer frame didn't +# mess up anything there. +gdb_test "down" +with_test_prefix "callee, after change in caller" { + gdb_test "p/x \$s16" " = 0x3f800000" +} + +# Verify that the value of the saved s16 we changed is correctly seen by the +# inferior. +gdb_breakpoint break_here_c temporary +gdb_continue_to_breakpoint "continue to break_here_c" +gdb_test "p/x value" " = 0x40000000" diff --git a/gdb/testsuite/gdb.arch/arm-pseudo-unwind.c b/gdb/testsuite/gdb.arch/arm-pseudo-unwind.c new file mode 100644 index 000000000000..d18876fe3be3 --- /dev/null +++ b/gdb/testsuite/gdb.arch/arm-pseudo-unwind.c @@ -0,0 +1,33 @@ +/* Copyright 2018-2023 Free Software Foundation, Inc. + + This file is part of GDB. + + 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 . */ + +#include + +uint64_t caller (void); + +static void +break_here_c (uint64_t value) +{ +} + +int +main (void) +{ + uint64_t value = caller (); + break_here_c (value); + return 0; +} diff --git a/gdb/testsuite/gdb.arch/arm-pseudo-unwind.exp b/gdb/testsuite/gdb.arch/arm-pseudo-unwind.exp new file mode 100644 index 000000000000..bfe81b7d5f21 --- /dev/null +++ b/gdb/testsuite/gdb.arch/arm-pseudo-unwind.exp @@ -0,0 +1,88 @@ +# Copyright 2018-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 . + +# This test is equivalent to amd64-pseudo-unwind, but specific to ARM. We +# use the raw register d8 which is 64 bits long. We use pseudo register s16, +# which is the low 32 bits of d8. + +if { ![istarget arm*-*-* ] } { + verbose "Skipping arm pseudo register unwind." + return +} + +standard_testfile arm-pseudo-unwind.c arm-pseudo-unwind-asm.S + +if { [prepare_for_testing "failed to prepare" ${testfile} \ + "${srcfile} ${srcfile2}" {debug additional_flags=-marm}] } { + return -1 +} + +clean_restart ${binfile} + +if ![runto_main] then { + fail "could not run to main" +} + +gdb_breakpoint break_here_asm temporary +gdb_continue_to_breakpoint "continue to callee" + +# Verify the value of d8/s16 in the inner frame (callee). +with_test_prefix "callee, before change" { + gdb_test "p/x \$d8" " = 0x2021222324252627" + gdb_test "p/x \$s16" " = 0x24252627" +} + +# Verify that we can change the value of the pseudo register (s16) in the inner +# frame (callee). +gdb_test_no_output "set \$s16 = 1.0" + +# Verify the value of d8/s16 in the inner frame (callee) after the change. +with_test_prefix "callee, after change" { + gdb_test "p/x \$d8" " = 0x202122233f800000" + gdb_test "p/x \$s16" " = 0x3f800000" +} + +# Go up one frame (to caller), and do the same. +gdb_test "up" + +# Verify the value of d8/s16 in the outer frame (caller). +with_test_prefix "caller, before change" { + gdb_test "p/x \$d8" " = 0x1011121314151617" + gdb_test "p/x \$s16" " = 0x14151617" +} + +# Verify that we can change the value of the pseudo register (s16) in the outer +# frame (caller). +gdb_test_no_output "set \$s16 = 2.0" + +# Verify the value of d8/s16 in the outer frame (caller) after the change. +with_test_prefix "caller, after change" { + gdb_test "p/x \$d8" " = 0x1011121340000000" + gdb_test "p/x \$s16" " = 0x40000000" +} + +# Go back to frame 0 (callee), check that the change to the outer frame didn't +# mess up anything there. +gdb_test "down" +with_test_prefix "callee, after change in caller" { + gdb_test "p/x \$d8" " = 0x202122233f800000" + gdb_test "p/x \$s16" " = 0x3f800000" +} + +# Verify that the value of the saved d8 we changed is correctly seen by the +# inferior. +gdb_breakpoint break_here_c temporary +gdb_continue_to_breakpoint "continue to break_here_c" +gdb_test "p/x value" " = 0x1011121340000000"