sframe: fix the defined SFRAME_FRE_TYPE_*_LIMIT constants

An earlier commit 3f107464 defined the SFRAME_FRE_TYPE_*_LIMIT
constants.  These constants are used (by gas and libsframe) to pick an
SFrame FRE type based on the function size.  Those constants, however,
were buggy, causing the generated SFrame sections to be bloated as
SFRAME_FRE_TYPE_ADDR2/SFRAME_FRE_TYPE_ADDR4 got chosen more often than
necessary.

gas/
	* sframe-opt.c (sframe_estimate_size_before_relax): Use
	typecast.
	(sframe_convert_frag): Likewise.

libsframe/
	* sframe.c (sframe_calc_fre_type): Use a more appropriate type
	for argument.  Adjust the check for SFRAME_FRE_TYPE_ADDR4_LIMIT
	to keep it warning-free but meaningful.

include/
	* sframe-api.h (sframe_calc_fre_type): Use a more appropriate
	type for the argument.
	* sframe.h (SFRAME_FRE_TYPE_ADDR1_LIMIT): Correct the constant.
	(SFRAME_FRE_TYPE_ADDR2_LIMIT): Likewise.
	(SFRAME_FRE_TYPE_ADDR4_LIMIT): Likewise.

(cherry picked from commit 725a19bfd1)
This commit is contained in:
Indu Bhagat 2023-01-06 09:30:20 -08:00
parent 2ffa66fc9f
commit b6250e0b72
4 changed files with 17 additions and 12 deletions

View File

@ -53,9 +53,9 @@ sframe_estimate_size_before_relax (fragS *frag)
widthS = exp->X_op_symbol;
width = resolve_symbol_value (widthS);
if (width < SFRAME_FRE_TYPE_ADDR1_LIMIT)
if (width < (offsetT) SFRAME_FRE_TYPE_ADDR1_LIMIT)
ret = 1;
else if (width < SFRAME_FRE_TYPE_ADDR2_LIMIT)
else if (width < (offsetT) SFRAME_FRE_TYPE_ADDR2_LIMIT)
ret = 2;
else
ret = 4;
@ -123,9 +123,9 @@ sframe_convert_frag (fragS *frag)
/* Calculate the applicable fre_type. */
fsizeS = exp->X_op_symbol;
fsize = resolve_symbol_value (fsizeS);
if (fsize < SFRAME_FRE_TYPE_ADDR1_LIMIT)
if (fsize < (offsetT) SFRAME_FRE_TYPE_ADDR1_LIMIT)
fre_type = SFRAME_FRE_TYPE_ADDR1;
else if (fsize < SFRAME_FRE_TYPE_ADDR2_LIMIT)
else if (fsize < (offsetT) SFRAME_FRE_TYPE_ADDR2_LIMIT)
fre_type = SFRAME_FRE_TYPE_ADDR2;
else
fre_type = SFRAME_FRE_TYPE_ADDR4;
@ -150,11 +150,11 @@ sframe_convert_frag (fragS *frag)
switch (frag->fr_subtype & 7)
{
case 1:
gas_assert (fsize < SFRAME_FRE_TYPE_ADDR1_LIMIT);
gas_assert (fsize < (offsetT) SFRAME_FRE_TYPE_ADDR1_LIMIT);
frag->fr_literal[frag->fr_fix] = diff;
break;
case 2:
gas_assert (fsize < SFRAME_FRE_TYPE_ADDR2_LIMIT);
gas_assert (fsize < (offsetT) SFRAME_FRE_TYPE_ADDR2_LIMIT);
md_number_to_chars (frag->fr_literal + frag->fr_fix, diff, 2);
break;
case 4:

View File

@ -96,7 +96,7 @@ sframe_fde_create_func_info (unsigned int fre_type, unsigned int fde_type);
/* Gather the FRE type given the function size. */
extern unsigned int
sframe_calc_fre_type (unsigned int func_size);
sframe_calc_fre_type (size_t func_size);
/* The SFrame Decoder. */

View File

@ -304,7 +304,8 @@ typedef struct sframe_frame_row_entry_addr1
/* Upper limit of start address in sframe_frame_row_entry_addr1
is 0x100 (not inclusive). */
#define SFRAME_FRE_TYPE_ADDR1_LIMIT ((SFRAME_FRE_TYPE_ADDR1 + 1) * 8)
#define SFRAME_FRE_TYPE_ADDR1_LIMIT \
(1ULL << ((SFRAME_FRE_TYPE_ADDR1 + 1) * 8))
/* Used when SFRAME_FRE_TYPE_ADDR2 is specified as FRE type. */
typedef struct sframe_frame_row_entry_addr2
@ -317,7 +318,8 @@ typedef struct sframe_frame_row_entry_addr2
/* Upper limit of start address in sframe_frame_row_entry_addr2
is 0x10000 (not inclusive). */
#define SFRAME_FRE_TYPE_ADDR2_LIMIT ((SFRAME_FRE_TYPE_ADDR2 * 2) * 8)
#define SFRAME_FRE_TYPE_ADDR2_LIMIT \
(1ULL << ((SFRAME_FRE_TYPE_ADDR2 * 2) * 8))
/* Used when SFRAME_FRE_TYPE_ADDR4 is specified as FRE type. */
typedef struct sframe_frame_row_entry_addr4
@ -330,7 +332,8 @@ typedef struct sframe_frame_row_entry_addr4
/* Upper limit of start address in sframe_frame_row_entry_addr2
is 0x100000000 (not inclusive). */
#define SFRAME_FRE_TYPE_ADDR4_LIMIT ((SFRAME_FRE_TYPE_ADDR4 * 2) * 8)
#define SFRAME_FRE_TYPE_ADDR4_LIMIT \
(1ULL << ((SFRAME_FRE_TYPE_ADDR4 * 2) * 8))
#ifdef __cplusplus
}

View File

@ -584,14 +584,16 @@ sframe_fde_create_func_info (unsigned int fre_type,
/* FIXME API for linker. Revisit if its better placed somewhere else? */
unsigned int
sframe_calc_fre_type (unsigned int func_size)
sframe_calc_fre_type (size_t func_size)
{
unsigned int fre_type = 0;
if (func_size < SFRAME_FRE_TYPE_ADDR1_LIMIT)
fre_type = SFRAME_FRE_TYPE_ADDR1;
else if (func_size < SFRAME_FRE_TYPE_ADDR2_LIMIT)
fre_type = SFRAME_FRE_TYPE_ADDR2;
else if (func_size < SFRAME_FRE_TYPE_ADDR4_LIMIT)
/* Adjust the check a bit so that it remains warning-free but meaningful
on 32-bit systems. */
else if (func_size <= (size_t) (SFRAME_FRE_TYPE_ADDR4_LIMIT - 1))
fre_type = SFRAME_FRE_TYPE_ADDR4;
return fre_type;
}