[V1 08/36] [SFrame-V3] sframe: gas: libsframe: use uint16_t for num_fres of FDE
Indu Bhagat
indu.bhagat@oracle.com
Mon Dec 29 09:28:41 GMT 2025
More information about the Binutils mailing list
Mon Dec 29 09:28:41 GMT 2025
- Previous message (by thread): [V1 07/36] [SFrame-V3] libsframe: add V3 APIs for adding and getting SFrame FDE
- Next message (by thread): [V1 09/36] [SFrame-V3] sframe: gas: libsframe: remove padding field from FDE
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
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.
---
[Changes from RFC]
- Remove unnecessary typecast for num_fres [Jens].
- Fixed up the commit log to reflect the minor shifting of the patch.
[End of changes from RFC]
---
gas/gen-sframe.c | 19 +++++++++++++++++--
include/sframe.h | 2 +-
libsframe/sframe.c | 2 +-
libsframe/testsuite/libsframe.decode/DATA2 | Bin 98 -> 94 bytes
4 files changed, 19 insertions(+), 4 deletions(-)
diff --git a/gas/gen-sframe.c b/gas/gen-sframe.c
index a3ebd61e499..34bb92086a7 100644
--- a/gas/gen-sframe.c
+++ b/gas/gen-sframe.c
@@ -725,8 +725,9 @@ output_sframe_funcdesc (symbolS *start_of_fre_section,
sfde_func_start_fre_off));
}
- /* Number of FREs. */
- out_four (sframe_fde->num_fres);
+ /* Number of FREs must fit uint16_t. */
+ gas_assert (sframe_fde->num_fres <= UINT16_MAX);
+ out_two (sframe_fde->num_fres);
/* SFrame FDE function info. */
unsigned char func_info;
@@ -2040,6 +2041,20 @@ sframe_do_fde (struct sframe_xlate_ctx *xlate_ctx,
= get_dw_fde_end_addrS (xlate_ctx->dw_fde);
}
+ /* Number of FREs must fit uint16_t. Check now, and do not emit the SFrame
+ FDE if it doesnt fit (although, it is not expected to happen for
+ real-world, useful programs). The approach of truncating the FDE and
+ emitting multiple SFrame FDEs instead, is not a clearly preferable
+ handling either. Its a divergence from the model where an SFrame FDE
+ encodes stack trace data between a .cfi_startproc and .cfi_endproc pair.
+ Further, some components (linkers, stack tracers) want to associate the
+ Start PC of a function to a known symbol in the file? */
+ if (xlate_ctx->num_xlate_fres > UINT16_MAX)
+ {
+ as_warn (_("no SFrame FDE emitted; Number of FREs exceeds UINT16_MAX"));
+ return SFRAME_XLATE_ERR_NOTREPRESENTED;
+ }
+
/* ABI/arch except s390x cannot represent FP without RA saved. */
if (sframe_ra_tracking_p ()
&& sframe_get_abi_arch () != SFRAME_ABI_S390X_ENDIAN_BIG)
diff --git a/include/sframe.h b/include/sframe.h
index e32a605186a..da6665148be 100644
--- a/include/sframe.h
+++ b/include/sframe.h
@@ -251,7 +251,7 @@ typedef struct sframe_func_desc_entry_v3
beginning of the SFrame Frame Row Entry sub-section. */
uint32_t sfde_func_start_fre_off;
/* Number of frame row entries for the function. */
- uint32_t sfde_func_num_fres;
+ uint16_t sfde_func_num_fres;
/* Additional information for stack tracing from the function:
- 4-bits: Identify the FRE type used for the function.
- 1-bit: Identify the PC type of the function - mask or inc.
diff --git a/libsframe/sframe.c b/libsframe/sframe.c
index 4ad02f8c0ad..6fed48ab563 100644
--- a/libsframe/sframe.c
+++ b/libsframe/sframe.c
@@ -2131,7 +2131,7 @@ sframe_encoder_write_fde (const sframe_header *sfhp ATTRIBUTE_UNUSED,
fdep->sfde_func_start_address = (int32_t)fde->func_start_pc_offset;
fdep->sfde_func_size = fde->func_size;
fdep->sfde_func_start_fre_off = fde->func_start_fre_off;
- fdep->sfde_func_num_fres = fde->func_num_fres;
+ fdep->sfde_func_num_fres = (uint16_t)fde->func_num_fres;
fdep->sfde_func_info = fde->func_info;
fdep->sfde_func_rep_size = fde->func_rep_size;
fdep->sfde_func_padding2 = 0;
diff --git a/libsframe/testsuite/libsframe.decode/DATA2 b/libsframe/testsuite/libsframe.decode/DATA2
index aa62398b2ca..7a218f86bcc 100644
Binary files a/libsframe/testsuite/libsframe.decode/DATA2 and b/libsframe/testsuite/libsframe.decode/DATA2 differ
--
2.43.0
- Previous message (by thread): [V1 07/36] [SFrame-V3] libsframe: add V3 APIs for adding and getting SFrame FDE
- Next message (by thread): [V1 09/36] [SFrame-V3] sframe: gas: libsframe: remove padding field from FDE
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
More information about the Binutils mailing list