[PATCH v3 00/11] s390: Support to generate .sframe in assembler and linker

Jens Remus jremus@linux.ibm.com
Fri Jun 27 11:08:38 GMT 2025


Changes in v3 (see individual patch notes for further details):
- Update "Changes from Version 1 to Version 2" in SFrame spec. (Indu)
- Align to improvements from commit 4e94f0075669 ("libsframe: fix issue
  finding FRE in PCMASK type SFrame FDEs"). (Indu)
- Incorporated review feedback from v2, mostly rewording commit
  messages, SFrame specification, code comments.

This patch series adds support on s390x to generate SFrame stack trace
information (.sframe section) in the assembler from CFI directives and
in the linker for the linker-generated .plt section.

Patches 1 and 2 are preparatory.  Patch 1 resolves an endianness
conversion issue in SFrame common code.  Patch 2 restructures the linker
dump tests on s390/s390x, to enable adding SFrame tests that are only
run if SFrame is supported.

Patch 3 adds initial support to generate SFrame stack trace information
from CFI directives in the assembler on s390x.  Due to differences in
the s390x ELF ABI [1] compared to the AArch64 and x86-64 AMD64 ELF ABIs
and the simplified assumptions of the SFrame format V2 there are a few
limitations, that mostly get addressed by patches 4 and 5.

Patches 4 and 5 address generic SFrame limitations, by introducing S390-
specific extensions to the SFrame format.  Patch 4 enables to represent
FP/RA saved in another register (instead of on the stack), which can be
observed in leaf functions, by encoding the DWARF register number as
FP/RA offset.  Patch 5 enables to represent FP without RA saved (on the
stack or in another register), by using an invalid RA offset value as
padding.

Patch 6 adds support to generate SFrame stack trace information for the
linker-generated .plt section in the linker on s390x.

Patch 7 (new) adds a libsframe test for PLT0/PLTN with only one FRE
each.

Patches 8 and 9 enable and improve the use of signed 8-bit SFrame CFA,
FP, and RA offsets on S390.  Patch 8 enables the use by storing the CFA
offset adjusted by a s390x-specific CFA adjustment of -160.  Patch 9
improves the use by additionally storing the CFA offset factorized, with
a s390x-specific CFA offset alignment factor of 8 factored out.

Patch 10 (new) adds a port of a new SFrame test on x86-64 to s390x.

Patch 11 (new) completes this series by adding a Binutils NEWS entry
announcing the s390 64-bit (s390x) support for SFrame and updating the
GAS NEWS entry (no longer initial support).

Open issues and limitations that could be addressed in SFrame, GCC, and
Glibc:

- Limitation: Potential use of non-SP/FP register as CFA base register.
  The s390x ELF ABI does not designate a dedicated frame pointer (FP)
  register.  With a recent update it does designate register 11 (r11)
  as preferred FP register, which is used by GCC and Clang on s390x.
  This will most likely remain a permanent limitation, mostly affecting
  hand-written assembler code.

- Issue: GCC use of non-SP/FP register as CFA base register.  GCC can
  be observed to use the non-FP register r14 as temporary CFA base
  register in the stack clash protector of variadic functions.  This
  could be addressed either in GCC or with the planned SFrame V3
  enhancement [2] to support non-SP/FP CFA base registers for topmost
  frames.

- Issue: Glibc use of non-preferred FP register r12 as frame pointer
  in _dl_runtime_profile.  I am working on Glibc patches to improve
  SFrame compatibility on s390x, which will resolve this issue.

- Limitation: Glibc use of non-default RA register r0 in fentry
  used for profiling.  This will most likely remain a permanent
  limitation, that the use of SFrame stack tracing, e.g. using perf,
  cannot be combined with profiling.
  Note that support for non-default RA registers for topmost frames
  could easily be implemented by representing a non-default RA register
  as default RA register saved in non-default RA register and then
  tracking the non-default RA register for the rest of that FDE.
  But this would not resolve the issue, as Glibc fentry does call
  another function using normal calling conventions.   With that the
  frame with the default RA register saved in the non-default RA
  register would no longer be the topmost in the call stack.  A
  SFrame stack tracer implementation can only access register contents
  in the topmost frame.

[1]: s390x ELF ABI, https://github.com/IBM/s390x-abi/releases
[2]: SFrame V3 TODOs,
     https://sourceware.org/binutils/wiki/sframe/sframev3todo

Regards,
Jens

Jens Remus (11):
  sframe: Ignore section padding when converting endianness
  s390: Explicitly list linker dump tests
  s390: Initial support to generate .sframe from CFI directives in
    assembler
  s390: Represent FP/RA saved in register in SFrame
  s390: Represent FP without RA saved in SFrame
  s390: Add SFrame stack trace information for .plt section
  libsframe: Add test for PLT0 and PLTN with only one FRE each
  s390: Store SFrame CFA offset adjusted
  s390: Store SFrame CFA offset adjusted and scaled down
  s390: sframe: Test handling of .cfi_def_cfa_register
  s390: Announce s390 64-bit (s390x) SFrame V2 support in binutils

 bfd/elf64-s390.c                              | 259 ++++++++++++++++++
 binutils/NEWS                                 |   7 +
 gas/NEWS                                      |   3 +
 gas/config/tc-s390.c                          |  55 ++++
 gas/config/tc-s390.h                          |  31 +++
 gas/gen-sframe.c                              |  99 ++++++-
 .../gas/cfi-sframe/cfi-sframe-s390x-1.d       |  23 ++
 .../gas/cfi-sframe/cfi-sframe-s390x-1.s       |  37 +++
 .../gas/cfi-sframe/cfi-sframe-s390x-2.d       |  23 ++
 .../gas/cfi-sframe/cfi-sframe-s390x-2.s       |  37 +++
 .../gas/cfi-sframe/cfi-sframe-s390x-3.d       |  19 ++
 .../gas/cfi-sframe/cfi-sframe-s390x-3.s       |   4 +
 .../gas/cfi-sframe/cfi-sframe-s390x-err-1.d   |  15 +
 .../gas/cfi-sframe/cfi-sframe-s390x-err-1.s   |  37 +++
 .../gas/cfi-sframe/cfi-sframe-s390x-err-2.d   |  15 +
 .../gas/cfi-sframe/cfi-sframe-s390x-err-2.s   |  37 +++
 .../gas/cfi-sframe/cfi-sframe-s390x-err-3.d   |  15 +
 .../gas/cfi-sframe/cfi-sframe-s390x-err-3.s   |   5 +
 .../cfi-sframe-s390x-fpra-offset-1.d          |  22 ++
 .../cfi-sframe-s390x-fpra-offset-1.s          |  15 +
 .../cfi-sframe-s390x-fpra-offset-2.d          |  22 ++
 .../cfi-sframe-s390x-fpra-offset-2.s          |  15 +
 .../cfi-sframe-s390x-fpra-register-1.d        |  22 ++
 .../cfi-sframe-s390x-fpra-register-1.s        |  15 +
 .../cfi-sframe-s390x-fpra-register-2.d        |  22 ++
 .../cfi-sframe-s390x-fpra-register-2.s        |  15 +
 gas/testsuite/gas/cfi-sframe/cfi-sframe.exp   |  19 +-
 include/sframe-api.h                          |  12 +-
 include/sframe.h                              |  59 +++-
 ld/NEWS                                       |   4 +
 ld/testsuite/ld-s390/s390.exp                 |  18 +-
 ld/testsuite/ld-s390/sframe-bar.s             |  21 ++
 ld/testsuite/ld-s390/sframe-foo.s             |   9 +
 ld/testsuite/ld-s390/sframe-plt-1.d           |  28 ++
 ld/testsuite/ld-s390/sframe-simple-1.d        |  31 +++
 libsframe/Makefile.in                         |  42 ++-
 libsframe/doc/sframe-spec.texi                | 116 +++++++-
 libsframe/sframe-dump.c                       |  28 +-
 libsframe/sframe.c                            |  31 ++-
 libsframe/testsuite/libsframe.find/find.exp   |   5 +
 libsframe/testsuite/libsframe.find/local.mk   |   5 +
 .../testsuite/libsframe.find/plt-findfre-2.c  | 192 +++++++++++++
 42 files changed, 1443 insertions(+), 46 deletions(-)
 create mode 100644 gas/testsuite/gas/cfi-sframe/cfi-sframe-s390x-1.d
 create mode 100644 gas/testsuite/gas/cfi-sframe/cfi-sframe-s390x-1.s
 create mode 100644 gas/testsuite/gas/cfi-sframe/cfi-sframe-s390x-2.d
 create mode 100644 gas/testsuite/gas/cfi-sframe/cfi-sframe-s390x-2.s
 create mode 100644 gas/testsuite/gas/cfi-sframe/cfi-sframe-s390x-3.d
 create mode 100644 gas/testsuite/gas/cfi-sframe/cfi-sframe-s390x-3.s
 create mode 100644 gas/testsuite/gas/cfi-sframe/cfi-sframe-s390x-err-1.d
 create mode 100644 gas/testsuite/gas/cfi-sframe/cfi-sframe-s390x-err-1.s
 create mode 100644 gas/testsuite/gas/cfi-sframe/cfi-sframe-s390x-err-2.d
 create mode 100644 gas/testsuite/gas/cfi-sframe/cfi-sframe-s390x-err-2.s
 create mode 100644 gas/testsuite/gas/cfi-sframe/cfi-sframe-s390x-err-3.d
 create mode 100644 gas/testsuite/gas/cfi-sframe/cfi-sframe-s390x-err-3.s
 create mode 100644 gas/testsuite/gas/cfi-sframe/cfi-sframe-s390x-fpra-offset-1.d
 create mode 100644 gas/testsuite/gas/cfi-sframe/cfi-sframe-s390x-fpra-offset-1.s
 create mode 100644 gas/testsuite/gas/cfi-sframe/cfi-sframe-s390x-fpra-offset-2.d
 create mode 100644 gas/testsuite/gas/cfi-sframe/cfi-sframe-s390x-fpra-offset-2.s
 create mode 100644 gas/testsuite/gas/cfi-sframe/cfi-sframe-s390x-fpra-register-1.d
 create mode 100644 gas/testsuite/gas/cfi-sframe/cfi-sframe-s390x-fpra-register-1.s
 create mode 100644 gas/testsuite/gas/cfi-sframe/cfi-sframe-s390x-fpra-register-2.d
 create mode 100644 gas/testsuite/gas/cfi-sframe/cfi-sframe-s390x-fpra-register-2.s
 create mode 100644 ld/testsuite/ld-s390/sframe-bar.s
 create mode 100644 ld/testsuite/ld-s390/sframe-foo.s
 create mode 100644 ld/testsuite/ld-s390/sframe-plt-1.d
 create mode 100644 ld/testsuite/ld-s390/sframe-simple-1.d
 create mode 100644 libsframe/testsuite/libsframe.find/plt-findfre-2.c

-- 
2.48.1



More information about the Binutils mailing list