[PATCH v2 03/11] s390: Initial support to generate .sframe from CFI directives in assembler

Indu Bhagat indu.bhagat@oracle.com
Fri Jun 6 17:38:46 GMT 2025


On 6/3/25 6:11 AM, Jens Remus wrote:
>>> +@section s390x
>>> +
>>> +A stack tracer implementation must initialize the SP to the designated SP
>>> +register value, the FP to the preferred FP register value, and the RA to the
>>> +designated RA register value in the topmost stack frame of the callchain.  This
>>> +is required, as either the SP or FP is used as CFA base register and as the FP
>>> +and/or RA are not necessarily saved on the stack.  For RA this may only be the
>>> +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.
>>> +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.
>>> +
>>> +The (64-bit) s390x ELF ABI does not mandate the precise location in a function
>>> +where the return address (RA) and frame pointer (FP) are saved, if at all.
>>> +Hence the need to track RA in the SFrame stack trace format.  As RA is being
>>> +tracked in this ABI, the second stack offset is always used to locate the RA
>>> +stack slot, by interpreting it as: RA = CFA + offset2.  RA remains unchanged,
>>> +if the offset is not available.  The third stack offset is used to locate the
>>> +FP stack slot, by interpreting it as: FP = CFA + offset3.  FP remains unchanged,
>>> +if the offset is not available.
>>> +It is recommended that a stack tracer implementation performs the required
>>> +checks to ensure that RA remains unchanged only for the topmost stack frame
>>> +in the callchain.
>>> +
>> I find the last statement difficult to follow. In light of the patches
>> 04/11 and 05/11, which allow RA to be saved in say FPR, or RA to be
>> not saved on stack respectively, I am not sure I fully grasp the scope
>> of the statement "RA remains unchanged only for the topmost stack
>> frame in the callchain".
> Let me try to explain what I intended to convey.  Maybe you can help me
> get the wording right.
> 
> A stack tracer using SFrame first initializes:
> 
>    SP = designated SP register content
>    FP = designated (s390x: preferred) SP register content
>    RA = designated RA register content, if arch uses RA tracking
> 
> Then for each frame it uses the SFrame CFA, FP, and RA tracking info to
> determine:
> 
>    CFA = CFA_base_reg + CFA_offset
> 
>    SP = CFA [+ SP_val_offset on s390x]
> 
>    if FP_offset != 0:
> 	FP = restore FP from stack at CFA + FP_offset (or register on s390x)
> 
>    if RA_offset == 0 && !topmost:
> 	error
>    if RA_offset != 0:
> 	RA = restore RA from stack at CFA + RA_offset (or register on s390x)
> 
> Whether RA may be unchanged (not saved on the stack nor in another
> register) is only valid in the topmost frame.  For the FP that may
> be the case in for any frame, as a frame is not forced to modify
> the FP.  Saved in another register is also only valid in the topmost
> frame, as the stack tracer only then has access to all register values.

(Sorry for the delay)

Thanks.  IMO, the following is clear(er):

It is recommended that a stack tracer implements a check to ensure that 
RA offset can have a value of SFRAME_FRE_RA_OFFSET_INVALID for topmost 
frame only.

And for better flow, I would recommend the above line be added before we 
start talking about the FP offset.  So, perhaps right after the 
statement : "RA remains unchanged, if the offset is not available or has 
a value of SFRAME_FRE_RA_OFFSET_INVALID"


More information about the Binutils mailing list