[binutils-gdb] libsframe: use proper FRE type when flipping SFrame V3 FREs
Jens Remus
jremus@sourceware.org
Tue Jan 20 09:25:17 GMT 2026
https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=9f3749fff938e51ed1a1d92b308a363b2f8197ce
commit 9f3749fff938e51ed1a1d92b308a363b2f8197ce
Author: Jens Remus <jremus@linux.ibm.com>
Date: Tue Jan 20 10:22:52 2026 +0100
libsframe: use proper FRE type when flipping SFrame V3 FREs
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.
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>
Diff:
---
.../gas/cfi-sframe/cfi-sframe-common-pr33810.d | 23 ++++++++++++++++++++++
.../gas/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(-)
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 00000000000..ae8b76a6eff
--- /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 00000000000..0cbbd991ca3
--- /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 2e0942657ae..a73e5c84033 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 52788d8ac15..3f76629665c 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-cvs
mailing list