[V2 00/36] SFrame V3 patchset
Indu Bhagat
indu.bhagat@oracle.com
Wed Jan 7 08:41:51 GMT 2026
Hi,
This is the V2 of the previously posted RFC series with the same name.
V1 posting: https://inbox.sourceware.org/binutils/20251229092910.1443618-1-indu.bhagat@oracle.com/
This patch series introduces SFrame Version 3 (SFrame V3) to the GNU Binutils.
With this series applied, the GNU Assembler (GAS) will emit SFrame V3 by
default, and libsframe will undergo a major version bump to support the new
format.
SFrame V3 at high level
-----------------------
SFrame V3 adds the following capabilities:
- support for text > 2 GiB
- mark signal frames
- support for "flexible" frames (e.g., these can be used to represent DRAP
pattern on AMD64)
- restructured SFrame index and SFrame attributes
This addresses the feature set listed on the wiki
(https://sourceware.org/binutils/wiki/sframe/sframev3todo), except the
following item:
Add support for AArch64 DW_negate_ra_state_with_pc
https://sourceware.org/binutils/wiki/sframe/sframev3todo#AArch64_DW_negate_ra_state_with_pc
which has now been deferred out of SFrame V3 for reasons noted on the wiki.
Key Format/Layout Changes
--------------------------
1. In SFrame V2, the Function Descriptor Entry (FDE) was a single monolithic
structure containing both search key and value (start pc offset, size, fre
offset) and metadata (info word, number of FREs, and other info).
SFrame V3 splits the FDE into two distinct entities to improve ease of format
evolution, cache locality and extensibility:
- FDE Index (sframe_func_desc_idx_v3): A fixed-size structure
containing only the essential data for binary searching (function
start offset, func size, and offset to the location in SFrame FRE
sub-section where Attributes/FREs are stored).
- FDE Attributes (sframe_func_desc_attr_v3): A variable-sized structure
stored before the SFrame Frame Row Entries (FREs). This contains
the metadata, including the FDE Type and Info words.
2. Reserve 5 bits for FDE types. Add a new FDE type SFRAME_FDE_TYPE_FLEX.
While standard FDEs handle the common SP/FP-based frames efficiently, Flex FDEs
allow encoding of complex patterns like DRAP (Dynamic Re-alignment of Stack
Pointer) or cases where the Frame Pointer (FP) or Return Address (RA) is
stored in a non-standard register or stack slot.
3. SFrame V2 used signed 32-bit integers for function start offsets,
effectively limiting the text section size to 2GB. SFrame V3 promotes the
sfde_func_start_offset to int64_t. This ensures future-proofing for large cloud
applications and huge executables.
To mitigate the size increase from 64-bit offsets, we have optimized other
fields:
- num_fres is reduced from 32-bit to 16-bit (65k FREs per function is
sufficient).
- Explicit padding field (2-bytes in SFrame V2) has been removed.
Note that with the change in #1 and #3, SFrame FDE index elements
continue to be at aligned boundaries.
4. Signal frames are now explicitly marked with a reserved bit in the function
info byte. Additionally, the assembler permits generating FDEs for signal
frames even if they contain zero FREs, allowing stack tracers to identify signal
trampolines even when full stack trace info is unavailable.
Overall Support
----------------
GAS: Adds --gsframe-3 (though V3 is default). Adds backend hooks for AArch64,
x86_64, and s390x to selectively enable Flex FDE generation.
LD: Adds --discard-sframe-sections to allow users to strip SFrame data entirely
if desired.
Readelf/Objdump: Fully support SFrame V3 dumping. Backward compatibility is
maintained for SFrame V2 textual dumps.
Libsframe: The library version is bumped to 3.0.0 due to binary incompatible
API changes.
Patch Organization
------------------
The series is organized as follows:
Patches 1-4: SFrame V2 backward compatibility tests and cleanup/preparatory
libsframe patches.
Patches 5-7: Prepare for V3 by bumping version and soname. Add some new V3
APIs.
Patches 8-18: Format definition changes for SFrame V3 (reduce type size of
num_fres, remove padding, 64-bit offsets, new FDE types).
Patches 19-21: Prepare libsframe for flex fde probing and dumping.
Patches 22-26: gas changes for flex fde generation and cfi handling (handling
.cfi_register, .cfi_offset differently).
Patch 27: Link-time optimization of SFrame handling.
Patch 28: FDE split into idx and attr.
Patches 29-36: New command lines, NEWS, and specification changes.
Pending work
-------------
Apart from the noted TBD items in the commit logs, following need to be worked
on:
- Specification changes are WIP
- More testing overall.
- Discuss s390x flex FDE usage.
For ease of review and testing, the complete set is available at branch:
users/ibhagat/sframe-v3-jan07-v2.
Thanks,
Indu Bhagat (36):
1-4
[SFrame-V3] readelf: testsuite: sframe: add new SFrame V2 test
[SFrame-V3] libsframe: testsuite: add a new test for SFrame V2
[SFrame-V3] libsframe: remove old sframe_decoder_get_funcdesc API
[SFrame-V3] sframe: use const for sframe_decoder_ctx object arg
5-7
[SFrame-V3] sframe: gas: bfd: ld: format bump to version 3
[SFrame-V3] libsframe: bump so version to libsframe.so.3.0.0
[SFrame-V3] libsframe: add V3 APIs for adding and getting SFrame FDE
8-18
[SFrame-V3] sframe: gas: libsframe: use uint16_t for num_fres of FDE
[SFrame-V3] sframe: gas: libsframe: remove padding field from FDE
[SFrame-V3] include: libsframe: bfd: gas: testsuite: support for
signed 64-bit offset in SFrame FDE
[SFrame-V3] sframe: gas: bfd: add support for signal frames
[SFrame-V3] gas: sframe: allow SFrame FDEs with 0 FREs for signal
frames
[SFrame-V3] include: sframe: s390x: keep unused bits when possible
[SFrame-V3] include: gas: libsframe: add 8-bits of func_info2 for
extensibility in FDE
[SFrame-V3] include: sframe: reserve 5 bits for new FDE types
[SFrame-V3] gas: bfd: include: libsframe: fixup terminology 'PC Type'
vs 'FDE Type'
[SFrame-V3] gas: sframe: use three states for location tracking
[SFrame-V3] gas: sframe: output new FDE type SFRAME_FDE_TYPE_FLEX
19-21
[SFrame-V3] libsframe: testsuite: add new argument to offset access
APIs
[SFrame-V3] libsframe: textual dump of fde type SFRAME_FDE_TYPE_FLEX
[SFrame-V3] sframe: gas: s390: aarch64: x86: add new backend hooks for
FLEX FDE
22 - 26
[SFrame-V3] sframe: gas: translate specific CFI directives for
SFRAME_FDE_TYPE_FLEX
[SFrame-V3] gas: x86: testsuite: add new testcases for
SFRAME_FDE_TYPE_FLEX
[SFrame-V3] gas: sframe: testsuite: handle .cfi_register FP/RA for
flex FDE
[SFrame-V3] gas: sframe: testsuite: reject .cfi_register REG_SP, REG
[SFrame-V3] gas: sframe: testsuite: handle .cfi_offset for RA
27 - 28
[SFrame-V3] bfd: ld: sframe: avoid unnecessary decoding of SFrame FREs
at link time
[SFrame-V3] include: gas: libsframe: split FDE into idx and attr
29 - 36
[SFrame-V3] gas: sframe: doc: testsuite: add new command line option
--gsframe-3
[SFrame-V3] ld: add --discard-sframe command line option
[SFrame-V3] ld: discard sframe sections when --discard-sframe
[SFrame-V3] ld: testsuite: x86: sframe: check link of signal frame and
outermost frames
[SFrame-V3] gas: binutils: ld: NEWS: add SFrame v3 related
announcements
[SFrame-V3] include: libsframe: remove SFRAME_F_FRAME_POINTER flag
[SFrame-V3][WIP] sframe: doc: specification changes for SFrame version
3
[SFrame-V3][RFC] sframe: gas: testsuite: enable flex FDE for s390x
bfd/elf-sframe.c | 65 +-
bfd/elf64-s390.c | 22 +-
bfd/elfxx-x86.c | 24 +-
binutils/NEWS | 8 +
.../binutils-all/s390/README-sframe-tests | 8 +
.../testsuite/binutils-all/s390/sframe.exp | 63 ++
.../s390/test-v2-ET_EXEC.sframe.bz2 | Bin 0 -> 4094 bytes
.../s390/test-v2-ET_EXEC.sframe.dump | 41 +
.../s390/test-v2-ET_REL.sframe.bz2 | Bin 0 -> 748 bytes
.../s390/test-v2-ET_REL.sframe.dump | 24 +
.../binutils-all/x86-64/README-sframe-tests | 53 ++
.../binutils-all/x86-64/objdump-sframe-01.d | 2 +-
.../binutils-all/x86-64/readelf-sframe-01.d | 2 +-
.../testsuite/binutils-all/x86-64/sframe.exp | 63 ++
.../x86-64/test-v2-ET_EXEC.sframe.bz2 | Bin 0 -> 2739 bytes
.../x86-64/test-v2-ET_EXEC.sframe.dump | 42 +
.../x86-64/test-v2-ET_REL.sframe.bz2 | Bin 0 -> 728 bytes
.../x86-64/test-v2-ET_REL.sframe.dump | 23 +
gas/NEWS | 9 +
gas/as.c | 15 +-
gas/as.h | 7 +
gas/config/tc-aarch64.c | 8 +
gas/config/tc-aarch64.h | 4 +
gas/config/tc-i386.c | 7 +
gas/config/tc-i386.h | 4 +
gas/config/tc-s390.c | 8 +
gas/config/tc-s390.h | 4 +
gas/doc/as.texi | 7 +-
gas/gen-sframe.c | 739 +++++++++++----
gas/gen-sframe.h | 31 +-
gas/sframe-opt.c | 13 +-
.../gas/cfi-sframe/cfi-sframe-aarch64-1.d | 2 +-
.../gas/cfi-sframe/cfi-sframe-aarch64-2.d | 2 +-
.../gas/cfi-sframe/cfi-sframe-aarch64-3.d | 2 +-
.../gas/cfi-sframe/cfi-sframe-aarch64-4.d | 2 +-
.../cfi-sframe-aarch64-pac-ab-key-1.d | 2 +-
.../cfi-sframe-aarch64-ra-undefined-1.d | 2 +-
.../gas/cfi-sframe/cfi-sframe-common-1.d | 2 +-
.../gas/cfi-sframe/cfi-sframe-common-10.d | 2 +-
.../gas/cfi-sframe/cfi-sframe-common-11.d | 2 +-
.../gas/cfi-sframe/cfi-sframe-common-12.d | 2 +-
.../gas/cfi-sframe/cfi-sframe-common-13.d | 19 +
.../gas/cfi-sframe/cfi-sframe-common-13.s | 3 +
.../gas/cfi-sframe/cfi-sframe-common-1d.d | 13 +
.../gas/cfi-sframe/cfi-sframe-common-1d.s | 3 +
.../gas/cfi-sframe/cfi-sframe-common-2.d | 2 +-
.../gas/cfi-sframe/cfi-sframe-common-3.d | 2 +-
.../gas/cfi-sframe/cfi-sframe-common-4.d | 2 +-
.../gas/cfi-sframe/cfi-sframe-common-5.d | 2 +-
.../gas/cfi-sframe/cfi-sframe-common-6.d | 2 +-
.../gas/cfi-sframe/cfi-sframe-common-7.d | 2 +-
.../gas/cfi-sframe/cfi-sframe-common-8.d | 2 +-
.../gas/cfi-sframe/cfi-sframe-common-9.d | 2 +-
.../gas/cfi-sframe/cfi-sframe-s390x-1.d | 2 +-
.../gas/cfi-sframe/cfi-sframe-s390x-2.d | 2 +-
.../gas/cfi-sframe/cfi-sframe-s390x-3.d | 2 +-
.../gas/cfi-sframe/cfi-sframe-s390x-err-3.d | 2 +-
...s390x-err-2.d => cfi-sframe-s390x-err-4.d} | 6 +-
.../gas/cfi-sframe/cfi-sframe-s390x-err-4.s | 5 +
.../cfi-sframe-s390x-fpra-offset-1.d | 2 +-
.../cfi-sframe-s390x-fpra-offset-2.d | 2 +-
.../cfi-sframe-s390x-fpra-register-1.d | 12 +-
.../cfi-sframe-s390x-fpra-register-2.d | 10 +-
.../cfi-sframe-s390x-non-spfp-cfa-1.d | 24 +
...-1.s => cfi-sframe-s390x-non-spfp-cfa-1.s} | 0
.../cfi-sframe-s390x-non-spfp-cfa-2.d | 24 +
...-2.s => cfi-sframe-s390x-non-spfp-cfa-2.s} | 0
.../cfi-sframe-s390x-ra-undefined-1.d | 2 +-
.../gas/cfi-sframe/cfi-sframe-x86_64-1.d | 2 +-
.../gas/cfi-sframe/cfi-sframe-x86_64-2.d | 2 +-
.../gas/cfi-sframe/cfi-sframe-x86_64-3.d | 2 +-
.../gas/cfi-sframe/cfi-sframe-x86_64-4.d | 29 +
.../gas/cfi-sframe/cfi-sframe-x86_64-4.s | 80 ++
.../gas/cfi-sframe/cfi-sframe-x86_64-5.d | 21 +
.../gas/cfi-sframe/cfi-sframe-x86_64-5.s | 12 +
.../gas/cfi-sframe/cfi-sframe-x86_64-6.d | 25 +
.../gas/cfi-sframe/cfi-sframe-x86_64-6.s | 16 +
.../cfi-sframe/cfi-sframe-x86_64-empty-1.d | 2 +-
.../cfi-sframe/cfi-sframe-x86_64-empty-2.d | 2 +-
.../cfi-sframe/cfi-sframe-x86_64-empty-3.d | 2 +-
.../cfi-sframe/cfi-sframe-x86_64-empty-4.d | 2 +-
...0x-err-1.d => cfi-sframe-x86_64-empty-5.d} | 8 +-
.../cfi-sframe/cfi-sframe-x86_64-empty-5.s | 8 +
.../cfi-sframe-x86_64-empty-pr33277.d | 2 +-
.../cfi-sframe/cfi-sframe-x86_64-esc-expr-1.d | 26 +
.../cfi-sframe/cfi-sframe-x86_64-esc-expr-1.s | 43 +
.../cfi-sframe/cfi-sframe-x86_64-esc-expr-2.d | 24 +
.../cfi-sframe/cfi-sframe-x86_64-esc-expr-2.s | 13 +
.../cfi-sframe/cfi-sframe-x86_64-esc-expr-3.d | 26 +
.../cfi-sframe/cfi-sframe-x86_64-esc-expr-3.s | 18 +
.../cfi-sframe/cfi-sframe-x86_64-pr33170.d | 2 +-
.../cfi-sframe/cfi-sframe-x86_64-pr33756.d | 2 +-
.../cfi-sframe-x86_64-ra-undefined-1.d | 2 +-
.../cfi-sframe-x86_64-ra-undefined-flex-1.d | 23 +
.../cfi-sframe-x86_64-ra-undefined-flex-1.s | 15 +
.../cfi-sframe/cfi-sframe-x86_64-signal-1.d | 18 +
.../cfi-sframe/cfi-sframe-x86_64-signal-1.s | 12 +
gas/testsuite/gas/cfi-sframe/cfi-sframe.exp | 16 +-
gas/testsuite/gas/cfi-sframe/common-empty-2.d | 2 +-
gas/testsuite/gas/cfi-sframe/common-empty-3.d | 2 +-
.../gas/scfi/x86_64/scfi-cfi-sections-1.d | 2 +-
.../gas/scfi/x86_64/scfi-dyn-stack-1.d | 2 +-
include/bfdlink.h | 4 +
include/sframe-api.h | 110 ++-
include/sframe.h | 144 ++-
ld/Makefile.am | 3 +-
ld/Makefile.in | 4 +-
ld/NEWS | 12 +
ld/configure | 11 +-
ld/configure.ac | 6 +
ld/emulparams/aarch64elf.sh | 1 +
ld/emulparams/aarch64linux.sh | 1 +
ld/emulparams/elf64_s390.sh | 1 +
ld/emulparams/elf_x86_64.sh | 1 +
ld/emulparams/sframe-info.sh | 15 +
ld/ld.texi | 10 +-
ld/ldlex.h | 2 +
ld/lexsup.c | 15 +-
ld/testsuite/ld-aarch64/sframe-simple-1.d | 2 +-
ld/testsuite/ld-s390/sframe-plt-1.d | 2 +-
ld/testsuite/ld-s390/sframe-simple-1.d | 2 +-
.../ld-x86-64/sframe-command-line-1.d | 8 +
ld/testsuite/ld-x86-64/sframe-ibt-plt-1.d | 2 +-
ld/testsuite/ld-x86-64/sframe-link-1.d | 38 +
ld/testsuite/ld-x86-64/sframe-plt-1.d | 2 +-
ld/testsuite/ld-x86-64/sframe-pltgot-1.d | 2 +-
ld/testsuite/ld-x86-64/sframe-pltgot-2.d | 2 +-
ld/testsuite/ld-x86-64/sframe-reloc-1.d | 2 +-
ld/testsuite/ld-x86-64/sframe-signal.s | 19 +
ld/testsuite/ld-x86-64/sframe-simple-1.d | 2 +-
ld/testsuite/ld-x86-64/sframe-start.s | 15 +
ld/testsuite/ld-x86-64/x86-64.exp | 2 +
libsframe/Makefile.in | 34 +
libsframe/doc/sframe-spec.texi | 709 +++++++++++----
libsframe/libsframe.ver | 18 +-
libsframe/libtool-version | 2 +-
libsframe/sframe-dump.c | 428 +++++++--
libsframe/sframe.c | 849 ++++++++++++++----
libsframe/testsuite/libsframe.decode/DATA-V2 | Bin 0 -> 98 bytes
libsframe/testsuite/libsframe.decode/DATA2 | Bin 98 -> 100 bytes
.../testsuite/libsframe.decode/decode.exp | 6 +
.../testsuite/libsframe.decode/frecnt-v2.c | 90 ++
libsframe/testsuite/libsframe.decode/local.mk | 6 +-
.../testsuite/libsframe.encode/encode-1.c | 30 +-
.../testsuite/libsframe.find/findfre-1.c | 53 +-
.../testsuite/libsframe.find/findfunc-1.c | 63 +-
.../testsuite/libsframe.find/plt-findfre-1.c | 38 +-
.../testsuite/libsframe.find/plt-findfre-2.c | 43 +-
148 files changed, 3839 insertions(+), 898 deletions(-)
create mode 100644 binutils/testsuite/binutils-all/s390/README-sframe-tests
create mode 100644 binutils/testsuite/binutils-all/s390/sframe.exp
create mode 100644 binutils/testsuite/binutils-all/s390/test-v2-ET_EXEC.sframe.bz2
create mode 100644 binutils/testsuite/binutils-all/s390/test-v2-ET_EXEC.sframe.dump
create mode 100644 binutils/testsuite/binutils-all/s390/test-v2-ET_REL.sframe.bz2
create mode 100644 binutils/testsuite/binutils-all/s390/test-v2-ET_REL.sframe.dump
create mode 100644 binutils/testsuite/binutils-all/x86-64/README-sframe-tests
create mode 100644 binutils/testsuite/binutils-all/x86-64/sframe.exp
create mode 100644 binutils/testsuite/binutils-all/x86-64/test-v2-ET_EXEC.sframe.bz2
create mode 100644 binutils/testsuite/binutils-all/x86-64/test-v2-ET_EXEC.sframe.dump
create mode 100644 binutils/testsuite/binutils-all/x86-64/test-v2-ET_REL.sframe.bz2
create mode 100644 binutils/testsuite/binutils-all/x86-64/test-v2-ET_REL.sframe.dump
create mode 100644 gas/testsuite/gas/cfi-sframe/cfi-sframe-common-13.d
create mode 100644 gas/testsuite/gas/cfi-sframe/cfi-sframe-common-13.s
create mode 100644 gas/testsuite/gas/cfi-sframe/cfi-sframe-common-1d.d
create mode 100644 gas/testsuite/gas/cfi-sframe/cfi-sframe-common-1d.s
rename gas/testsuite/gas/cfi-sframe/{cfi-sframe-s390x-err-2.d => cfi-sframe-s390x-err-4.d} (54%)
create mode 100644 gas/testsuite/gas/cfi-sframe/cfi-sframe-s390x-err-4.s
create mode 100644 gas/testsuite/gas/cfi-sframe/cfi-sframe-s390x-non-spfp-cfa-1.d
rename gas/testsuite/gas/cfi-sframe/{cfi-sframe-s390x-err-1.s => cfi-sframe-s390x-non-spfp-cfa-1.s} (100%)
create mode 100644 gas/testsuite/gas/cfi-sframe/cfi-sframe-s390x-non-spfp-cfa-2.d
rename gas/testsuite/gas/cfi-sframe/{cfi-sframe-s390x-err-2.s => cfi-sframe-s390x-non-spfp-cfa-2.s} (100%)
create mode 100644 gas/testsuite/gas/cfi-sframe/cfi-sframe-x86_64-4.d
create mode 100644 gas/testsuite/gas/cfi-sframe/cfi-sframe-x86_64-4.s
create mode 100644 gas/testsuite/gas/cfi-sframe/cfi-sframe-x86_64-5.d
create mode 100644 gas/testsuite/gas/cfi-sframe/cfi-sframe-x86_64-5.s
create mode 100644 gas/testsuite/gas/cfi-sframe/cfi-sframe-x86_64-6.d
create mode 100644 gas/testsuite/gas/cfi-sframe/cfi-sframe-x86_64-6.s
rename gas/testsuite/gas/cfi-sframe/{cfi-sframe-s390x-err-1.d => cfi-sframe-x86_64-empty-5.d} (50%)
create mode 100644 gas/testsuite/gas/cfi-sframe/cfi-sframe-x86_64-empty-5.s
create mode 100644 gas/testsuite/gas/cfi-sframe/cfi-sframe-x86_64-esc-expr-1.d
create mode 100644 gas/testsuite/gas/cfi-sframe/cfi-sframe-x86_64-esc-expr-1.s
create mode 100644 gas/testsuite/gas/cfi-sframe/cfi-sframe-x86_64-esc-expr-2.d
create mode 100644 gas/testsuite/gas/cfi-sframe/cfi-sframe-x86_64-esc-expr-2.s
create mode 100644 gas/testsuite/gas/cfi-sframe/cfi-sframe-x86_64-esc-expr-3.d
create mode 100644 gas/testsuite/gas/cfi-sframe/cfi-sframe-x86_64-esc-expr-3.s
create mode 100644 gas/testsuite/gas/cfi-sframe/cfi-sframe-x86_64-ra-undefined-flex-1.d
create mode 100644 gas/testsuite/gas/cfi-sframe/cfi-sframe-x86_64-ra-undefined-flex-1.s
create mode 100644 gas/testsuite/gas/cfi-sframe/cfi-sframe-x86_64-signal-1.d
create mode 100644 gas/testsuite/gas/cfi-sframe/cfi-sframe-x86_64-signal-1.s
create mode 100644 ld/emulparams/sframe-info.sh
create mode 100644 ld/testsuite/ld-x86-64/sframe-command-line-1.d
create mode 100644 ld/testsuite/ld-x86-64/sframe-link-1.d
create mode 100644 ld/testsuite/ld-x86-64/sframe-signal.s
create mode 100644 ld/testsuite/ld-x86-64/sframe-start.s
create mode 100644 libsframe/testsuite/libsframe.decode/DATA-V2
create mode 100644 libsframe/testsuite/libsframe.decode/frecnt-v2.c
--
2.43.0
More information about the Binutils
mailing list