[RFC 19/28] [SFrame-V3] sframe: gas: translate specific CFI directives for SFRAME_FDE_TYPE_FLEX_TOPMOST_FRAME
Indu Bhagat
indu.bhagat@oracle.com
Tue Dec 16 06:14:53 GMT 2025
More information about the Binutils mailing list
Tue Dec 16 06:14:53 GMT 2025
- Previous message (by thread): [RFC 19/28] [SFrame-V3] sframe: gas: translate specific CFI directives for SFRAME_FDE_TYPE_FLEX_TOPMOST_FRAME
- Next message (by thread): [RFC 19/28] [SFrame-V3] sframe: gas: translate specific CFI directives for SFRAME_FDE_TYPE_FLEX_TOPMOST_FRAME
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
On 12/15/25 4:54 AM, Jens Remus wrote:
> On 12/9/2025 10:07 AM, Indu Bhagat wrote:
>> This patch updates the SFrame generation in GAS to translate specific CFI
>> directives into the new SFrame V3 FDE type: SFRAME_FDE_TYPE_FLEX_TOPMOST_FRAME.
>>
>> The primary goal is to support code patterns where:
>> - the Canonical Frame Address (CFA) is not defined by a simple offset
>> from the Stack Pointer (SP) or Frame Pointer (FP), or where the CFA
>> rule involves a dereference. Such patterns are generated by compilers
>> for stack realignment (e.g., DRAP on x86_64, or when mixing legacy
>> codes that keep 4-byte stack alignment with modern codes that keep
>> 16-byte stack alignment for SSE compatibility).
>> - the Frame Pointer is not defined by a simple offset from the CFA,
>> but may even involve another register and/or dereferencing.
>> - the Return Address is not defined by a simple offset from the CFA,
>> but may even involve another register and/or dereferencing.
>>
>> Support for non-SP/FP based CFA: Update sframe_xlate_do_def_cfa () and
>> sframe_xlate_do_def_cfa_register () to detect when a non-SP/FP register
>> is used for the CFA.
>>
>> Support for CFA expressions: A vital part of supporting the
>> above-mentioned cases on AMD64 is support for CFA expressions. Add
>> sframe_xlate_do_escape_cfa_expr () to parse simple
>> DW_CFA_def_cfa_expression sequence in .cfi_escape.
>>
>> Support for FP expressions: Update sframe_xlate_do_escape_expr () to
>> handle DW_CFA_expression involving `DW_OP_breg6` (rbp) on AMD64,
>> allowing for tracking of the Frame Pointer when it is saved with a
>> dereference rule in the DRAP pattern.
>>
>> The "support" for both CFA expressions and FP expressions is quite
>> minimal, and is tailored to the most commonly seen occurences generated
>
> Nit: occurrences
>
OK
>> by GCC.
>>
>> Add a helper sframe_fre_reg_encodable_p () to verify if a DWARF register
>> number can be encoded in the limited bits (5 bits) available in the
>> SFrame format.
>>
>> This functionality is currently implemented only for the
>> SFRAME_ABI_AMD64_ENDIAN_LITTLE ABI. Support for other ABIs may be added
>> without format version bump, as the necessary specification changes will
>> already be in place.
>
> Why did you limit it to AMD64?
>
Only for design and coding related ease. I also needed some reviews of
the overall direction etc.. We can enable flexible frames for s390x too.
>> diff --git a/gas/gen-sframe.c b/gas/gen-sframe.c
>
>> @@ -1189,30 +1204,46 @@ sframe_xlate_do_def_cfa (struct sframe_xlate_ctx *xlate_ctx,
>> sframe_fre_set_begin_addr (cur_fre,
>> get_dw_fde_start_addrS (xlate_ctx->dw_fde));
>> }
>> - /* Define the current CFA rule to use the provided register and
>> - offset. However, if the register is not FP/SP, skip creating
>> - SFrame stack trace info for the function. */
>> - if (cfi_insn->u.ri.reg != SFRAME_CFA_SP_REG
>> - && cfi_insn->u.ri.reg != SFRAME_CFA_FP_REG)
>> - {
>> - as_warn (_("no SFrame FDE emitted; "
>> - "non-SP/FP register %u in .cfi_def_cfa"),
>> - cfi_insn->u.ri.reg);
>> - return SFRAME_XLATE_ERR_NOTREPRESENTED; /* Not represented. */
>> - }
>> - else if (sframe_fre_stack_offset_bound_p (cfi_insn->u.ri.offset, true))
>> - {
>> - sframe_fre_set_cfa_base_reg (cur_fre, cfi_insn->u.ri.reg);
>> - sframe_fre_set_cfa_offset (cur_fre, cfi_insn->u.ri.offset);
>> - cur_fre->merge_candidate = false;
>> - }
>> - else
>> +
>> + offsetT offset = cfi_insn->u.ri.offset;
>> + bool bound_p = sframe_fre_stack_offset_bound_p (offset, true);
>> + if (!bound_p)
>> {
>> as_warn (_("no SFrame FDE emitted; "
>> ".cfi_def_cfa with unsupported offset value"));
>> return SFRAME_XLATE_ERR_NOTREPRESENTED;
>> }
>>
>> + /* Define the current CFA rule to use the provided register and
>> + offset. Typically, the CFA rule uses SP/FP based CFA. However, with
>> + SFrame V3 specification, if the CFA register is not FP/SP, SFrame FDE type
>> + SFRAME_FDE_TYPE_FLEX_TOPMOST_FRAME type may be used.
>> +
>> + ATM however, GAS implements non-SP/FP based CFA only for AMD64, where such
>> + a CFA pattern may be seen (e.g., DRAP, stack alignment). On s390x, this
>> + may be seen for (GCC) generated code for static stack clash protection.
>> + This remains sufficiently rare and is currently unimplemented for s390x.
>> + */
>> + if (cfi_insn->u.ri.reg != SFRAME_CFA_SP_REG
>> + && cfi_insn->u.ri.reg != SFRAME_CFA_FP_REG)
>> + {
>> + if (sframe_get_abi_arch () != SFRAME_ABI_AMD64_ENDIAN_LITTLE
>> + || !sframe_fre_reg_encodable_p (cfi_insn->u.ri.reg))
>
> Maybe use an architecture-configurable knob instead? For example:
>
> /* Whether to support SFrame FLEX_TOPMOST_FRAME. */
> extern bool x86_sframe_flex_topmost_frame_p (void);
> #define sframe_flex_topmost_frame_p x86_sframe_flex_topmost_frame_p
>
> And then change above as follows:
>
> if (!sframe_flex_topmost_frame_p () || !sframe_fre_reg_encodable_p (cfi_insn->u.ri.reg))
>
>
Yeah, there is some clutter because of those (sframe_get_abi_arch () !=
SFRAME_ABI_AMD64_ENDIAN_LITTLE) checks. Perhaps
sframe_flex_topmost_frame_p () will help there too.
>> + {
>> + as_warn (_("no SFrame FDE emitted; "
>> + "non-SP/FP register %u in .cfi_def_cfa"),
>> + cfi_insn->u.ri.reg);
>> + return SFRAME_XLATE_ERR_NOTREPRESENTED;
>> + }
>> + else
>> + xlate_ctx->flex_topmost_p = true;
>> + }
>> +
>> + sframe_fre_set_cfa_base_reg (cur_fre, cfi_insn->u.ri.reg);
>> + sframe_fre_set_cfa_offset (cur_fre, cfi_insn->u.ri.offset);
>> + cur_fre->merge_candidate = false;
>> + cur_fre->cfa_deref_p = false;
>> +
>> return SFRAME_XLATE_OK;
>> }
>>
>> @@ -1234,14 +1265,23 @@ sframe_xlate_do_def_cfa_register (struct sframe_xlate_ctx *xlate_ctx,
>> if (cfi_insn->u.r != SFRAME_CFA_SP_REG
>> && cfi_insn->u.r != SFRAME_CFA_FP_REG)
>> {
>> - as_warn (_("no SFrame FDE emitted; "
>> - "non-SP/FP register %u in .cfi_def_cfa_register"),
>> - cfi_insn->u.r);
>> - return SFRAME_XLATE_ERR_NOTREPRESENTED; /* Not represented. */
>> + if (sframe_get_abi_arch () != SFRAME_ABI_AMD64_ENDIAN_LITTLE)
>
> Likewise:
>
> if (!sframe_flex_topmost_frame_p ())
>
OK.
>> + {
>> + as_warn (_("no SFrame FDE emitted; "
>> + "non-SP/FP register %u in .cfi_def_cfa_register"),
>> + cfi_insn->u.ri.reg);
>> + return SFRAME_XLATE_ERR_NOTREPRESENTED;
>> + }
>> + else
>> + /* Currently, SFRAME_FDE_TYPE_FLEX_TOPMOST_FRAME is generated for AMD64
>> + only. */
>> + xlate_ctx->flex_topmost_p = true;
>> }
>> +
>> sframe_fre_set_cfa_base_reg (cur_fre, cfi_insn->u.r);
>> if (last_fre)
>> sframe_fre_set_cfa_offset (cur_fre, sframe_fre_get_cfa_offset (last_fre));
>> + cur_fre->cfa_deref_p = false;
>>
>> cur_fre->merge_candidate = false;
>>
>> @@ -1574,6 +1614,98 @@ sframe_xlate_do_gnu_window_save (struct sframe_xlate_ctx *xlate_ctx,
>> return SFRAME_XLATE_ERR_NOTREPRESENTED; /* Not represented. */
>> }
> Thanks and regards,
> Jens
- Previous message (by thread): [RFC 19/28] [SFrame-V3] sframe: gas: translate specific CFI directives for SFRAME_FDE_TYPE_FLEX_TOPMOST_FRAME
- Next message (by thread): [RFC 19/28] [SFrame-V3] sframe: gas: translate specific CFI directives for SFRAME_FDE_TYPE_FLEX_TOPMOST_FRAME
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
More information about the Binutils mailing list