From patchwork Tue Nov 28 22:36:10 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ilya Leoshkevich X-Patchwork-Id: 80947 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 50C8A385B530 for ; Tue, 28 Nov 2023 22:40:56 +0000 (GMT) X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from mx0a-001b2d01.pphosted.com (mx0a-001b2d01.pphosted.com [148.163.156.1]) by sourceware.org (Postfix) with ESMTPS id 8324F3858409 for ; Tue, 28 Nov 2023 22:40:39 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 8324F3858409 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=linux.ibm.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=linux.ibm.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 8324F3858409 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=148.163.156.1 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1701211242; cv=none; b=Xx9lkS5bpN/r5SMX8Ug24HqUl86e5atn9oWVUN7RlVSzQRUMCjYUzg+TGp0hgkjfhvYdVI5sQ4Hfzy9/IhqZStcoxHtcJ7L7vBiRO9Hhrnl9OXbKLJDeB9/vjgyfKBsVIkUVNne8SIG+mqC8CLGdgY828uNeOoCwK80nJ6Nw9FM= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1701211242; c=relaxed/simple; bh=28YvA4f4zFO27QVm/jwF5TWNx9OBXEZOHsVXbubR1Y4=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=X5z3hob+epgLi0pKtBsR+/FguVX4tt6MQlyKvkdexeJjSvdgfPOUQFFOphOLwmYlLF8cAigr0Ckfxe3A70q/JjFPxzcSbEHTkYqIWJnuTMu0L7Zgpgg19NxYmeXo+nnCDZOIDkh7+A7liu8A2Bc0HsHdo073j4+38e86jyLYCGg= ARC-Authentication-Results: i=1; server2.sourceware.org Received: from pps.filterd (m0360083.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 3ASLjZuZ020538; Tue, 28 Nov 2023 22:40:36 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=from : to : cc : subject : date : message-id : content-transfer-encoding : mime-version; s=pp1; bh=ZU9Vle2bMwGkRZ7eHcnP0A3TIeS5dfFptuGvd9XM/jA=; b=nGjAytaj57UikcpBg+HAeJqCpGM7NHM3WDcaW6Hj3ZqxMz9Bf6dOemKuJWdrUDIUNC1q 7UMOyFcjk3qrgbNM+mc0TxpNbzjbKVBQth7f9no9/RG9U8yq7nBWdJEDhcrVRIxtiub5 uA+aWBYpMsiqELT20MG0ZlvHonoHZqpffmPz1UyRjs6C8y2I652VOBgZVXNl8DZVwLqa sGkTo2jWeruOo2xiHn1KKevim6DPDgfzu77fEvMahwjnGJvlkz7fDzxYAp9/kz6MyMKJ ZBoBt2bj47G9tYlUTEZ/rgz/PdpycTNqG3xbCnKX1e1jSfalyzxYiTRE4O/0FrbPPRO7 Og== Received: from pps.reinject (localhost [127.0.0.1]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 3unnn26129-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 28 Nov 2023 22:40:35 +0000 Received: from m0360083.ppops.net (m0360083.ppops.net [127.0.0.1]) by pps.reinject (8.17.1.5/8.17.1.5) with ESMTP id 3ASMeRSq014294; Tue, 28 Nov 2023 22:40:35 GMT Received: from ppma21.wdc07v.mail.ibm.com (5b.69.3da9.ip4.static.sl-reverse.com [169.61.105.91]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 3unnn260j8-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 28 Nov 2023 22:40:35 +0000 Received: from pps.filterd (ppma21.wdc07v.mail.ibm.com [127.0.0.1]) by ppma21.wdc07v.mail.ibm.com (8.17.1.19/8.17.1.19) with ESMTP id 3ASJsc7V028308; Tue, 28 Nov 2023 22:37:09 GMT Received: from smtprelay02.fra02v.mail.ibm.com ([9.218.2.226]) by ppma21.wdc07v.mail.ibm.com (PPS) with ESMTPS id 3ukv8nka30-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 28 Nov 2023 22:37:08 +0000 Received: from smtpav07.fra02v.mail.ibm.com (smtpav07.fra02v.mail.ibm.com [10.20.54.106]) by smtprelay02.fra02v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 3ASMb5aX10748588 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Tue, 28 Nov 2023 22:37:06 GMT Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id D378220043; Tue, 28 Nov 2023 22:37:05 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 86E6820040; Tue, 28 Nov 2023 22:37:05 +0000 (GMT) Received: from heavy.boeblingen.de.ibm.com (unknown [9.171.93.155]) by smtpav07.fra02v.mail.ibm.com (Postfix) with ESMTP; Tue, 28 Nov 2023 22:37:05 +0000 (GMT) From: Ilya Leoshkevich To: Andreas Arnez , Simon Marchi , Tom Tromey Cc: gdb-patches@sourceware.org, Keith Seitz , Ilya Leoshkevich Subject: [PATCH v2] gdb/s390: Add packed-stack support to the backchain unwinder Date: Tue, 28 Nov 2023 23:36:10 +0100 Message-ID: <20231128223702.869501-1-iii@linux.ibm.com> X-Mailer: git-send-email 2.43.0 X-TM-AS-GCONF: 00 X-Proofpoint-GUID: RIuWK1E54bSKtfdQ6hcZzzmDfVXCmbj3 X-Proofpoint-ORIG-GUID: -ULVEQQjp4D-_znd2FkDEaMk2ER2sIaI X-Proofpoint-UnRewURL: 0 URL was un-rewritten MIME-Version: 1.0 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.272,Aquarius:18.0.997,Hydra:6.0.619,FMLib:17.11.176.26 definitions=2023-11-28_24,2023-11-27_01,2023-05-22_02 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 bulkscore=0 impostorscore=0 priorityscore=1501 mlxlogscore=999 malwarescore=0 adultscore=0 lowpriorityscore=0 phishscore=0 spamscore=0 mlxscore=0 suspectscore=0 clxscore=1011 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2311060000 definitions=main-2311280178 X-Spam-Status: No, score=-12.1 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, 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 Regtested on s390x-redhat-linux. Ok for master? v1: https://sourceware.org/pipermail/gdb-patches/2023-October/203562.html https://sourceware.org/pipermail/gdb-patches/2023-November/204230.html Move variable declarations closer to their first usages, add a test (Keith). Ignore the return value of the 2nd try_backchain() call, it does not cause any warnings, since try_backchain() is not marked with __attribute__ ((__warn_unused_result__)). Furthermore, the logic does not require any special actions if it fails. Currently it's not possible to unwind s390 kernel stacks past eBPF progs. There is no DWARF debug info or symbols for eBPF progs, therefore doing so requires using the backchain unwinder. The kernel uses the packed-stack ABI, which the backchain unwinder does not support. As far as unwinding is concerned, the difference between the "regular" ABI and the packed-stack ABI are frame offsets for backchain, stack pointer and program counter. Parameterize the existing code that does the backchain unwinding by these three values; try the "regular" ones first, and the packed-stack ones as a fallback. The backchain unwinder is tried last, so this addition does not alter the unwinding flow, unless it's about to fail anyway. While at it, move variable declarations closer to their first usages in order to better match the modern GDB code style. Add a test. Reviewed-by: Keith Seitz --- gdb/s390-tdep.c | 82 +++++++++++++++-------- gdb/testsuite/gdb.arch/s390-backchain.S | 60 +++++++++++++++++ gdb/testsuite/gdb.arch/s390-backchain.exp | 40 +++++++++++ 3 files changed, 153 insertions(+), 29 deletions(-) create mode 100644 gdb/testsuite/gdb.arch/s390-backchain.S create mode 100644 gdb/testsuite/gdb.arch/s390-backchain.exp diff --git a/gdb/s390-tdep.c b/gdb/s390-tdep.c index 54b5c89e5e3..2e97a52690e 100644 --- a/gdb/s390-tdep.c +++ b/gdb/s390-tdep.c @@ -2520,49 +2520,41 @@ s390_prologue_frame_unwind_cache (frame_info_ptr this_frame, return 1; } -/* Unwind THIS_FRAME and write the information into unwind cache INFO using - back chain unwinding. Helper for s390_frame_unwind_cache. */ +/* Unwind THIS_FRAME using back chain unwinding for the ABI described by + WORD_SIZE, BYTE_ORDER, BACKCHAIN_IDX, SP_IDX and PC_IDX. If successful, + write the information into unwind cache INFO and return true, otherwise + return false. Helper for s390_backchain_frame_unwind_cache. */ -static void -s390_backchain_frame_unwind_cache (frame_info_ptr this_frame, - struct s390_unwind_cache *info) +static bool +try_backchain (frame_info_ptr this_frame, struct s390_unwind_cache *info, + int word_size, enum bfd_endian byte_order, int backchain_idx, + int sp_idx, int pc_idx) { - struct gdbarch *gdbarch = get_frame_arch (this_frame); - int word_size = gdbarch_ptr_bit (gdbarch) / 8; - enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); - CORE_ADDR backchain; - ULONGEST reg; - LONGEST sp, tmp; - int i; - - /* Set up ABI call-saved/call-clobbered registers. */ - for (i = 0; i < S390_NUM_REGS; i++) - if (!s390_register_call_saved (gdbarch, i)) - info->saved_regs[i].set_unknown (); - - /* CC is always call-clobbered. */ - info->saved_regs[S390_PSWM_REGNUM].set_unknown (); - /* Get the backchain. */ - reg = get_frame_register_unsigned (this_frame, S390_SP_REGNUM); - if (!safe_read_memory_integer (reg, word_size, byte_order, &tmp)) + ULONGEST reg = get_frame_register_unsigned (this_frame, S390_SP_REGNUM); + LONGEST tmp; + if (!safe_read_memory_integer (reg + backchain_idx * word_size, word_size, + byte_order, &tmp)) tmp = 0; - backchain = (CORE_ADDR) tmp; + CORE_ADDR backchain = (CORE_ADDR) tmp; /* A zero backchain terminates the frame chain. As additional sanity check, let's verify that the spill slot for SP in the save area pointed to by the backchain in fact links back to the save area. */ + LONGEST sp; if (backchain != 0 - && safe_read_memory_integer (backchain + 15*word_size, - word_size, byte_order, &sp) + && safe_read_memory_integer (backchain + sp_idx * word_size, word_size, + byte_order, &sp) && (CORE_ADDR)sp == backchain) { /* We don't know which registers were saved, but it will have to be at least %r14 and %r15. This will allow us to continue unwinding, but other prev-frame registers may be incorrect ... */ - info->saved_regs[S390_SP_REGNUM].set_addr (backchain + 15*word_size); - info->saved_regs[S390_RETADDR_REGNUM].set_addr (backchain + 14*word_size); + info->saved_regs[S390_SP_REGNUM].set_addr (backchain + + sp_idx * word_size); + info->saved_regs[S390_RETADDR_REGNUM].set_addr (backchain + + pc_idx * word_size); /* Function return will set PC to %r14. */ info->saved_regs[S390_PSWA_REGNUM] @@ -2570,10 +2562,42 @@ s390_backchain_frame_unwind_cache (frame_info_ptr this_frame, /* We use the current value of the frame register as local_base, and the top of the register save area as frame_base. */ - info->frame_base = backchain + 16*word_size + 32; + const int gpr_count = 16; + const int fpr_count = 4; + info->frame_base = backchain + gpr_count * word_size + fpr_count * 8; info->local_base = reg; + + return true; } + return false; +} + +/* Unwind THIS_FRAME and write the information into unwind cache INFO using + back chain unwinding. Helper for s390_frame_unwind_cache. */ + +static void +s390_backchain_frame_unwind_cache (frame_info_ptr this_frame, + struct s390_unwind_cache *info) +{ + struct gdbarch *gdbarch = get_frame_arch (this_frame); + int word_size = gdbarch_ptr_bit (gdbarch) / 8; + enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); + int i; + + /* Set up ABI call-saved/call-clobbered registers. */ + for (i = 0; i < S390_NUM_REGS; i++) + if (!s390_register_call_saved (gdbarch, i)) + info->saved_regs[i].set_unknown (); + + /* CC is always call-clobbered. */ + info->saved_regs[S390_PSWM_REGNUM].set_unknown (); + + /* Try the regular ABI. */ + if (!try_backchain (this_frame, info, word_size, byte_order, 0, 15, 14)) + /* Try the packed stack ABI. */ + try_backchain (this_frame, info, word_size, byte_order, 19, 18, 17); + info->func = get_frame_pc (this_frame); } diff --git a/gdb/testsuite/gdb.arch/s390-backchain.S b/gdb/testsuite/gdb.arch/s390-backchain.S new file mode 100644 index 00000000000..e006705fff9 --- /dev/null +++ b/gdb/testsuite/gdb.arch/s390-backchain.S @@ -0,0 +1,60 @@ +/* Copyright 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 . */ + +ok: + j 0f + nop +0: + xgr %r2,%r2 + br %r14 + +f: + j 0f + nop +0: + stmg %r14,%r15,112(%r15) + lgr %r14,%r15 + lay %r15,-160(%r15) + stg %r14,0(%r15) + brasl %r14,ok + lmg %r14,%r15,272(%r15) + br %r14 + +f_packed: + j 0f + nop +0: + stmg %r14,%r15,136(%r15) + lgr %r14,%r15 + lay %r15,-24(%r15) + stg %r14,152(%r15) + brasl %r14,f + lmg %r14,%r15,160(%r15) + br %r14 + + .globl main +main: + j 0f + nop +0: + stmg %r14,%r15,112(%r15) + lgr %r14,%r15 + lay %r15,-160(%r15) + stg %r14,0(%r15) + brasl %r14,f_packed + lmg %r14,%r15,272(%r15) + br %r14 diff --git a/gdb/testsuite/gdb.arch/s390-backchain.exp b/gdb/testsuite/gdb.arch/s390-backchain.exp new file mode 100644 index 00000000000..9dd2e876238 --- /dev/null +++ b/gdb/testsuite/gdb.arch/s390-backchain.exp @@ -0,0 +1,40 @@ +# Copyright 2023 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# Test unwinding of mixed normal and packed-stack functions with backchain. +# This is an extreme case that does not occur in practice, but there is no +# reason for GDB not to support it. +# The actual use case is JITed eBPF code in the Linux kernel. The testcase +# reflects all its peculiarities: packed stack, no debuginfo, non-standard +# prologue that confuses s390_analyze_prologue(). + +require {istarget "s390*-*-*"} + +standard_testfile .S + +# Compile without the debug option. +if { [prepare_for_testing "failed to prepare" $testfile $srcfile {}] } { + return -1 +} + +if ![runto_main] { + return -1 +} + +gdb_breakpoint "ok" +gdb_continue_to_breakpoint "ok" +gdb_test "backtrace" \ + "#0\[ \t\]*$hex in ok .*\n#1\[ \t\]*$hex in f .*\n#2\[ \t\]*$hex in f_packed .*\n#3\[ \t\]*$hex in main .*" \ + "backtrace"