[RFC 08/28] [SFrame-V3] sframe: gas: libsframe: use uint16_t for num_fres of FDE

Indu Bhagat indu.bhagat@oracle.com
Sun Dec 28 21:52:52 GMT 2025


On 12/19/25 1:33 AM, Jens Remus wrote:
> On 12/9/2025 10:07 AM, Indu Bhagat wrote:
>> 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.
> Nice!
> 
>> diff --git 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;
> 
> The (struct) sframe_func_desc_entry_v3 field sfde_func_num_fres is
> defined as uint16_t here.
> 
>>     /* Additional information for stack tracing from the function:
>>        - 4-bits: Identify the FRE type used for the function.
>>        - 1-bit: Identify the FDE type of the function - mask or inc.
> 
>> diff --git a/libsframe/sframe.c b/libsframe/sframe.c
> 
>> @@ -151,7 +151,7 @@ sframe_fde_tbl_init (sf_fde_tbl *fde_tbl, const char *fde_buf,
>>   	  fde_tbl->entry[i].func_start_addr = fdep->sfde_func_start_address;
>>   	  fde_tbl->entry[i].func_size = fdep->sfde_func_size;
>>   	  fde_tbl->entry[i].func_start_fre_off = fdep->sfde_func_start_fre_off;
>> -	  fde_tbl->entry[i].func_num_fres = fdep->sfde_func_num_fres;
>> +	  fde_tbl->entry[i].func_num_fres = (uint16_t)fdep->sfde_func_num_fres;
> 
> Why does the uint16_t field then need to be casted to uint16_t here?
> 
>>   	  fde_tbl->entry[i].func_info = fdep->sfde_func_info;
>>   	  fde_tbl->entry[i].func_rep_size = fdep->sfde_func_rep_size;
>>   	}
>> @@ -576,7 +576,7 @@ sframe_decode_fde (const char *buf, size_t buf_size, uint8_t ver,
>>   	return SFRAME_ERR;
>>   
>>         sframe_func_desc_entry_v3 *fdep = (sframe_func_desc_entry_v3 *) buf;
>> -      *num_fres = fdep->sfde_func_num_fres;
>> +      *num_fres = (uint16_t)fdep->sfde_func_num_fres;
> 
> Likewise.
> 

These can be removed. Thanks

>>         *fre_type = SFRAME_V1_FUNC_FRE_TYPE (fdep->sfde_func_info);
>>         *fre_offset = fdep->sfde_func_start_fre_off;
>>   
>> @@ -2131,7 +2131,7 @@ sframe_encoder_write_fde (const sframe_header *sfhp ATTRIBUTE_UNUSED,
>>     fdep->sfde_func_start_address = (int32_t)fde->func_start_addr;
>>     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;
> 
> The cast here is required as (struct) sframe_func_desc_entry_int field
> func_num_fres is uint32_t.
> 
>>     fdep->sfde_func_info = fde->func_info;
>>     fdep->sfde_func_rep_size = fde->func_rep_size;
>>     fdep->sfde_func_padding2 = 0;
> Regards,
> Jens



More information about the Binutils mailing list