[PATCH v3 08/11] s390: Store SFrame CFA offset adjusted

Jens Remus jremus@linux.ibm.com
Mon Jul 7 15:07:55 GMT 2025


Hello Indu,

thank you for the review and feedback!

On 06.07.2025 01:25, Indu Bhagat via Binutils wrote:
> On 6/27/25 4:08 AM, Jens Remus wrote:
>> In SFrame V2 the size of the offsets following an SFrame FRE can be
>> either signed 8-bit, 16-bit, or 32-bit integer, which the largest offset
> 
> Typo: "with" the largest offset

Sure.  My bad.

>> determining their size:
>>    1. CFA offset from CFA base register
>>    2. RA (stack save slot) offset from CFA, usually -48 on s390x if saved
>>    3. FP (stack save slot) offset from CFA, usually -72 on s390x if saved
>> The FP and RA offsets from CFA, when FP/RA saved on the stack, usually
>> have fixed values that fit into signed 8-bit SFrame offsets.  Likewise
>> the DWARF register numbers on s390x of general registers (GR; 0-15) and
>> floating-point registers (FPR; 16-31), when FP/RA saved in registers.
>> With that the CFA offset from CFA base register has the greatest impact
>> on the signed SFrame offset size.
>>
>> The s390x ELF ABI [1] defines the CFA as stack pointer (SP) at call
>> site +160. [2]  Therefore the minimum CFA offset from CFA base register
>> on s390x is 160.  This does not fit into a signed 8-bit integer and
>> therefore effectively prevents any use of signed 8-bit SFrame offsets
>> on s390x.
>>
>> For s390x store the CFA offset from CFA base register adjusted by -160
>> to enable the use of signed 8-bit SFrame offsets.
>>
>> [1]: s390x ELF ABI, https://github.com/IBM/s390x-abi/releases
>> [2]: s390x ELF ABI, commit 4e38ad9c8a88 ("Document the CFA"),
>>       https://github.com/IBM/s390x-abi/commit/4e38ad9c8a88
>>
>> include/
>>     * sframe.h (SFRAME_S390X_CFA_OFFSET_ADJUSTMENT): Define
>>     s390x-specific CFA offset adjustment.
>>     (SFRAME_V2_FRE_S390X_CFA_OFFSET_ENCODE,
>>     SFRAME_V2_FRE_S390X_CFA_OFFSET_DECODE): New s390x-specific
>>     macros.  Use SFRAME_S390X_CFA_OFFSET_ADJUSTMENT to en-/decode
>>     CFA offset.
>>
>> bfd/
>>     * elf64-s390.c (elf_s390x_sframe_plt_fre): Use
>>     SFRAME_V2_FRE_S390X_CFA_OFFSET_ENCODE on CFA offset to store it
>>     adjusted and switch to 8-bit offsets.
>>
>> gas/
>>     * gen-sframe.c (sframe_fre_set_cfa_offset): For s390x use
>>     SFRAME_V2_FRE_S390X_CFA_OFFSET_ENCODE on CFA offset to store it
>>     adjusted.
>>     (sframe_fre_get_cfa_offset): New helper.  For s390x use
>>     SFRAME_V2_FRE_S390X_CFA_OFFSET_DECODE on CFA offset to undo its
>>     adjustment.
>>     (sframe_xlate_do_def_cfa_register): Use new helper
>>     sframe_fre_get_cfa_offset.
>>
>> libsframe/
>>     * sframe.c (sframe_fre_get_cfa_offset): For s390x use
>>     SFRAME_V2_FRE_S390X_CFA_OFFSET_DECODE on CFA offset to undo its
>>     adjustment.
>>     * doc/sframe-spec.texi (s390x,
>>     SFRAME_S390X_CFA_OFFSET_ADJUSTMENT,
>>     SFRAME_V2_FRE_S390X_CFA_OFFSET_ENCODE,
>>     SFRAME_V2_FRE_S390X_CFA_OFFSET_DECODE): Document s390x-specific
>>     adjustment of CFA offset.
>>
>> libsframe/testsuite/
>>     * libsframe.find/plt-findfre-2.c (add_plt0_fde, add_pltn_fde):
>>     Use SFRAME_V2_FRE_S390X_CFA_OFFSET_ENCODE to enable use of
>>     1-byte SFrame offsets.
>>
>> Suggested-by: Indu Bhagat <indu.bhagat@oracle.com>
>> Signed-off-by: Jens Remus <jremus@linux.ibm.com>
> 
> One comment for sframe-spec.texi below.
> 
> Otherwise, LGTM.
> 
> Reviewed-by: Indu Bhagat <indu.bhagat@oracle.com>

>> diff --git a/gas/gen-sframe.c b/gas/gen-sframe.c

>> @@ -134,10 +134,26 @@ sframe_fre_set_cfa_base_reg (struct sframe_row_entry *fre,
>>     fre->merge_candidate = false;
>>   }
>>   +static offsetT
>> +sframe_fre_get_cfa_offset (const struct sframe_row_entry * fre)

The recent fix of relocatable SFrame links now include "sframe-api.h".
This cases above new internal helper to clash with the external SFrame
API function of same name.  For V4 I have prefixed the internal helper
with "__", which I somewhat dislike.  Any better suggestion to resolve?

>> +{
>> +  offsetT offset = fre->cfa_offset;
>> +
>> +  /* For s390x undo adjustment of CFA offset (to enable 8-bit offsets).  */
>> +  if (sframe_get_abi_arch () == SFRAME_ABI_S390X_ENDIAN_BIG)
>> +    offset = SFRAME_V2_FRE_S390X_CFA_OFFSET_DECODE (offset);
>> +
>> +  return offset;
>> +}
>> +
>>   static void
>>   sframe_fre_set_cfa_offset (struct sframe_row_entry *fre,
>>                  offsetT cfa_offset)
>>   {
>> +  /* For s390x adjust CFA offset to enable 8-bit offsets.  */
>> +  if (sframe_get_abi_arch () == SFRAME_ABI_S390X_ENDIAN_BIG)
>> +    cfa_offset = SFRAME_V2_FRE_S390X_CFA_OFFSET_ENCODE (cfa_offset);
>> +
>>     fre->cfa_offset = cfa_offset;
>>     fre->merge_candidate = false;
>>   }
>> @@ -1036,7 +1052,7 @@ sframe_xlate_do_def_cfa_register (struct sframe_xlate_ctx *xlate_ctx,
>>       }
>>     sframe_fre_set_cfa_base_reg (cur_fre, cfi_insn->u.r);
>>     if (last_fre)
>> -    sframe_fre_set_cfa_offset (cur_fre, last_fre->cfa_offset);
>> +    sframe_fre_set_cfa_offset (cur_fre, sframe_fre_get_cfa_offset (last_fre));
>>       cur_fre->merge_candidate = false;

>> diff --git a/libsframe/doc/sframe-spec.texi b/libsframe/doc/sframe-spec.texi

>> @@ -144,6 +144,12 @@ an FP/RA offset.
>>   @item SFRAME_FRE_RA_OFFSET_INVALID: Invalid RA offset value (like
>>   SFRAME_CFA_FIXED_RA_INVALID).  Used on s390x as padding offset to represent
>>   FP without RA saved.
>> +@item SFRAME_S390X_CFA_OFFSET_ADJUSTMENT: CFA offset (from CFA base register)
>> +adjustment value.  Used to enable use of 8-bit SFrame offsets on s390x.
>> +@item SFRAME_V2_FRE_S390X_CFA_OFFSET_ENCODE: Encode CFA offset (i.e. apply
>> +CFA offset adjustment).
>> +@item SFRAME_V2_FRE_S390X_CFA_OFFSET_DECODE: Decode CFA offset (i.e. unapply
>> +CFA offset adjustment).
> 
> Comma after i.e. : "i.e.,"
> Instead of unapply, perhaps "revert the CFA offset adjustment" may be better.

Ok.

>>   @end itemize
>>   @end itemize
>>   @@ -865,7 +871,15 @@ case in the topmost stack frame of the callchain.  For FP this may be the case
>>   in any stack frame.
>>     Irrespective of the ABI, the first stack offset is always used to locate the
>> -CFA, by interpreting it as: CFA = @code{BASE_REG} + offset1.
>> +CFA.  On s390x the value of the offset is stored adjusted by the s390x-specific
>> +@code{SFRAME_S390X_CFA_OFFSET_ADJUSTMENT} to enable the use of signed 8-bit
>> +offsets on s390x.
>> +s390x-specific helpers @code{SFRAME_V2_FRE_S390X_CFA_OFFSET_ENCODE} and
>> +@code{SFRAME_V2_FRE_S390X_CFA_OFFSET_DECODE} are provided to perform and undo
>> +the adjustment.  The CFA offset can therefore be interpreted as:
>> +CFA = @code{BASE_REG} + @code{SFRAME_V2_FRE_S390X_CFA_OFFSET_DECODE(offset1)}
>> +or
>> +CFA = @code{BASE_REG} + offset1 - @code{SFRAME_S390X_CFA_OFFSET_ADJUSTMENT}.
>>   The identification of the @code{BASE_REG} is done by using the
>>   @code{fre_cfa_base_reg_id} field in the SFrame FRE info word.

Regards,
Jens
-- 
Jens Remus
Linux on Z Development (D3303)
+49-7031-16-1128 Office
jremus@de.ibm.com

IBM

IBM Deutschland Research & Development GmbH; Vorsitzender des Aufsichtsrats: Wolfgang Wendt; Geschäftsführung: David Faller; Sitz der Gesellschaft: Böblingen; Registergericht: Amtsgericht Stuttgart, HRB 243294
IBM Data Privacy Statement: https://www.ibm.com/privacy/



More information about the Binutils mailing list