From patchwork Fri Dec 1 16:27:31 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Marchi X-Patchwork-Id: 81153 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 AFD28384F9AF for ; Fri, 1 Dec 2023 16:32:35 +0000 (GMT) X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from simark.ca (simark.ca [158.69.221.121]) by sourceware.org (Postfix) with ESMTPS id D9AEB386101B for ; Fri, 1 Dec 2023 16:31:59 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org D9AEB386101B Authentication-Results: sourceware.org; dmarc=fail (p=none dis=none) header.from=efficios.com Authentication-Results: sourceware.org; spf=fail smtp.mailfrom=efficios.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org D9AEB386101B Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=158.69.221.121 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1701448322; cv=none; b=MMeb8DKnmNll7wyxYsxwOjlumfJ8Fol5HSMTTYKfe2IuNHiKEzlowIZ+4z80dqOg2Uvt8x0EfYq/C0QW4+qlqUmPW5cHp6rrT3/S8DU7OPBH7gaUxwQYmYIDBIj5I5Iccu0hreeVmTZ3pvhdLrT6woB9aaXjdps6m7x0ZNrEj8s= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1701448322; c=relaxed/simple; bh=fSuD6VIy+SnFgKfhT6lMgxXkAsJmrfkRiJPGl6SLxj8=; h=From:To:Subject:Date:Message-ID:MIME-Version; b=eB5/GIluQyLkltN1TaBUhkEBevrMSlinsd67Fi5HaJOovItIsq70nzhDF47crGEoMalcxclVakuVba/ifjYBud0wL3DsfDibE3JsDTnAw/W6bqV87/6Agcvo7HUxk9e64m+nxsvX4jhkuV2nKTA/Lk9m+xH8eBK9Us4/uTupcLE= ARC-Authentication-Results: i=1; server2.sourceware.org Received: from smarchi-efficios.internal.efficios.com (192-222-143-198.qc.cable.ebox.net [192.222.143.198]) (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 270A31E0C0; Fri, 1 Dec 2023 11:31:59 -0500 (EST) From: Simon Marchi To: gdb-patches@sourceware.org Cc: Luis Machado , John Baldwin , "Aktemur, Tankut Baris" , Simon Marchi , John Baldwin Subject: [PATCH 18/24] gdb: migrate i386 and amd64 to the new gdbarch_pseudo_register_write Date: Fri, 1 Dec 2023 11:27:31 -0500 Message-ID: <20231201162751.741751-19-simon.marchi@efficios.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20231201162751.741751-1-simon.marchi@efficios.com> References: <20231201162751.741751-1-simon.marchi@efficios.com> MIME-Version: 1.0 X-Spam-Status: No, score=-3496.6 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_NONE, KAM_DMARC_STATUS, SPF_HELO_PASS, SPF_SOFTFAIL, 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 New in v2: - Move some changes from here to the previous patch (where they belong) 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 Reviewed-By: John Baldwin --- gdb/amd64-tdep.c | 39 +++---------- gdb/i386-tdep.c | 146 +++++++++++++++++------------------------------ gdb/i386-tdep.h | 6 +- 3 files changed, 61 insertions(+), 130 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 228b390245f6..d5602917aa8c 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")); @@ -8678,8 +8635,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,