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 75245384AB68 for ; Mon, 22 Apr 2024 15:59:22 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 75245384AB68 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 75245384AB68 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=1713801567; cv=none; b=rFScyGWlntD9JPA2WhPTzxkQWXikL63AvwQn4msH6lz23bI+O8WNAWz/DzRL2sY1dg9hDeoozDl0xcdAXBWzfegrD39NsvkvTA272OuOpeCV7D2JpWR4EWmsfe7PUH/dFNBWdHWyHo4bDeZlCNyAW2QiMIwnpbbxL1Y7pYiwAzo= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1713801567; c=relaxed/simple; bh=H/EHlOwq9KoEINo8jRJD6+PGxqsvMA6eRNbcV74C6DM=; h=DKIM-Signature:From:To:Subject:Date:Message-Id:MIME-Version; b=EK/3yyWj1+NHF9LyPW8CPSpHvOQ7JrZ57RAPYcQfq10uPiea9lAnzdsJv30GspFxHxqC0A3xoqY43Gvd8xyLkE+ky1T7YYHOMH2dXH0qAMM3VP66gAWfGSEx/9w1YWifXU22g8jw1hK0sFnlfKjjEXDc4BtzH85DhTmhaMsHuxA= ARC-Authentication-Results: i=1; server2.sourceware.org Received: from pps.filterd (m0353729.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 43MFvZZ9032041; Mon, 22 Apr 2024 15:59:20 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=Vpfn6Z5aAcXvxWL+LoSInwV00SrfUdGdo60u6F0ThNk=; b=ZtIcIQD9DA4SvkqslcmkCQ4UQ7/SA0sVP/fXrCE3HgsJTJ5KtrNyqSb6tzI5O2H67weT VB3IrCGl38CUzOdGoKRA1yGm/MDRZ/l2WLxIgx7uJRLmsi7TOMIe/txEuAbmEyrpDOPR ljccNQdaVowP3ItOhKcxF/nGM94K4kNxvVIGaRXxqTJS7O/j7OCNn8d3dZOGmtDVitOj HhwpIbdStYgrYY13ikxPSykc+mYsjxgxQ3x2crA2VGM7izPcAhTO8FrZP75ropTr8/+n o22bIv/4f6QgptSOaBgV1aGKovnZaXcowy96uXs8XNWsauZ1bNBMQCzb7OiX3/P1WO3t jQ== Received: from ppma11.dal12v.mail.ibm.com (db.9e.1632.ip4.static.sl-reverse.com [50.22.158.219]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 3xnu058040-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 22 Apr 2024 15:59:20 +0000 Received: from pps.filterd (ppma11.dal12v.mail.ibm.com [127.0.0.1]) by ppma11.dal12v.mail.ibm.com (8.17.1.19/8.17.1.19) with ESMTP id 43MEwR7u028763; Mon, 22 Apr 2024 15:59:19 GMT Received: from smtprelay04.fra02v.mail.ibm.com ([9.218.2.228]) by ppma11.dal12v.mail.ibm.com (PPS) with ESMTPS id 3xmtr283t5-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 22 Apr 2024 15:59:19 +0000 Received: from smtpav07.fra02v.mail.ibm.com (smtpav07.fra02v.mail.ibm.com [10.20.54.106]) by smtprelay04.fra02v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 43MFx7OD12976568 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Mon, 22 Apr 2024 15:59:09 GMT Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id A1E9920043; Mon, 22 Apr 2024 15:59:07 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 7CAC02004F; Mon, 22 Apr 2024 15:59:07 +0000 (GMT) Received: from tuxmaker.boeblingen.de.ibm.com (unknown [9.152.85.9]) by smtpav07.fra02v.mail.ibm.com (Postfix) with ESMTP; Mon, 22 Apr 2024 15:59:07 +0000 (GMT) From: Jens Remus To: binutils@sourceware.org, Indu Bhagat Cc: Jens Remus , Andreas Krebbel Subject: [RFC PATCH 1/1] sframe: Represent FP without RA on stack Date: Mon, 22 Apr 2024 17:59:05 +0200 Message-Id: <20240422155905.2497883-2-jremus@linux.ibm.com> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20240422155905.2497883-1-jremus@linux.ibm.com> References: <20240422155905.2497883-1-jremus@linux.ibm.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-TM-AS-GCONF: 00 X-Proofpoint-GUID: VKUNdwxsCg7Y8_9lq8XIqZCGKgIGTdNW X-Proofpoint-ORIG-GUID: VKUNdwxsCg7Y8_9lq8XIqZCGKgIGTdNW X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1011,Hydra:6.0.619,FMLib:17.11.176.26 definitions=2024-04-22_09,2024-04-22_01,2023-05-22_02 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 lowpriorityscore=0 spamscore=0 mlxlogscore=999 clxscore=1015 malwarescore=0 mlxscore=0 bulkscore=0 suspectscore=0 phishscore=0 impostorscore=0 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2404010000 definitions=main-2404220067 X-Spam-Status: No, score=-11.8 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_EF,GIT_PATCH_0,KAM_ASCII_DIVIDERS,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: If an architecture uses both SFrame RA and FP tracking SFrame assumes that the RA offset is the 2nd offset and the FP offset is the 3rd offset following the SFrame FRE. An architecture does not need to store both on the stack. SFrame cannot represent a FP without RA on stack. Update the SFrame V2 FRE info word format to redefine the 4-bit offset count field from the SFrame V1 FRE info word as 4-bit offset presence flags field in the SFrame V2 FRE info word. This allows up to four optional offsets to be tracked. While the mandatory CFA offset is represented in the offset presence flags, it could be omitted to free up one offset presence flag for an optional offset. include/ * sframe.h: Updated SFrame FRE info word for V2. Redefine the 4-bit offset count field as offset presence bits. (SFRAME_V2_FRE_INFO): New macro to build the SFrame V2 FRE info word using offset presence bits instead of offset count. (SFRAME_V2_FRE_OFFSET_FLAGS): New macro to extract the offset presence flags from the SFrame V2 FRE info word. gas/ * gen-sframe.c (sframe_v2_set_fre_info): New function to build the SFrame V2 FRE info word using offset presence bits instead of offset count. (sframe_set_version): Use new sframe_v2_set_fre_info to set the SFrame V2 FRE info word. (sframe_set_fre_info): Redefine parameter num_offsets as offset_count_or_flags. (get_fre_offset_flags): New helper to compute the offset presence flags required for a SFrame V2 FRE. (output_sframe_row_entry): Use new get_fre_offset_flags helper and pass the offset presence flags instead of offset count to sframe_set_fre_info. (sframe_do_fde): Revert commit "gas: Skip SFrame FDE if FP without RA on stack". libsframe/ * sframe.c (sframe_get_fre_offset_count): Compute offset count from offset presence bits using a lookup table. (sframe_get_fre_offset_index): New helper to compute the offset index from the offset presence bits and the offset ID. (sframe_fre_get_cfa_offset, sframe_fre_get_fp_offset, sframe_fre_get_ra_offset): Use new sframe_get_fre_offset_index helper to determine the CFA, FP, and RA offset index. Signed-off-by: Jens Remus --- Notes (jremus): TODO: - Change wording of SFRAME_FRE_{CFA,FP,RA}_OFFSET_IDX, as they no longer represent an index, which the FP offset actually never really did. Maybe use _ID instead of _IDX? - Update SFrame V2 specification accordingly. Can this change still be included in V2 or would it require a V3? gas/gen-sframe.c | 66 ++++++++++++++++++++++++++++------------------ include/sframe.h | 13 ++++++--- libsframe/sframe.c | 51 +++++++++++++++++++++++++++-------- 3 files changed, 90 insertions(+), 40 deletions(-) diff --git a/gas/gen-sframe.c b/gas/gen-sframe.c index 4cc86eb6c815..7f3b406c7882 100644 --- a/gas/gen-sframe.c +++ b/gas/gen-sframe.c @@ -251,7 +251,7 @@ fre_offset_func_map[SFRAME_FRE_OFFSET_FUNC_MAP_INDEX_MAX+1] = static struct sframe_version_ops sframe_ver_ops; /* SFrame (SFRAME_VERSION_1) set FRE info. */ - +/* static unsigned char sframe_v1_set_fre_info (unsigned int base_reg, unsigned int num_offsets, unsigned int offset_size, bool mangled_ra_p) @@ -261,6 +261,19 @@ sframe_v1_set_fre_info (unsigned int base_reg, unsigned int num_offsets, fre_info = SFRAME_V1_FRE_INFO_UPDATE_MANGLED_RA_P (mangled_ra_p, fre_info); return fre_info; } +*/ + +/* SFrame (SFRAME_VERSION_2) set FRE info. */ + +static unsigned char +sframe_v2_set_fre_info (unsigned int base_reg, unsigned int offset_flags, + unsigned int offset_size, bool mangled_ra_p) +{ + unsigned char fre_info; + fre_info = SFRAME_V2_FRE_INFO (base_reg, offset_flags, offset_size); + fre_info = SFRAME_V1_FRE_INFO_UPDATE_MANGLED_RA_P (mangled_ra_p, fre_info); + return fre_info; +} /* SFrame (SFRAME_VERSION_1) set function info. */ static unsigned char @@ -280,10 +293,10 @@ sframe_set_version (uint32_t sframe_version ATTRIBUTE_UNUSED) { sframe_ver_ops.format_version = SFRAME_VERSION_2; - /* These operations remain the same for SFRAME_VERSION_2 as fre_info and - func_info have not changed from SFRAME_VERSION_1. */ + sframe_ver_ops.set_fre_info = sframe_v2_set_fre_info; - sframe_ver_ops.set_fre_info = sframe_v1_set_fre_info; + /* This operation remains the same for SFRAME_VERSION_2 as func_info + has not changed from SFRAME_VERSION_1. */ sframe_ver_ops.set_func_info = sframe_v1_set_func_info; } @@ -291,10 +304,10 @@ sframe_set_version (uint32_t sframe_version ATTRIBUTE_UNUSED) /* SFrame set FRE info. */ static unsigned char -sframe_set_fre_info (unsigned int base_reg, unsigned int num_offsets, +sframe_set_fre_info (unsigned int base_reg, unsigned int offset_count_or_flags, unsigned int offset_size, bool mangled_ra_p) { - return sframe_ver_ops.set_fre_info (base_reg, num_offsets, + return sframe_ver_ops.set_fre_info (base_reg, offset_count_or_flags, offset_size, mangled_ra_p); } @@ -353,6 +366,24 @@ get_fre_num_offsets (struct sframe_row_entry *sframe_fre) return fre_num_offsets; } +/* Get offset flags necessary for the SFrame Frame Row Entry. */ + +static unsigned int +get_fre_offset_flags (struct sframe_row_entry *sframe_fre) +{ + /* CFA offset must always be present. */ + unsigned int fre_offset_flags = 1 << SFRAME_FRE_CFA_OFFSET_IDX; + + if (sframe_fre->bp_loc == SFRAME_FRE_ELEM_LOC_STACK) + fre_offset_flags |= 1 << SFRAME_FRE_FP_OFFSET_IDX; +#ifdef SFRAME_FRE_RA_TRACKING + if (sframe_ra_tracking_p () + && sframe_fre->ra_loc == SFRAME_FRE_ELEM_LOC_STACK) + fre_offset_flags |= 1 << SFRAME_FRE_RA_OFFSET_IDX; +#endif + return fre_offset_flags; +} + /* Get the minimum necessary offset size (in bytes) for this SFrame frame row entry. */ @@ -494,6 +525,7 @@ output_sframe_row_entry (symbolS *fde_start_addr, { unsigned char fre_info; unsigned int fre_num_offsets; + unsigned int fre_offset_flags; unsigned int fre_offset_size; unsigned int fre_base_reg; expressionS exp; @@ -524,8 +556,9 @@ output_sframe_row_entry (symbolS *fde_start_addr, size of offset in this frame row entry. */ fre_base_reg = get_fre_base_reg_id (sframe_fre); fre_num_offsets = get_fre_num_offsets (sframe_fre); + fre_offset_flags = get_fre_offset_flags (sframe_fre); fre_offset_size = sframe_get_fre_offset_size (sframe_fre); - fre_info = sframe_set_fre_info (fre_base_reg, fre_num_offsets, + fre_info = sframe_set_fre_info (fre_base_reg, fre_offset_flags, fre_offset_size, sframe_fre->mangled_ra_p); out_one (fre_info); @@ -1497,25 +1530,6 @@ sframe_do_fde (struct sframe_xlate_ctx *xlate_ctx, = get_dw_fde_end_addrS (xlate_ctx->dw_fde); } -#ifdef SFRAME_FRE_RA_TRACKING - if (sframe_ra_tracking_p ()) - { - struct sframe_row_entry *fre; - - /* Iterate over the scratchpad FREs and validate them. */ - for (fre = xlate_ctx->first_fre; fre; fre = fre->next) - { - /* SFrame format cannot represent FP on stack without RA on stack. */ - if (fre->ra_loc != SFRAME_FRE_ELEM_LOC_STACK - && fre->bp_loc == SFRAME_FRE_ELEM_LOC_STACK) - { - as_warn (_("skipping SFrame FDE due to FP without RA on stack")); - return SFRAME_XLATE_ERR_NOTREPRESENTED; - } - } - } -#endif /* SFRAME_FRE_RA_TRACKING */ - return SFRAME_XLATE_OK; } diff --git a/include/sframe.h b/include/sframe.h index 90bc92a32f84..093dca6cda9a 100644 --- a/include/sframe.h +++ b/include/sframe.h @@ -241,14 +241,14 @@ typedef struct sframe_fre_info { /* Information about - 1 bit: base reg for CFA - - 4 bits: Number of offsets (N). A value of upto 3 is allowed to track - all three of CFA, FP and RA (fixed implicit order). + - 4 bits: Flags for offsets. Upto 3 are allowed to track + all three of CFA, FP and RA (fixed order). - 2 bits: information about size of the offsets (S) in bytes. Valid values are SFRAME_FRE_OFFSET_1B, SFRAME_FRE_OFFSET_2B, SFRAME_FRE_OFFSET_4B - 1 bit: Mangled RA state bit (aarch64 only). ---------------------------------------------------------------------------------- - | Mangled-RA (aarch64) | Size of offsets | Number of offsets | base_reg | + | Mangled-RA (aarch64) | Size of offsets | Flags for offsets | base_reg | | Unused (amd64, s390) | | | | ---------------------------------------------------------------------------------- 8 7 5 1 0 @@ -264,6 +264,11 @@ typedef struct sframe_fre_info (((0 & 0x1) << 7) | (((offset_size) & 0x3) << 5) | \ (((offset_num) & 0xf) << 1) | ((base_reg_id) & 0x1)) +/* Note: Set mangled_ra_p to zero by default. */ +#define SFRAME_V2_FRE_INFO(base_reg_id, offset_flags, offset_size) \ + (((0 & 0x1) << 7) | (((offset_size) & 0x3) << 5) | \ + (((offset_flags) & 0xf) << 1) | ((base_reg_id) & 0x1)) + /* Set the mangled_ra_p bit as indicated. */ #define SFRAME_V1_FRE_INFO_UPDATE_MANGLED_RA_P(mangled_ra_p, fre_info) \ ((((mangled_ra_p) & 0x1) << 7) | ((fre_info) & 0x7f)) @@ -273,6 +278,8 @@ typedef struct sframe_fre_info #define SFRAME_V1_FRE_OFFSET_SIZE(data) (((data) >> 5) & 0x3) #define SFRAME_V1_FRE_MANGLED_RA_P(data) (((data) >> 7) & 0x1) +#define SFRAME_V2_FRE_OFFSET_FLAGS(data) (((data) >> 1) & 0xf) + /* SFrame Frame Row Entry definitions. Used for AMD64, AARCH64, and S390. diff --git a/libsframe/sframe.c b/libsframe/sframe.c index 460face4168e..f43f9eaecfd1 100644 --- a/libsframe/sframe.c +++ b/libsframe/sframe.c @@ -115,7 +115,10 @@ sframe_get_hdr_size (sframe_header *sfh) static uint8_t sframe_fre_get_offset_count (uint8_t fre_info) { - return SFRAME_V1_FRE_OFFSET_COUNT (fre_info); + unsigned int fre_offset_flags = SFRAME_V2_FRE_OFFSET_FLAGS (fre_info); + const char flags_to_count[16] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 }; + + return flags_to_count[fre_offset_flags]; } static uint8_t @@ -130,6 +133,19 @@ sframe_get_fre_ra_mangled_p (uint8_t fre_info) return SFRAME_V1_FRE_MANGLED_RA_P (fre_info); } +static int +sframe_get_fre_offset_index (uint8_t fre_info, unsigned int tracked_offset) +{ + unsigned int fre_offset_flags = SFRAME_V2_FRE_OFFSET_FLAGS (fre_info); + const char flags_to_count[16] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 }; + unsigned int mask = (1 << tracked_offset) - 1; + + if ((fre_offset_flags & (1 << tracked_offset)) == 0) + return -1; + + return flags_to_count[fre_offset_flags & mask]; +} + /* Access functions for info from function descriptor entry. */ static uint32_t @@ -680,7 +696,13 @@ int32_t sframe_fre_get_cfa_offset (sframe_decoder_ctx *dctx ATTRIBUTE_UNUSED, sframe_frame_row_entry *fre, int *errp) { - return sframe_get_fre_offset (fre, SFRAME_FRE_CFA_OFFSET_IDX, errp); + int cfa_offset_idx = sframe_get_fre_offset_index (fre->fre_info, + SFRAME_FRE_CFA_OFFSET_IDX); + if (cfa_offset_idx == -1) + return sframe_set_errno (errp, SFRAME_ERR_FREOFFSET_NOPRESENT); + sframe_assert (cfa_offset_idx == 0); + + return sframe_get_fre_offset (fre, cfa_offset_idx, errp); } /* Get the FP offset from the FRE. If the offset is invalid, sets errp. */ @@ -689,7 +711,7 @@ int32_t sframe_fre_get_fp_offset (sframe_decoder_ctx *dctx, sframe_frame_row_entry *fre, int *errp) { - uint32_t fp_offset_idx = 0; + int fp_offset_idx; int8_t fp_offset = sframe_decoder_get_fixed_fp_offset (dctx); /* If the FP offset is not being tracked, return the fixed FP offset from the SFrame header. */ @@ -700,13 +722,13 @@ sframe_fre_get_fp_offset (sframe_decoder_ctx *dctx, return fp_offset; } - /* In some ABIs, the stack offset to recover RA (using the CFA) from is - fixed (like AMD64). In such cases, the stack offset to recover FP will - appear at the second index. */ - fp_offset_idx = ((sframe_decoder_get_fixed_ra_offset (dctx) - != SFRAME_CFA_FIXED_RA_INVALID) - ? SFRAME_FRE_RA_OFFSET_IDX - : SFRAME_FRE_FP_OFFSET_IDX); + /* Get the FP offset index and check that it is valid. */ + fp_offset_idx = sframe_get_fre_offset_index (fre->fre_info, + SFRAME_FRE_FP_OFFSET_IDX); + if (fp_offset_idx == -1) + return sframe_set_errno (errp, SFRAME_ERR_FREOFFSET_NOPRESENT); + + /* Otherwise, get the FP offset from the FRE. */ return sframe_get_fre_offset (fre, fp_offset_idx, errp); } @@ -716,6 +738,7 @@ int32_t sframe_fre_get_ra_offset (sframe_decoder_ctx *dctx, sframe_frame_row_entry *fre, int *errp) { + int ra_offset_idx; int8_t ra_offset = sframe_decoder_get_fixed_ra_offset (dctx); /* If the RA offset was not being tracked, return the fixed RA offset from the SFrame header. */ @@ -726,8 +749,14 @@ sframe_fre_get_ra_offset (sframe_decoder_ctx *dctx, return ra_offset; } + /* Get the RA offset index and check that it is valid. */ + ra_offset_idx = sframe_get_fre_offset_index (fre->fre_info, + SFRAME_FRE_RA_OFFSET_IDX); + if (ra_offset_idx == -1) + return sframe_set_errno (errp, SFRAME_ERR_FREOFFSET_NOPRESENT); + /* Otherwise, get the RA offset from the FRE. */ - return sframe_get_fre_offset (fre, SFRAME_FRE_RA_OFFSET_IDX, errp); + return sframe_get_fre_offset (fre, ra_offset_idx, errp); } /* Get whether the RA is mangled. */ -- 2.40.1