Commit Graph

98 Commits

Author SHA1 Message Date
Indu Bhagat
8b66cb3b29 doc: sframe: mention errata 1 of SFrame version 2
With the changes of an added flag SFRAME_F_FDE_FUNC_START_PCREL, s390x
support and new section type SHT_GNU_SFRAME, indicate that this document
specifies the errata 1 of SFrame version 2.  This will help distinguish
the document / specification better from previous releases.

libsframe/doc/
	* sframe-spec.texi: Mention errata 1 of SFrame version 2.
2025-07-25 23:38:40 -07:00
Indu Bhagat
387efef5fe libsframe: relax the assertion limit for fre_start_addr
Fix PR ld/33131 Failed assertion when linking gccgo

Make amendments in both sframe_decoder_get_fre and
sframe_encoder_add_fre.

Since GNU as and the dw2gencfi code generally accepts such CFI, its best
to allow in SFrame FREs too.

libsframe/
	PR ld/33131.
	* sframe.c (sframe_decoder_get_fre): Relax the assertion a bit.
	(sframe_encoder_add_fre): Likewise.
2025-07-14 17:08:21 -07:00
Indu Bhagat
6a959b1270 libsframe: bump version to 2.0
Remove LIBSFRAME_1.1, LIBSFRAME_1.0 nodes and add a new LIBSFRAME_2.0
node (non-inheritance version) to create new global versioned symbols.
Also announce libsframe.so.2 in NEWS.

New APIs:
     sframe_decoder_get_flags;
     sframe_decoder_get_offsetof_fde_start_addr;
     sframe_encoder_get_flags;
     sframe_encoder_get_offsetof_fde_start_addr;

Removed APIs: (already deprecated since X-2 release)
     sframe_get_funcdesc_with_addr;

APIs with changed semantics:
     sframe_decoder_get_funcdesc_v2;
     sframe_encoder_add_funcdesc_v2;
     sframe_encoder_write;

lisbframe/
	* libsframe.ver: Define new LIBSFRAME_2.0.
	* libtool-version: Bump the 'current' numeral to indicate a binary
	incompatible release.
include/
	* sframe-api.h (sframe_get_funcdesc_with_addr): Remove
	deprecated interface.
libsframe/
	* sframe.c (sframe_get_funcdesc_with_addr): Likewise.
binutils/
	* NEWS: Announce new versioned release of libsframe.
2025-07-12 01:09:17 -07:00
Indu Bhagat
ddcac08407 libsframe: fixup comment and minor style issues
Also, use ATTRIBUTE_UNUSED consistently.

libsframe/
	* sframe.c (sframe_encoder_add_funcdesc): Fix function-level
	comment and use ATTRIBUTE_UNUSED consistently.
	(sframe_encoder_add_funcdesc_v2): Use ATTRIBUTE_UNUSED
	consistently.
2025-07-12 00:10:36 -07:00
Indu Bhagat
6ab3f09a68 gas: elf: binutils: add new section type SHT_GNU_SFRAME
So far, SFrame sections were of type SHT_PROGBITS.

As per ELF specification, SHT_PROGBITS indicates that the section holds
information defined by the program, whose format and meaning are
determined solely by the program.

On the linker side, SHT_PROGBITS should be reserved for the simple "cat
contents after applying relocs" semantics.

Currently, the only way to know that a section contains SFrame stack
trace data is if consumer checks for section name.  Such a check for
section name is not quite conformant to ELF principles.

Some of this was discussed here
https://sourceware.org/pipermail/binutils/2025-March/140181.html

With this change, the SFrame sections generated by gas, ld will have
section type set to SHT_GNU_SFRAME.   The new section type is defined in
the SHT_LOOS/SHT_HIOS space.  The SFrame parsing routine
_bfd_elf_parse_sframe () now admits sections only when the the section
type is SHT_GNU_SFRAME.

No special handling / validation is done at the moment for the case of
manual creation of SFrame sections via obj_elf_section ().  Add function
level comments for now to add a note about this.

Although the default handling for (sh_type >= SHT_LOOS && sh_type <=
SHT_HIOS) is sufficient when SHT_GNU_SFRAME is in that range, it makes
sense to add it as a case of its own.

bfd/
	* elf-sframe.c (_bfd_elf_parse_sframe): Check if section type is
	SHT_GNU_SFRAME.
	(_bfd_elf_set_section_sframe): Set SHT_GNU_SFRAME for output
	SFrame section.
	* elflink.c (obj_elf_section): Use section type for check
	instead of section name.
	* elfxx-x86.c: Set SHT_GNU_SFRAME for SFrame sections for
	.plt* sections.
	* elf.c (bfd_section_from_shdr): Add case for SHT_GNU_SFRAME.
binutils/
	* readelf.c (get_os_specific_section_type_name): Add
	SHT_GNU_SFRAME.
gas/
	* NEWS: Announce emitted SFrame sections have SHT_GNU_SFRAME
	set.
	* config/obj-elf.c (obj_elf_attach_to_group): Add comments to
	indicate no special handling for SFrame yet.
	* dw2gencfi.c (cfi_finish): Set SHT_GNU_SFRAME for emitted
	SFrame section.
ld/
	* NEWS: Announce emitted SFrame sections have SHT_GNU_SFRAME
	set.
gas/testsuite/
	* gas/cfi-sframe/cfi-sframe.exp: Add new test.
	* gas/cfi-sframe/cfi-sframe-common-1b.d: New test.
	* gas/cfi-sframe/cfi-sframe-common-1b.s: New test.
include/
	* elf/common.h (SHT_GNU_SFRAME): Add new section type for SFrame
	stack trace information.
libsframe/doc/
	* sframe-spec.texi: Add expected ELF section type.
2025-07-11 23:32:58 -07:00
Indu Bhagat
5a23093ab4 libsframe: testsuite: fix PR libsframe/33140
Commit 0d4d5a2633 missed some necessary adjustments to the testcase
after rebase.  SFrame FDE function start address data is now an offset
in PCREL encoding; reflect with a new flag SFRAME_F_FDE_START_ADDR_PCREL
in the header.

Adjust the newly added testcase.

PR libsframe/33140 SFrame test failures on x86-64

libsframe/testsuite/
	* libsframe.find/plt-findfre-2.c: Adjust for the new FDE func
	start addr encoding.
2025-07-11 10:29:54 -07:00
Jens Remus
95847aaba1 s390: Store SFrame CFA offset adjusted and scaled down
In SFrame V2 the size of the offsets following an SFrame FRE can be
either signed 8-bit, 16-bit, or 32-bit integer, with the largest offset
determining their size:
  1. CFA offset from CFA base register
  2. RA (stack save slot) offset from CFA, usually -48 on s390x if saved
  3. FP (stack save slot) offset from CFA, usually -72 on s390x if saved
The FP and RA offsets from CFA, when FP/RA saved on the stack, usually
have fixed values that fit into signed 8-bit SFrame offsets.  Likewise
the DWARF register numbers on s390x of general registers (GR; 0-15) and
floating-point registers (FPR; 16-31), when FP/RA saved in registers.
With that the CFA offset from CFA base register has the greatest impact
on the signed SFrame offset size.

The s390x ELF ABI defines the stack pointer (SP) to be 8-byte aligned
[1] and the CFA as SP at call site + 160 [2].  The CFA offset from CFA
base register is therefore always a multiple of 8.

On s390x store the SFrame CFA offset from CFA base register scaled down
by the s390x-specific CFA alignment factor of 8, in addition to the
adjustment by the s390x-specific CFA adjustment of -160, to further
improve the use of signed 8-bit SFrame offsets.  This is similar to the
DWARF data alignment factor getting factored out from certain offsets
stored in DWARF CFI.

[1]: s390x ELF ABI, sections "Register Roles" and "Stack Frame
     Allocation", https://github.com/IBM/s390x-abi/releases
[2]: s390x ELF ABI, commit 4e38ad9c8a88 ("Document the CFA"),
     https://github.com/IBM/s390x-abi/commit/4e38ad9c8a88

include/
	* sframe.h (SFRAME_S390X_CFA_OFFSET_ALIGNMENT_FACTOR): Define
	s390x-specific CFA offset alignment factor.
	(SFRAME_V2_S390X_CFA_OFFSET_ENCODE,
	SFRAME_V2_S390X_CFA_OFFSET_DECODE): Scale down/up by
	SFRAME_S390X_CFA_OFFSET_ALIGNMENT_FACTOR.

libsframe/
	* doc/sframe-spec.texi (s390x,
	SFRAME_S390X_CFA_OFFSET_ALIGNMENT_FACTOR): Document s390x-
	specific CFA offset alignment factor.

Signed-off-by: Jens Remus <jremus@linux.ibm.com>
2025-07-11 10:29:40 +02:00
Jens Remus
c1056133a3 s390: Store SFrame CFA offset adjusted
In SFrame V2 the size of the offsets following an SFrame FRE can be
either signed 8-bit, 16-bit, or 32-bit integer, with the largest offset
determining their size:
  1. CFA offset from CFA base register
  2. RA (stack save slot) offset from CFA, usually -48 on s390x if saved
  3. FP (stack save slot) offset from CFA, usually -72 on s390x if saved
The FP and RA offsets from CFA, when FP/RA saved on the stack, usually
have fixed values that fit into signed 8-bit SFrame offsets.  Likewise
the DWARF register numbers on s390x of general registers (GR; 0-15) and
floating-point registers (FPR; 16-31), when FP/RA saved in registers.
With that the CFA offset from CFA base register has the greatest impact
on the signed SFrame offset size.

The s390x ELF ABI [1] defines the CFA as stack pointer (SP) at call
site +160. [2]  Therefore the minimum CFA offset from CFA base register
on s390x is 160.  This does not fit into a signed 8-bit integer and
therefore effectively prevents any use of signed 8-bit SFrame offsets
on s390x.

For s390x store the CFA offset from CFA base register adjusted by -160
to enable the use of signed 8-bit SFrame offsets.

[1]: s390x ELF ABI, https://github.com/IBM/s390x-abi/releases
[2]: s390x ELF ABI, commit 4e38ad9c8a88 ("Document the CFA"),
     https://github.com/IBM/s390x-abi/commit/4e38ad9c8a88

include/
	* sframe.h (SFRAME_S390X_CFA_OFFSET_ADJUSTMENT): Define
	s390x-specific CFA offset adjustment.
	(SFRAME_V2_S390X_CFA_OFFSET_ENCODE,
	SFRAME_V2_S390X_CFA_OFFSET_DECODE): New s390x-specific
	macros.  Use SFRAME_S390X_CFA_OFFSET_ADJUSTMENT to en-/decode
	CFA offset.

bfd/
	* elf64-s390.c (elf_s390x_sframe_plt_fre): Use
	SFRAME_V2_S390X_CFA_OFFSET_ENCODE on CFA offset to store it
	adjusted and switch to 8-bit offsets.

gas/
	* gen-sframe.c (sframe_fre_set_cfa_offset): For s390x use
	SFRAME_V2_S390X_CFA_OFFSET_ENCODE on CFA offset to store it
	adjusted.
	(sframe_fre_get_cfa_offset): New helper.  For s390x use
	SFRAME_V2_S390X_CFA_OFFSET_DECODE on CFA offset to undo its
	adjustment.
	(sframe_xlate_do_def_cfa_register): Use new helper
	sframe_fre_get_cfa_offset.

libsframe/
	* sframe.c (sframe_fre_get_cfa_offset): For s390x use
	SFRAME_V2_S390X_CFA_OFFSET_DECODE on CFA offset to undo its
	adjustment.
	* doc/sframe-spec.texi (s390x,
	SFRAME_S390X_CFA_OFFSET_ADJUSTMENT,
	SFRAME_V2_S390X_CFA_OFFSET_ENCODE,
	SFRAME_V2_S390X_CFA_OFFSET_DECODE): Document s390x-specific
	adjustment of CFA offset.

libsframe/testsuite/
	* libsframe.find/plt-findfre-2.c (add_plt0_fde, add_pltn_fde):
	Use SFRAME_V2_S390X_CFA_OFFSET_ENCODE to enable use of 1-byte
	SFrame offsets.

Suggested-by: Indu Bhagat <indu.bhagat@oracle.com>
Signed-off-by: Jens Remus <jremus@linux.ibm.com>
2025-07-11 10:29:40 +02:00
Jens Remus
0d4d5a2633 libsframe: Add test for PLT0 and PLTN with only one FRE each
On s390x the PLT0 and PLTN entries are described with one SFrame FRE
each.  Add a test case for this particularity.

libsframe/testsuite/
	* libsframe.find/find.exp (plt-findfre-2): Add new test.
	* libsframe.find/plt-findfre-2.c: New test for PLT0 and PLTN
	with only one FRE each.
	* libsframe.find/local.mk (plt-findfre-2): Add new test.

libsframe/
	* Makefile.in: Regenerate.
2025-07-11 10:29:40 +02:00
Jens Remus
955570f097 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 s390x 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_FRE_RA_OFFSET_INVALID): New define.  Used as
	padding offset.
	* sframe-api.h (sframe_fre_get_ra_offset): Add comment that for
	s390x an offset value of SFRAME_FRE_RA_OFFSET_INVALID indicates
	that the RA is not saved.

gas/
	* gen-sframe.c (get_fre_num_offsets): For s390x account padding
	RA offset, if FP without RA saved.
	(sframe_get_fre_offset_size): Likewise.
	(output_sframe_row_entry): For s390x 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 s390x.

libsframe/
	* sframe.c (sframe_fre_get_ra_offset): Add comment that for
	s390x an offset value of SFRAME_FRE_RA_OFFSET_INVALID indicates
	that the RA is not saved.
	* sframe-dump.c (dump_sframe_func_with_fres): Treat invalid
	RA offsets as if they were undefined.  Display them as "U"
	to distinguish them.
	* doc/sframe-spec.texi (s390x): Document s390x-specific use of
	SFRAME_FRE_RA_OFFSET_INVALID to represent FP without RA saved.

gas/testsuite/
	* gas/cfi-sframe/cfi-sframe.exp: Rename s390x-specific tests.
	* gas/cfi-sframe/cfi-sframe-s390x-fpra-offset-err-1.s: Rename
	to ...
	* cfi-sframe/cfi-sframe-s390x-fpra-offset-err-1.d: Likewise.
	* gas/cfi-sframe/cfi-sframe-s390x-fpra-offset-2.s: This.
	* gas/cfi-sframe/cfi-sframe-s390x-fpra-offset-2.d: Likewise.
	Update test verification pattern accordingly.
	* cfi-sframe/cfi-sframe-s390x-fpra-register-err-1.s: Rename
	to ...
	* cfi-sframe/cfi-sframe-s390x-fpra-register-err-1.d: Likewise.
	* gas/cfi-sframe/cfi-sframe-s390x-fpra-register-2.s: This.
	* gas/cfi-sframe/cfi-sframe-s390x-fpra-register-2.d: Likewise.
	Update test verification pattern accordingly.

Signed-off-by: Jens Remus <jremus@linux.ibm.com>
2025-07-11 10:29:40 +02:00
Jens Remus
61b808e087 s390: Represent FP/RA saved in register in SFrame
GCC on s390x, when in a leaf function, can be observed to save the
frame pointer (FP) and/or return address (RA) register in a floating-
point registers (FPR) instead of on the stack.  This is declared using
the following CFI directive:

  .cfi_register <fp/ra-regnum>, <fpr-regnum>

SFrame cannot represent the FP and/or RA being saved in another
register.  It does only track the CFA base register (SP/FP), CFA offset
from CFA base register, and FP and RA save area offsets from CFA.

On s390x the FP and/or RA are only saved in another FPR when in a leaf
function.  That is a function that does not call any other function.
Therefore it can ever only be the topmost function in a call chain.
An unwinder by default has access to all registers of the function that
is the topmost on the call stack.  Therefore no further information
is required to restore FP/RA from the FPR.

Represent FP/RA saved in another register on s390x, by encoding the
DWARF register number shifted by one to the left with the least-
significant bit set in the offset as follows:

  offset = (regnum << 1) | 1

The use of the least-significant bit of the offset as indication is
possible, as the stack pointer (SP), the CFA, and any register save
area slots are 8-byte aligned according to the s390x ELF ABI:
- The stack pointer (SP) "shall maintain an 8-byte alignment". [1]
- The CFA is defined as SP at call site +160. [2]
- Pointers and 8-byte integers, such as general register values, must
  be 8-byte aligned. [3]
SFrame FP and RA stack offsets must therefore always be a multiple of
8 on s390x.  Note that for the same reason the DWARF data alignment
factor is -8 on s390x (see DWARF2_CIE_DATA_ALIGNMENT).

Add s390x-specific SFrame (error) tests for FP/RA saved in FPRs in leaf
function.

[1]: s390x ELF ABI, sections "Register Roles" and "Stack Frame
     Allocation", https://github.com/IBM/s390x-abi/releases
[2]: s390x ELF ABI, commit 4e38ad9c8a88 ("Document the CFA"),
     https://github.com/IBM/s390x-abi/commit/4e38ad9c8a88
[3]: s390x ELF ABI, section "Fundamental Types", table "Scalar types",
     https://github.com/IBM/s390x-abi/releases

include/
	* sframe.h (SFRAME_V2_S390X_OFFSET_IS_REGNUM): New s390x-
	specific macro to test whether an SFrame FP/RA offset is a DWARF
	register number.
	(SFRAME_V2_S390X_OFFSET_ENCODE_REGNUM): New s390x-specific macro
	to encode a DWARF register number into an SFrame FP/RA offset.
	(SFRAME_V2_S390X_OFFSET_DECODE_REGNUM): New s390x-specific macro
	to decode an SFrame FP/RA offset into a DWARF register number.
	* sframe-api.h (sframe_fre_get_fp_offset,
	sframe_fre_get_fp_offset): Add comment that for s390x the offset
	may be an encoded register number.

gas/
	* gen-sframe.c (s390_sframe_xlate_do_register): New S390-
	specific function.  Uses SFRAME_V2_S390X_OFFSET_ENCODE_REGNUM to
	represent FP/RA saved in another register on s390x.
	(sframe_xlate_do_register): Invoke s390_sframe_xlate_do_register
	on s390x.

libsframe/
	* sframe.c (sframe_fre_get_fp_offset, sframe_fre_get_fp_offset):
	Add comment that for s390x the offset may be an encoded register
	number.
	* sframe-dump.c (is_sframe_abi_arch_s390x): New helper to test
	whether ABI/arch is s390x.
	(dump_sframe_func_with_fres): Use
	SFRAME_V2_S390X_OFFSET_IS_REGNUM and
	SFRAME_V2_S390X_OFFSET_DECODE_REGNUM to dump FP/RA saved in
	another register on s390x.
	* doc/sframe-spec.texi (s390x): Document s390x-specific
	representation of FP/RA saved in another register.

gas/testsuite/
	* gas/cfi-sframe/cfi-sframe.exp: Update s390x-specific SFrame
	(error) tests.
	* gas/cfi-sframe/cfi-sframe-s390x-fpra-register-err-2.s: Rename
	to ...
	* gas/cfi-sframe/cfi-sframe-s390x-fpra-register-err-2.d:
	Likewise.
	* gas/cfi-sframe/cfi-sframe-s390x-fpra-register-1.s: This.  Test
	no longer triggers a warning, as SFrame can represent FP and RA
	saved in registers.
	* gas/cfi-sframe/cfi-sframe-s390x-fpra-register-1.d: Likewise.
	* gas/cfi-sframe/cfi-sframe-s390x-fpra-register-err-1.d: Test
	now triggers a different warning, as SFrame can represent FP and
	RA saved in registers, but not FP without RA saved in register.

Signed-off-by: Jens Remus <jremus@linux.ibm.com>
2025-07-11 10:29:40 +02:00
Jens Remus
d27d82f560 s390: Initial support to generate .sframe from CFI directives in assembler
This introduces initial support to generate .sframe from CFI directives
in assembler on s390 64-bit (s390x).  Due to SFrame V2 format
limitations it has the following limitations, some of them getting
addressed by subsequent patches, which cause generation of SFrame FDE
to be skipped:

- SFrame FP/RA tracking only supports register contents being saved on
  the stack (i.e. .cfi_offset).  It does not support FP/RA register
  contents being saved in other registers (i.e. .cfi_register).  GCC on
  s390x can be observed to save the FP/RA register contents in floating-
  point registers, but only in leaf functions.
  This issue is detailed further and resolved in the subsequent commit
  "s390: Represent FP/RA saved in register in SFrame".

- SFrame FP/RA tracking cannot represent FP without RA saved.  This is
  because the format assumes SFrame FDE offset2 to be the RA offset, if
  there are two offsets, and offset3 to be the FP offset, if there are
  three offsets.  There is no mean to distinguish whether offset2 is the
  RA or FP offset, if there are only two offsets.
  This issue is detailed further and resolved in the subsequent commit
  "s390: Represent FP without RA saved in SFrame".

- SFrame assumes a dedicated FP register number.  The s390x ELF ABI [1]
  does only designate register 11 as preferred FP register number.  In
  general GCC and Clang on s390x use register 11 as frame pointer.
  GCC on s390x can be observed to use register 14 as frame pointer in
  the stack clash protector in the function prologue.
  glibc on s390x contains hand-written assembler code that uses
  register 12 as frame pointer.

This s390x support is largely based on the AArch64 support from commit
b52c4ee466 ("gas: generate .sframe from CFI directives").

The SFrame ABI/arch identifier SFRAME_ABI_S390X_ENDIAN_BIG is introduced
for s390x and added to the SFrame format specification.

The s390x ELF ABI [1] specifies the following C calling conventions for
s390x architecture:
- Register 15 is the stack pointer (SP).
- Register 14 contains the return address (RA) at function entry.
- There is no dedicated frame pointer register.  Register 11 is the
  preferred frame pointer (FP). [2]  GCC and Clang in general use
  register 11 as frame pointer.
- The CFA is defined as SP at call site +160. [3]  The SP at call site
  can therefore be derived from the CFA using a SP value offset from CFA
  of -160.

The s390x ELF ABI [1] does not assign any standard save slot to each
register in the register save area of a stack frame.  Neither the
return address (RA, r14) nor preferred frame pointer (FP, r11)
necessarily need to be saved.  Therefore SFrame RA and FP tracking is
used.

Support for SFrame on s390 is only enabled for the 64-bit s390x ELF ABI
(z/Architecture with 64-bit addressing mode).  It is disabled for the
32-bit s390 ELF ABI (ESA/390 or z/Architecture with 32-bit addressing
mode).

s390x-specific SFrame assembler and linker tests are added, including
error tests for use of a non-preferred frame pointer (FP) register and
specification of a non-default return address (RA) register.

[1]: s390x ELF ABI, https://github.com/IBM/s390x-abi/releases
[2]: s390x ELF ABI, commit f00421825979 ("Add information about the frame
     pointer register"),
     https://github.com/IBM/s390x-abi/commit/f00421825979
[3]: s390x ELF ABI, commit 4e38ad9c8a88 ("Document the CFA"),
     https://github.com/IBM/s390x-abi/commit/4e38ad9c8a88

include/
	* sframe.h: Add reference to s390x architecture in comments.
	(SFRAME_ABI_S390X_ENDIAN_BIG): Define SFrame ABI/arch identifier
	for s390x.
	(SFRAME_S390X_SP_VAL_OFFSET): Define s390x-specific SP value
	offset from CFA.

libsframe/
	* sframe.c (need_swapping): Add SFRAME_ABI_S390X_ENDIAN_BIG.
	* doc/sframe-spec.texi (SFRAME_ABI_S390X_ENDIAN_BIG, s390x,
	SFRAME_S390X_SP_VAL_OFFSET): Document SFrame ABI/arch identifier
	for s390x, add references to s390x architecture, and document
	s390x-specifics, such as the SP value offset from CFA of -160.

gas/
	* config/tc-s390.h: s390x support to generate .sframe from CFI
	directives in assembler.
	(support_sframe_p): Define.
	(SFRAME_CFA_SP_REG, SFRAME_CFA_FP_REG, SFRAME_CFA_RA_REG):
	Define.
	(sframe_ra_tracking_p): Define.
	(sframe_cfa_ra_offset): Define.
	(sframe_get_abi_arch): Define.
	* config/tc-s390.c: s390x support to generate .sframe from CFI
	directives in assembler.
	(s390_sframe_cfa_sp_reg, s390_sframe_cfa_fp_reg,
	s390_sframe_cfa_ra_reg): New.  Initialize to DWARF register
	numbers of stack pointer (SP, r15), preferred frame pointer
	(FP, r11), and return address (RA, r14) registers.
	(s390_support_sframe_p): New function.  Return true if s390x.
	(s390_sframe_ra_tracking_p): New function.  Return true.
	(s390_sframe_cfa_ra_offset): New function.  Return
	SFRAME_CFA_FIXED_RA_INVALID.
	(s390_sframe_get_abi_arch): New function.  Return
	SFRAME_ABI_S390X_ENDIAN_BIG if s390x, otherwise zero.
	* gen-sframe.c: Add reference to s390x architecture in comments.
	(sframe_xlate_do_val_offset): Add support for s390x-specific
	SFRAME_S390X_SP_VAL_OFFSET.
	* NEWS: Add news entry.

gas/testsuite/
	* gas/cfi-sframe/cfi-sframe.exp: Enable common SFrame tests for
	s390x.  Add s390x-specific SFrame (error) tests.
	* gas/cfi-sframe/cfi-sframe-s390x-1.d: New s390x-specific SFrame
	test.
	* gas/cfi-sframe/cfi-sframe-s390x-1.s: Likewise.
	* gas/cfi-sframe/cfi-sframe-s390x-2.d: Likewise.
	* gas/cfi-sframe/cfi-sframe-s390x-2.s: Likewise.
	* gas/cfi-sframe/cfi-sframe-s390x-err-1.d: New s390x-specific
	SFrame error test that uses a non-default frame-pointer register
	as CFA base register.
	* gas/cfi-sframe/cfi-sframe-s390x-err-1.s: Likewise.
	* gas/cfi-sframe/cfi-sframe-s390x-err-2.d: Likewise.
	* gas/cfi-sframe/cfi-sframe-s390x-err-2.s: Likewise.
	* gas/cfi-sframe/cfi-sframe-s390x-err-3.d: New s390x-specific
	SFrame error test that uses a non-default return address
	register.
	* gas/cfi-sframe/cfi-sframe-s390x-err-3.s: Likewise.
	* gas/cfi-sframe/cfi-sframe-s390x-fpra-offset-1.d: New s390x-
	specific SFrame test that saves RA and FP individually on the
	stack.
	* gas/cfi-sframe/cfi-sframe-s390x-fpra-offset-1.s: Likewise.
	* gas/cfi-sframe/cfi-sframe-s390x-fpra-offset-err-1.d: New
	s390x-specific SFrame error test that saves FP and RA
	individually, to trigger FP without RA saved.
	* gas/cfi-sframe/cfi-sframe-s390x-fpra-offset-err-1.s: Likewise.
	* gas/cfi-sframe/cfi-sframe-s390x-fpra-register-err-1.d: New
	s390x-specific SFrame error test that saves FP and RA
	individually in registers.
	* gas/cfi-sframe/cfi-sframe-s390x-fpra-register-err-1.s:
	Likewise.
	* gas/cfi-sframe/cfi-sframe-s390x-fpra-register-err-2.d: New
	s390x-specific SFrame error test that saves RA and FP
	individually in registers.
	* gas/cfi-sframe/cfi-sframe-s390x-fpra-register-err-2.s:
	Likewise.

ld/testsuite/
	* ld-s390/s390.exp: Add simple SFrame test.
	* ld-s390/sframe-simple-1.d: New simple SFrame test.
	* ld-s390/sframe-bar.s: Likewise.
	* ld-s390/sframe-foo.s: Likewise.

Signed-off-by: Jens Remus <jremus@linux.ibm.com>
2025-07-11 10:29:40 +02:00
Jens Remus
b36a8e57ea sframe: Ignore section padding when converting endianness
The .sframe section may have a trailing padding due to the architecture-
specific default section alignment.  Do not treat this padding as error
when converting between target and host endianness.

This can be observed when building Binutils with SFrame s390x support on
x86-64 for s390x using configure option "--target=s390x-ibm-linux-gnu"
and running the GAS test suite.

While at it reuse the determined SFrame section header size.

libsframe/
	* sframe.c (flip_sframe): Ignore .sframe section padding.  Reuse
	SFrame header size.

Reported-by: Indu Bhagat <indu.bhagat@oracle.com>
Signed-off-by: Jens Remus <jremus@linux.ibm.com>
2025-07-11 10:29:40 +02:00
Indu Bhagat
0b1bf2fc98 bfd: gas: ld: libsframe: adopt new encoding for FDE func start addr field
This patch convenes a set of changes in bfd, gas, ld, libsframe towards
moving to the new encoding for the 'sfde_func_start_address' field in
SFrame FDE.

First, gas must now mark all SFrame sections with the new flag
SFRAME_F_FDE_FUNC_START_PCREL.  gas was already emitting the field
in the said encoding.

	* gas/gen-sframe.c (output_sframe_internal): Emit the flag
	SFRAME_F_FDE_FUNC_START_PCREL.

Similarly for ld, adopt the new semantics of sfde_func_start_address
consistently.  This means:
  - When merging SFrame sections, check that all input SFrame sections
    have the SFRAME_F_FDE_FUNC_START_PCREL flag set.  If the check
    fails, ld errors out.
  - When merging SFrame sections, keep even the in-memory contents of
    the FDE function start address (buffer passed to libsframe
    sframe_encoder_write () for writing out) encoded in the new
    semantics.  While it is, in theory, possible that instead of doing this
    change here, we adjust the value of sfde_func_start_address at the final
    write (sframe_encoder_write) time.  But latter is not favorable for
    maintenanance and may be generally confusing for developers.
  - When creating SFrame for PLT entries, emit flag
    SFRAME_F_FDE_FUNC_START_PCREL.

include/
        * sframe-api.h (SFRAME_F_LD_MUSTHAVE_FLAGS): New definition.
bfd/
	* elf-sframe.c (_bfd_elf_merge_section_sframe): Check for flag
	combinatation SFRAME_F_LD_MUSTHAVE_FLAGS set for all input and
	output SFrame sections.  If not, error out.  Also, adopt the new
        semantics of function start address encoding.
	* bfd/elfxx-x86.c (_bfd_x86_elf_create_sframe_plt): Emit flag
	SFRAME_F_FDE_FUNC_START_PCREL.

Next, for dumping SFrame sections, now that we are emitting the same
encoding in GAS, non-relocatable and relocatable SFrame links, it is the
time to set relocate to TRUE in debug_displays[].

binutils/
	* dwarf.c (struct dwarf_section_display): Allow sframe sections
	  to now be relocated.
gas/testsuite/
	* gas/cfi-sframe/cfi-sframe-aarch64-pac-ab-key-1.d: Update the
	test.  Relocatable SFrame sections now display non-zero value
	(appropriate function start address).

Now, as the SFrame sections on-disk and in-memory use the new semantics of
sfde_func_start_address encoding (i.e., function start address is the
offset from the sfde_func_start_address field to the start PC), the
calculation to make it human readable (i.e., relatable to the addresses
in .text sections) needs adjustment.

libsframe/
	* sframe-dump.c (dump_sframe_func_with_fres): Adjust the
	function start address for dumping.

Now that both the emission of the new encoding, and the relocation of
sections before dumping them is in place, it is time to adjust the
testcases.

gas/testsuite/
	* gas/cfi-sframe/cfi-sframe-aarch64-1.d: Update expected output
	to include SFRAME_F_FDE_FUNC_START_PCREL instead of NONE.
	* gas/cfi-sframe/cfi-sframe-aarch64-2.d: Likewise.
	* gas/cfi-sframe/cfi-sframe-aarch64-3.d: Likewise.
	* gas/cfi-sframe/cfi-sframe-aarch64-4.d: Likewise.
	* gas/cfi-sframe/cfi-sframe-common-1.d: Likewise.
	* gas/cfi-sframe/cfi-sframe-common-10.d: Likewise.
	* gas/cfi-sframe/cfi-sframe-common-11.d: Likewise.
	* gas/cfi-sframe/cfi-sframe-common-2.d: Likewise.
	* gas/cfi-sframe/cfi-sframe-common-3.d: Likewise.
	* gas/cfi-sframe/cfi-sframe-common-4.d: Likewise.
	* gas/cfi-sframe/cfi-sframe-common-5.d: Likewise.
	* gas/cfi-sframe/cfi-sframe-common-6.d: Likewise.
	* gas/cfi-sframe/cfi-sframe-common-7.d: Likewise.
	* gas/cfi-sframe/cfi-sframe-common-8.d: Likewise.
	* gas/cfi-sframe/cfi-sframe-common-9.d: Likewise.
	* gas/cfi-sframe/cfi-sframe-x86_64-1.d: Likewise.
	* gas/cfi-sframe/cfi-sframe-x86_64-2.d: Likewise.
	* gas/cfi-sframe/cfi-sframe-x86_64-empty-1.d: Likewise.
	* gas/cfi-sframe/cfi-sframe-x86_64-empty-2.d: Likewise.
	* gas/cfi-sframe/cfi-sframe-x86_64-empty-3.d: Likewise.
	* gas/cfi-sframe/cfi-sframe-x86_64-empty-4.d: Likewise.
	* gas/cfi-sframe/common-empty-1.d: Likewise.
	* gas/cfi-sframe/common-empty-2.d: Likewise.
	* gas/cfi-sframe/common-empty-3.d: Likewise.
	* gas/scfi/x86_64/scfi-cfi-sections-1.d: Likewise.
	* gas/scfi/x86_64/scfi-dyn-stack-1.d: Likewise.
ld/testsuite/
	* ld-aarch64/sframe-simple-1.d: Update expected output to
	include SFRAME_F_FDE_FUNC_START_PCREL.
	* ld-x86-64/sframe-ibt-plt-1.d: Likewise.
	* ld-x86-64/sframe-plt-1.d: Likewise.
	* ld-x86-64/sframe-pltgot-1.d: Likewise.
	* ld-x86-64/sframe-pltgot-2.d: Likewise.
	* ld-x86-64/sframe-simple-1.d: Likewise.

Naturally, the change of semantics for 'SFrame FDE function start address'
has consequences on the implementation in libsframe.  As per the new
semantics:
  - Function start address in the SFrame FDE (sfde_func_start_address)
    is an offset from the FDE function start address field to the start
    PC of the associated function.

Note that, the libsframe library brings the SFrame section contents into
its own memory to create a sframe_decoder_ctx object via sframe_decode
().  Many internal and user-interfacing APIs then may use
sframe_decoder_ctx object to interact and fulfill the work.

In context of changing semantics for sfde_func_start_address, following
relevant examples may help understand the impact:
  - sframe_find_fre () finds a the SFrame stack trace data (SFrame FRE)
    given a lookup offset (offset of lookup_pc from the start of SFrame
    section).  Now that the sfde_func_start_address includes the
    distance from the sfde_func_start_address field to the start of
    SFrame section itself, the comparison checks of
    sfde_func_start_address with the incoming lookup offset need
    adjustment.
  - Some internal functions (sframe_get_funcdesc_with_addr_internal ()
    finds SFrame FDE by using binary seach comparing
    sfde_func_start_address fields, etc.) need adjustments.
  - sframe_encoder_write () sorts the SFrame FDEs before writing out
    the SFrame data.  Sorting of SFrame FDE via the internal function
    sframe_sort_funcdesc() needs adjustments: the new encoding of
    sfde_func_start_address means the distances are not from the same
    anchor, so cannot be sorted directly.

This patch takes the approach of adding a new internal function:
  - sframe_decoder_get_secrel_func_start_addr (): This function returns
    the offset of the start PC of the function from the start of SFrame
    section, i.e., it gives a section-relative offset.

As the sframe_decoder_get_secrel_func_start_addr () API needs the value
of the function index in the FDE list, another internal API needs
sframe_fre_check_range_p () adjustments too.

Sorting the FDEs (via sframe_sort_funcdesc ()) is done by first bringing
all offsets in sfde_func_start_address relative to start of SFrame
section, followed by sorting, and then readjusting the offsets accroding
to the new position in the FDE list.

libsframe/
	* sframe.c (sframe_decoder_get_secrel_func_start_addr): New
	static function.
        (sframe_fre_check_range_p): Adjust the interface a bit.
	(sframe_get_funcdesc_with_addr_internal): Use
	sframe_decoder_get_secrel_func_start_addr () when comparing
	sfde_func_start_address with user input offset.
        (sframe_find_fre): Adopt the new semantics.
        (sframe_sort_funcdesc): Likewise.

For the libsframe testsuite, use the new encoding for FDE func start
addr: distance between the FDE sfde_func_start_address field and the
start PC of the function itself.

Use SFRAME_F_FDE_FUNC_START_PCREL flag, though the sframe_encode ()
interface in libsframe applies no sanity checks for the encoding itself.

libsframe/testsuite/
	* libsframe.find/findfre-1.c: Adjust to use the new
	SFRAME_F_FDE_FUNC_START_PCREL specific encoding.
	* libsframe.find/findfunc-1.c: Likewise.
	* libsframe.find/plt-findfre-1.c: Likewise.
	* libsframe/testsuite/libsframe.decode/DATA2: Update data file
	due to usage of new SFRAME_F_FDE_FUNC_START_PCREL flag.
	* libsframe/testsuite/libsframe.encode/encode-1.c: Use flag
	SFRAME_F_FDE_FUNC_START_PCREL.
2025-07-06 12:53:03 -07:00
Indu Bhagat
dcb0cf7bb2 include: sframe: doc: define new flag SFRAME_F_FDE_FUNC_START_PCREL
Add a new flag SFRAME_F_FDE_FUNC_START_PCREL to SFrame stack trace
format.  If set, this flag indicates that the function start address
field (sfde_func_start_address) is the offset to the function start
address from the SFrame FDE function start address field itself.

Such an encoding is friendlier to the exisitng PC-REL relocations
available in the ABIs supported in SFrame: AMD64 (R_X86_64_PC32) and
AArch64 (R_AARCH64_PREL32).  In subsequent patches, we will make the
implementation in gas and ld to both:
  - emit the values in the same (above-mentioned) encoding uniformly.
  - set the flag SFRAME_F_FDE_FUNC_START_PCREL in the SFrame header
    for consumers to be able to distinguish.

Define SFRAME_V2_F_ALL_FLAGS in sframe.h to help keep the implementation
less error-prone by keeping a set of all defined flags at a central
place.  Adjust the check in sframe_header_sanity_check_p () to use the
SFRAME_V2_F_ALL_FLAGS instead.

Add documentation for SFRAME_F_FDE_FUNC_START_PCREL.  Update the
documentation about the encoding of the sfde_func_start_address field.

Also, update the section "Changes from Version 1 to Version 2" to
include the specification of the new flag SFRAME_F_FDE_FUNC_START_PCREL
as an erratum to the SFrame Version 2 specification.

include/
        * sframe.h (SFRAME_F_FDE_FUNC_START_PCREL): New definition.
        (SFRAME_V2_F_ALL_FLAGS): Likewise.
libsframe/
	* sframe-dump.c (dump_sframe_header_flags): Update to include
	the new flag SFRAME_F_FDE_FUNC_START_PCREL.
	* sframe.c (sframe_header_sanity_check_p): Use
	SFRAME_V2_F_ALL_FLAGS.
libsframe/doc/
	* sframe-spec.texi: Add details about the new flag.  Also update
	the defails about the sfde_func_start_address encoding.
2025-07-06 12:53:03 -07:00
Indu Bhagat
72dac98050 include: libsframe: add APIs for offsetof FDE func start addr field
These APIs will be later used by the linker to arrange SFrame FDEs in
the output SFrame section.

include/
        * sframe-api.h (sframe_decoder_get_offsetof_fde_start_addr): New
	declaration.
        (sframe_encoder_get_offsetof_fde_start_addr): Likewise.

libsframe/
        * libsframe.ver: List the new APIs.
        * sframe.c (sframe_decoder_get_offsetof_fde_start_addr): New
	definition.
        (sframe_encoder_get_offsetof_fde_start_addr): Likewise.
2025-07-06 12:53:03 -07:00
Indu Bhagat
ef5573ced1 libsframe: refactor code for dumping section flags
To prepare code for accommodating new flag additions easily as the
format evolves.

libsframe/
        * sframe-dump.c (SFRAME_HEADER_FLAGS_STR_MAX_LEN): Remove.
        (dump_sframe_header_flags): .. to here. New definition.
        (PRINT_FLAG): New definition.
        (dump_sframe_header): Move some implementation from here ..
2025-07-06 12:53:03 -07:00
Indu Bhagat
251c6789b3 include: libsframe: add APIs for SFrame header flags
Add new APIs, one each for getting flags from the SFrame decoder and
SFrame encoder context objects respectively.

These will later be used by the linker to uniformly access the flags,
given the SFrame decoder and SFrame encoder objects.

Use the new API, where applicable, within libsframe.

include/
        * sframe-api.h (sframe_decoder_get_flags): New declaration.
        (sframe_encoder_get_flags): Likewise.
libsframe/
	* libsframe.ver: List new APIs.
        * sframe.c (sframe_decoder_get_flags): New definition.
	(sframe_encoder_get_flags): Likewise.
        (sframe_get_funcdesc_with_addr_internal): Use the new API.
        (sframe_encoder_get_flags): Likewise.
        (sframe_encoder_write_sframe): Likewise.
2025-07-06 12:53:03 -07:00
Indu Bhagat
87f5e2edca libsframe: fix error code in sframe_decode
When sanity check of SFrame header fails, set error code to
SFRAME_ERR_BUF_INVAL instead of the current SFRAME_ERR_NOMEM.
2025-07-05 19:11:15 -07:00
Indu Bhagat
d984b08bb7 sframe: fix PR libsframe/33051
Fix PR libsframe/Bug 33051 - ASAN: heap-buffer-overflow
../../src/libsframe/sframe.c:1054 in
sframe_get_funcdesc_with_addr_internal

The previous commit 9d2a24349e (libsframe: correct binary search for
SFrame FDE) adapted the binary search logic in
sframe_get_funcdesc_with_addr_internal.  Adjusting the upper end of the
search index was missed.

The search must only be done for FDEs starting at index 0 and up until
num_fdes - 1.  Prior logic of searching (before commit 9d2a24349e) was
a bit different.

libsframe/
	* sframe.c: Use the correct high index.
2025-06-03 23:10:46 -07:00
Indu Bhagat
a797dd2a54 sframe: doc: add date to the pdf output
libsframe/doc/
	* sframe-spec.texi: Include date with each publication.
2025-06-03 06:54:55 -07:00
Jens Remus
2adbf167ca libsframe: handle SFrame FRE start/end IP offsets as unsigned
The SFrame FRE start address (fre_start_addr) is defined as unsigned
32-bit integer, as it is an offset from SFrame FDE function start
address (sfde_func_start_address) and functions only grow upwards
(towards higher addresses).

The SFrame FRE start IP offset is a synonym to the SFrame FRE start
address.  The SFrame FRE end IP offset is either the value of the
subsequent FDE start address minus one, if that exists, or the FDE
function size minus one otherwise.  Both should therefore be handled
as unsigned 32-bit integer.

In libsframe the "lookup PC" (pc) and SFrame FDE function start address
(sfde_func_start_address) are both signed integers, as they are actually
offsets from the SFrame section.  The unsigned FDE start/end IP offsets
may therefore only be safely compared against the offset of the lookup
PC from FDE function start address if the FDE function start address is
lower or equal to the lookup PC, as this guarantees the offset to be
always positive:

Given:

  lookup_pc = pc - sframe_addr

  sfde_func_start_address = func_start_addr - sframe_addr

If the FDE function start address is lower or equal than the lookup PC,
which both are signed offsets from SFrame section, then the function
start address is also lower or equal to the PC, which are both unsigned:

  sfde_func_start_address <= lookup_pc
  func_start_addr - sframe_addr <= pc - sframe_addr
  func_start_addr <= pc

With that the offset of the lookup PC from FDE function start address
(lookup_pc - sfde_func_start_address) must always be positive, if
FDE function start address is lower or equal to the lookup PC:

  lookup_pc - sfde_func_start_address
  = pc - sframe_addr - (func_start_addr - sframe_addr)
  = pc - func_start_addr

libsframe/
	* sframe.c (sframe_find_fre): Define and handle start_ip_offset
	and end_ip_offset as unsigned (same as FRE fre_start_addr).
	(sframe_fre_check_range_p): Likewise.  Define PC offset (from
	function start address) as unsigned.

Signed-off-by: Jens Remus <jremus@linux.ibm.com>
2025-05-26 11:02:47 -07:00
Jens Remus
ada5c6fa08 libsframe: stop search for SFrame FRE if its start IP is greater than PC
The SFrame FREs for an SFrame FDE are sorted on their start address.
Therefore the linear search for a matching SFrame FRE can be stopped,
if its start address is greater than the searched for PC.

libsframe/
	* sframe.c (sframe_find_fre): Stop search if FRE's start IP is
	greater than PC.

Signed-off-by: Jens Remus <jremus@linux.ibm.com>
2025-05-26 11:02:29 -07:00
Jens Remus
9d2a24349e libsframe: correct binary search for SFrame FDE
sframe_get_funcdesc_with_addr_internal erroneously returns the last FDE,
if its function start address is lower than the searched for address.

Simplify the binary search for a SFrame FDE for a given address.  Only
return an FDE, if the searched for address is within the bounds of the
FDE function start address and function size.

libsframe/
	* sframe.c (sframe_get_funcdesc_with_addr_internal): Correct
	binary search for SFrame FDE.

libsframe/testsuite/
	* libsframe.find/plt-findfre-1.c: Add test for out of range
	PLT6.

Signed-off-by: Jens Remus <jremus@linux.ibm.com>
2025-05-26 11:01:14 -07:00
Indu Bhagat
f0d72d3508 libsframe: testsuite: improve findfunc-1 testcase
The testcase had usages of some magic numbers, making it difficult to
keep up when format changes come along.

libsframe/testsuite/
	* libsframe.find/findfunc-1.c: Restructure a bit.  Run test for two
	ways of placement of .sframe and .text.
2025-05-26 10:54:56 -07:00
Indu Bhagat
0d15aea98b libsframe: testsuite: improve findfre-1 testcase
The testcase had usages of some magic numbers, making it difficult to
keep up when format changes come along.

libsframe/testsuite/
	* libsframe.find/findfre-1.c: Restructure a bit.  Run test for two
	ways of placement of .sframe and .text.
2025-05-26 10:54:35 -07:00
Indu Bhagat
4e94f00756 libsframe: fix issue finding FRE in PCMASK type SFrame FDEs
SFrame FDEs of type SFRAME_FDE_TYPE_PCMASK are used for repetitive code
patterns, e.g., pltN entries.  For SFrame FDEs of type
SFRAME_FDE_TYPE_PCMASK, sframe_fre_check_range_p erroneously tested the
given PC instead of the masked PC offset from function start address.
Therefore it only worked correctly by chance, e.g., if the function start
address was aligned on the repetition block size.

For regular SFrame FDEs the PC offset from function start address must
be within a SFrame FRE's start IP offset and end IP offset.  For SFrame
FDEs of type SFRAME_FDE_TYPE_PCMASK, the masked PC offset must be within
that range.

SFrame FRE start/end IP offsets are relative to the SFrame FDE function
start address. For regular SFrame FDEs, the PC offset from function
start address must be within a SFrame FRE's start IP offset and end IP
offset.  For SFRAME_FDE_TYPE_PCMASK type FDEs, the masked PC offset must
be within that range.

Exercise the testcase for a variety of placements; without the fix some
of these tests will fail.  Also, make the testcase itself easier to
follow by adding appropriate vars where applicable.

libsframe/
	* sframe.c (sframe_fre_check_range_p): Fix logic for
	SFRAME_FDE_TYPE_PCMASK type FDE.
libsframe/testsuite/
	* libsframe.find/plt-findfre-1.c: Adjust the test for a variety
	of placements of .sframe and .plt.

Co-Authored-by: Jens Remus <jremus@linux.ibm.com>
2025-05-26 10:54:06 -07:00
Jens Remus
45576ca2a8 doc: sframe: Clarify FDE/FRE function/range start address fields
The function start address in a SFrame FDE (sfde_func_start_address)
is encoded as a signed offset to the function start address from the
SFrame section.

The PC range start address in a SFrame FRE (sfre_start_address) is
encoded as an unsigned offset to the range from the function start
address.

Signed-off-by: Jens Remus <jremus@linux.ibm.com>
2025-02-04 15:13:24 +01:00
Alan Modra
e8e7cf2abe Update year range in copyright notice of binutils files 2025-01-01 18:29:57 +10:30
Clément Chigot
1ca8994049 libsframe: remove runstatedir in Makefile.in
The regeneration was made with Ubuntu automake which has this runstatedir
additional variable, compared to the usual automake.
2024-07-10 10:24:45 +02:00
Clément Chigot
db79be6121 libsframe: accept --target configure option
Libsframe was missing AC_CANONICAL_TARGET, meaning that --target was
ignored. This could prevent libsframe.a to be installed in some cases,
the host fetching its canonical value while the target isn't. Both
having a different value, INSTALL_LIBBFD would be false.
2024-07-10 10:13:45 +02:00
Indu Bhagat
604b972e61 doc: sframe: add appendix for generating stack traces
Add an appendix to provide a rough outline to show how to generate stack
traces using the SFrame format.  Such content should hopefully aid the
reader assimmilate the information in the specification.

libsframe/
	* doc/sframe-spec.texi: Add new appendix.
2024-07-09 10:23:31 -07:00
Indu Bhagat
6dacff8a2f doc: sframe: segregate the ABI/arch-specific components
The recipe to interpret the SFrame FRE stack offsets is
ABI/arch-specific.

Although, there is other information in the specification that is
ABI-specific (like pauth_key usage in AArch64), those pieces of
information are now assimmilated in the SFrame specification in a way
that it is fairly difficult to carve then out into a ABI/arch-specific
section without confusing the readers.

For future though, the specification must strive to keep the generic
parts and ABI/arch-specific parts clearly laid out in separate sections.

libsframe/
	* doc/sframe-spec.texi: Reorder and adapt the contents.
2024-07-09 10:23:31 -07:00
Jens Remus
5c7f6da432 readelf/objdump: Display SFrame fixed RA offset as 'f' in dump
For the SFrame FRE frame-pointer (FP) offset from CFA a 'u' is displayed
if it is unavailable.

For the SFrame FRE return-address (RA) offset from CFA a 'u' was
displayed if the ABI uses a fixed RA offset from CFA. By chance a
'u' was also displayed if the RA offset is unavailable, as the string
buffer was not initialized after formatting the FP offset. Note that it
could not occur that the FP offset was erroneously displayed as RA
offset, as the SFrame format cannot have a FRE with FP offset without
RA offset.

For the FRE RA offset display 'f' if the ABI uses a fixed RA offset
from CFA. Display a 'u' if it is unavailable.

libsframe/
	* sframe-dump.c: Display SFrame fixed RA offset as 'f' in dump.

gas/testsuite/
	* gas/cfi-sframe/cfi-sframe-common-4.d: Test for RA displayed
	either as 'u' (if RA tracking) or as 'f' (fixed RA offset if no
	RA tracking).
	* gas/cfi-sframe/cfi-sframe-common-5.d: Likewise.
	* gas/cfi-sframe/cfi-sframe-common-6.d: Likewise.
	* gas/cfi-sframe/cfi-sframe-common-7.d: Likewise.
	* gas/cfi-sframe/cfi-sframe-common-8.d: Likewise.
	* gas/cfi-sframe/cfi-sframe-x86_64-1.d: Test for RA displayed
	as 'f' (fixed RA offset), as x86-64 does not use RA tracking.
	* gas/scfi/x86_64/scfi-cfi-sections-1.d: Likewise.
	* gas/scfi/x86_64/scfi-dyn-stack-1.d: Likewise.

ld/testsuite/
	* ld-x86-64/sframe-plt-1.d: Test for RA displayed as 'f' (fixed
	RA offset), as x86-64 does not use RA tracking.
	* ld-x86-64/sframe-simple-1.d: Likewise.

Signed-off-by: Jens Remus <jremus@linux.ibm.com>
2024-07-04 10:34:12 +02:00
Jens Remus
76f05e1dfb readelf/objdump: Dump SFrame CFA fixed FP and RA offsets
The SFrame format allows architectures to specify fixed offsets from the
CFA, if any, from which the frame pointer (FP) and/or return address
(RA) may be recovered. These offsets are stored in the SFrame header.

For instance the SFrame generation in the assembler for x86 AMD64
specifies a fixed offset from the CFA, from which the return address
(RA) may be recovered.

When dumping the SFrame header, for instance in readelf/objdump with
option --sframe, do also dump the specified fixed offsets from the CFA,
if any, from which the frame pointer (FP) and return address (RA) may
be recovered.

Update the common SFrame test case verification patterns to allow for
the optional dumping of the CFA fixed FP/RA offsets. Update the x86-
specific SFrame and SCFI test case verification patterns to require a
CFA fixed RA offset of -8.

libsframe/
	* sframe-dump.c: Dump CFA fixed FP and RA offsets.

gas/testsuite/
	* gas/cfi-sframe/cfi-sframe-common-1.d: Test for optional fixed
	FP and RA offsets.
	* gas/cfi-sframe/cfi-sframe-common-2.d: Likewise.
	* gas/cfi-sframe/cfi-sframe-common-3.d: Likewise.
	* gas/cfi-sframe/cfi-sframe-common-4.d: Likewise.
	* gas/cfi-sframe/cfi-sframe-common-5.d: Likewise.
	* gas/cfi-sframe/cfi-sframe-common-6.d: Likewise.
	* gas/cfi-sframe/cfi-sframe-common-7.d: Likewise.
	* gas/cfi-sframe/cfi-sframe-common-8.d: Likewise.
	* gas/cfi-sframe/cfi-sframe-x86_64-1.d: Test for fixed
	RA offset.
	* gas/cfi-sframe/common-empty-1.d: Test for optional fixed
	FP and RA offsets.
	* gas/cfi-sframe/common-empty-2.d: Likewise.
	* gas/cfi-sframe/common-empty-3.d: Likewise.
	* gas/scfi/x86_64/scfi-cfi-sections-1.d: Test for SFrame fixed
	RA offset.
	* gas/scfi/x86_64/scfi-dyn-stack-1.d: Likewise.

ld/testsuite/
	* ld-x86-64/sframe-plt-1.d: Test for SFrame fixed RA offset.
	* ld-x86-64/sframe-simple-1.d: Likewise.

Signed-off-by: Jens Remus <jremus@linux.ibm.com>
2024-07-04 10:34:12 +02:00
Indu Bhagat
f8ed9c5722 doc: sframe: small improvements for readability
Update some of the content to make the specification document hopefully
clearer:
  - Fix some typos.
  - Use Title case consistently for headings.
  - Update text around detection of foreign endianness.
  - Split the structure field "Name" in each table to two separate
    colunms for additional attention: "Type" and "Name".
  - Rename "SFrame endianness" section to "SFrame magic number and
    endianness"
  - Update text around provisions for extending SFrame for future
    ABIs/architectures.  Make it clear by tagging all provisions with an
    explicit index item "Provisions for future ABIs".
  - Add a paragraph on sort order of SFrame FDEs.
  - Add a statement for SFRAME_F_FRAME_POINTER flag.
  - Add a statement to assert that SFrame version 1 is now obsolete and
    should not be used.

libsframe/
	* doc/sframe-spec.texi: Small improvements for readability.
2024-06-25 22:27:12 -07:00
Matthieu Longo
3dee0baea2 autoupdate: add square brackets around arguments of AC_INIT
https://www.gnu.org/savannah-checkouts/gnu/autoconf/manual/autoconf-2.72/autoconf.html#index-AC_005fINIT-2
2024-06-10 08:25:56 +09:30
H.J. Lu
303da223b1 mmap: Avoid the sanitizer configure check failure
When -fsanitize=address,undefined is used to build, the mmap configure
check failed with

=================================================================
==231796==ERROR: LeakSanitizer: detected memory leaks

Direct leak of 4096 byte(s) in 1 object(s) allocated from:
    #0 0x7cdd3d0defdf in __interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:69
    #1 0x5750c7f6d72b in main /home/alan/build/gas-san/all/bfd/conftest.c:239

Direct leak of 4096 byte(s) in 1 object(s) allocated from:
    #0 0x7cdd3d0defdf in __interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:69
    #1 0x5750c7f6d2e1 in main /home/alan/build/gas-san/all/bfd/conftest.c:190

SUMMARY: AddressSanitizer: 8192 byte(s) leaked in 2 allocation(s).

Replace AC_FUNC_MMAP with GCC_AC_FUNC_MMAP to avoid the sanitizer
configure check failure.

bfd/

	* configure.ac: Replace AC_FUNC_MMAP with GCC_AC_FUNC_MMAP.
	* Makefile.in: Regenerated.
	* aclocal.m4: Likewise.
	* configure: Likewise.

binutils/

	* configure.ac: Replace AC_FUNC_MMAP with GCC_AC_FUNC_MMAP.
	* Makefile.in: Regenerated.
	* aclocal.m4: Likewise.
	* configure: Likewise.

ld/

	* configure.ac: Replace AC_FUNC_MMAP with GCC_AC_FUNC_MMAP.
	* Makefile.in: Regenerated.
	* aclocal.m4: Likewise.
	* configure: Likewise.

libctf/

	* configure.ac: Replace AC_FUNC_MMAP with GCC_AC_FUNC_MMAP.
	* Makefile.in: Regenerated.
	* aclocal.m4: Likewise.
	* configure: Likewise.

libsframe/

	* configure.ac: Replace AC_FUNC_MMAP with GCC_AC_FUNC_MMAP.
	* Makefile.in: Regenerated.
	* aclocal.m4: Likewise.
	* configure: Likewise.
2024-04-10 03:57:46 -07:00
Mark Wielaard
aa5a36b118 libsframe: Fix calloc argument order in dump_sframe_header
GCC14 warns about the order of the arguments to calloc

libsframe/sframe-dump.c: In function ‘dump_sframe_header’:
libsframe/sframe-dump.c:70:39: warning: ‘calloc’ sizes specified with ‘sizeof’ in the earlier argument and not in the later argument [-Wcalloc-transposed-args]
   70 |   flags_str = (char*) calloc (sizeof (char), SFRAME_HEADER_FLAGS_STR_MAX_LEN);
      |                                       ^~~~
libsframe/sframe-dump.c:70:39: note: earlier argument should specify number of elements, later size of each element

Fix this by swapping the size and count arguments.

libsframe/

	* sframe-dump.c (dump_sframe_header): Swap arguments to calloc
2024-01-22 18:19:03 +01:00
Alan Modra
fd67aa1129 Update year range in copyright notice of binutils files
Adds two new external authors to etc/update-copyright.py to cover
bfd/ax_tls.m4, and adds gprofng to dirs handled automatically, then
updates copyright messages as follows:

1) Update cgen/utils.scm emitted copyrights.
2) Run "etc/update-copyright.py --this-year" with an extra external
   author I haven't committed, 'Kalray SA.', to cover gas testsuite
   files (which should have their copyright message removed).
3) Build with --enable-maintainer-mode --enable-cgen-maint=yes.
4) Check out */po/*.pot which we don't update frequently.
2024-01-04 22:58:12 +10:30
Alan Modra
6a6859cbff regen config
This regenerates config files changed by the previous 44 commits.
Note that subject lines in these commits mostly match the gcc git
originating commit.
2023-08-12 10:27:57 +09:30
Indu Bhagat
a5cddf7b64 doc: sframe: update specification for SFRAME_VERSION_2
Add details for the changes made from Version 1 to Version 2 of the format.

Also add details about alignment in the SFrame format.  A portion of the
SFrame stack trace format has an unaligned on-disk representation.  Add
description at relevant points in the specificatin to clarify the
alignment related details.
2023-06-29 16:32:26 -07:00
Indu Bhagat
ce9a87252c sframe: bfd: gas: ld: format bump to SFrame version 2
SFrame version 2 encodes the size of repetitive insn block explicitly
in the format.  Add information in the SFrame FDE to convey the size
of the block of repeating instructions.  This information is used only
for SFrame FDEs of type SFRAME_FDE_TYPE_PCMASK.

Introduce two extra bytes for padding: this ensures that the memory
accesses to the members of the SFrame Frame Descriptor Entry (FDE) are
naturally aligned.

gas generates SFrame section with version SFRAME_VERSION_2 by default.

libsframe provides two new APIs to:
  - get an SFrame FDE data from the decoder context, and
  - add an SFrame FDE to the encoder context.
The additional argument (for rep_block_size) is useful for SFrame FDEs
where FDE type is SFRAME_FDE_TYPE_PCMASK.

The linker will generate the output SFrame sections in the
SFRAME_VERSION_2 format.  If the input sections offered to the linker
are not all in the SFRAME_VERSION_2 format, the linker issues an error
to the user.

objdump/readelf will show the following message to the user if .sframe
section in SFRAME_VERSION_1 format is seen:

 "No further information can be displayed.  SFrame version not
 supported."

In other words, like the rest of the binutils, only the current SFrame
format version, i.e., SFRAME_VERSION_2 is supported by the textual dump
facilities.

bfd/
	* elf-sframe.c (_bfd_elf_merge_section_sframe): Generate an
	output SFrame section with version SFRAME_VERSION_2.  Also,
	error out if the SFrame sections do not all have
	SFRAME_VERSION_2.
	* elfxx-x86.c (_bfd_x86_elf_create_sframe_plt): Generate SFrame
	section for plt entries with version SFRAME_VERSION_2.
gas/
	* gen-sframe.c (sframe_set_version): Update to SFRAME_VERSION_2.
	(output_sframe): Likewise.
gas/testsuite/
	* gas/cfi-sframe/cfi-sframe-aarch64-1.d: Use SFRAME_VERSION_2.
	* gas/cfi-sframe/cfi-sframe-aarch64-2.d: Likewise.
	* gas/cfi-sframe/cfi-sframe-aarch64-pac-ab-key-1.d: Likewise.
	* gas/cfi-sframe/cfi-sframe-common-1.d: Likewise.
	* gas/cfi-sframe/cfi-sframe-common-2.d: Likewise.
	* gas/cfi-sframe/cfi-sframe-common-3.d: Likewise.
	* gas/cfi-sframe/cfi-sframe-common-4.d: Likewise.
	* gas/cfi-sframe/cfi-sframe-common-5.d: Likewise.
	* gas/cfi-sframe/cfi-sframe-common-6.d: Likewise.
	* gas/cfi-sframe/cfi-sframe-common-7.d: Likewise.
	* gas/cfi-sframe/cfi-sframe-common-8.d: Likewise.
	* gas/cfi-sframe/cfi-sframe-x86_64-1.d: Likewise.
	* gas/cfi-sframe/common-empty-1.d: Likewise.
	* gas/cfi-sframe/common-empty-2.d: Likewise.
	* gas/cfi-sframe/common-empty-3.d: Likewise.
ld/testsuite/
	* ld-aarch64/sframe-simple-1.d: Adjust for SFRAME_VERSION_2.
	* ld-x86-64/sframe-plt-1.d: Likewise.
	* ld-x86-64/sframe-simple-1.d: Likewise.
libsframe/
	* libsframe.ver: Add the new APIs.
	* sframe.c (sframe_decoder_get_funcdesc_v2): New definition.
	(sframe_encoder_add_funcdesc_v2): Likewise.
	(sframe_header_sanity_check_p): Include SFRAME_VERSION_2.
	(sframe_fre_check_range_p): Get rep_block_size info from SFrame
	FDE.
	* sframe-dump.c (dump_sframe_header): Add support for
	SFRAME_VERSION_2.
	(dump_sframe): Inform user if SFrame section in SFRAME_VERSION_1
	format is seen.
libsframe/testsuite/
	* libsframe.decode/DATA-BE: Regenerated data file.
	* libsframe.decode/DATA1: Likewise.
	* libsframe.decode/DATA2: Likewise.
	* libsframe.find/plt-findfre-1.c: Use new API in the testcase.
include/
	* sframe.h: Add member to encode size of the code block of
	repeating instructions.  Add 2 bytes of padding.
	* sframe-api.h (sframe_decoder_get_funcdesc_v2): New
	declaration.
	(sframe_encoder_add_funcdesc_v2): Likewise.
2023-06-29 16:31:58 -07:00
Indu Bhagat
9f71b60bd4 libsframe: add new APIs to get SFrame version
While the SFrame preamble is guaranteed to not change between versions,
providing these access APIs from the SFrame decoder and encoder APIs is
for convenience only.  The linker may want to use these APIs as the
format evolves.

include/
	* sframe-api.h (sframe_decoder_get_version): New declaration.
	(sframe_encoder_get_version): Likewise.

libsframe/
	* libsframe/libsframe.ver: Add new APIs.
	* libsframe/sframe.c (sframe_decoder_get_version): New
	definition.
	(sframe_encoder_get_version): Likewise.
2023-06-29 16:28:56 -07:00
Indu Bhagat
3169b734cf libsframe: fix sframe_find_fre for pltN entries
For a toy application on x86_64, for example, following is the SFrame
stack trace information for the 3 pltN entries of 16 bytes each:

   func idx [1]: pc = 0x401030, size = 48 bytes
   STARTPC[m]      CFA       FP        RA
   0000000000000000  sp+8      u         u
   000000000000000b  sp+16     u         u

The data in first column is the start_ip_offset.  Also note that the FDE
is of type SFRAME_FDE_TYPE_PCMASK (denoted by the [m] on LHS).

Where each pltN (note: excluding plt0 entry) entry looks like:

  401030: jmp    *0x2fca(%rip)
  401036: push   $0x0
  40103b: jmp    401020<_init+0x20>

  401040: jmp    *0x2fc2(%rip)
  401046: push   $0x1
  40104b: jmp    401020<_init+0x20>

  401050: jmp    *0x2fba(%rip)
  401056: push   $0x2
  40105b: jmp    401020<_init+0x20>

Now, to find SFrame stack trace information from an FDE of type
SFRAME_FDE_TYPE_PCMASK, sframe_find_fre () was doing an operation
like,
  (start_ip_offset & 0xf) >= (pc & 0xf)

This works for pltN entry of size, say, less than 16 bytes.  But if the
pltN entries or similar code stubs (for which SFrame FDE of type
SFRAME_FDE_TYPE_PCMASK may be used), evolve to be of size > 16 bytes,
this will cease to work.

To match the range covered by the SFrame FRE, one should instead perform
a modulo operation.  The constant for the modulo operation must be the
size of the pltN entry.  Further, this constant should ideally be
encoded in the format, as it may be different for each ABI.

In SFrame Version 2 of the format, we will move towards encoding it
explicitly in the SFrame FDE.  For now, fix up the logic to at least
move towards modulo operation.

libsframe/
	* sframe.c (sframe_fre_check_range_p): New definition.
	(sframe_find_fre): Refactor a bit and use the new definition
	above.
include/
	* sframe.h (SFRAME_FDE_TYPE_PCMASK): Update comment.
libsframe/doc/
	* sframe-spec.texi: Fix the text for SFRAME_FDE_TYPE_PCMASK FDE
	type.
2023-06-29 11:03:32 -07:00
Indu Bhagat
df6f1afb6d libsframe: bfd: use uint32_t for return type of get_num_fidx APIs
Keep the data types usage in libsframe look consistent.

bfd/
	* elf-sframe.c (_bfd_elf_merge_section_sframe): Use uint32_t
	type alias.
	* libsframe/sframe.c (sframe_decoder_get_funcdesc_at_index):
	Likewise.
	(sframe_decoder_get_num_fidx): Likewise.
	(sframe_encoder_get_num_fidx): Likewise.
include/
	* sframe-api.h (sframe_decoder_get_num_fidx): Likewise.
	(sframe_encoder_get_num_fidx): Likewise.
2023-06-27 12:01:56 -07:00
Indu Bhagat
3412dcec61 libsframe: use appropriate data types for args of sframe_encode
include/
	* sframe-api.h (sframe_encode): Use of uint8_t is more
	appropriate.
libsframe/
	* sframe.c (sframe_encode): Likewise.
2023-06-27 12:01:56 -07:00
Indu Bhagat
a9f1da26da libsframe: use uint8_t for return type of sframe_fre_get_base_reg_id
Use a more appropriate data type.

include/
	* sframe-api.h (sframe_fre_get_base_reg_id): Use uint8_t as
	return type.
libsframe/
	* sframe-dump.c (dump_sframe_func_with_fres): Use uint8_t type
	for base reg id.
	* sframe.c (sframe_fre_get_base_reg_id): Use uin8_t as return
	type.
2023-06-27 12:01:56 -07:00
Indu Bhagat
de4879feca libsframe: use uint8_t instead of unsigned char for abi_arch
Use uint8_t consistently for identifying ABI/arch in SFrame format.

bfd/
	* elf-sframe.c (_bfd_elf_merge_section_sframe):
libsframe/
	* sframe-dump.c (is_sframe_abi_arch_aarch64): Use uint8_t for
	local variable.
	* sframe.c (sframe_decoder_get_abi_arch): Update return type to
	uint8_t.
	(sframe_encoder_get_abi_arch): Likewise.
include/
	* sframe-api.h (sframe_decoder_get_abi_arch): Likewise.
	(sframe_encoder_get_abi_arch): Likewise.
2023-06-27 12:01:56 -07:00
Indu Bhagat
49e4485cba libsframe: bfd: use uint32_t for return type of sframe_calc_fre_type
Use uint32_t type alias consistently for all APIs in libsframe.

bfd/
	* elfxx-x86.c (_bfd_x86_elf_create_sframe_plt): Adjust for the
	changed return type.
libsframe/
	* sframe.c (sframe_calc_fre_type): Use uint32_t for return type.
include/
	* sframe-api.h (sframe_calc_fre_type): Likewise.
2023-06-27 12:01:56 -07:00