From patchwork Mon Jan 13 15:56:56 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tom de Vries X-Patchwork-Id: 104697 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 38FBA3857707 for ; Mon, 13 Jan 2025 15:58:36 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 38FBA3857707 Authentication-Results: sourceware.org; dkim=pass (1024-bit key, unprotected) header.d=suse.de header.i=@suse.de header.a=rsa-sha256 header.s=susede2_rsa header.b=unDV3r9N; dkim=pass header.d=suse.de header.i=@suse.de header.a=ed25519-sha256 header.s=susede2_ed25519 header.b=6vtLPTQi; dkim=pass (1024-bit key) header.d=suse.de header.i=@suse.de header.a=rsa-sha256 header.s=susede2_rsa header.b=Aa7Qv5Ay; dkim=neutral header.d=suse.de header.i=@suse.de header.a=ed25519-sha256 header.s=susede2_ed25519 header.b=3M3fqmAV X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from smtp-out1.suse.de (smtp-out1.suse.de [IPv6:2a07:de40:b251:101:10:150:64:1]) by sourceware.org (Postfix) with ESMTPS id 1DBBC3858D21 for ; Mon, 13 Jan 2025 15:57:02 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 1DBBC3858D21 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=suse.de Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=suse.de ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 1DBBC3858D21 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2a07:de40:b251:101:10:150:64:1 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1736783822; cv=none; b=MMilCzOy8YaQq/Ln4/yG8GbdT4KIkgQ27hag6Hq/jBzkzGhZb9bUlhNo3HseUKYWRwl6OJCRnre2YoZDKACzSGf2bVN8XGRe9FrhdVzUXXnV6pI7jLeidflUiL0YBBPCG5hWm62oR+EH+kxcAK54hQMJP1Zt3Mkzbr+05xVCPYo= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1736783822; c=relaxed/simple; bh=IqTdB0ltVkAnnGzXvceUqRP7bg6/yyjpgN3+90nj2uk=; h=DKIM-Signature:DKIM-Signature:DKIM-Signature:DKIM-Signature:From: To:Subject:Date:Message-ID:MIME-Version; b=xnXymt0BefivJsmn4SPPncRSL8WdAvv3F5O+OzwFypvrVaNM2oZ6b3zsqegKBxF5M80znRKqWPJShmWSxvXQA4wovR+GvF+QxugsDTuOyRW854JoIJB+wDTX3fvXTOXdsJ8uce29piJTz1RQe9VVAf/vH4vvzDywXsBAv4w57f0= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 1DBBC3858D21 Received: from imap1.dmz-prg2.suse.org (unknown [10.150.64.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by smtp-out1.suse.de (Postfix) with ESMTPS id D50522115C for ; Mon, 13 Jan 2025 15:57:00 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1736783821; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding; bh=+Gf82eLSkCVmdc9HeUqXjklxb/dSTFA6k3atA6Gn6BU=; b=unDV3r9Na3+D2/Uo+jQV4++ls2EFeT8b8RPDFp0c1mAAd+mo7yGTJkq8ma4TnjjwrlZo2T +CZlPgS8xQwi3TeBKZUPw711nzV8OSCCk5JjBm4bJU9oWJyPO2himMRuP/3bT8jLfntKZe 5cgLqR28xI8mT24HqKGWD4soIUQmNvM= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1736783821; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding; bh=+Gf82eLSkCVmdc9HeUqXjklxb/dSTFA6k3atA6Gn6BU=; b=6vtLPTQiDeMyVPIKK6nfN7neq6M4/eICc1/tAJCItdAO/miCQz/sDQEBAQX0rPTWdEObE6 /3hZAdDJ/HovreAA== Authentication-Results: smtp-out1.suse.de; none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1736783820; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding; bh=+Gf82eLSkCVmdc9HeUqXjklxb/dSTFA6k3atA6Gn6BU=; b=Aa7Qv5AyemhqEEQ1/H4O9ARkjxc3c1KflJPOt6rSTlcs0TF28jOtG1850HSYM2j4kX32x+ g1U1UH8aV6mEfBpTLrDFcYmwq8k3DhWzOyS517wu03TvLyf/IoYsyiCcdVI7m5UZmvvHZp 5Bx5m0APtJCKdDbQ6kLsXOVSVgkdzgw= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1736783820; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding; bh=+Gf82eLSkCVmdc9HeUqXjklxb/dSTFA6k3atA6Gn6BU=; b=3M3fqmAVi3iDKHSc4gj18Ctdzr22WosRy5O1mWq3kBfvW91ddRDYgwxPxD1oAASWCidhad iaZoxOgee0UjecDw== Received: from imap1.dmz-prg2.suse.org (localhost [127.0.0.1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by imap1.dmz-prg2.suse.org (Postfix) with ESMTPS id BD20A13310 for ; Mon, 13 Jan 2025 15:57:00 +0000 (UTC) Received: from dovecot-director2.suse.de ([2a07:de40:b281:106:10:150:64:167]) by imap1.dmz-prg2.suse.org with ESMTPSA id Tzu3LMw3hWdaVwAAD6G6ig (envelope-from ) for ; Mon, 13 Jan 2025 15:57:00 +0000 From: Tom de Vries To: gdb-patches@sourceware.org Subject: [PATCH] [gdb] Fix gdb.base/return.exp on s390x-linux Date: Mon, 13 Jan 2025 16:56:56 +0100 Message-ID: <20250113155656.11978-1-tdevries@suse.de> X-Mailer: git-send-email 2.43.0 MIME-Version: 1.0 X-Spam-Level: X-Spamd-Result: default: False [-2.80 / 50.00]; BAYES_HAM(-3.00)[99.99%]; MID_CONTAINS_FROM(1.00)[]; NEURAL_HAM_LONG(-1.00)[-1.000]; R_MISSING_CHARSET(0.50)[]; NEURAL_HAM_SHORT(-0.20)[-1.000]; MIME_GOOD(-0.10)[text/plain]; TO_DN_NONE(0.00)[]; FUZZY_BLOCKED(0.00)[rspamd.com]; DKIM_SIGNED(0.00)[suse.de:s=susede2_rsa,suse.de:s=susede2_ed25519]; ARC_NA(0.00)[]; RCPT_COUNT_ONE(0.00)[1]; TO_MATCH_ENVRCPT_ALL(0.00)[]; RCVD_COUNT_TWO(0.00)[2]; FROM_HAS_DN(0.00)[]; RCVD_TLS_ALL(0.00)[]; PREVIOUSLY_DELIVERED(0.00)[gdb-patches@sourceware.org]; FROM_EQ_ENVFROM(0.00)[]; RCVD_VIA_SMTP_AUTH(0.00)[]; MIME_TRACE(0.00)[0:+]; DBL_BLOCKED_OPENRESOLVER(0.00)[imap1.dmz-prg2.suse.org:helo] X-Spam-Score: -2.80 X-Spam-Status: No, score=-12.4 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.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 Starting commit 7fcdec025c0 ("GDB: Use gdb::array_view for buffers used in register reading and unwinding"), test-case gdb.base/return.exp fails on s390x-linux like this: ... (gdb) PASS: gdb.base/return.exp: continue to return of -5 return 5^M Make func2 return now? (y or n) y^M gdb/frame.c:1207: internal-error: frame_register_unwind: \ Assertion `buffer.size () >= value->type ()->length ()' failed.^M ... This happens as follows. Function frame_register_unwind is called with regnum 13 (r11). The value of r11 was saved in register f0 in the prologue: ... ldgr %f0,%r11 ... and the CFI tells us so: ... DW_CFA_register: r11 in r16 (f0) ... or more precisely, it tells us that r11 was saved in DWARF register 16. The s390x ABI specifies that DWARF register 16 maps onto either 8-byte register f0 or 16-byte register v0 (where f0 is part of v0), and s390_dwarf_reg_to_regnum maps DWARF register 16 to v0, if available. So this bit in frame_register_unwind: ... value = frame_unwind_register_value (next_frame, regnum); ... ends up returning the 16-byte value of v0. Before the aforementioned commit, this memcpy would be triggered: ... memcpy (bufferp, value->contents_all ().data (), value->type ()->length ()); ... which would: - copy the correct info into the 8 bytes buffer (sort of by accident because it assumes that value->offset () == 0, which happens to be the case), but also - write past the end of the buffer. The commit adds an assert that prevents writing past the end of the buffer, and consequently it triggers. Fix this by only considering the portion of the value required to fill the buffer. Tested on s390x-linux. --- gdb/frame.c | 47 ++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 40 insertions(+), 7 deletions(-) base-commit: 127f733f88717bdb52f03c12c0c2d240bbc892e3 diff --git a/gdb/frame.c b/gdb/frame.c index 10a32dcd896..da00cbd5d1d 100644 --- a/gdb/frame.c +++ b/gdb/frame.c @@ -1193,8 +1193,39 @@ frame_register_unwind (const frame_info_ptr &next_frame, int regnum, gdb_assert (value != NULL); - *optimizedp = value->optimized_out (); - *unavailablep = !value->entirely_available (); + /* The s390x ABI specifies that DWARF register 16 maps onto either + 8-byte register f0 or 16-byte register v0 (where f0 is part of v0), and + s390_dwarf_reg_to_regnum maps DWARF register 16 to v0, if available. + + So, if a function saves register r11 in the prologue to register f0: + + ldgr %f0,%r11 + + then it's represented like this in the CFI: + + DW_CFA_register: r11 in r16 (f0) + + and unwinding 8-byte register r11 gets us the value of 16-byte register + v0. + + Handle this by not considering more bytes than fit in the buffer. + + Then there's i386_unwind_pc which passes an 8-byte buffer, while the + register may be either 8-byte (for x86_64) or 4-byte (for i386). + + Handle this by not considering more bytes than are provided in the + value. */ + size_t copy_len = std::min (buffer.size (), + value->type ()->length () - value->offset ()); + + if (value->lazy ()) + value->fetch_lazy (); + *optimizedp + = value->bits_any_optimized_out (value->offset () * 8, + copy_len * 8); + *unavailablep + = !value->bytes_available (value->offset (), copy_len); + *lvalp = value->lval (); *addrp = value->address (); if (*lvalp == lval_register) @@ -1204,13 +1235,15 @@ frame_register_unwind (const frame_info_ptr &next_frame, int regnum, if (!buffer.empty ()) { - gdb_assert (buffer.size () >= value->type ()->length ()); - if (!*optimizedp && !*unavailablep) - memcpy (buffer.data (), value->contents_all ().data (), - value->type ()->length ()); + { + auto value_part + = value->contents_all ().slice (value->offset (), copy_len); + + memcpy (buffer.data (), value_part.data (), copy_len); + } else - memset (buffer.data (), 0, value->type ()->length ()); + memset (buffer.data (), 0, copy_len); } /* Dispose of the new value. This prevents watchpoints from