gas: ld: libsframe: Support for SFrame FDEs without any FREs

Allow SFrame sections without any FREs, that can occur if they solely
contain FDEs without any FREs.  For FDEs without and FREs set the
offset to the first FRE to zero.

libsframe/
	* sframe.c (sframe_encoder_write_sframe): Allow SFrame sections
	without any FREs.  For FDEs without any FREs set the offset to
	the first FRE to zero.

gas/
	* gen-sframe.c (output_sframe_funcdesc): For FDEs without any
	FREs set the offset to the first FRE to zero.

Signed-off-by: Jens Remus <jremus@linux.ibm.com>
This commit is contained in:
Jens Remus
2025-10-15 17:45:48 +02:00
parent abe6b29caf
commit c47ec3b44a
2 changed files with 20 additions and 7 deletions

View File

@@ -652,12 +652,18 @@ output_sframe_funcdesc (symbolS *start_of_fre_section,
sfde_func_size));
/* Offset to the first frame row entry. */
exp.X_op = O_subtract;
exp.X_add_symbol = fre_symbol; /* Minuend. */
exp.X_op_symbol = start_of_fre_section; /* Subtrahend. */
exp.X_add_number = 0;
emit_expr (&exp, sizeof_member (sframe_func_desc_entry,
sfde_func_start_fre_off));
if (sframe_fde->num_fres == 0)
/* For FDEs without any FREs, set sfde_func_start_fre_off to zero. */
out_four (0);
else
{
exp.X_op = O_subtract;
exp.X_add_symbol = fre_symbol; /* Minuend. */
exp.X_op_symbol = start_of_fre_section; /* Subtrahend. */
exp.X_add_number = 0;
emit_expr (&exp, sizeof_member (sframe_func_desc_entry,
sfde_func_start_fre_off));
}
/* Number of FREs. */
out_four (sframe_fde->num_fres);

View File

@@ -1882,7 +1882,7 @@ sframe_encoder_write_sframe (sframe_encoder_ctx *encoder)
- buffers must be malloc'd by the caller. */
if ((contents == NULL) || (buf_size < hdr_size))
return sframe_set_errno (&err, SFRAME_ERR_BUF_INVAL);
if (fr_info == NULL)
if (ehp->sfh_num_fres > 0 && fr_info == NULL)
return sframe_set_errno (&err, SFRAME_ERR_FRE_INVAL);
/* Write out the FRE table first.
@@ -1905,6 +1905,13 @@ sframe_encoder_write_sframe (sframe_encoder_ctx *encoder)
fre_type = sframe_get_fre_type (fdep);
num_fres = fdep->sfde_func_num_fres;
/* For FDEs without any FREs, set sfde_func_start_fre_off to zero. */
if (num_fres == 0)
fdep->sfde_func_start_fre_off = 0;
if (num_fres > 0 && fr_info == NULL)
return sframe_set_errno (&err, SFRAME_ERR_FRE_INVAL);
for (j = 0; j < num_fres; j++)
{
fre_index = global + j;