[PATCH] libsframe: use proper FRE type when flipping SFrame V3 FREs

Indu Bhagat indu.bhagat@oracle.com
Tue Jan 20 07:22:01 GMT 2026


On 1/19/26 7:46 AM, Jens Remus wrote:
> flip_sframe_fdes_with_fres_v3 was erroneously using a fixed FRE type
> of 0 (= SFRAME_FRE_TYPE_ADDR1) when endianness byte-flipping the FREs,
> regardless of the actual FRE type (i.e. ADDR1, ADDR2, or ADDR4).  This
> only affected cross builds, where the .sframe section data may needed
> to be endianness byte-flipped (e.g. binutils cross-built for s390
> 64-bit (s390x) on x86-64).
> 
> As a consequence objdump/readelf with option --sframe could fail to dump
> e.g. s390 64-bit (s390x) .sframe section data on x86-64 with the
> following error message:
> 
>    Error: SFrame decode failure: Buffer does not contain SFrame data.
> 
> The linker ld-sframe test "PR ld/33401 (Step 1: Create relocatable
> object and check R_*_NONE)" cross-build for s390 64-bit (s390x) on
> x86-64 could fail with ld error message:
> 
>    error in tmpdir/StatePlaying.o(.sframe); no .sframe will be created
> 
> The linker ld-sframe test "PR ld/33401 (Step 1: Create relocatable
> object and check R_*_NONE)" cros-build for s390 64-bit (s390x) on
> x86-64 could fail with BDF assertion:
> 
>    BFD (GNU Binutils) ... assertion fail .../bfd/elf-sframe.c:153
> 
> Add a common cfi-sframe assembler test, that forces a FDE type of
> SFRAME_FRE_TYPE_ADDR2.  When the test is run cross-build it may
> exercise the SFrame FDE and FDE endianness byte flipping.
> 

LGTM.  Thanks!

> libsframe/
> 	PR ld/33810
> 	* sframe.c (sframe_decode_fde_attr_v3): Decode and return FRE
> 	type from FDE attributes.
> 	(flip_sframe_fdes_with_fres_v3): Use proper FRE type from
> 	FDE attributes when flipping FREs.
> 
> gas/testsuite/
> 	PR ld/33810
> 	* gas/cfi-sframe/cfi-sframe.exp (cfi-sframe-common-pr33810): Run
> 	new test.
> 	* gas/cfi-sframe/cfi-sframe-common-pr33810.d: New test.
> 	* gas/cfi-sframe/cfi-sframe-common-pr33810.s: Likewise.
> 
> Bug: https://sourceware.org/pr33810
> Fixes: 8ab6e4c72ab6 ("[SFrame-V3] include: gas: libsframe: split FDE into idx and attr")
> Reported-by: Alan Modra <amodra@gmail.com>
> Signed-off-by: Jens Remus <jremus@linux.ibm.com>
> ---
>   .../cfi-sframe/cfi-sframe-common-pr33810.d    | 23 +++++++++++++++++++
>   .../cfi-sframe/cfi-sframe-common-pr33810.s    |  7 ++++++
>   gas/testsuite/gas/cfi-sframe/cfi-sframe.exp   |  2 ++
>   libsframe/sframe.c                            | 13 +++++------
>   4 files changed, 38 insertions(+), 7 deletions(-)
>   create mode 100644 gas/testsuite/gas/cfi-sframe/cfi-sframe-common-pr33810.d
>   create mode 100644 gas/testsuite/gas/cfi-sframe/cfi-sframe-common-pr33810.s
> 
> diff --git a/gas/testsuite/gas/cfi-sframe/cfi-sframe-common-pr33810.d b/gas/testsuite/gas/cfi-sframe/cfi-sframe-common-pr33810.d
> new file mode 100644
> index 000000000000..ae8b76a6effb
> --- /dev/null
> +++ b/gas/testsuite/gas/cfi-sframe/cfi-sframe-common-pr33810.d
> @@ -0,0 +1,23 @@
> +#as: --gsframe
> +#objdump: --sframe=.sframe
> +#name: SFrame FRE type SFRAME_FRE_TYPE_ADDR2 (PR 33810)
> +#...
> +Contents of the SFrame section .sframe:
> +
> +  Header :
> +
> +    Version: SFRAME_VERSION_3
> +    Flags: SFRAME_F_FDE_FUNC_START_PCREL
> +#?    CFA fixed FP offset: \-?\d+
> +#?    CFA fixed RA offset: \-?\d+
> +    Num FDEs: 1
> +    Num FREs: 3
> +
> +  Function Index :
> +    func idx \[0\]: pc = 0x0, size = 264 bytes
> +    STARTPC + CFA + FP + RA +
> +#...
> +    0+0004 +sp\+16 +u +[uf] +
> +    0+0104 +sp\+32 +u +[uf] +
> +
> +#pass
> diff --git a/gas/testsuite/gas/cfi-sframe/cfi-sframe-common-pr33810.s b/gas/testsuite/gas/cfi-sframe/cfi-sframe-common-pr33810.s
> new file mode 100644
> index 000000000000..0cbbd991ca38
> --- /dev/null
> +++ b/gas/testsuite/gas/cfi-sframe/cfi-sframe-common-pr33810.s
> @@ -0,0 +1,7 @@
> +	.cfi_startproc
> +	.long 0
> +	.cfi_def_cfa_offset 16
> +	.ds.b 0x100
> +	.cfi_def_cfa_offset 32
> +	.long 0
> +	.cfi_endproc
> diff --git a/gas/testsuite/gas/cfi-sframe/cfi-sframe.exp b/gas/testsuite/gas/cfi-sframe/cfi-sframe.exp
> index 2e0942657ae9..a73e5c84033e 100644
> --- a/gas/testsuite/gas/cfi-sframe/cfi-sframe.exp
> +++ b/gas/testsuite/gas/cfi-sframe/cfi-sframe.exp
> @@ -53,6 +53,8 @@ if  { ([istarget "x86_64-*-*"] || [istarget "aarch64*-*-*"]
>   
>       run_dump_test "common-empty-2"
>       run_dump_test "common-empty-3"
> +
> +    run_dump_test "cfi-sframe-common-pr33810"
>   }
>   
>   # x86-64 specific tests
> diff --git a/libsframe/sframe.c b/libsframe/sframe.c
> index 52788d8ac152..3f76629665cb 100644
> --- a/libsframe/sframe.c
> +++ b/libsframe/sframe.c
> @@ -647,15 +647,14 @@ sframe_decode_fde_idx_v3 (const char *buf, size_t buf_size,
>   
>   static int
>   sframe_decode_fde_attr_v3 (const char *buf, size_t buf_size,
> -			   uint16_t *num_fres)
> +			   uint16_t *num_fres, uint32_t *fre_type)
>   {
>     if (buf_size < sizeof (sframe_func_desc_attr_v3))
>       return SFRAME_ERR;
>   
> -  /* sfda_func_num_fres is the first member of sframe_func_desc_attr_v3.  */
> -  const struct { uint16_t x; } ATTRIBUTE_PACKED *p = (void *)buf;
> -  *num_fres = p->x;
> -
> +  const sframe_func_desc_attr_v3 *fdap = (sframe_func_desc_attr_v3 *) buf;
> +  *num_fres = fdap->sfda_func_num_fres;
> +  *fre_type = SFRAME_V3_FDE_FRE_TYPE (fdap->sfda_func_info);
>     return 0;
>   }
>   static int
> @@ -855,7 +854,7 @@ flip_sframe_fdes_with_fres_v3 (char *frame_buf, size_t buf_size,
>         /* Handle FDE attr (only in V3).  */
>         fp = fres + fre_offset;
>         if (to_foreign && sframe_decode_fde_attr_v3 (fp, buf_end - fp,
> -						   &num_fres))
> +						   &num_fres, &fre_type))
>   	goto bad;
>   
>         if (flip_fde_attr_v3 (fp, buf_end - fp))
> @@ -864,7 +863,7 @@ flip_sframe_fdes_with_fres_v3 (char *frame_buf, size_t buf_size,
>         fre_bytes_flipped += sizeof (sframe_func_desc_attr_v3);
>   
>         if (!to_foreign && sframe_decode_fde_attr_v3 (fp, buf_end - fp,
> -						    &num_fres))
> +						    &num_fres, &fre_type))
>   	goto bad;
>   
>         /* Handle FREs.  */



More information about the Binutils mailing list