Commit graph

168 commits

Author SHA1 Message Date
Alan Modra
366f377305 libsframe testsuite format mismatches on 32-bit host
libsframe.find/findfre-1.c:177:41: warning: format ‘%lx’ expects argument of type ‘long unsigned int’, but argument 2 has type ‘int64_t’ {aka ‘long long int’} [-Wformat=]

	* testsuite/sframe-test.h: Include inttypes.h.
	* testsuite/libsframe.find/findfre-1.c (main): Use PRIx64 to print
	int64_t vars.
	* testsuite/libsframe.find/findfre-flex-1.c (main): Likewise.
	* testsuite/libsframe.find/findfunc-1.c (main): Likewise.
	* testsuite/libsframe.find/plt-findfre-1.c (main): Likewise.
	* testsuite/libsframe.find/plt-findfre-2.c (main): Likewise.
2026-04-06 10:46:06 +09:30
Alan Modra
3949fb481a Free sframe encoder context
Like the patch to free sframe decoder data, this also needs to ensure
the function doing the free is passed the actual context address.

bfd/
	* elf-sframe.c (_bfd_elf_write_section_sframe): Don't pass
	address of local var to sframe_encoder_free, pass the actual
	context address.
	* elf64-s390.c (elf_s390_link_hash_table_free): New function.
	(elf_s390_link_hash_table_create): Set hash_table_free.  Tidy
	zmalloc call.
	(_bfd_s390_elf_write_sframe_plt): Don't pass address of local
	var to sframe_encoder_free, pass the actual context address.
	* elflink.c: Include sframe-api.h.
	(_bfd_elf_link_hash_table_free): Free sframe encoder data.
	* elfxx-x86.c (elf_x86_link_hash_table_free): Likewise.
	(_bfd_x86_elf_write_sframe_plt): Don't pass address of local
	var to sframe_encoder_free, pass the actual context address.
libsframe/
	* sframe.c (sframe_encode): Free context on error return path.
2026-02-11 15:31:33 +10:30
Alan Modra
82861a8901 Double-free sframe_decode tempbuf
If an error occurs after assigning tempbuf to dctx->sfd_buf, then
tempbuf will be freed twice.  Avoid that by moving tempbuf and its
free on errors into the block where it is used.

	* sframe.c (sframe_decode): Localise tempbuf.
2026-02-11 15:30:24 +10:30
Indu Bhagat
2c4129c4cc sframe: doc: minor fixups in language for clarity
libsframe/doc/
	* sframe-spec.texi: Minor language and formatting fixup.
2026-02-05 23:17:41 -08:00
Indu Bhagat
05dba89586 doc: sframe: restore DRAFT marker for all outputs
Now that the 2.46 branch is created, restore DRAFT markers for the
development master branch.

libsframe/doc/
	* sframe-spec.texi: restore DRAFT marker for all outputs.
2026-01-30 12:42:54 -08:00
Indu Bhagat
4edeb9be08 include: libsframe: rename SFrame V3 Flexible FDE macros to CTRLWORD
The existing SFrame V3 macros for Flexible FDEs used the term 'OFFSET'
to refer to the data word encoding control/register data word. This can
be confusing, as the control data word (register ID, dereference flags)
is distinct from a stack offset.

This patch renames these macros to use 'CTRLWORD' to better reflect
their purpose. It also updates the assembler and libsframe dumper to
use the new nomenclature.

No functional change.

Reviewed-by: Jens Remus <jremus@linux.ibm.com>

gas/
	* gen-sframe.c (sframe_get_fre_dataword_size): Use
	SFRAME_V3_FLEX_FDE_CTRLWORD_ENCODE.
	(output_sframe_row_entry_datawords): Likewise.
include/
	* sframe.h (SFRAME_V3_FLEX_FDE_REG_ENCODE): Rename from ..
	(SFRAME_V3_FLEX_FDE_CTRLWORD_ENCODE): .. to.
	(SFRAME_V3_FLEX_FDE_CTRLWORD_REGNUM): Rename from
	SFRAME_V3_FLEX_FDE_OFFSET_REG_NUM to this.
	(SFRAME_V3_FLEX_FDE_CTRLWORD_DEREF_P): Rename from
	SFRAME_V3_FLEX_FDE_OFFSET_REG_DEREF_P to this.
	(SFRAME_V3_FLEX_FDE_CTRLWORD_REG_P): Rename from
	SFRAME_V3_FLEX_FDE_OFFSET_REG_P to this.
	(SFRAME_V3_FRE_RA_UNDEFINED_P): Add new V3 macro.
libsframe/
	* sframe-dump.c (dump_sframe_func_fres_flex): Update all
	callers to use the new CTRLWORD macros.
libsframe/testsuite/
	* libsframe.decode/be-flipping-v3.c: Use renamed macros.
2026-01-29 20:02:57 -08:00
Indu Bhagat
7e369225d8 sframe: doc: prepare SFrame specification for release
Remove the DRAFT marker before release.  Currently needs to be done
manually.

libsframe/
	* doc/sframe-spec.texi: Remove DRAFT marker.
2026-01-23 16:25:21 -08:00
Indu Bhagat
1a6274360a sframe: doc: minor typos and cosmetic fixes
libsframe/
	* doc/sframe-spec.texi: Minor edits.
2026-01-23 14:59:11 -08:00
Indu Bhagat
efaf24f786 libsframe: rename sframe_fre_* internal APIs to use data word instead of offset
Rename three internal functions:
  - sframe_fre_get_offset_count to sframe_fre_get_dataword_count
  - sframe_fre_get_offset_size to sframe_fre_get_dataword_size
  - sframe_fre_offset_bytes_size to sframe_fre_datawords_bytes_size.

libsframe/
	* sframe.c: Rename functions and variables.
2026-01-23 14:21:56 -08:00
Indu Bhagat
664e033cf8 libsframe: rename flip_fre_stack_offsets to flip_fre_datawords
Also adjust function level comment for flip_fre_datawords.

libsframe/
	* sframe.c (flip_fre_stack_offsets): Rename to
	flip_fre_datawords.
2026-01-23 14:21:35 -08:00
Indu Bhagat
aba17f004d libsframe: rename offset in user-facing sframe_frame_row_entry struct
This patch is the first patch to align libsframe with the terminology
change of moving from 'offset' to 'data word'.  With the introduction of
flexible FDE type SFRAME_FDE_TYPE_FLEX, the variable-length data
following an SFrame FRE header can now represent signed offsets or
unsigned control data. Consequently, 'data word' is adopted as the more
generic term.

This change updates the names used in the user-facing
sframe_frame_row_entry structure.  While some API function names remain
unchanged to preserve existing contracts, the underlying data buffers
and size macros now reflect the data word' terminology.

libsframe is a tricky spot for such a terminology change: some of APIs
are still used to read (may be followed by endian swap) for dumping
SFrame V2 sections in textual format.  Some classic examples are
sframe_decode_fre, and flip_fre (both are static functions).  But moving
forward, using the term 'data word' for such APIs and their internal too
may be better.  Subsequent commits will achieve just that.

include/
	* sframe-api.h (MAX_NUM_DATAWORDS): Rename from
	MAX_NUM_STACK_OFFSETS.
	(MAX_DATAWORD_BYTES): Rename from MAX_OFFSET_BYTES.
	(struct sframe_frame_row_entry): Rename fre_offsets to
	fre_datawords.
libsframe/
	* sframe.c (sframe_fre_sanity_check_p): Use MAX_NUM_DATAWORDS.
	(sframe_get_fre_offset): Update internal pointers to use
	'offsets' and access fre_datawords.
	(sframe_get_fre_udata): Rename local variables to
	dataword_cnt/dataword_size and update to use
	SFRAME_FRE_DATAWORD_* constants.
	(sframe_decode_fre): Use fre_datawords and MAX_DATAWORD_BYTES.
	(sframe_encoder_add_fre): Use fre_datawords.
	(sframe_encoder_write_fre): Use fre_datawords.
2026-01-23 14:21:15 -08:00
Indu Bhagat
b41e01add4 sframe: doc: terminology change from offset to data word
ChangeLog:
	* libsframe/doc/sframe-spec.texi
2026-01-23 14:20:33 -08:00
Alan Modra
5fab123e20 sframe fre sanity checks
I noticed the fre esz check in flip_sframe_fdes_with_fres_* was wrong,
testing against the full buffer size rather than the remaining size.
It is also ineffective at stopping buffer overflows to check after the
buffer accesses have occurred.

Likely many more buffer overflow checks in the sframe code are needed
before anyone can claim it is secure.  Even in the fre code, I see
things like sframe_decoder_get_fres_buf merrily iterating over fres
without a concern for buffer overflow.

	* sframe.c (flip_fre): Add fp_size param.  Use it to avoid
	buffer overflow on fuzzed input.
	(flip_sframe_fdes_with_fres_v2): Pass remaining buffer size to
	flip_fre.  Remove now redundant and wrong esz check.
	(flip_sframe_fdes_with_fres_v3): Likewise.
2026-01-22 17:57:35 +10:30
Alan Modra
efcfd08547 libsframe misaligned uint32_t
I saw asan complaints about misaligned loads and stores when taking a
quick look at pr33810 before Jens' patch was applied.  They have
disappeared now, but it looks to me like a FRE can start on any
address boundary and there is no padding or suchlike to align the
FRE fields.

	* sframe.c (flip_fre_stack_offsets): Let the compiler know
	that integers may be misaligned.
2026-01-21 17:47:03 +10:30
Jens Remus
9f3749fff9 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: 8ab6e4c72a ("[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>
2026-01-20 10:22:52 +01:00
Indu Bhagat
55575b6058 [SFrame-V3] libsframe: testsuite: add new testcases for SFRAME_FDE_TYPE_FLEX
This patch adds two new tests for SFrame V3 changes, focusing on the
newly added flexible FDE TYPE SFRAME_FDE_TYPE_FLEX.

Following tests are added:
  - be-flipping-v3.c: Validates that big-endian SFrame V3 data is
    correctly endian flipped when run on little-endian hosts.  It
    verifies the decoding of CFA offsets and the new V3 register/offset
    metadata bitfields using the SFRAME_V3_FLEX_FDE_OFFSET_REG_* macros.
  - findfre-flex-1.c: Tests a variety of sframe_find_fre lookup
    scenarios, apart from checking the basic encoder/decoder APIs.

Documentation for the binary test data DATA-BE-V3 is provided in
README-be-flipping-v3 to ensure reproducibility.

libsframe/
	* Makefile.in: Regenerate.
	* testsuite/libsframe.decode/DATA-BE-V3: New test data.
	* testsuite/libsframe.decode/README-be-flipping-v3: New file.
	* testsuite/libsframe.decode/be-flipping-v3.c: New test.
	* testsuite/libsframe.decode/decode.exp: Run be-flipping-v3.
	* testsuite/libsframe.decode/local.mk: Add be-flipping-v3.
	* testsuite/libsframe.find/find.exp: Run findfre-flex-1.
	* testsuite/libsframe.find/findfre-flex-1.c: New test.
	* testsuite/libsframe.find/local.mk: Add findfre-flex-1.
2026-01-15 17:02:28 -08:00
Indu Bhagat
c1929fda66 [SFrame-V3] sframe: s390: gas: testsuite: enable flex FDE for s390x
This commit amalgamates a patch set proposed by Jens Remus to enable the
SFrame Version 3 Flexible FDE Type (SFRAME_FDE_TYPE_FLEX) generation for
the s390x ABI.

Previously, s390x relied on architecture-specific encoding (shifting register
numbers into offset fields) to represent register recovery rules.  This limited
the complexity of CFI that could be supported.  With Flex FDE enabled:
  - s390x can now represent .cfi_def_cfa using non-SP/FP registers.
  - The architecture-specific function s390_sframe_xlate_do_register () in GAS
    is replaced by the generic Flex FDE generation path.
  - The SFrame V3 specific macros for s390x register encoding are removed
    from libsframe/include, as the generic Flex FDE format handles explicit
    register columns natively.

The testsuite is updated to replace negative tests (which asserted
warnings or empty SFrame generation for these patterns) with positive
tests verifying valid Flex FDE generation.

Co-authored-by: Jens Remus <jremus@linux.ibm.com>

gas/
	* config/tc-s390.c (s390_support_flex_fde_p): Return true to
	enable Flex FDE generation.
	* gen-sframe.c (s390_sframe_xlate_do_register): Disable s390x
	specific implementation.
	(sframe_xlate_do_register): Invoke generic Flex FDE path now
	that flex FDE generation is supported.
gas/testsuite/
	* gas/cfi-sframe/cfi-sframe-s390x-err-1.d: Removed.
	* gas/cfi-sframe/cfi-sframe-s390x-err-1.s: Moved to...
	* gas/cfi-sframe/cfi-sframe-s390x-non-spfp-cfa-1.s: ...here.
	* gas/cfi-sframe/cfi-sframe-s390x-err-2.d: Removed.
	* gas/cfi-sframe/cfi-sframe-s390x-err-2.s: Moved to...
	* gas/cfi-sframe/cfi-sframe-s390x-non-spfp-cfa-2.s: ...here.
	* gas/cfi-sframe/cfi-sframe-s390x-fpra-register-1.d: Update to
	expect Flex FDE output.
	* gas/cfi-sframe/cfi-sframe-s390x-fpra-register-2.d: Likewise.
	* gas/cfi-sframe/cfi-sframe.exp: Run renamed tests.
include/
	* sframe.h (SFRAME_V3_S390X_OFFSET_IS_REGNUM): Remove.
	(SFRAME_V3_S390X_OFFSET_ENCODE_REGNUM): Remove.
	(SFRAME_V3_S390X_OFFSET_DECODE_REGNUM): Remove.
libsframe/
	* sframe-dump.c (sframe_s390x_offset_regnum_p): Return false
	for SFrame V3.
	(sframe_s390x_offset_decode_regnum): Remove V3 support.
2026-01-15 17:02:28 -08:00
Indu Bhagat
4553b29a0e [SFrame-V3] sframe: doc: specification changes for SFrame version 3
Update the SFrame specification to document Version 3. This version
introduces fundamental changes to support additional scenarios (e.g.,
s390x register-based recovery, x86_64 DRAP) using a 'Flexible FDE'
definition while maintaining compactness for standard frames.

Key changes documented include:
  - The SFrame Function Descriptor Entry (FDE) is split into two
    distinct structures:
      [sframe_func_desc_idx] Fixed-size index for binary search.
      [sframe_func_desc_attr] Variable-location attributes including new
      info bytes.
  - Flexible FDEs (SFRAME_FDE_TYPE_FLEX)
    A new FDE type that interprets FRE bytes not as simple stack
    offsets, but as pairs of "Control Data" and "Offset". This
    allows encoding complex recovery rules (e.g., "CFA = *(RBP - 8)")
    without bloating the format for standard cases.
  - Provision for defining new FDE types in future.  A total of 5 bits
    are reserved for this purpose.
  - Make explicit distinction between FDE Types vs. PC Type
      [FDE Type] Defines how to interpret stack trace data (Default vs. Flex).
      [PC Type] Defines how PCs are advanced for an FDE (Increment vs. Mask).
  - Other renames like sfde_func_start_address is renamed to
    sfdi_func_start_offset to accurately reflect that it is a relative
    offset, not an absolute address.
  - Remove SFRAME_F_FRAME_POINTER from SFrame V3.  The corresponding bit
    is now unused in SFrame V3.

libsframe/doc/
	* sframe-spec.texi: Update text for SFrame Version 3.
	(Changes from Version 2 to Version 3): New section.
	(The SFrame FDE Index): New section documenting sframe_func_desc_idx.
	(The SFrame FDE Attribute): New section documenting
	sframe_func_desc_attr.
	(The SFrame FDE Info Bytes): Expanded to document sfda_func_info and
	sfda_func_info2 split.
	(The SFrame FDE PC Types): Document SFRAME_V3_FDE_PCTYPE_INC and
	SFRAME_V3_FDE_PCTYPE_MASK.
	(The SFrame FDE Types): Document SFRAME_FDE_TYPE_DEFAULT and
	SFRAME_FDE_TYPE_FLEX.
	(Interpretation of SFrame FREs): Split into Default and Flexible
	interpretation.
	(Flexible FDE Type Interpretation): Document the Control
	Data/Offset pair encoding.
2026-01-15 17:02:28 -08:00
Indu Bhagat
2a99ed6340 [SFrame-V3] include: libsframe: remove SFRAME_F_FRAME_POINTER flag
SFrame V3 has 8 precious flag bits, two of which are being used.  More
flag byte (s) can be added to the auxiliary header when it comes to
that.  But for now, it may be worthwhile to use the 8-bits frugally.

SFRAME_F_FRAME_POINTER flag bit was added with the intention of marking
binaries built with frame-pointer preserved.  A stack tracer could then
use this information, to unambiguously ascertain whether frame-pointer
based stack traces will be precise.  But such a marking of binary will
ideally be done by the linker, and at the moment adding such a framework
is not justified for such small gain.  The outcome of this is that
SFRAME_F_FRAME_POINTER is never set in SFrame V2 binaries.

Remove the definition SFRAME_F_FRAME_POINTER for SFrame V3.  The
relinquished bit can be used (in future format incarnations) when
reading/dumping SFrame V2 sections are no longer supported by consumers.
Changing the values of existing flags, e.g.,
SFRAME_F_FDE_FUNC_START_PCREL, is not being done for V3, to avoid
version-specific flag bit reading (albeit doable) in consumers.

Related changes to the specification are done in a subsequent commit.

include/
	* sframe.h (SFRAME_V3_F_ALL_FLAGS): Remove
	SFRAME_F_FRAME_POINTER from the set of V3 flags.
libsframe/
	* sframe-dump.c (dump_sframe_header_flags): Add a comment for
	clarity.
2026-01-15 17:02:27 -08:00
Indu Bhagat
8ab6e4c72a [SFrame-V3] include: gas: libsframe: split FDE into idx and attr
This patch introduces a structural change to the SFrame V3 format. It
shifts the SFrame Function Descriptor Entry (FDE) (a physical entity in
SFrame V2) into a conceptual one in SFrame V3, such that an FDE is now
split into two distinct parts to optimize the binary search table and
data organization:
 - FDE Index (sframe_func_desc_idx_v3): This structure contains the
   essential indexing information: the function start address offset,
   function size in bytes, and the offset to the SFrame FDE
   attribute/Frame Row Entries (FREs) area for the function.
 - FDE Attributes (sframe_func_desc_attr_v3): The metadata regarding the
   function (number and size of FREs, FDE type, and repetition block
   size etc.) is moved to a new structure.

On-Disk Layout: In V3, the "Attributes" are now stored immediately
preceding the SFrame FREs for that function. The sfde_func_start_fre_off
now points to the attr structure, and the actual FREs follow immediately
after.  IOW, the "Attributes" are now moved to the FRE sub-section,
located immediately preceding the FREs for the respective function.

The above layout has the advantage that:
  a) its cleaner with separation between the index elements vs other data
  b) the index has better cache locality (by virtue of it being smaller
     than the layout in SFrame V2).
  c) As the format evolves, the guarantees of alignment for FDE index
     are easier to maintain.  FDE attr, being in the SFrame FRE
     sub-section, carry no guarantees of alignment.

This had been previously suggested and communicated in an earlier
discussion on binutils mailling list
https://inbox.sourceware.org/binutils/29b1f7b0-61ea-410c-8aca-d5dd6115e668@oracle.com/

The read/write paths in sframe.c are updated to account for this split.

sframe_fde_tbl_init now requires access to the FRE buffer to populate
the internal FDE table, as the attributes are no longer resident in the
FDE section.

flip_sframe is refactored into version-specific handlers (_v2 and _v3)
because the endian-swapping logic now differs significantly. In V3, the
iterator must jump from the FDE table to the FRE section to swap the
attributes.

Lastly, the two entities generating SFrame sections (GAS and GNU ld)
both now must _not_ set the sfde_func_start_fre_off to zero, when the
number of FREs is zero.  This is because now there will be some valid
attr data at that location.

Backward Compatibility: Due to the need to support readelf/objdump for
SFrame V2 sections, the patch explicitly maintains V2 support via
separate code paths (e.g., flip_sframe_fdes_with_fres_v2)

Note about alignment: Now that the sframe_func_desc_idx_v3 is refactored
out of the conceptual SFrame FDE, SFrame FDE index member elements are
at aligned boundaries again.  The alignment property for SFrame FDE was
broken from an ealier patch "[08/36] sframe: gas: libsframe: use
uint16_t for num_fres of FDE" up until this one.

include/
	* sframe.h (sframe_func_desc_entry_v3): Remove sfde_func_num_fres,
	sfde_func_info, sfde_func_info2, and sfde_func_rep_size.  Rename
	to sframe_func_desc_idx_v3.
	(sframe_func_desc_attr_v3): New SFrame FDE attribute structure.
libsframe/
	* sframe.c (sframe_fde_tbl_init): Add argument for FRE buffer.
	Read attributes from the FRE section for V3.
	(flip_fde_desc): Rename from flip_fde. Check size against
	sframe_func_desc_entry_v3.
	(flip_fde_attr_v3): New function.
	(sframe_decode_fde_desc_v2): New function extracted from
	sframe_decode_fde.
	(sframe_decode_fde_desc_v3): New function.
	(sframe_decode_fde_attr_v3): New function.
	(flip_sframe_fdes_with_fres_v2): New function for V2 flipping.
	(flip_sframe_fdes_with_fres_v3): New function for V3 flipping.
	(flip_sframe): Dispatch to version-specific flip functions.
	(sframe_decode): Pass FRE buffer to sframe_fde_tbl_init.
	(sframe_decoder_get_offsetof_fde_start_addr): Adjust for subset
	of sframe_func_desc_entry_v3 restructured into
	sframe_func_desc_idx_v3.
	(sframe_encoder_get_offsetof_fde_start_addr): Likewise.
	(sframe_find_fre): Skip attribute size to find FREs in V3.
	(sframe_decoder_get_fre): Likewise.
	(sframe_decoder_get_fres_buf): Likewise.
	(sframe_encoder_add_fre): Add attribute size to byte count.
	(sframe_encoder_add_fres_buf): Read attributes from buffer.
	(sframe_encoder_write_fde): Write only FDE index fields.
	(sframe_encoder_write_func_attr): New function.
	(sframe_encoder_write_sframe): Write FDE attributes before FREs.
gas/
	* gen-sframe.c (output_sframe_funcdesc): Do not reset
	sfde_func_start_fre_off to zero when zero num FREs.
	(output_sframe_func_desc_attr): New refactored out function.
	(output_sframe_internal): Invoke output_sframe_func_desc_attr.
libsframe/testsuite/
	* libsframe.decode/DATA2: Regenerate data file.
2026-01-15 17:02:27 -08:00
Indu Bhagat
9d1500135a [SFrame-V3] bfd: ld: sframe: avoid unnecessary decoding of SFrame FREs at link time
At link time, in _bfd_elf_merge_section_sframe (), it suffices to bring
over the all per-function stack trace metadata (all FREs) as a blob into
the SFrame encoder object.  There is no need to "decode" each SFrame
FRE, only to add them in a serial fashion.

This is an optimization, and not directly related to any SFrame V3
related changes to the specification.  This should also bring us a step
closer to supporting SFrame for targets which use linker relaxations.
Removing the need to decode the input FREs can allow the linker to
simply use the available set of FREs from (relocated) contents.  To
support targets using linker relaxations in SFrame, other changes in the
SFrame parse functionality time may also be necessary, but this brings
us just a step closer.

Add two new APIs to accomplish this:
 - sframe_decoder_get_fres_buf, and
 - sframe_encoder_add_fres_buf

bfd/
	* elf-sframe.c (_bfd_elf_merge_section_sframe): Get all FRE data
	and add it all in bulk.
libsframe/
	* libsframe.ver: Add new APIs.
	* sframe.c (sframe_buf_fre_entry_size): New internal API to get
	size of one SFrame FRE at the indicated buffer location, without
	fully "decoding" the SFrame FRE.
	(sframe_decoder_get_fres_buf): New definition.
	(sframe_encoder_add_fres_buf): New definition.
include/
	* sframe-api.h (sframe_decoder_get_fres_buf): New declaration.
	(sframe_encoder_add_fres_buf): New declaration.
2026-01-15 17:02:26 -08:00
Indu Bhagat
acb66ce9d2 [SFrame-V3] libsframe: textual dump of fde type SFRAME_FDE_TYPE_FLEX
Refactor the SFrame textual dumper in sframe-dump.c to properly handle
the new FDE type.

In SFrame V2, the textual dumper could afford to be oblivious to the
exact DWARF register number for stack-pointer and frame-pointer
registers in each ABI.  This is because a single bit was used to
differentiate between the two (irrespective of the ABI), and the dumper
could easily just use a:
    const char *base_reg_str[] = {"fp", "sp"};
to get the register name.

With the introduction of new SFrame FDE type SFRAME_FDE_TYPE_FLEX, which
carry DWARF register numbers if applicable, this needs to change.  E.g.,
for some patterns on AMD64, one may see CFA is the value at 'r10+0'; or
FP is the value at 'rbp+8'.  This means that for textual dump, we now
need a mapping from:
  - the ABI-specific frame-pointer to string "fp"
  - the ABI-specific stack-pointer to string "sp"
This is done via the SFRAME_ABI_REG_MAP helper macros and the new
sframe_get_reg_name () API.

For registers other than stack-pointer and frame-pointer, the SFrame
textual dump does not print the register name (say, "rax"), but just the
number (i.e., "r0").

Check the func_info2 byte and dispatch the stack frame row entry (FRE)
dumping to the correct function: either dump_sframe_func_fre_simple or
dump_sframe_func_fre_flex.

Ensure the display is consistent to previous semantics.  When flex FDE
is in effect, there may not always be an RA offset (after the CFA
offsets).  A padding offset for RA is present if FP offsets follow.  So
if a padding offset for RA is seen, we will display "U".  If no RA
offset is seen, however, we will display a "u" unless its an ABI where
RA offset is fixed (in the latter case we display "f").

libsframe/
	* sframe-dump.c (SFRAME_SP): Define mapping from stack-pointer
	register number to "sp".
	(SFRAME_FP): Define mapping from frame-pointer register number
	to "fp".
	(SFRAME_ABI_REG_MAP): Helper macro to define per-ABI-arch
	mappings.
	(sframe_get_reg_name): Helper API to get register name.
	(dump_sframe_func_with_fres): Refactor a bit...
	(dump_sframe_func_fre_simple): ..into this.
	(sframe_format_fre_disp): New definition.
	(dump_sframe_func_fre_flex): Likewise.
	(dump_sframe): Allow both SFrame version 2 and version 3.
2026-01-15 17:02:26 -08:00
Indu Bhagat
a50279706b [SFrame-V3] libsframe: testsuite: add new argument to offset access APIs
For FDE type SFRAME_FDE_TYPE_FLEX, the offsets are not only laid out
differently, they also have different encoding:
  - first data item is of unsigned type, it indicates the "Control Word"
  - second data item is of signed  type, it indicates the "Offset Word"
(The usage of "Word" above is colloquial, does not indicate a machine word of
a specific size.)

Adjust the APIs in libsframe to get stack frame offsets by adding a new
argument type.  Also add a new API to read the data items as unsigned
types of the specified size: sframe_get_fre_udata.

At the moment, like the generation routines in GAS, the textual dump
routines in sframe-dump.c are also unaware of the FDE type
SFRAME_FDE_TYPE_FLEX.  In the next commits, these capabilities will be
added.

include/
	* sframe-api.h (MAX_NUM_STACK_OFFSETS): Increase the number of
	stack offsets to 6 to accommodate the FDE type
	SFRAME_FDE_TYPE_FLEX.
	(sframe_get_fre_udata): New declaration.
	(sframe_fre_get_cfa_offset): Add new arg.
	(sframe_fre_get_fp_offset): Likewise.
	(sframe_fre_get_ra_offset): Likewise.
libsframe/
	* libsframe/sframe-dump.c (dump_sframe_func_with_fres): Pass
	SFRAME_FDE_TYPE_DEFAULT for FDE type.
	* sframe.c (sframe_fre_get_cfa_offset): Handle FDE type.
	(sframe_fre_get_fp_offset): Likewise.
	(sframe_fre_get_ra_offset): Likewise.
	* libsframe/libsframe.ver: Add new API sframe_get_fre_udata.
libsframe/testsuite/
	* libsframe.find/findfre-1.c: Pass SFRAME_FDE_TYPE_DEFAULT for
	FDE type.
	* libsframe.find/findfunc-1.c: Likewise.
	* libsframe.find/plt-findfre-1.c: Likewise.
	* libsframe.find/plt-findfre-2.c: Likewise.
2026-01-15 17:02:25 -08:00
Indu Bhagat
ba7a34eecd [SFrame-V3] gas: bfd: include: libsframe: fixup terminology 'PC Type' vs 'FDE Type'
In SFrame V2, we did use the the term 'FDE Type' for the two designated
'PC Type' for the SFrame FDEs (SFRAME_FDE_TYPE_PCINC,
SFRAME_FDE_TYPE_PCMASK).  In hindsight, 'FDE Type' was an inappropriate
term for the said intent.  Fix this terminology by defining two new
constants:
 - SFRAME_V3_FDE_PCTYPE_MASK
 - SFRAME_V3_FDE_PCTYPE_INC

The old constants from V2 (SFRAME_FDE_TYPE_PCINC,
SFRAME_FDE_TYPE_PCMASK) remain, but are now unused in the codebase.

The term 'FDE Type' should be used for the actual FDE Types.  In a
subsequent commit, we will add SFRAME_FDE_TYPE_FLEX FDE Type for SFrame
V3.

bfd/
	* elf64-s390.c (_bfd_s390_elf_create_sframe_plt): Rename
	inappropriate SFRAME_FDE_TYPE_PCINC to SFRAME_V3_FDE_PCTYPE_INC.
	* elfxx-x86.c (_bfd_x86_elf_create_sframe_plt): Likewise.  Also
	rename inappropriate SFRAME_FDE_TYPE_PCMASK to
	SFRAME_V3_FDE_PCTYPE_MASK.
gas/
	* gen-sframe.c (output_sframe_funcdesc): Likewise.
	* sframe-opt.c (sframe_convert_frag): Likewise.
libsframe/
	* sframe-dump.c (dump_sframe_func_with_fres): Likewise.
	* sframe.c (sframe_fre_check_range_p): Likewise.
	(sframe_fde_create_func_info): Likewise.
libsframe/testsuite/
	* libsframe.encode/encode-1.c: Likewise.
	* libsframe.find/findfre-1.c: Likewise.
	* libsframe.find/findfunc-1.c: Likewise.
	* libsframe.find/plt-findfre-1.c: Likewise.
	* libsframe.find/plt-findfre-2.c: Likewise.
2026-01-15 17:02:25 -08:00
Indu Bhagat
c953fe86fa [SFrame-V3] include: gas: libsframe: add 8-bits of func_info2 for extensibility in FDE
The existing field func_info (in the SFrame FDE) is used to convey important
information around the encoding and interpretation of the rest of the
stack trace data for the respective SFrame FDE: the SFrame FRE type,
SFrame FDE PC type, etc.

Currently there is 1 bit left for AArch64, and 2 bits for AMD64, s390x
(and other future ABIs to be supported).  Provision some additional
space now (specifically an additional 8-bits) for future needs for V3
and beyond.

Compared to V2, this now increases the size of SFrame FDE by 1 byte in
V3.  In this patch, the additional func_info2 byte is not used
functionally yet.  Hence, rather mechanical changes in libsframe, bfd
and libsframe/testsuite accompany.  We will put func_info2 into use in a
later patch by reserving 5 of these bits for SFrame FDE types.

With the addition of a new byte for additional func info (func_info2),
add a new arg to allow usecases like textual dumper to get all data
members in one API: sframe_decoder_get_funcdesc_v3.  To keep the APIs
symmetric looking, add new arg to sframe_encoder_add_funcdesc_v3 too.

Since bfd uses these APIs, carry out the mechanical change in the
respective APIs too.  And of course, the testsuite which exercises these
APIs.

bfd/
	* elf-sframe.c (_bfd_elf_merge_section_sframe): Get and set
	func_info2.
	* elf64-s390.c (_bfd_s390_elf_create_sframe_plt): Pass 0 for
	func_info2 for SFrame FDE for PLT.
	* elfxx-x86.c (_bfd_x86_elf_create_sframe_plt): Likewise.
gas/
	* gen-sframe.c (output_sframe_funcdesc): Emit the uint8_t for
	func_info2.
libsframe/
	* sframe-dump.c (dump_sframe_func_with_fres):
	* sframe.c (sframe_fde_tbl_init): Handle the new additional
	member.
	(sframe_encoder_write_fde): Likewise.
	* sframe.c (sframe_decoder_get_funcdesc_v3): Update func_info2.
libsframe/testsuite/
	* libsframe.decode/DATA2: Update data file with SFrame section
	data.
	* libsframe.encode/encode-1.c: Pass 0 for func_info2 arg.
	* libsframe.find/findfre-1.c: Likewise.
	* libsframe.find/findfunc-1.c: Likewise.
	* libsframe.find/plt-findfre-1.c: Likewise.
	* libsframe.find/plt-findfre-2.c: Likewise.
include/
	* sframe.h: Add new uint8_t sfde_func_info2 to
	sframe_func_desc_entry_v3.
	* sframe-api.h (sframe_decoder_get_funcdesc_v3): New arg.
	(sframe_encoder_add_funcdesc_v3): Likewise.
2026-01-15 17:02:25 -08:00
Indu Bhagat
0bdf18b8a5 [SFrame-V3] sframe: gas: bfd: add support for signal frames
Reserve a bit in function info byte in the SFrame FDE to designate
signal frames.

Also update the SFrame opt code in GAS and dumping routines in libsframe
to handle signal frame bit.

include/
	* sframe.h (SFRAME_V3_FDE_SIGNAL_P): Extract signal frame bit.
	(SFRAME_V3_FDE_UPDATE_SIGNAL_P): Set signal frame bit.
gas/
	* gen-sframe.c (get_dw_fde_signal_p): New function to retrieve signal
	frame state from DWARF FDE.
	(sframe_v3_set_func_info): Renamed from sframe_v1_set_func_info.
	Accept signal_p argument and encode it.
	(sframe_set_version): Update ops to use sframe_v3_set_func_info.
	(sframe_set_func_info): Pass signal_p to the ops hook.
	(output_sframe_funcdesc): Retrieve signal frame marker and pass to
	sframe_set_func_info.
	* gen-sframe.h (struct sframe_version_ops): Update set_func_info
	signature.
	* sframe-opt.c (sframe_convert_frag): Preserve signal_p bit during
	fragment conversion.  While at it, use SFRAME_V3_* macros where
	applicable.
libsframe/testsuite/
	* gas/cfi-sframe/cfi-sframe-common-13.d: New test.
	* gas/cfi-sframe/cfi-sframe-common-13.s: New test.
	* gas/cfi-sframe/cfi-sframe.exp: Run new test.
libsframe/
	* sframe-dump.c (dump_sframe_func_with_fres): Decode signal frame bit
	and print "S" attribute in the dump output.
2026-01-15 17:02:24 -08:00
Indu Bhagat
982b494403 [SFrame-V3] include: libsframe: bfd: gas: testsuite: support for signed 64-bit offset in SFrame FDE
This change enables support text > 2 GiB in SFrame format.

Each SFrame FDE needs to hold information about the start PC of the
function it pertains to.  Currently, the field 'sfde_func_start_address'
in SFrame FDE is encoded as a 32-bit offset to the start PC of the
function from the field itself.

In SFrame V2, this offset was a signed 32-bit offset.  The signedness
gives the flexibility of having .sframe ELF section before or after the
.text* sections.  But the size of 32-bit puts the limitation that
.sframe togther with the .text* sections must fit the 2 GiB range.

Currently, if the linker sees the offset not representable as 32-bit
signed offset, it issues an error (not seen in the wild, simulated by
forcing a function to align via an '.align  2147483648' directive):

  test.o:(.sframe+0x1c): relocation truncated to fit: R_X86_64_PC32 against `.text'
  make: *** [Makefile:7: all] Error 1

ATM, EH Frame also suffers with the same issue.

Moving forward, some cloud applications have been shown to be nearing
1.5 GiB threshold.  Extending the offset to int64_t now seems to be good
choice to make now for future-proof'ing the sections.

The use of int64_t offset is done for all SFrame V3 sections.  This
bump from int32_t to int64_t should not lead to an increase in the size
of SFrame sections, because of the following additional changes to the
SFrame FDE specification:
  - Reduce the type of sfde_func_num_fres (from uint32_t to uint16_t)
  - Remove the 2 bytes of padding (sfde_func_padding2). These served the
    two-fold purpose of keeping FDE data aligned _and_ unused space for
    future needs.

Now that the offset is int64_t, start using the
sframe_decoder_get_funcdesc_v3 () instead of
sframe_decoder_get_funcdesc_v2 () in GNU ld.

This patch changes the offset type in the SFrame FDE definition to an
int64_t.  No further changes in gas are necessary because the code
already accounts for writing out as per the size of the member of the
struct:

  emit_expr (&exp, sizeof_member (sframe_func_desc_entry,
                                  sfde_func_start_offset));

bfd/
	* elf-sframe.c (sframe_read_value): Signed offset for start PC
	is 8-bytes now.
	(_bfd_elf_merge_section_sframe): Likewise.
	* elf64-s390.c (_bfd_s390_elf_create_sframe_plt): Use V3 API.
	(elf_s390_finish_dynamic_sections): Signed offset for start PC
	is 8-bytes now.
	* elfxx-x86.c (_bfd_x86_elf_create_sframe_plt): Use V3 API.
	(_bfd_x86_elf_finish_dynamic_sections): Signed offset for start
	PC is 8-bytes now.
gas/
	* sframe.c (output_sframe_funcdesc): Rename to
	sfde_func_start_offset.
libsframe/
	* libsframe/sframe.c (sframe_fde_tbl_init): Rename to
	sfde_func_start_offset.
	(flip_fde): Likewise.
	(sframe_decoder_get_secrel_func_start_addr): Use int64_t.
	(sframe_fre_check_range_p): Likewise.
	(sframe_decoder_get_offsetof_fde_start_addr): Rename to
	sfde_func_start_offset.
	(sframe_get_funcdesc_with_addr_internal): Use int64_t.
	(sframe_find_fre): Likewise.
	(sframe_encoder_get_offsetof_fde_start_addr): Rename to
	sfde_func_start_offset.
	(sframe_encoder_add_funcdesc_internal): Use int64_t.
	(sframe_encoder_add_funcdesc): Likewise.  And rename to
	sfde_func_start_offset.
	(sframe_encoder_write_fde): Rename to sfde_func_start_offset.
libsframe/testsuite/
	* libsframe.decode/DATA2: Regenerate the data file.
	* libsframe.encode/encode-1.c: Use int64_t for start pc offset.
	* libsframe.find/findfre-1.c: Likewise.
	* libsframe.find/findfunc-1.c: Likewise.
	* libsframe.find/plt-findfre-1.c: Likewise.
	* libsframe.find/plt-findfre-2.c: Likewise.
include/
	* sframe-api.h (sframe_find_fre): Update arg type to int64_t.
	(sframe_encoder_add_funcdesc): Likewise.
	* sframe.h: Change data type to int64_t.
2026-01-15 17:02:24 -08:00
Indu Bhagat
ed8de13c68 [SFrame-V3] sframe: gas: libsframe: remove padding field from FDE
Remove the unused sfde_func_padding2 member from the
sframe_func_desc_entry_v3 structure.

A later patch in this series reorganizes the members of the FDE
structure in a way explicit padding is no longer necessary to keep
natural alignment.  So remove the explicit padding now.

Reviewed-by: Jens Remus <jremus@linux.ibm.com>

include/
	* sframe.h: Remove sfde_func_padding2 from
	sframe_func_desc_entry_v3.
gas/
	* gen-sframe.c (output_sframe_funcdesc): Stop writing
	sfde_func_padding2.
libsframe/
	* sframe.c (sframe_encoder_write_fde): Stop writing
	sfde_func_padding2.
	* testsuite/libsframe.decode/DATA2: Regenerate binary test data.
2026-01-15 17:02:24 -08:00
Indu Bhagat
5775384269 [SFrame-V3] sframe: gas: libsframe: use uint16_t for num_fres of FDE
Reduce the size of the num_fres field in the Function Descriptor Entry
(FDE) from 32 bits to 16 bits.

The number of Frame Row Entries (FREs) for a single function is extremely
unlikely to exceed 65,535 in real-world scenarios. Reducing this field
saves 2 bytes per FDE, contributing to a smaller overall SFrame section size.

(BTW, these savings will be eaten up by a later commit which adds
support for text > 2 GiB by increasing an offset from int32_t to
int64_t).

Safety checks are added to the assembler to warn and skip SFrame FDE
generation if a function's FRE count exceeds UINT16_MAX.

Note regarding alignment: With the current patch, the members of
sframe_func_desc_entry_v3 are not at aligned boundaries anymore.  Recall
that all sframe_func_desc_entry_v3 entries are stored together in the
"SFrame FDE sub-section" forming an index.  Only after a later patch in
the series "[29/36] [SFrame-V3] include: gas: libsframe: split FDE into
desc and attr" will the alignment properties of SFrame index will be
restored.

include/
	* sframe.h (sframe_func_desc_entry_v3): Change sfde_func_num_fres
	type to uint16_t.
gas/
	* gen-sframe.c (output_sframe_funcdesc): Write 2 bytes for num_fres
	and assert it fits in uint16_t.
	(sframe_do_fde): Add check to skip FDE emission if num_fres exceeds
	UINT16_MAX.
libsframe/
	* sframe.c (sframe_encoder_write_fde): Cast num_fres to uint16_t
	to ensure correctly written out data.
	* testsuite/libsframe.decode/DATA2: Update binary test data.
2026-01-15 17:02:24 -08:00
Indu Bhagat
20477cd103 [SFrame-V3] libsframe: add V3 APIs for adding and getting SFrame FDE
(Similar to V2) Add two new APIs for adding and getting SFrame FDE:
 - sframe_encoder_add_funcdesc_v3
 - sframe_decoder_get_funcdesc_v3

Note the argument for the function start address is int64_t instead of
int32_t (the latter is used in sframe_encoder_add_funcdesc_v2 and
sframe_encoder_get_funcdesc_v2).  The new V3 APIs will be used in a
subsequent commit to extend SFrame V3 to support text > 2 GiB by
allowing int64_t offsets by default.

Similar to the analogous V2 APIs, they return 0 on success and
SFRAME_ERR (in case of sframe_decoder_get_funcdesc_v3) or error code (in
case of sframe_encoder_add_funcdesc_v3) on failure.

Reviewed-by: Jens Remus <jremus@linux.ibm.com>

include/
	* sframe-api.h (sframe_decoder_get_funcdesc_v3): New
	declaration.
	(sframe_encoder_add_funcdesc_v3): Likewise.
libsframe/
	* libsframe.ver: Add the new APIs.
	* sframe.c (sframe_decoder_get_funcdesc_v3): New definition.
	(sframe_encoder_add_funcdesc_v3): Likewise.
2026-01-15 17:02:24 -08:00
Indu Bhagat
6f68bf969f [SFrame-V3] libsframe: bump so version to libsframe.so.3.0.0
Consolidate the 2.0 and 2.1 nodes into a new 3.0 node.

In subsequent patches for releasing SFrame V3, libsframe APIs will be
affected.  A non-exhaustive list of noteworthy changes are mentioned
next.

Some existing APIs (breaking binary compatibility) by adding an
additional arg to these:
  - sframe_fre_get_ra_offset
  - sframe_fre_get_fp_offset
  - sframe_fre_get_cfa_offset

Change of argument type:
  - sframe_find_fre

The behaviour of some APIs will change:
 - sframe_encoder_write now writes out V3.

And lastly removal of two APIs:
  - sframe_decoder_get_funcdesc
  - sframe_encoder_add_funcdesc

Above make this release of the library binary incompatible with previous
release, hence a version bump and new version node 3.0.

Reviewed-by: Jens Remus <jremus@linux.ibm.com>

libsframe/
	* libsframe.ver: Create a new 3.0 node.  Remove the 2.0 node.
	* libtool-version: Bump the so version.
2026-01-15 17:02:24 -08:00
Indu Bhagat
2d6c3272da [SFrame-V3] sframe: gas: bfd: ld: format bump to version 3
Bump version to SFRAME_VERSION_3.  Introduce a new definition of SFrame
FDE for version 3, which is a duplicate of SFrame FDE in V2, for now.
In other words, no changes to the format specification yet.

GNU as emits SFrame V3 by default.  SFrame encoder (ld) emits SFrame V3
sections.  In a later commit, we will add a new command line option to
gas: --gsframe-3 which will bind the implementation in gas to emit
SFrame V3.

Also, adjust the testcases for the new version string
"SFRAME_VERSION_3".

bfd/
	* elf-sframe.c (_bfd_elf_merge_section_sframe): Linker emits
	the latest version by default.
	* elf64-s390.c (_bfd_s390_elf_create_sframe_plt): Linker emitted
	PLT sections are also SFRAME_VERSION_3.
	* elfxx-x86.c (_bfd_x86_elf_create_sframe_plt): Likewise.
gas/
	* gen-sframe.c (sframe_set_version): GAS emits SFrame V3 by
	default.
	(output_sframe): Likewise.
libsframe/
	* sframe-dump.c (dump_sframe): Enable dumping for both
	SFRAME_VERSION_2 and SFRAME_VERSION_3.
include/ChangeLog:
	* sframe.h (SFRAME_VERSION_3): New definition.
	(SFRAME_VERSION): Current version is now SFRAME_VERSION_3.
	(SFRAME_V3_FDE_FUNC_INFO): New definition.
	(SFRAME_V3_FDE_FRE_TYPE): Likewise.
	(SFRAME_V3_FDE_PC_TYPE): Likewise.
	(SFRAME_V3_AARCH64_FDE_PAUTH_KEY): Likewise.
	(SFRAME_V3_FDE_UPDATE_PAUTH_KEY): Likewise.
binutils/testsuite/
	* all affected tests: Replace SFRAME_VERSION_2 with
	SFRAME_VERSION_3.
gas/testsuite/
	* all affected tests: Likewise.
ld/testsuite/
	* all affected tests: Likewise.
libsframe/testsuite/
	* all affected tests: Likewise.
2026-01-15 17:02:24 -08:00
Indu Bhagat
8bfa079ba5 [SFrame-V3] sframe: use const for sframe_decoder_ctx object arg
As the library version will be bumped soon, include this change now.
Note the arg names in sframe-dump.c APIs have 'sfd_ctx' instead of the
usual 'dctx'.  We can address this cosmetic change at a later time.
Other cosmetic changes, e.g. to make fixing function-level comments more
consistent, are left out of the patch for now.

Additionally, constify the return type of static function
sframe_decoder_get_header, now that the call sites consistently use a
const object.

Reviewed-by: Jens Remus <jremus@linux.ibm.com>
2026-01-15 17:02:24 -08:00
Indu Bhagat
1c63bcda87 [SFrame-V3] libsframe: remove old sframe_decoder_get_funcdesc API
sframe_decoder_get_funcdesc () was added for SFRAME_VERSION_1.  This has
since been obsoleted by introduction of SFRAME_VERSION_2 and its
corresponding sframe_decoder_get_funcdesc_v2 API.

Remove from the version script file as well.  We will bump the version
of the library to 3.0.0 in a subsequent patch (closer to release) and
consolidate the entries into a new LIBSFRAME_3.0 node.

Reviewed-by: Jens Remus <jremus@linux.ibm.com>

include/
	* sframe-api.h (sframe_decoder_get_funcdesc): Remove.
libsframe/
	* libsframe.ver: Likewise.
	* sframe.c (sframe_decoder_get_funcdesc): Remove definition.
2026-01-15 17:02:23 -08:00
Indu Bhagat
6150c6c061 [SFrame-V3] libsframe: testsuite: add a new test for SFrame V2
The existing frecnt-2.c testcase reads the SFrame section from the
provided DATA2 buffer.  It exercises the sframe_decode (),
sframe_decoder_get_num_fidx (), and sframe_decoder_get_funcdesc_v2 ()
APIs.  Currently DATA2 file is the SFrame section created from the test
input (mentioned in the comments in the file) in SFrame version 2
format.

Moving forward, creating SFrame V2 section via GNU assembler and GNU ld
will not be supported.  But textual dump of SFrame V2 sections via
readelf/objdump will need to be supported.  Add a test similar to
frecnt-2.c using SFrame version 2 binary data to the libsframe
testsuite.  Such a test will help ensure that sframe_decode () and
related APIs remain tested for multiple supported arches till the
support for dumping V2 sections is to be maintained.

Duplicate frecnt-2.c to create a frecnt-v2.c, the latter will test with
a SFrame V2 input section always.

Reviewed-by: Jens Remus <jremus@linux.ibm.com>

libsframe/
	* Makefile.in: Regenerated.
libsframe/testsuite/
	* libsframe.decode/decode.exp: Add new test.
	* libsframe.decode/local.mk: Likewise
	* libsframe.decode/DATA-V2: New SFrame V2 test data file.
	* libsframe.decode/frecnt-v2.c: New test.
2026-01-15 17:02:23 -08:00
Indu Bhagat
d451f10806 libsframe: add README and mention expectations
libsframe is not meant for consumption by tools external to GNU
Binutils.

libsframe/
	* Makefile.in: Regenerate.
	* libsframe/README: New file.
2026-01-05 11:53:13 -08:00
Alan Modra
c8f306af2f Update year range in copyright notice of binutils files
Avoid warnings about invalid escapes in etc/update-copyright.py by
using raw strings, add BinutilsFilter to skip psql.rc and add
"Kalray SA." as another copyright holder.
2026-01-01 23:22:14 +10:30
Indu Bhagat
613184627d libsframe: refactor out sframe_fre_grow_tbl
Usage of a global int number_of_entries is likely unnecessary.  The same
global is used for growing the FDE tbl too, when adding FDEs.  At the
moment, however, carve out a new function to grow the FRE table, and
use a macro instead of 'number_of_entries'.

This refactoring helps provide basis for a later patch where we add
SFrame FREs in bulk instead of one at a time to the SFrame encoder
object.

Reviewed-by: Jens Remus <jremus@linux.ibm.com>

libsframe/
	* sframe.c (SFRAME_FRE_ALLOC_LEN): New definition.
	(sframe_grow_fre_tbl): New definition.
	(sframe_encoder_add_fre): Use the new function.
2025-12-24 00:59:07 -08:00
Indu Bhagat
1041022101 libsframe: use tmp variable for realloc pattern
If realloc fails, the original buffer isnt free'd otherwise.

Reviewed-by: Jens Remus <jremus@linux.ibm.com>

libsframe/
	* sframe.c (sframe_encoder_add_fre): Use tmp variable.
	(sframe_encoder_add_funcdesc_internal): Likewise.
2025-12-24 00:57:55 -08:00
Indu Bhagat
7ca80bc6da libsframe: refactor sframe_decoder_add_funcdesc for internal use
sframe_encoder_add_funcdesc () was added for SFRAME_VERSION_1.  This has
since been obsoleted by introduction of SFRAME_VERSION_2 and its
corresponding sframe_decoder_add_funcdesc_v2 API.

Refactor the functionality into an internal-only API:
sframe_encoder_add_funcdesc_internal (). Ensure it returns the error
code for the caller to take necessary action or pass to user.

Keep only two args for sframe_encoder_add_funcdesc: function size and
function start addr.  This simple barebone API will be used in a
subsequent commit to adjust the link-time behaviour of SFrame sections.

Reviewed-by: Jens Remus <jremus@linux.ibm.com>

include/
	* sframe-api.h (sframe_encoder_add_funcdesc): Remove args to
	create the barebone API.
libsframe/
	* sframe.c (sframe_encoder_add_funcdesc): Refactor out into
	sframe_encoder_add_funcdesc_internal.  Change args.
	(sframe_encoder_add_funcdesc_v2): Use the new internal API.
	* libsframe.ver: Move sframe_encoder_add_funcdesc to 2.1 node.
2025-12-24 00:51:43 -08:00
Indu Bhagat
d1a0fa4704 gas: libsframe: use SFRAME_V2_* macro where available
No functional change.

Reviewed-by: Jens Remus <jremus@linux.ibm.com>

gas/
	* sframe-opt.c (sframe_convert_frag): Use SFRAME_V2_
	prefixed macro instead.
libsframe/
	* sframe-dump.c (dump_sframe_func_with_fres): Likewise.
	* sframe.c (sframe_get_fre_type): Likewise.
	(sframe_get_fde_type): Likewise.
	(sframe_fre_check_range_p): Likewise.
	(sframe_fde_create_func_info): Likewise.
2025-12-24 00:42:14 -08:00
Indu Bhagat
705a1d47a4 libsframe: implement an internal-only SFrame FDE representation
Up until now, libsframe has used the same SFrame FDE representation as
the on-disk representation (sframe_func_desc_entry).  The choice made by
the author of the library, back when it was first contributed, perhaps
sufficed the needs then.  But looking forward, we need to be able to
allow reading and dumping out of not just sections with version
SFRAME_VERSION_2 but also future supported versions.

Note that libsframe did not (and still does not) expose the SFrame FDE
representation in any public APIs;  doing so is not recommended.

For the path forward, create an internal-only SFrame FDE representation
(sframe_func_desc_entry_int).  libsframe now keeps all in-memory FDEs of
type sframe_func_desc_entry_int.  Doing so means instead of memcpy, we
need to resort to member-by-member mapping.  This can be seen in
sframe_fde_tbl_init (read time) and the new function
sframe_encoder_write_fde (write time).

Other than that, replace out the previous direct interaction with
on-disk format when:
  - flipping SFrame contents before decoding them in sframe_decode.
  - flipping SFrame contents before writing them out in sframe_encode.

Reviewed-by: Jens Remus <jremus@linux.ibm.com>
2025-12-24 00:41:02 -08:00
Indu Bhagat
f5d28014be include: gas: bfd: sframe: clean the abstraction
... between specification and implmentation.

Move to definition in the implementation (gas/ld/libsframe) and not the
specification (include/sframe.h).  At this time the implementation in
gas and ld generate the sections in the latest SFrame version only.

Reviewed-by: Jens Remus <jremus@linux.ibm.com>

bfd/
	* elf-sframe.c: Add definition here.
gas/
	* gen-sframe.c: Likewise.
libsframe/
	* sframe.c: Likewise.
include/
	* sframe.h: Remove the definition.
2025-12-23 14:59:59 -08:00
Indu Bhagat
a54b5ab904 libsframe: testsuite: fix build failure
Previous commit 4651bea119 to fix PR ld/32789 missed making the
necessary changes to the libsframe testsuite.

libsframe/testsuite/
	PR ld/32789
	PR libsframe/33731
	* libsframe.encode/encode-1.c: Add additional arg for sorting
	FDEs.  Set to true.
	* libsframe.find/findfre-1.c: Likewise.
	* libsframe.find/findfunc-1.c: Likewise.
	* libsframe.find/plt-findfre-1.c: Likewise.
	* libsframe.find/plt-findfre-2.c: Likewise.
2025-12-19 23:36:53 -08:00
Indu Bhagat
4651bea119 bfd: include: sframe: fix PR ld/32789
Currently, when SFrame sections are emitted after linking the input
SFrame sections, the SFrame FDEs are sorted on start PC.  Doing so for
relocatable links has no effect (SFrame FDEs remain in place), because
the start PC is unrelocated data.  For relocatable links, then, the
emitted SFrame FDEs in the output section remain in the same order as
that in the respective input BFD.

The assembler does not guarantee the emission of SFrame FDEs in the same
order as the placement of the associated .text* sections,
(SFRAME_F_FDE_SORTED is not set in the ET_REL objs generated by GAS).
This means setting SFRAME_F_FDE_SORTED by the linker was wrong when:
  - doing relocatable link, and
  - the input bfds contain multiple .text sections, say .text.hot,
    .text.init, .text.unlikely etc.

For relocatable links, skip sorting the SFrame FDEs.  Do not set
SFRAME_F_FDE_SORTED for relocatable links.

This is achieved by adding an explicit argument (bool sort_fde_p) to the
sframe_encoder_write API.  Move the API from 2.0 to the 2.1 node as this
is an ABI-incompatible change.  Skip bumping the "current" in
libsframe/libtool-version ATM, we will do so closer to release.

When writing of SFrame data for PLT entries, indicate sort_fde_p to
false: these sections are like the other SFrame sections for any other
ET_REL binary.

Add a test in ld/testsuite/ld-sframe/sframe.exp, these tests are run for
all ABIs supported for SFrame.  In this test, for object file generated
for pr32789-1a.c:
  - the emitted SFrame FDEs by GAS are in the order of the .text* in the
    input assembly (i.e., .text.init, .text, .text.exit)
  - the emitted .text* sections by GAS are placed in the following order
    .text, .text.init, .text.exit.
  - GAS does not set SFRAME_F_FDE_SORTED, as expected.

Reviewed-by: Jens Remus <jremus@linux.ibm.com>

bfd/
	PR ld/32789
	* elf-sframe.c (_bfd_elf_write_section_sframe): Skip sorting the
	SFrame FDEs for relocatable links.
	* elf64-s390.c (_bfd_s390_elf_write_sframe_plt): Additional
	argument to sframe_encoder_write.
	* elfxx-x86.c (_bfd_x86_elf_write_sframe_plt): Likewise.
libsframe/
	* libsframe.ver: Move from 2.0 node to 2.1.
	* sframe.c (sframe_encoder_write_sframe): Conditionalize based
	on argument sort_fde_p.
	(sframe_encoder_write): New argument to indicate whether SFrame
	FDEs are to be sorted in output.
include/
	* sframe-api.h (sframe_encoder_write): New argument.
ld/testsuite/
	PR ld/32789
	* ld/testsuite/ld-sframe/sframe.exp: New test.
	* ld/testsuite/ld-sframe/pr32789-1.rd: New test.
	* ld/testsuite/ld-sframe/pr32789-1.sd: New test.
	* ld/testsuite/ld-sframe/pr32789-1a.c: New test.
	* ld/testsuite/ld-sframe/pr32789-1b.c: New test.
	* ld/testsuite/ld-x86-64/sframe-reloc-1.d: Remove
	SFRAME_F_FDE_SORTED.
2025-12-19 23:11:45 -08:00
Alan Modra
44e7622937 PR 33721 load/store of misaligned address
This fixes PR33721 by a common technique of declaring a packed struct
to access unaligned integer fields.  (See eg. linux kernel
include/vdso/unaligned.h)  I've tidied the PR29856 fix for a similar
bug too (not that there was anything wrong with that fix).

	PR 33721
	PR 29856
	* sframe.c (flip_fre_start_address): Use a packed struct to
	access 2-byte and 4-byte unaligned fields.  Make addr a void*.
	(sframe_decode_fre_start_address): Similarly, and remove
	unnecessary casts.  Always set *fre_start_addr.
2025-12-17 08:00:24 +10:30
Indu Bhagat
39b6fee484 libsframe: testsuite: remove usage of ##__VA_ARGS__
'##__VA_ARGS' is a GNU extension, the usage of which in the testsuite of
libsframe may cause failure to build on platforms where the compiler may
not support the GNU extension.

This GNU extension swallows the preceding comma if the variable
arguments list is empty.  In libsframe testsuite though, an empty list
is never used.  Usages will remain of the following type:
  - TEST (cond, "string", vars);
or
  - TEST (cond, "string");

Mailing list discussion:
https://sourceware.org/pipermail/binutils/2025-November/145825.html

PR libsframe/33437

libsframe/testsuite/
	PR libsframe/33437
	* sframe-test.h: Replace ##__VA_ARGS__ with __VA_ARGS__.
2025-11-25 22:44:00 -08:00
Indu Bhagat
a806da18ad libsframe: bugfix in flip_sframe
A previous commit bdb0d62281 to make flip_fde version aware added a new
argument for passing the remaning buffer size to the involved functions.
Fix the passed value to the intended.

libsframe/
        * sframe.c (flip_sframe): Correct the passed value of buf size.
2025-11-25 20:46:08 -08:00
Indu Bhagat
b91966e2df libsframe: rename encoder to ectx for readability
Addressing (an old) review comment suggesting this housekeeping item.
Use consistent naming style in libsframe.  sframe_decoder_ctx objects
are named 'dctx', so use 'ectx' for sframe_encoder_ctx objects.

Make necessary changes in all the applicable declarations and definitions.

Reviewed-by: Jens Remus <jremus@linux.ibm.com>
2025-11-09 00:34:27 -08:00
Indu Bhagat
b263aca0a5 libsframe: fix checks in flip_fde
Adjust the sanity checks for flip_fde workflow and optional trailing
section padding to account for the case of ihp->sfh_fdeoff != 0 or
ihp->sfh_freoff != total FDEs size.

Reviewed-by: Jens Remus <jremus@linux.ibm.com>

libsframe/
        * sframe.c (flip_sframe): Fix checks in flip_fde to accommodate
	cases when sfh_fdeoff != 0 or when SFrame FREs are placed after
	a gap from SFrame FDEs.
2025-11-08 23:33:22 -08:00