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 A3A543858418 for ; Thu, 22 Feb 2024 16:01:44 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org A3A543858418 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 A3A543858418 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=1708617725; cv=none; b=QINeWSET9VLLqhoAIHsxbEkYpyn++9ByB0wCmsMoujw7Qa1sDusk6kD6U5LFs8lqvTSSYe8AO83y/BVWLTY300ByUbaebDwT5pGpfjqpgVPy3tckWbjPziq7Q7CImcU7s8pGazRQoHWglQOVtZT4/smrz21ujmoOS093gMiZ36g= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1708617725; c=relaxed/simple; bh=VLyyx7GXsrBlk1SfnMjS/MfLB7l+muVpqC3V1EDNm/A=; h=DKIM-Signature:From:To:Subject:Date:Message-Id:MIME-Version; b=jp8aQb/8FyOaynu5MMtiObn/MU+TcVUoRcJ11gnaYinYWEUfso7QuPwIkh+RNRikSnq7JhNkuWeczozXS3pUIUY4qsLOH4eVNrwF+S8vpbQEnFqv9tE/twIENvn0Cncacbr/Ek+wpZSS3rPx6TMwngugoyN2guh1KyNPbhcPwgs= 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 41MF7bAx016235; Thu, 22 Feb 2024 16:01:37 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 : content-transfer-encoding : mime-version; s=pp1; bh=3177u7vYZkOj6itgz6YrRkpwCcrBf8Q3Ywv1TWTnbjY=; b=hCBLO7Nx85nlT60OPFpYsNzP0guX4iWWrUiYINL5LhUI2KKebLcJhjmZsEd2C/Ks/e8a 0W1gnCsoq5fUGiVo0/c8U/cwpFHu7y3kF1rXOzn2RggeKxflmuzSu59W9eSZ98Hr/msG AWzNUmk3suvikvOU8kS0ZCJudKO1Lkv1/EO9WaA8f9TD94EdcFxVnnOvCAjHvF1ruuKv 5NRz0Py9KB7y11G+3gTYJWoxuUWi+qsepvy8l4H1b4DSTLT7MZFVVeEZcjJMPn6q385I 1bwnyvSdQoJ2X8PRUVBBzsdpZmWcX3KLOmctOCtE0WLZguC5u3vl6wOw9SICvV1mBfJI eQ== Received: from ppma22.wdc07v.mail.ibm.com (5c.69.3da9.ip4.static.sl-reverse.com [169.61.105.92]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 3we8mk9nnd-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 22 Feb 2024 16:01:35 +0000 Received: from pps.filterd (ppma22.wdc07v.mail.ibm.com [127.0.0.1]) by ppma22.wdc07v.mail.ibm.com (8.17.1.19/8.17.1.19) with ESMTP id 41MDVeOc013452; Thu, 22 Feb 2024 16:01:33 GMT Received: from smtprelay06.fra02v.mail.ibm.com ([9.218.2.230]) by ppma22.wdc07v.mail.ibm.com (PPS) with ESMTPS id 3wb7h0qeyr-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 22 Feb 2024 16:01:33 +0000 Received: from smtpav02.fra02v.mail.ibm.com (smtpav02.fra02v.mail.ibm.com [10.20.54.101]) by smtprelay06.fra02v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 41MG1R9d42664546 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 22 Feb 2024 16:01:29 GMT Received: from smtpav02.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 9269D20071; Thu, 22 Feb 2024 16:01:27 +0000 (GMT) Received: from smtpav02.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 61E5E2006B; Thu, 22 Feb 2024 16:01:27 +0000 (GMT) Received: from tuxmaker.boeblingen.de.ibm.com (unknown [9.152.85.9]) by smtpav02.fra02v.mail.ibm.com (Postfix) with ESMTP; Thu, 22 Feb 2024 16:01:27 +0000 (GMT) From: Jens Remus To: binutils@sourceware.org, Indu Bhagat Cc: Jens Remus , Andreas Krebbel Subject: [RFC PATCH 9/9] s390: Initial support to generate .sframe from CFI directives in assembler Date: Thu, 22 Feb 2024 17:01:23 +0100 Message-Id: <20240222160123.2554459-10-jremus@linux.ibm.com> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20240222160123.2554459-1-jremus@linux.ibm.com> References: <20240222160123.2554459-1-jremus@linux.ibm.com> X-TM-AS-GCONF: 00 X-Proofpoint-GUID: JiF3DGh_wDre6-ScIgztCCWdyuJYMXXV X-Proofpoint-ORIG-GUID: JiF3DGh_wDre6-ScIgztCCWdyuJYMXXV Content-Transfer-Encoding: 8bit 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.1011,Hydra:6.0.619,FMLib:17.11.176.26 definitions=2024-02-22_11,2024-02-22_01,2023-05-22_02 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 spamscore=0 malwarescore=0 bulkscore=0 adultscore=0 lowpriorityscore=0 mlxlogscore=999 suspectscore=0 mlxscore=0 priorityscore=1501 clxscore=1015 impostorscore=0 phishscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2311290000 definitions=main-2402220127 X-Spam-Status: No, score=-11.3 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_EF,GIT_PATCH_0,KAM_ASCII_DIVIDERS,KAM_STOCKGEN,RCVD_IN_MSPIKE_H3,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 List-Id: This introduces initial support to generate .sframe from CFI directives in assembler on s390x. Due to the following SFrame limitations it is incomplete and does not work for most real-world applications (i.e. generation of SFrame FDE is skipped): - SFrame FP/RA tracking assumes the register contents to be saved on the stack (i.e. .cfi_offset). It does not support FP/RA register contents being saved in other registers (i.e. .cfi_register). GCC on s390x can be observed to save the FP/RA register contents in other registers (e.g. floating-point registers). - SFrame assumes a static RA register number. While the s390x ELF ABI [1] specifies register 14 to contain the return address on entry, GCC can be observed to copy the return address to another register and may even use that to return. Additionally glibc on s390x has two functions (mcount and fentry) that specify register 0 to hold the return address. This would either require a change to glibc (if possible) or SFrame support to track the RA register number specified in CFI directive .cfi_return_column. - SFrame assumes a static FP register number. The s390x ELF ABI [1] does not specify any FP register number. GCC and clang on s390x usually use register 11 as frame pointer. GCC on s390x can also be observed to use register 14 (e.g. binutils and glibc builds). glibc on s390x contains code that uses register 12 for the frame pointer. This would require SFrame support to track the SP/FP register number specified in CFI directives .cfi_def_cfa and .cfi_def_cfa_register. - SFrame does not support CFI directive .cfi_val_offset. glibc on s390x has two functions (mcount and fentry), that make use of that CFI directive. This would either require a change in glibc (if possible) or SFrame to support CFI directive .cfi_val_offset. This s390x support is largely based on the AArch64 support from commit b52c4ee46657 ("gas: generate .sframe from CFI directives"). SFrame ABI/arch identifier SFRAME_ABI_S390_ENDIAN_BIG is introduced for s390 and added to the SFrame specification. According to the s390x ELF ABI [1] the following calling conventions are used on s390x architecture: - Register 15 is used as stack pointer (SP). The CFA is initially located at offset +160 from the SP. - Register 14 is used as return address (RA). - There is no dedicated frame pointer. GCC and LLVM currently use register 11 as frame pointer. The s390x ELF ABI [1] standard stack frame layout has the following conventions: - The return address (RA, r15) may be saved at offset -40 from the CFA. Unlike x86 AMD64 architecture it is not necessarily saved on the stack. Also compilers may use a non-standard stack frame layout, such as but not limited to GCC with option -mpacked-stack. Therefore SFrame RA tracking is used. - The potential frame pointer (FP, r11) may be saved at offset -72 from the CFA. It is not necessarily saved on the stack and compilers may use a non-standard stack frame layout (see above). Therefore SFrame FP tracking is used. Support for SFrame is only enabled for z/Architecture (s390x) with 64-bit architecture mode. It is disabled for 32-bit architecture mode and ESA/390 (s390). Add s390-specific SFrame test cases. As for the error test cases add ones that use a non-default frame pointer (FP) register number and ones that save the return address (RA) in a non-default RA register number. [1] ELF ABI s390x Supplement: https://github.com/IBM/s390x-abi/releases [2] ELF ABI s390 Supplement: https://refspecs.linuxfoundation.org/ELF/zSeries/lzsabi0_s390.html https://refspecs.linuxfoundation.org/ELF/zSeries/lzsabi0_s390.pdf include/ * sframe.h (SFRAME_ABI_S390_ENDIAN_BIG): Define SFrame ABI/arch identifier for s390x. Reference s390x architecture in comments. libsframe/ * doc/sframe-spec.texi: Document SFrame ABI/arch identifier for s390x and reference s390x architecture. gas/ * config/tc-s390.h: s390x support to generate .sframe from CFI directives in assembler. * config/tc-s390.c: Likewise. * gen-sframe.c: Reference s390x architecture in comments. gas/testsuite/ * gas/cfi-sframe/cfi-sframe.exp: Enable common SFrame test cases for s390x. Add s390-specific SFrame test cases. * gas/cfi-sframe/cfi-sframe-s390-1.s: New s390-specific SFrame test case. * gas/cfi-sframe/cfi-sframe-s390-1.d: Likewise. * gas/cfi-sframe/cfi-sframe-s390-2.s: Likewise. * gas/cfi-sframe/cfi-sframe-s390-2.d: Likewise. * gas/cfi-sframe/cfi-sframe-s390-err-1.s: New s390-specific SFrame error test case that uses a non-default register number for the frame pointer. * gas/cfi-sframe/cfi-sframe-s390-err-1.l: Likewise. * gas/cfi-sframe/cfi-sframe-s390-err-2.s: Likewise. * gas/cfi-sframe/cfi-sframe-s390-err-2.l: Likewise. * gas/cfi-sframe/cfi-sframe-s390-err-3.s: New s390-specific SFrame error test case that uses a non-default register number to save the return address. * gas/cfi-sframe/cfi-sframe-s390-err-3.l: Likewise. * gas/cfi-sframe/cfi-sframe-s390-err-4.s: New s390-specific SFrame error test case that used a non-default return column (return address) register number. * gas/cfi-sframe/cfi-sframe-s390-err-4.l: Likewise. Reviewed-by: Andreas Krebbel Signed-off-by: Jens Remus --- Notes (jremus): The SFrame support for s390x provided by this patch still has some open issues, which need to be addressed. Any ideas or assistance to overcome the SFrame limitations listed in the commit description are very welcome. Note that unlike the AArch64 and x68 AMD64 implementation this s390x implementation does statically initialize the architecture-dependent variables s390_sframe_cfa_{sp|fp|ra}_reg, which are referenced by the SFrame interface macros SFRAME_CFA_{SP|FP|RA}_REG. The other implementations do initialize them in md_begin. I verified that all occurrences of the macros SFRAME_CFA_{SP|FP|RA}_REG are in context of test/read and never write. Is there a reason to define the SFrame interface macros SFRAME_CFA_{SP|FP|RA}_REG to variables? For instance should the SFrame common code be able to modify these? Currently I do not see how it would work well, if the architecture-specific code would change these at run time. Similar for the predicate sframe_ra_tracking_p. Example #1: Warnings when compiling binutils with SFrame $ ../configure CC="gcc -B$HOME/temp/binutils-gcc/bin -Wa,--gsframe" \ CXX="g++ -B$HOME/temp/binutils-gcc/bin -Wa,--gsframe" \ --prefix=$HOME/temp/binutils-sframe $ make -j $(nprocs) 2>&1 | tee make.log $ grep --only-matching "Warning:.*" make.log | sort | uniq -c 1 Warning: skipping SFrame FDE due to .cfi_def_cfa specifying CFA base register other than SP or FP (14 instead of 15 or 11) 205 Warning: skipping SFrame FDE due to .cfi_register specifying FP register (11) 56 Warning: skipping SFrame FDE due to .cfi_register specifying SP register (15) Example #2: Warnings when compiling glibc with SFrame $ ../configure CC="gcc -B$HOME/temp/binutils-sframe/bin -Wa,--gsframe" \ CXX="g++ -B$HOME/temp/binutils-sframe/bin -Wa,--gsframe" \ --prefix=$HOME/temp/glibc-sframe $ make -j $(nprocs) 2>&1 | tee make.log $ grep --only-matching "Warning:.*" make.log | sort | uniq -c 2 Warning: skipping SFrame FDE due to .cfi_def_cfa_register specifying CFA base register other than SP or FP (12 instead of 15 or 11) 7 Warning: skipping SFrame FDE due to .cfi_def_cfa specifying CFA base register other than SP or FP (14 instead of 15 or 11) 225 Warning: skipping SFrame FDE due to .cfi_register specifying FP register (11) 187 Warning: skipping SFrame FDE due to .cfi_register specifying SP register (15) 2 Warning: skipping SFrame FDE due to DWARF CFI op CFI_escape (0x103) 2 Warning: skipping SFrame FDE due to non-default DWARF return column (0 instead of 14) .cfi_def_cfa 14, ... originates from GCC generated code, which uses register %r14 as frame pointer (FP). .cfi_def_cfa_register 12 originates from hand-written assembler code sysdeps/s390/s390-64/dl-trampoline.S, which uses register %r12 as frame pointer (FP). .cfi_return_column 0 and .cfi_escape both originate from hand-written assembler code sysdeps/s390/s390-64/s390x-mcount.S, which is compiled twice (with and without -DSHARED). - .cfi_escape 0x14, 0x15, 0x14: Is used to code ".cfi_val_offset r15, -160", which would require binutils 2.28+ (glibc currently supports a minimum binutils 2.25). This CFI directive states that the contents of register %r15 are CFA-160 (not to be confused with saved at CFA-160). - .cfi_return_column 0: The following comment explains why register %r0 contains the return address: "The _mcount implementation now has to call __mcount_internal with the address of .LP0 as first parameter and the return address as second parameter. &.LP0 was loaded to %r1 and the return address is in %r14. _mcount may not modify any register. Alternatively, at the start of each function __fentry__ is called using a single brasl 0,__fentry__ instruction. In this case %r0 points to the callee, and %r14 points to the caller. These values need to be passed to __mcount_internal using the same sequence as for _mcount, so the code below is shared between both functions. The only major difference is that __fentry__ cannot return through %r0, in which the return address is located, because br instruction is a no-op with this register. Therefore %r1, which is clobbered by the PLT anyway, is used." Excerpt of the relevant glibc source code: .globl C_SYMBOL_NAME(MCOUNT_SYMBOL) .type C_SYMBOL_NAME(MCOUNT_SYMBOL), @function cfi_startproc .align ALIGNARG(4) C_LABEL(MCOUNT_SYMBOL) cfi_return_column (glue(r, MCOUNT_CALLEE_REG)) /* Save the caller-clobbered registers. */ aghi %r15,-224 cfi_adjust_cfa_offset (224) /* binutils 2.28+: .cfi_val_offset r15, -160 */ .cfi_escape \ /* DW_CFA_val_offset */ 0x14, \ /* r15 */ 0x0f, \ /* scaled offset */ 0x14 stmg %r14,%r5,160(%r15) cfi_offset (r14, -224) cfi_offset (r0, -224+16) ... gas/config/tc-s390.c | 55 +++++++++++++++++++ gas/config/tc-s390.h | 31 +++++++++++ gas/gen-sframe.c | 2 +- .../gas/cfi-sframe/cfi-sframe-s390-1.d | 23 ++++++++ .../gas/cfi-sframe/cfi-sframe-s390-1.s | 37 +++++++++++++ .../gas/cfi-sframe/cfi-sframe-s390-2.d | 23 ++++++++ .../gas/cfi-sframe/cfi-sframe-s390-2.s | 37 +++++++++++++ .../gas/cfi-sframe/cfi-sframe-s390-err-1.d | 15 +++++ .../gas/cfi-sframe/cfi-sframe-s390-err-1.s | 37 +++++++++++++ .../gas/cfi-sframe/cfi-sframe-s390-err-2.d | 15 +++++ .../gas/cfi-sframe/cfi-sframe-s390-err-2.s | 37 +++++++++++++ .../gas/cfi-sframe/cfi-sframe-s390-err-3.d | 15 +++++ .../gas/cfi-sframe/cfi-sframe-s390-err-3.s | 6 ++ .../gas/cfi-sframe/cfi-sframe-s390-err-4.d | 15 +++++ .../gas/cfi-sframe/cfi-sframe-s390-err-4.s | 5 ++ gas/testsuite/gas/cfi-sframe/cfi-sframe.exp | 13 ++++- include/sframe.h | 7 ++- libsframe/doc/sframe-spec.texi | 8 ++- 18 files changed, 374 insertions(+), 7 deletions(-) create mode 100644 gas/testsuite/gas/cfi-sframe/cfi-sframe-s390-1.d create mode 100644 gas/testsuite/gas/cfi-sframe/cfi-sframe-s390-1.s create mode 100644 gas/testsuite/gas/cfi-sframe/cfi-sframe-s390-2.d create mode 100644 gas/testsuite/gas/cfi-sframe/cfi-sframe-s390-2.s create mode 100644 gas/testsuite/gas/cfi-sframe/cfi-sframe-s390-err-1.d create mode 100644 gas/testsuite/gas/cfi-sframe/cfi-sframe-s390-err-1.s create mode 100644 gas/testsuite/gas/cfi-sframe/cfi-sframe-s390-err-2.d create mode 100644 gas/testsuite/gas/cfi-sframe/cfi-sframe-s390-err-2.s create mode 100644 gas/testsuite/gas/cfi-sframe/cfi-sframe-s390-err-3.d create mode 100644 gas/testsuite/gas/cfi-sframe/cfi-sframe-s390-err-3.s create mode 100644 gas/testsuite/gas/cfi-sframe/cfi-sframe-s390-err-4.d create mode 100644 gas/testsuite/gas/cfi-sframe/cfi-sframe-s390-err-4.s diff --git a/gas/config/tc-s390.c b/gas/config/tc-s390.c index 09a903aea2db..af0d705b63f7 100644 --- a/gas/config/tc-s390.c +++ b/gas/config/tc-s390.c @@ -24,6 +24,8 @@ #include "subsegs.h" #include "dwarf2dbg.h" #include "dw2gencfi.h" +#include "sframe.h" +#include "gen-sframe.h" #include "opcode/s390.h" #include "elf/s390.h" @@ -83,6 +85,17 @@ const char FLT_CHARS[] = "dD"; /* The dwarf2 data alignment, adjusted for 32 or 64 bit. */ int s390_cie_data_alignment; +/* Register numbers used for SFrame stack trace info. */ + +/* Stack-pointer DWARF register number according to s390x ELF ABI. */ +unsigned int s390_sframe_cfa_sp_reg = 15; + +/* Frame-pointer DWARF register number accoring to s390x GCC/LLVM convention. */ +unsigned int s390_sframe_cfa_fp_reg = 11; + +/* Return-address DWARF register number according to s390x ELF ABI. */ +unsigned int s390_sframe_cfa_ra_reg = DWARF2_DEFAULT_RETURN_COLUMN; + /* The target specific pseudo-ops which we support. */ /* Define the prototypes for the pseudo-ops */ @@ -2639,6 +2652,48 @@ tc_s390_regname_to_dw2regnum (char *regname) return regnum; } +/* Whether SFrame stack trace info is supported. */ + +bool +s390_support_sframe_p (void) +{ + /* At this time, SFrame is supported for s390x (64-bit) only. */ + return (s390_arch_size == 64); +} + +/* Specify if RA tracking is needed. */ + +bool +s390_sframe_ra_tracking_p (void) +{ + return true; +} + +/* Specify the fixed offset to recover RA from CFA. + (useful only when RA tracking is not needed). */ + +offsetT +s390_sframe_cfa_ra_offset (void) +{ + return (offsetT) SFRAME_CFA_FIXED_RA_INVALID; +} + +/* Get the abi/arch indentifier for SFrame. */ + +unsigned char +s390_sframe_get_abi_arch (void) +{ + unsigned char sframe_abi_arch = 0; + + if (s390_support_sframe_p ()) + { + gas_assert (target_big_endian); + sframe_abi_arch = SFRAME_ABI_S390_ENDIAN_BIG; + } + + return sframe_abi_arch; +} + void s390_elf_final_processing (void) { diff --git a/gas/config/tc-s390.h b/gas/config/tc-s390.h index cd353045a822..c8f172d8737b 100644 --- a/gas/config/tc-s390.h +++ b/gas/config/tc-s390.h @@ -98,3 +98,34 @@ extern int s390_cie_data_alignment; extern void s390_elf_final_processing (void); #define elf_tc_final_processing s390_elf_final_processing + +/* SFrame */ + +/* Whether SFrame stack trace info is supported. */ +extern bool s390_support_sframe_p (void); +#define support_sframe_p s390_support_sframe_p + +/* The stack-pointer register number for SFrame stack trace info. */ +extern unsigned int s390_sframe_cfa_sp_reg; +#define SFRAME_CFA_SP_REG s390_sframe_cfa_sp_reg + +/* The frame-pointer register number for SFrame stack trace info. */ +extern unsigned int s390_sframe_cfa_fp_reg; +#define SFRAME_CFA_FP_REG s390_sframe_cfa_fp_reg + +/* The return address register number for SFrame stack trace info. */ +extern unsigned int s390_sframe_cfa_ra_reg; +#define SFRAME_CFA_RA_REG s390_sframe_cfa_ra_reg + +/* Specify if RA tracking is needed. */ +extern bool s390_sframe_ra_tracking_p (void); +#define sframe_ra_tracking_p s390_sframe_ra_tracking_p + +/* Specify the fixed offset to recover RA from CFA. + (useful only when RA tracking is not needed). */ +extern offsetT s390_sframe_cfa_ra_offset (void); +#define sframe_cfa_ra_offset s390_sframe_cfa_ra_offset + +/* The abi/arch indentifier for SFrame. */ +unsigned char s390_sframe_get_abi_arch (void); +#define sframe_get_abi_arch s390_sframe_get_abi_arch diff --git a/gas/gen-sframe.c b/gas/gen-sframe.c index 339f4412ca05..08849cdafa81 100644 --- a/gas/gen-sframe.c +++ b/gas/gen-sframe.c @@ -673,7 +673,7 @@ output_sframe_internal (void) #endif out_one (fixed_ra_offset); - /* None of the AMD64, or AARCH64 ABIs need the auxiliary header. + /* None of the AMD64, AARCH64, or S390 ABIs need the auxiliary header. When the need does arise to use this field, the appropriate backend must provide this information. */ out_one (0); /* Auxiliary SFrame header length. */ diff --git a/gas/testsuite/gas/cfi-sframe/cfi-sframe-s390-1.d b/gas/testsuite/gas/cfi-sframe/cfi-sframe-s390-1.d new file mode 100644 index 000000000000..211804a2309a --- /dev/null +++ b/gas/testsuite/gas/cfi-sframe/cfi-sframe-s390-1.d @@ -0,0 +1,23 @@ +#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: 6 + + Function Index : + + func idx \[0\]: pc = 0x0, size = 40 bytes + STARTPC +CFA +FP +RA + + 0+0000 +sp\+160 +u +u + + 0+0006 +sp\+160 +c\-72 +c\-48 + + 0+000c +sp\+336 +c\-72 +c\-48 + + 0+0010 +fp\+336 +c\-72 +c\-48 + + 0+001c +sp\+160 +u +u + + 0+001e +fp\+336 +c\-72 +c\-48 + +#pass diff --git a/gas/testsuite/gas/cfi-sframe/cfi-sframe-s390-1.s b/gas/testsuite/gas/cfi-sframe/cfi-sframe-s390-1.s new file mode 100644 index 000000000000..56d8425ae2b1 --- /dev/null +++ b/gas/testsuite/gas/cfi-sframe/cfi-sframe-s390-1.s @@ -0,0 +1,37 @@ + .cfi_sections .sframe + .cfi_startproc + stmg %r6,%r15,48(%r15) + .cfi_offset 6, -112 + .cfi_offset 7, -104 + .cfi_offset 8, -96 + .cfi_offset 9, -88 + .cfi_offset 10, -80 + .cfi_offset 11, -72 + .cfi_offset 12, -64 + .cfi_offset 13, -56 + .cfi_offset 14, -48 + .cfi_offset 15, -40 + lay %r15,-176(%r15) + .cfi_def_cfa_offset 336 + lgr %r11,%r15 + .cfi_def_cfa_register 11 + lay %r15,-128(%r15) +.Lreturn: + lmg %r6,%r15,224(%r11) + .cfi_remember_state + .cfi_restore 15 + .cfi_restore 14 + .cfi_restore 13 + .cfi_restore 12 + .cfi_restore 11 + .cfi_restore 10 + .cfi_restore 9 + .cfi_restore 8 + .cfi_restore 7 + .cfi_restore 6 + .cfi_def_cfa 15, 160 + br %r14 + .cfi_restore_state + lay %r15,-128(%r15) + j .Lreturn + .cfi_endproc diff --git a/gas/testsuite/gas/cfi-sframe/cfi-sframe-s390-2.d b/gas/testsuite/gas/cfi-sframe/cfi-sframe-s390-2.d new file mode 100644 index 000000000000..211804a2309a --- /dev/null +++ b/gas/testsuite/gas/cfi-sframe/cfi-sframe-s390-2.d @@ -0,0 +1,23 @@ +#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: 6 + + Function Index : + + func idx \[0\]: pc = 0x0, size = 40 bytes + STARTPC +CFA +FP +RA + + 0+0000 +sp\+160 +u +u + + 0+0006 +sp\+160 +c\-72 +c\-48 + + 0+000c +sp\+336 +c\-72 +c\-48 + + 0+0010 +fp\+336 +c\-72 +c\-48 + + 0+001c +sp\+160 +u +u + + 0+001e +fp\+336 +c\-72 +c\-48 + +#pass diff --git a/gas/testsuite/gas/cfi-sframe/cfi-sframe-s390-2.s b/gas/testsuite/gas/cfi-sframe/cfi-sframe-s390-2.s new file mode 100644 index 000000000000..4d58cdaf64a7 --- /dev/null +++ b/gas/testsuite/gas/cfi-sframe/cfi-sframe-s390-2.s @@ -0,0 +1,37 @@ + .cfi_sections .sframe + .cfi_startproc + stmg %r6,%r15,48(%r15) + .cfi_rel_offset 6, 48 + .cfi_rel_offset 7, 56 + .cfi_rel_offset 8, 64 + .cfi_rel_offset 9, 72 + .cfi_rel_offset 10, 80 + .cfi_rel_offset 11, 88 + .cfi_rel_offset 12, 96 + .cfi_rel_offset 13, 104 + .cfi_rel_offset 14, 112 + .cfi_rel_offset 15, 120 + lay %r15,-176(%r15) + .cfi_def_cfa_offset 336 + lgr %r11,%r15 + .cfi_def_cfa_register 11 + lay %r15,-128(%r15) +.Lreturn: + lmg %r6,%r15,224(%r11) + .cfi_remember_state + .cfi_restore 15 + .cfi_restore 14 + .cfi_restore 13 + .cfi_restore 12 + .cfi_restore 11 + .cfi_restore 10 + .cfi_restore 9 + .cfi_restore 8 + .cfi_restore 7 + .cfi_restore 6 + .cfi_def_cfa 15, 160 + br %r14 + .cfi_restore_state + lay %r15,-128(%r15) + j .Lreturn + .cfi_endproc diff --git a/gas/testsuite/gas/cfi-sframe/cfi-sframe-s390-err-1.d b/gas/testsuite/gas/cfi-sframe/cfi-sframe-s390-err-1.d new file mode 100644 index 000000000000..a2724802c04b --- /dev/null +++ b/gas/testsuite/gas/cfi-sframe/cfi-sframe-s390-err-1.d @@ -0,0 +1,15 @@ +#name: SFrame generation on s390 +#as: --gsframe +#warning: skipping SFrame FDE due to .cfi_def_cfa_register specifying CFA base register other than SP or FP \(10 instead of 15 or 11\) +#objdump: --sframe=.sframe +#... +Contents of the SFrame section .sframe: + + Header : + + Version: SFRAME_VERSION_2 + Flags: NONE + Num FDEs: 0 + Num FREs: 0 + +#pass diff --git a/gas/testsuite/gas/cfi-sframe/cfi-sframe-s390-err-1.s b/gas/testsuite/gas/cfi-sframe/cfi-sframe-s390-err-1.s new file mode 100644 index 000000000000..85e36c39d2a3 --- /dev/null +++ b/gas/testsuite/gas/cfi-sframe/cfi-sframe-s390-err-1.s @@ -0,0 +1,37 @@ + .cfi_sections .sframe + .cfi_startproc + stmg %r6,%r15,48(%r15) + .cfi_offset 6, -112 + .cfi_offset 7, -104 + .cfi_offset 8, -96 + .cfi_offset 9, -88 + .cfi_offset 10, -80 + .cfi_offset 11, -72 + .cfi_offset 12, -64 + .cfi_offset 13, -56 + .cfi_offset 14, -48 + .cfi_offset 15, -40 + lay %r15,-176(%r15) + .cfi_def_cfa_offset 336 + lgr %r10,%r15 + .cfi_def_cfa_register 10 # non-default frame pointer register + lay %r15,-128(%r15) +.Lreturn: + lmg %r6,%r15,224(%r10) + .cfi_remember_state + .cfi_restore 15 + .cfi_restore 14 + .cfi_restore 13 + .cfi_restore 12 + .cfi_restore 11 + .cfi_restore 10 + .cfi_restore 9 + .cfi_restore 8 + .cfi_restore 7 + .cfi_restore 6 + .cfi_def_cfa 15, 160 + br %r14 + .cfi_restore_state + lay %r15,-128(%r15) + j .Lreturn + .cfi_endproc diff --git a/gas/testsuite/gas/cfi-sframe/cfi-sframe-s390-err-2.d b/gas/testsuite/gas/cfi-sframe/cfi-sframe-s390-err-2.d new file mode 100644 index 000000000000..914f01ad9ffe --- /dev/null +++ b/gas/testsuite/gas/cfi-sframe/cfi-sframe-s390-err-2.d @@ -0,0 +1,15 @@ +#name: SFrame generation on s390 +#as: --gsframe +#warning: skipping SFrame FDE due to .cfi_def_cfa specifying CFA base register other than SP or FP \(10 instead of 15 or 11\) +#objdump: --sframe=.sframe +#... +Contents of the SFrame section .sframe: + + Header : + + Version: SFRAME_VERSION_2 + Flags: NONE + Num FDEs: 0 + Num FREs: 0 + +#pass diff --git a/gas/testsuite/gas/cfi-sframe/cfi-sframe-s390-err-2.s b/gas/testsuite/gas/cfi-sframe/cfi-sframe-s390-err-2.s new file mode 100644 index 000000000000..0bb274a9e991 --- /dev/null +++ b/gas/testsuite/gas/cfi-sframe/cfi-sframe-s390-err-2.s @@ -0,0 +1,37 @@ + .cfi_sections .sframe + .cfi_startproc + stmg %r6,%r15,48(%r15) + .cfi_offset 6, -112 + .cfi_offset 7, -104 + .cfi_offset 8, -96 + .cfi_offset 9, -88 + .cfi_offset 10, -80 + .cfi_offset 11, -72 + .cfi_offset 12, -64 + .cfi_offset 13, -56 + .cfi_offset 14, -48 + .cfi_offset 15, -40 + lay %r15,-176(%r15) + .cfi_def_cfa_offset 336 + lgr %r10,%r15 + .cfi_def_cfa 10, 336 # non-default frame pointer register + lay %r15,-128(%r15) +.Lreturn: + lmg %r6,%r15,224(%r10) + .cfi_remember_state + .cfi_restore 15 + .cfi_restore 14 + .cfi_restore 13 + .cfi_restore 12 + .cfi_restore 11 + .cfi_restore 10 + .cfi_restore 9 + .cfi_restore 8 + .cfi_restore 7 + .cfi_restore 6 + .cfi_def_cfa 15, 160 + br %r14 + .cfi_restore_state + lay %r15,-128(%r15) + j .Lreturn + .cfi_endproc diff --git a/gas/testsuite/gas/cfi-sframe/cfi-sframe-s390-err-3.d b/gas/testsuite/gas/cfi-sframe/cfi-sframe-s390-err-3.d new file mode 100644 index 000000000000..54a7252f81a3 --- /dev/null +++ b/gas/testsuite/gas/cfi-sframe/cfi-sframe-s390-err-3.d @@ -0,0 +1,15 @@ +#name: SFrame generation on s390 +#as: --gsframe +#warning: skipping SFrame FDE due to .cfi_register specifying RA register \(14\) +#objdump: --sframe=.sframe +#... +Contents of the SFrame section .sframe: + + Header : + + Version: SFRAME_VERSION_2 + Flags: NONE + Num FDEs: 0 + Num FREs: 0 + +#pass diff --git a/gas/testsuite/gas/cfi-sframe/cfi-sframe-s390-err-3.s b/gas/testsuite/gas/cfi-sframe/cfi-sframe-s390-err-3.s new file mode 100644 index 000000000000..f0a5bd577304 --- /dev/null +++ b/gas/testsuite/gas/cfi-sframe/cfi-sframe-s390-err-3.s @@ -0,0 +1,6 @@ + .cfi_sections .sframe + .cfi_startproc + lgr %r7,%r14 + .cfi_register 14, 7 # non-default return address register + br %r7 + .cfi_endproc diff --git a/gas/testsuite/gas/cfi-sframe/cfi-sframe-s390-err-4.d b/gas/testsuite/gas/cfi-sframe/cfi-sframe-s390-err-4.d new file mode 100644 index 000000000000..71769e7cf077 --- /dev/null +++ b/gas/testsuite/gas/cfi-sframe/cfi-sframe-s390-err-4.d @@ -0,0 +1,15 @@ +#name: SFrame generation on s390 +#as: --gsframe +#warning: skipping SFrame FDE due to non-default DWARF return column \(7 instead of 14\) +#objdump: --sframe=.sframe +#... +Contents of the SFrame section .sframe: + + Header : + + Version: SFRAME_VERSION_2 + Flags: NONE + Num FDEs: 0 + Num FREs: 0 + +#pass diff --git a/gas/testsuite/gas/cfi-sframe/cfi-sframe-s390-err-4.s b/gas/testsuite/gas/cfi-sframe/cfi-sframe-s390-err-4.s new file mode 100644 index 000000000000..cfdea75e0b95 --- /dev/null +++ b/gas/testsuite/gas/cfi-sframe/cfi-sframe-s390-err-4.s @@ -0,0 +1,5 @@ + .cfi_sections .sframe + .cfi_startproc + .cfi_return_column 7 # non-default return address register + br %r7 + .cfi_endproc diff --git a/gas/testsuite/gas/cfi-sframe/cfi-sframe.exp b/gas/testsuite/gas/cfi-sframe/cfi-sframe.exp index cfae28d39aaf..9411c0e6c9ce 100644 --- a/gas/testsuite/gas/cfi-sframe/cfi-sframe.exp +++ b/gas/testsuite/gas/cfi-sframe/cfi-sframe.exp @@ -64,7 +64,8 @@ proc gas_x86_64_check { } { } # common tests -if { ([istarget "x86_64-*-*"] || [istarget "aarch64*-*-*"]) \ +if { ([istarget "x86_64-*-*"] || [istarget "aarch64*-*-*"] || + [istarget "s390x-*-*"]) \ && [gas_sframe_check] } then { global ASFLAGS @@ -99,3 +100,13 @@ if { [istarget "aarch64*-*-*"] && [gas_sframe_check] } then { run_dump_test "cfi-sframe-aarch64-2" run_dump_test "cfi-sframe-aarch64-pac-ab-key-1" } + +# s390 specific tests +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-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" +} diff --git a/include/sframe.h b/include/sframe.h index b3d0c2e937d3..90bc92a32f84 100644 --- a/include/sframe.h +++ b/include/sframe.h @@ -93,6 +93,7 @@ extern "C" #define SFRAME_ABI_AARCH64_ENDIAN_BIG 1 /* AARCH64 big endian. */ #define SFRAME_ABI_AARCH64_ENDIAN_LITTLE 2 /* AARCH64 little endian. */ #define SFRAME_ABI_AMD64_ENDIAN_LITTLE 3 /* AMD64 little endian. */ +#define SFRAME_ABI_S390_ENDIAN_BIG 4 /* S390 big endian. */ /* SFrame FRE types. */ #define SFRAME_FRE_TYPE_ADDR1 0 @@ -190,7 +191,7 @@ typedef struct sframe_func_desc_entry - 2-bits: Unused. ------------------------------------------------------------------------ | Unused | PAC auth A/B key (aarch64) | FDE type | FRE type | - | | Unused (amd64) | | | + | | Unused (amd64, s390) | | | ------------------------------------------------------------------------ 8 6 5 4 0 */ uint8_t sfde_func_info; @@ -248,7 +249,7 @@ typedef struct sframe_fre_info - 1 bit: Mangled RA state bit (aarch64 only). ---------------------------------------------------------------------------------- | Mangled-RA (aarch64) | Size of offsets | Number of offsets | base_reg | - | Unused (amd64) | | | | + | Unused (amd64, s390) | | | | ---------------------------------------------------------------------------------- 8 7 5 1 0 @@ -274,7 +275,7 @@ typedef struct sframe_fre_info /* SFrame Frame Row Entry definitions. - Used for both AMD64 and AARCH64. + Used for AMD64, AARCH64, and S390. An SFrame Frame Row Entry is a self-sufficient record which contains information on how to generate the stack trace for the specified range of diff --git a/libsframe/doc/sframe-spec.texi b/libsframe/doc/sframe-spec.texi index d0f99bd698eb..a81faf49f5c1 100644 --- a/libsframe/doc/sframe-spec.texi +++ b/libsframe/doc/sframe-spec.texi @@ -74,8 +74,8 @@ The SFrame stack trace information is provided in a loaded section, known as the @code{.sframe} section. When available, the @code{.sframe} section appears in a new segment of its own, PT_GNU_SFRAME. -The SFrame format is currently supported only for select ABIs, namely, AMD64 -and AAPCS64. +The SFrame format is currently supported only for select ABIs, namely, AMD64, +AAPCS64, and s390. A portion of the SFrame format follows an unaligned on-disk representation. Some data structures, however, (namely the SFrame header and the SFrame @@ -366,6 +366,10 @@ in the format. @item @code{SFRAME_ABI_AMD64_ENDIAN_LITTLE} @tab 3 @tab AMD64 little-endian +@tindex SFRAME_ABI_S390_ENDIAN_BIG +@item @code{SFRAME_ABI_S390_ENDIAN_BIG} +@tab 4 @tab s390 big-endian + @end multitable The presence of an explicit identification of ABI/arch in SFrame may allow -- 2.40.1