sframe: fix the defined SFRAME_FRE_TYPE_*_LIMIT constants
authorIndu Bhagat <indu.bhagat@oracle.com>
Fri, 6 Jan 2023 17:30:20 +0000 (09:30 -0800)
committerIndu Bhagat <indu.bhagat@oracle.com>
Fri, 6 Jan 2023 17:30:56 +0000 (09:30 -0800)
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.

gas/sframe-opt.c
include/sframe-api.h
include/sframe.h
libsframe/sframe.c

index 01138f28deb55225a7e97800befa50cd115ad276..ec0509f89779f6f62f2b7544ba961e7f09d4cd11 100644 (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:
index cdffc25d2cd1c5b3a62e7e9b860746ec39ece844..405e30c27e89b1821960771c32c0137d8da10718 100644 (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.  */
 
index 7e7840b605caeda3296d1fb877064e38ac8ac310..58ef07dcc21546816369a3100493b21e33088366 100644 (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
 }
index d206780289ac66a2f96280875096bbfb1e5a220e..ea3169ba7aa7f11ce0cf30f1e3bb732c8ae3123b 100644 (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;
 }