From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mx0a-001b2d01.pphosted.com (mx0a-001b2d01.pphosted.com [148.163.156.1]) by sourceware.org (Postfix) with ESMTPS id 1CF1D3858D38 for ; Fri, 12 Apr 2024 17:39:00 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 1CF1D3858D38 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 1CF1D3858D38 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=1712943542; cv=none; b=E/3QzcJxZ4kHUw//CW3tNF5VbpKdX/lPstIxn+AMZgV9jGQWemjDWza2wDKbHDIqlqagSJIDUQJny/FNjXZrEI1+q4V6kZk+/5Dzs4XqOivBoTiDP2xitV5hmTZ6xVhk4ovcE+YkJKPYlAF/qIJkUo2guAjQcUTi3Zc9LjbNN4g= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1712943542; c=relaxed/simple; bh=CO69X3pZTrUndsteWdaYE0eBT+B6BWNeFeTpx29V03w=; h=DKIM-Signature:From:To:Subject:Date:Message-Id:MIME-Version; b=KUzoHvLQmxoMR0ecoGF+G/jcjg3rzvUmFI4UYHH/SezZjxD2zj3UBkZ4ljk+E7A//6/REUBPTKnzLd95VBYcgc2AVKtWV5KHmnJifxfpeXYKt8ETno5r5ov0JULtrM1MqRzJoJmQRhzC1LIqddebkKrnah3tWPjgBtNdYyAqa88= ARC-Authentication-Results: i=1; server2.sourceware.org Received: from pps.filterd (m0356517.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 43CFwsa0030902; Fri, 12 Apr 2024 16:36:48 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding; s=pp1; bh=SqKonKGypMU5PMXTRqYWBGzXppHqwcIbUZgGaH7RJsw=; b=hDftTk3CrGjzr+PgRInCwR/V8qgGcpsF2scmprmRdBdQrbNII3+LgcwhKAgM4mvoNiBV TuIj953xOjudEWceknkV3NvvySNAFOtpkVKyC68YIhibZBsAxTypgU1hr0QLLwhfNxqg 0qBBPYmpavLWJiFdFfRR13223VlPh5OoaAuXKwx74QYYvXvFSaBcu/EeLbuc+XODTjOP 0U0SCqBFgSrcQH6q/z9P656HHoeuBnSnFB1B8xMS2vjDIlKqvErkLvHBTDBsCBchlBqO 2lZYZmZKV+wKdA/GEiz0xzai7f7WL77iB4ptHEmgLQLGEffNmSWRTZ9jo3J4odRLB1vz 0w== Received: from ppma12.dal12v.mail.ibm.com (dc.9e.1632.ip4.static.sl-reverse.com [50.22.158.220]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 3xf5b4ggbn-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 12 Apr 2024 16:36:33 +0000 Received: from pps.filterd (ppma12.dal12v.mail.ibm.com [127.0.0.1]) by ppma12.dal12v.mail.ibm.com (8.17.1.19/8.17.1.19) with ESMTP id 43CDoFi8013590; Fri, 12 Apr 2024 16:36:33 GMT Received: from smtprelay04.fra02v.mail.ibm.com ([9.218.2.228]) by ppma12.dal12v.mail.ibm.com (PPS) with ESMTPS id 3xbgqu36ap-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 12 Apr 2024 16:36:32 +0000 Received: from smtpav05.fra02v.mail.ibm.com (smtpav05.fra02v.mail.ibm.com [10.20.54.104]) by smtprelay04.fra02v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 43CGaRJq23069234 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 12 Apr 2024 16:36:30 GMT Received: from smtpav05.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id BC2D52004D; Fri, 12 Apr 2024 16:36:27 +0000 (GMT) Received: from smtpav05.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 9C3982004E; Fri, 12 Apr 2024 16:36:27 +0000 (GMT) Received: from tuxmaker.boeblingen.de.ibm.com (unknown [9.152.85.9]) by smtpav05.fra02v.mail.ibm.com (Postfix) with ESMTP; Fri, 12 Apr 2024 16:36:27 +0000 (GMT) From: Jens Remus To: binutils@sourceware.org, Indu Bhagat Cc: Jens Remus , Andreas Krebbel Subject: [RFC PATCH v3 2/2] s390: SFrame track FP/RA saved in register Date: Fri, 12 Apr 2024 18:36:25 +0200 Message-Id: <20240412163625.965517-3-jremus@linux.ibm.com> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20240412163625.965517-1-jremus@linux.ibm.com> References: <20240412163625.965517-1-jremus@linux.ibm.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-TM-AS-GCONF: 00 X-Proofpoint-ORIG-GUID: sgCsGx05XIdST8EzfsMhgFRbtevuwMLs X-Proofpoint-GUID: sgCsGx05XIdST8EzfsMhgFRbtevuwMLs X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.272,Aquarius:18.0.1011,Hydra:6.0.619,FMLib:17.11.176.26 definitions=2024-04-12_12,2024-04-09_01,2023-05-22_02 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 clxscore=1015 priorityscore=1501 lowpriorityscore=0 phishscore=0 suspectscore=0 spamscore=0 mlxlogscore=999 impostorscore=0 mlxscore=0 adultscore=0 malwarescore=0 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2404010000 definitions=main-2404120121 X-Spam-Status: No, score=-12.3 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_EF,GIT_PATCH_0,RCVD_IN_MSPIKE_H4,RCVD_IN_MSPIKE_WL,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 List-Id: GCC on s390x, when in a leaf function, can be observed to save the frame pointer (FP) and/or return address (RA) register in a floating- point registers (FPR) instead of on the stack. This is declared using the following CFI directive: .cfi_register , SFrame cannot represent the FP and/or RA being saved in another register. It does only track the CFA base register (SP/FP), CFA offset from CFA base register, and FP and RA save area offsets from CFA. On s390x the FP and/or RA are only saved in another FPR when in a leaf function. That is a function that does not call any other functions. Therefore it can ever only be the topmost function in a call chain. During function return, if the RA would be restored into a non-default RA register, the function would also only ever be the topmost function on the call stack. An unwinder by default has access to all registers of the function that if the topmost on the call stack. Therefore no further information would be required for those registers. Represent the FP/RA in another register on s390, by encoding the register number shifted by one to the left with the least-significant bit set in the offset as follows: offset = (regno << 1) | 1 Add s390-specific SFrame (error) test cases for FP/RA being saved in FPRs in leaf-function. gas/ * gen-sframe.c (s390_sframe_xlate_do_register): New s390- specific function to represent FP/RA in another register on s390. (sframe_xlate_do_register): Invoke s390_sframe_xlate_do_register on s390. libsframe/ * sframe-dump.c (is_sframe_abi_arch_s390): New helper to test whether ABI/arch is s390. (dump_sframe_func_with_fres): Dump FP/RA in another register on s390. gas/testsuite/ * gas/cfi-sframe/cfi-sframe.exp: Update s390-specific SFrame (error) test cases. * gas/cfi-sframe/cfi-sframe-s390-3.s: New s390-specific SFrame test case for FP/RA saved in register on s390. * gas/cfi-sframe/cfi-sframe-s390-3.d: Likewise. * gas/cfi-sframe/cfi-sframe-s390-err-6.s: New s390-specific SFrame error test case for FP without RA saved in register. * gas/cfi-sframe/cfi-sframe-s390-err-6.d: Likewise. * gas/cfi-sframe/cfi-sframe-s390-err-3.s: s390-specific SFrame error test case 3 no longer triggers an error and is renamed as test case 4. * gas/cfi-sframe/cfi-sframe-s390-err-3.d: Likewise. * gas/cfi-sframe/cfi-sframe-s390-4.s: Likewise. * gas/cfi-sframe/cfi-sframe-s390-4.d: Likewise. Added expected SFrame dump output. Signed-off-by: Jens Remus * gas/testsuite/gas/cfi-sframe/cfi-sframe-s390-4.d: # GCL: missing file * gas/testsuite/gas/cfi-sframe/cfi-sframe-s390-err-3.d -> gas/testsuite/gas/cfi-sframe/cfi-sframe-s390-err-6.d: # GCL: missing file * gas/testsuite/gas/cfi-sframe/cfi-sframe-s390-err-3.s -> gas/testsuite/gas/cfi-sframe/cfi-sframe-s390-4.s: # GCL: missing file --- Notes (jremus): Changes v2 -> v3: - New patch. Currently there is no mean to determine whether a function is a leaf function. Neither an annotation that a section of the assembler code does not call any function. Both would guarantee that the code will only ever appear topmost on the call stack, so that the unwinder by default has access to all registers. Therefore SFrame generation cannot determine whether saving of FP/RA registers in other registers such as FPR is actually valid. It needs to trust the CFI, as it would need to to anyway. The s390-specific functionality could be made dependent on TC_S390 at compile-time instead of on sframe_get_abi_arch() at run-time. sframe_fre_set_{bp|ra}_track() could be renamed to sframe_fre_set_{fp|ra}_track_offset() and new sframe_fre_set_{fp|ra}_track_register() could be introduced. These would call some architecture-specific callback to perform the encoding of the dw2renum as offset. gas/gen-sframe.c | 35 +++++++++++++++++++ .../gas/cfi-sframe/cfi-sframe-s390-3.d | 22 ++++++++++++ .../gas/cfi-sframe/cfi-sframe-s390-3.s | 15 ++++++++ .../gas/cfi-sframe/cfi-sframe-s390-4.d | 21 +++++++++++ ...frame-s390-err-3.s => cfi-sframe-s390-4.s} | 0 ...e-s390-err-3.d => cfi-sframe-s390-err-6.d} | 2 +- .../gas/cfi-sframe/cfi-sframe-s390-err-6.s | 15 ++++++++ gas/testsuite/gas/cfi-sframe/cfi-sframe.exp | 4 ++- libsframe/sframe-dump.c | 22 ++++++++++-- 9 files changed, 132 insertions(+), 4 deletions(-) create mode 100644 gas/testsuite/gas/cfi-sframe/cfi-sframe-s390-3.d create mode 100644 gas/testsuite/gas/cfi-sframe/cfi-sframe-s390-3.s create mode 100644 gas/testsuite/gas/cfi-sframe/cfi-sframe-s390-4.d rename gas/testsuite/gas/cfi-sframe/{cfi-sframe-s390-err-3.s => cfi-sframe-s390-4.s} (100%) rename gas/testsuite/gas/cfi-sframe/{cfi-sframe-s390-err-3.d => cfi-sframe-s390-err-6.d} (74%) create mode 100644 gas/testsuite/gas/cfi-sframe/cfi-sframe-s390-err-6.s diff --git a/gas/gen-sframe.c b/gas/gen-sframe.c index 93a5eebcc9d8..4cc86eb6c815 100644 --- a/gas/gen-sframe.c +++ b/gas/gen-sframe.c @@ -1150,6 +1150,37 @@ sframe_xlate_do_val_offset (struct sframe_xlate_ctx *xlate_ctx ATTRIBUTE_UNUSED, return SFRAME_XLATE_OK; } +/* S390-specific translate DW_CFA_register into SFrame context. + Return SFRAME_XLATE_OK if success. */ + +static int +s390_sframe_xlate_do_register (struct sframe_xlate_ctx *xlate_ctx, + struct cfi_insn_data *cfi_insn) +{ + /* The scratchpad FRE currently being updated with each cfi_insn + being interpreted. This FRE eventually gets linked in into the + list of FREs for the specific function. */ + struct sframe_row_entry *cur_fre = xlate_ctx->cur_fre; + + gas_assert (cur_fre); + + /* Change the rule for the register indicated by the register number to + be the specified register. Encode the register number as offset by + shifting it to the left by one and setting the least-significant bit + (LSB). The LSB can be used to differentiate offsets from register + numbers, as offsets from CFA are always a multiple of -8 on s390x. */ + if (cfi_insn->u.rr.reg1 == SFRAME_CFA_FP_REG) + sframe_fre_set_bp_track (cur_fre, cfi_insn->u.rr.reg2 << 1 | 1); +#ifdef SFRAME_FRE_RA_TRACKING + else if (sframe_ra_tracking_p () + && cfi_insn->u.rr.reg1 == SFRAME_CFA_RA_REG) + sframe_fre_set_ra_track (cur_fre, cfi_insn->u.rr.reg2 << 1 | 1); +#endif + + /* Safe to skip. */ + return SFRAME_XLATE_OK; +} + /* Translate DW_CFA_register into SFrame context. Return SFRAME_XLATE_OK if success. */ @@ -1157,6 +1188,10 @@ static int sframe_xlate_do_register (struct sframe_xlate_ctx *xlate_ctx ATTRIBUTE_UNUSED, struct cfi_insn_data *cfi_insn) { + /* Conditionally invoke S390-specific implementation. */ + if (sframe_get_abi_arch () == SFRAME_ABI_S390_ENDIAN_BIG) + return s390_sframe_xlate_do_register (xlate_ctx, cfi_insn); + /* Previous value of register1 is register2. However, if the specified register1 is not interesting (FP or RA reg), the current DW_CFA_register instruction can be safely skipped without sacrificing the asynchronicity of diff --git a/gas/testsuite/gas/cfi-sframe/cfi-sframe-s390-3.d b/gas/testsuite/gas/cfi-sframe/cfi-sframe-s390-3.d new file mode 100644 index 000000000000..722874113225 --- /dev/null +++ b/gas/testsuite/gas/cfi-sframe/cfi-sframe-s390-3.d @@ -0,0 +1,22 @@ +#objdump: --sframe=.sframe +#name: SFrame generation on s390 +#... +Contents of the SFrame section .sframe: + + Header : + + Version: SFRAME_VERSION_2 + Flags: NONE + Num FDEs: 1 + Num FREs: 5 + + Function Index : + + func idx \[0\]: pc = 0x0, size = 26 bytes + STARTPC +CFA +FP +RA + + 0+0000 +sp\+160 +u +u + + 0+0004 +sp\+160 +u +r16 + + 0+0008 +sp\+160 +r17 +r16 + + 0+0014 +sp\+160 +u +r16 + + 0+0018 +sp\+160 +u +u + +#pass diff --git a/gas/testsuite/gas/cfi-sframe/cfi-sframe-s390-3.s b/gas/testsuite/gas/cfi-sframe/cfi-sframe-s390-3.s new file mode 100644 index 000000000000..1d4497178ada --- /dev/null +++ b/gas/testsuite/gas/cfi-sframe/cfi-sframe-s390-3.s @@ -0,0 +1,15 @@ + .cfi_sections .sframe + .cfi_startproc + ldgr %f0,%r14 + .cfi_register 14, 16 + ldgr %f2,%r11 + .cfi_register 11, 17 + la %r11,0 + la %r14,0 +.Lreturn: + lgdr %r11,%f2 + .cfi_restore 11 + lgdr %r14,%f0 + .cfi_restore 14 + br %r14 + .cfi_endproc diff --git a/gas/testsuite/gas/cfi-sframe/cfi-sframe-s390-4.d b/gas/testsuite/gas/cfi-sframe/cfi-sframe-s390-4.d new file mode 100644 index 000000000000..3c013ac2b6fe --- /dev/null +++ b/gas/testsuite/gas/cfi-sframe/cfi-sframe-s390-4.d @@ -0,0 +1,21 @@ +#name: SFrame generation on s390 +#as: --gsframe +#objdump: --sframe=.sframe +#... +Contents of the SFrame section .sframe: + + Header : + + Version: SFRAME_VERSION_2 + Flags: NONE + Num FDEs: 1 + Num FREs: 2 + + Function Index : + + func idx \[0\]: pc = 0x0, size = 6 bytes + STARTPC +CFA +FP +RA + + 0+0000 +sp\+160 +u +u + + 0+0004 +sp\+160 +u +r7 + + +#pass: diff --git a/gas/testsuite/gas/cfi-sframe/cfi-sframe-s390-err-3.s b/gas/testsuite/gas/cfi-sframe/cfi-sframe-s390-4.s similarity index 100% rename from gas/testsuite/gas/cfi-sframe/cfi-sframe-s390-err-3.s rename to gas/testsuite/gas/cfi-sframe/cfi-sframe-s390-4.s diff --git a/gas/testsuite/gas/cfi-sframe/cfi-sframe-s390-err-3.d b/gas/testsuite/gas/cfi-sframe/cfi-sframe-s390-err-6.d similarity index 74% rename from gas/testsuite/gas/cfi-sframe/cfi-sframe-s390-err-3.d rename to gas/testsuite/gas/cfi-sframe/cfi-sframe-s390-err-6.d index 4b3262f02f02..57af27d26419 100644 --- a/gas/testsuite/gas/cfi-sframe/cfi-sframe-s390-err-3.d +++ b/gas/testsuite/gas/cfi-sframe/cfi-sframe-s390-err-6.d @@ -1,6 +1,6 @@ #name: SFrame generation on s390 #as: --gsframe -#warning: skipping SFrame FDE due to .cfi_register specifying RA register +#warning: skipping SFrame FDE due to FP without RA on stack #objdump: --sframe=.sframe #... Contents of the SFrame section .sframe: diff --git a/gas/testsuite/gas/cfi-sframe/cfi-sframe-s390-err-6.s b/gas/testsuite/gas/cfi-sframe/cfi-sframe-s390-err-6.s new file mode 100644 index 000000000000..48b01ac5f57b --- /dev/null +++ b/gas/testsuite/gas/cfi-sframe/cfi-sframe-s390-err-6.s @@ -0,0 +1,15 @@ + .cfi_sections .sframe + .cfi_startproc + ldgr %f2,%r11 + .cfi_register 11, 17 + ldgr %f0,%r14 + .cfi_register 14, 16 + la %r11,0 + la %r14,0 +.Lreturn: + lgdr %r14,%f0 + .cfi_restore 14 + lgdr %r11,%f2 + .cfi_restore 11 + br %r14 + .cfi_endproc diff --git a/gas/testsuite/gas/cfi-sframe/cfi-sframe.exp b/gas/testsuite/gas/cfi-sframe/cfi-sframe.exp index f97fa9e170a2..8b97b02222b3 100644 --- a/gas/testsuite/gas/cfi-sframe/cfi-sframe.exp +++ b/gas/testsuite/gas/cfi-sframe/cfi-sframe.exp @@ -105,9 +105,11 @@ if { [istarget "aarch64*-*-*"] && [gas_sframe_check] } then { if { [istarget "s390x*-*-*"] && [gas_sframe_check] } then { run_dump_test "cfi-sframe-s390-1" run_dump_test "cfi-sframe-s390-2" + run_dump_test "cfi-sframe-s390-3" + run_dump_test "cfi-sframe-s390-4" run_dump_test "cfi-sframe-s390-err-1" run_dump_test "cfi-sframe-s390-err-2" - run_dump_test "cfi-sframe-s390-err-3" run_dump_test "cfi-sframe-s390-err-4" run_dump_test "cfi-sframe-s390-err-5" + run_dump_test "cfi-sframe-s390-err-6" } diff --git a/libsframe/sframe-dump.c b/libsframe/sframe-dump.c index 69633d53a33a..40ea531314ba 100644 --- a/libsframe/sframe-dump.c +++ b/libsframe/sframe-dump.c @@ -40,6 +40,14 @@ is_sframe_abi_arch_aarch64 (sframe_decoder_ctx *sfd_ctx) return aarch64_p; } +/* Return TRUE if the SFrame section is associated with the s390 ABIs. */ + +static bool +is_sframe_abi_arch_s390 (sframe_decoder_ctx *sfd_ctx) +{ + return sframe_decoder_get_abi_arch (sfd_ctx) == SFRAME_ABI_S390_ENDIAN_BIG; +} + static void dump_sframe_header (sframe_decoder_ctx *sfd_ctx) { @@ -175,7 +183,12 @@ dump_sframe_func_with_fres (sframe_decoder_ctx *sfd_ctx, /* Dump SP/FP info. */ if (err[1] == 0) - sprintf (temp, "c%+d", fp_offset); + { + if (is_sframe_abi_arch_s390 (sfd_ctx) && (fp_offset & 1)) + sprintf (temp, "r%d", fp_offset >> 1); + else + sprintf (temp, "c%+d", fp_offset); + } else strcpy (temp, "u"); printf ("%-10s", temp); @@ -187,7 +200,12 @@ dump_sframe_func_with_fres (sframe_decoder_ctx *sfd_ctx, != SFRAME_CFA_FIXED_RA_INVALID) strcpy (temp, "f"); else if (err[2] == 0) - sprintf (temp, "c%+d", ra_offset); + { + if (is_sframe_abi_arch_s390 (sfd_ctx) && (ra_offset & 1)) + sprintf (temp, "r%d", ra_offset >> 1); + else + sprintf (temp, "c%+d", ra_offset); + } else strcpy (temp, "u"); -- 2.40.1