[PATCH v1] PowerPC: Initial SFrame support for 64-bit PowerPC ELF ABI

Jens Remus jremus@linux.ibm.com
Wed Mar 25 08:47:31 GMT 2026


On 3/24/2026 6:02 PM, Abhay Kandpal wrote:
> Inspired by s390 commit d27d82f560a8 ("s390: Initial support to generate
> .sframe from CFI directives in assembler").
> 
> Support for SFrame on PowerPC 64 is only enabled for the 64-bit PowerPC
> ELF ABI.
> 
> The SFrame ABI/arch identifiers SFRAME_ABI_PPC64_ENDIAN_BIG and
> SFRAME_ABI_PPC64_ENDIAN_LITTLE are introduced for PowerPC 64 big/little
> endian and added to the SFrame format specification.
> 
> Port x86-64 commit d7f343eaad3f ("x86-64: Remove sframe relocs against
> discarded sections").
> 
> Based on s390 64-bit (s390x) commit 955570f0973d ("s390: Represent FP
> without RA saved in SFrame").
> 
> 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 a SFrame FRE.  An architecture does not necessarily need to
> save both on the stack (or in register) at the same time or even at all.
> SFrame cannot represent FP without RA saved on stack (or in a register),
> since it cannot distinguish whether the 2nd offset is the RA or FP
> offset.
> 
> For PPC64 use an invalid SFrame RA offset from CFA value of zero as
> padding to represent the FP being saved when the RA is not saved.  This
> aligns with the existing invalid SFrame fixed RA offset from CFA value
> of zero.  In a stack tracer this then also naturally falls into place,
> as it can skip restoring the RA in the topmost frame, if both the fixed
> RA offset (from SFrame header) and the RA offset (from FDE) are zero,
> without any need to test architecture-specific flags.
> 
> include/
> 	* sframe.h (SFRAME_ABI_PPC64_ENDIAN_BIG,
> 	SFRAME_ABI_PPC64_ENDIAN_LITTLE): Define.
> 	* sframe-api.h (sframe_fre_get_ra_offset): Add PPC64 to comment
> 	for RA offset value of SFRAME_FRE_RA_OFFSET_INVALID indicating
> 	that the RA is not saved.
> 
> libsframe/
> 	* sframe.c (need_swapping): Handle SFRAME_ABI_PPC64_ENDIAN_BIG
> 	and SFRAME_ABI_PPC64_ENDIAN_LITTLE.
> 	* doc/sframe-spec.texi (SFRAME_ABI_PPC64_ENDIAN_BIG,
> 	SFRAME_ABI_PPC64_ENDIAN_LITTLE, PPC64): Document SFrame ABI/arch
> 	identifier for PPC64, add references to 64-bit PowerPC
> 	architecture, and document PPC64-specifics.
> 	* sframe-dump.c (ppc64_sframe_abi_reg_map): Define register map
> 	for PPC64.
> 	(sframe_get_reg_name): Use PPC64 register map for PPC64.
> 	(dump_sframe_func_fres_simple): Update comment to mention PPC64
> 	for RA offset padding.
> 
> gas/
> 	* NEWS: Mention powerpc64 support to generate SFrame from CFI
> 	directives.
> 	* config/tc-ppc.h (support_sframe_p, SFRAME_CFA_SP_REG,
> 	SFRAME_CFA_FP_REG, SFRAME_CFA_RA_REG, sframe_ra_tracking_p,
> 	sframe_cfa_ra_offset, sframe_get_abi_arch,
> 	sframe_support_flex_fde_p): Define.
> 	* config/tc-ppc.c (ppc_support_sframe_p,
> 	ppc_sframe_get_abi_arch): New functions.  Return whether SFrame
> 	is supported and the SFrame ABI/arch identifier.
> 	gen-sframe.c (get_fre_dataword_count): For PPC64 account padding
> 	RA offset, if FP without RA saved.
> 	(sframe_get_fre_dataword_size): Likewise.
> 	(output_sframe_row_entry_datawords): For PPC64 write a padding
> 	RA offset, if FP without RA needs to be represented.
> 	(sframe_do_fde): Enable FP without RA saved to be represented
> 	on PPC64.
> 
> gas/testsuite/
> 	* gas/cfi-sframe/cfi-sframe.exp: Enable common SFrame tests
> 	on PPC64.
> 	* gas/cfi-sframe/cfi-sframe-common-8.s: Use registers 2 and 3,
> 	as register 1 is SP on PPC64.
> 	* gas/cfi-sframe/cfi-sframe-common-10.s: Likewise.
> 	* gas/cfi-sframe/cfi-sframe-ppc64-1.s: New test.
> 	* gas/cfi-sframe/cfi-sframe-ppc64-1.d: Likewise.
> 	* gas/cfi-sframe/cfi-sframe-ppc64-3.s: New test.
> 	* gas/cfi-sframe/cfi-sframe-ppc64-3.d: Likewise.
> 	* gas/cfi-sframe/cfi-sframe-ppc64-err-3.s: New test.
> 	* gas/cfi-sframe/cfi-sframe-ppc64-err-3.d: Likewise.

 	* gas/cfi-sframe/cfi-sframe-ppc64-fpra-offset-1.s: New test.
 	* gas/cfi-sframe/cfi-sframe-ppc64-fpra-offset-1.d: Likewise.

> 	* gas/cfi-sframe/cfi-sframe-ppc64-fpra-offset-2.s: New test.
> 	* gas/cfi-sframe/cfi-sframe-ppc64-fpra-offset-2.d: Likewise.
> 	* gas/cfi-sframe/cfi-sframe-ppc64-fpra-register-2.s: New test.
> 	* gas/cfi-sframe/cfi-sframe-ppc64-fpra-register-2.d: Likewise.
> 	* gas/cfi-sframe/cfi-sframe-ppc64-non-spfp-cfa-2.s: New test.
> 	* gas/cfi-sframe/cfi-sframe-ppc64-non-spfp-cfa-2.d: Likewise.
> 	* gas/cfi-sframe/cfi-sframe-ppc64-pr33756.s: New test.
> 	* gas/cfi-sframe/cfi-sframe-ppc64-pr33756.d: Likewise.
> 	* gas/cfi-sframe/cfi-sframe-ppc64-ra-undefined-1.s: New test.
> 	* gas/cfi-sframe/cfi-sframe-ppc64-ra-undefined-1.d: Likewise.
> 
> bfd/
> 	* elf64-ppc.c (ppc64_elf_relocate_section): Remove sframe relocs
> 	against discarded sections.
> 
> Co-authored-by: Jens Remus <jremus@linux.ibm.com>
> Signed-off-by: Abhay Kandpal <abhay@linux.ibm.com>
LGTM.  Please see my minor comments.

Let's see what Indu has to say. :-)

> diff --git a/gas/NEWS b/gas/NEWS
> index e384d1135c0..fbc755861ce 100644
> --- a/gas/NEWS
> +++ b/gas/NEWS
> @@ -1,5 +1,10 @@
>  -*- text -*-
>  
> +Changes in 2.47:
> +

Nit: IIUC above line is added by the binutils maintainer before a new
release, so please drop that.

> +* Add support to generate SFrame stack trace information (.sframe)
> +  from CFI directives on PowerPC 64-bit (powerpc64).
> +
>  Changes in 2.46:
>  
>  * Add support for AMD Zen6 processor.

> diff --git a/gas/testsuite/gas/cfi-sframe/cfi-sframe-ppc64-fpra-offset-1.s b/gas/testsuite/gas/cfi-sframe/cfi-sframe-ppc64-fpra-offset-1.s
> new file mode 100644
> index 00000000000..6053b54534a
> --- /dev/null
> +++ b/gas/testsuite/gas/cfi-sframe/cfi-sframe-ppc64-fpra-offset-1.s
> @@ -0,0 +1,17 @@
> +	.cfi_sections .sframe
> +	.cfi_startproc
> +	mflr 0
> +	std 0,112(1)
> +	.cfi_offset 65, 112
> +	std 31,88(1)
> +	.cfi_offset 31, 88

Is it intentional that RA (= LR) and FP are saved at non-default
offsets?  Are these within the red zone on PPC64?

> +	li 31,0
> +	li 0,0
> +.Lreturn:
> +	ld 31,88(1)
> +	.cfi_restore 31
> +	ld 0,112(1)
> +	mtlr 0
> +	.cfi_restore 65
> +	blr
> +	.cfi_endproc


> diff --git a/gas/testsuite/gas/cfi-sframe/cfi-sframe-ppc64-fpra-offset-2.s b/gas/testsuite/gas/cfi-sframe/cfi-sframe-ppc64-fpra-offset-2.s
> new file mode 100644
> index 00000000000..67798c24191
> --- /dev/null
> +++ b/gas/testsuite/gas/cfi-sframe/cfi-sframe-ppc64-fpra-offset-2.s
> @@ -0,0 +1,18 @@
> +	.cfi_sections .sframe
> +	.cfi_startproc
> +	# No stack allocation, CFA = SP+0 implicitly
> +	std 31,88(1)            # Save FP at SP+88
> +	.cfi_offset 31, 88      # FP at CFA+88
> +	mflr 0                  # Get LR
> +	std 0,112(1)            # Save RA at SP+112
> +	.cfi_offset 65, 112     # RA at CFA+112

Likewise (non-default offsets intentional?).

> +	li 31,0                 # Clear registers
> +	li 0,0
> +.Lreturn:
> +	ld 0,112(1)             # Restore RA
> +	mtlr 0
> +	.cfi_restore 65
> +	ld 31,88(1)             # Restore FP
> +	.cfi_restore 31
> +	blr
> +	.cfi_endproc

Thanks and regards,
Jens
-- 
Jens Remus
Linux on Z Development (D3303)
jremus@de.ibm.com / jremus@linux.ibm.com

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



More information about the Binutils mailing list