aboutsummaryrefslogtreecommitdiff
path: root/gas/gen-sframe.c
diff options
context:
space:
mode:
authorIndu Bhagat <indu.bhagat@oracle.com>2022-12-09 10:25:14 -0800
committerIndu Bhagat <indu.bhagat@oracle.com>2022-12-09 10:25:14 -0800
commit989aabcb564dccc7804f174fc582b0639357a9bb (patch)
tree0601a91e7efe876b93b4055cd3ca6691ad2ee1ec /gas/gen-sframe.c
parent3f107464e35cf63a529358a1c240821b30c35d2b (diff)
downloadgdb-989aabcb564dccc7804f174fc582b0639357a9bb.zip
gdb-989aabcb564dccc7804f174fc582b0639357a9bb.tar.gz
gdb-989aabcb564dccc7804f174fc582b0639357a9bb.tar.bz2
gas: sframe: fine tune the fragment fixup for SFrame func info
SFrame function info is an unsigned 8-bit field comprising of the following (from LSB to MSB): - 4-bits: FRE type - 1-bit: FRE start address encoding - 3-bits: Unused At the moment, the most-significat 4-bits are zero (The FRE start address encoding of SFRAME_FDE_TYPE_PCINC has a value of zero, and the upper 3-bits are unused). So the current implementation works without this patch. To be precise, however, the fragment fixup logic is meant to fixup only the least-significant 4-bits (i.e., only the FRE type needs to be updated according to the function size). This patch makes the gas implementation a bit more resilient: In the future, when the format does evolve to make use of the currently unused 3-bits in various ways, the values in those 3-bits can be propagated unchanged while the fragment fixup continues to update the lowermost 4-bits to indicate the selected FRE type. ChangeLog: * gas/gen-sframe.c (create_func_info_exp): New definition. (output_sframe_funcdesc): Call create_func_info_exp. * gas/sframe-opt.c (sframe_estimate_size_before_relax): The associated fragment uses O_modulus now. (sframe_convert_frag): Adjust the fragment fixup code according to the new composite exp.
Diffstat (limited to 'gas/gen-sframe.c')
-rw-r--r--gas/gen-sframe.c55
1 files changed, 44 insertions, 11 deletions
diff --git a/gas/gen-sframe.c b/gas/gen-sframe.c
index 896fbe4..075720f 100644
--- a/gas/gen-sframe.c
+++ b/gas/gen-sframe.c
@@ -396,8 +396,8 @@ sframe_get_fre_offset_size (struct sframe_row_entry *sframe_fre)
- <val> and <width> are themselves expressionS.
- <val> stores the expression which when evaluated gives the value of the
start address offset of the FRE.
- - <width> stores the expression when when evaluated gives the number of
- bytes needed to encode the start address offset of the FRE.
+ - <width> stores the expression when evaluated gives the number of bytes
+ needed to encode the start address offset of the FRE.
The use of OP_absent as the X_op_symbol helps identify this expression
later when fragments are fixed up. */
@@ -431,6 +431,41 @@ create_fre_start_addr_exp (expressionS *cexp, symbolS *fre_pc_begin,
cexp->X_add_number = 0;
}
+/* Create a composite exression CEXP (for SFrame FDE function info) such that:
+
+ exp = <rest_of_func_info> OP_modulus <width>, where,
+
+ - <rest_of_func_info> and <width> are themselves expressionS.
+ - <rest_of_func_info> stores a constant expression where X_add_number is
+ used to stash away the func_info. The upper 4-bits of the func_info are copied
+ back to the resulting byte by the fragment fixup logic.
+ - <width> stores the expression when evaluated gives the size of the
+ funtion in number of bytes.
+
+ The use of OP_modulus as the X_op_symbol helps identify this expression
+ later when fragments are fixed up. */
+
+static void
+create_func_info_exp (expressionS *cexp, symbolS *dw_fde_end_addrS,
+ symbolS *dw_fde_start_addrS, uint8_t func_info)
+{
+ expressionS width;
+ expressionS rest_of_func_info;
+
+ width.X_op = O_subtract;
+ width.X_add_symbol = dw_fde_end_addrS;
+ width.X_op_symbol = dw_fde_start_addrS;
+ width.X_add_number = 0;
+
+ rest_of_func_info.X_op = O_constant;
+ rest_of_func_info.X_add_number = func_info;
+
+ cexp->X_op = O_modulus;
+ cexp->X_add_symbol = make_expr_symbol (&rest_of_func_info);
+ cexp->X_op_symbol = make_expr_symbol (&width);
+ cexp->X_add_number = 0;
+}
+
#endif
static void
@@ -538,19 +573,17 @@ output_sframe_funcdesc (symbolS *start_of_fre_section,
out_four (sframe_fde->num_fres);
/* SFrame FDE function info. */
+ unsigned char func_info;
+ func_info = sframe_set_func_info (SFRAME_FDE_TYPE_PCINC,
+ SFRAME_FRE_TYPE_ADDR4);
#if SFRAME_FRE_TYPE_SELECTION_OPT
- expressionS width;
- width.X_op = O_subtract;
- width.X_add_symbol = dw_fde_end_addrS;
- width.X_op_symbol = dw_fde_start_addrS;
- width.X_add_number = 0;
+ expressionS cexp;
+ create_func_info_exp (&cexp, dw_fde_end_addrS, dw_fde_start_addrS,
+ func_info);
frag_grow (1); /* Size of func info is unsigned char. */
frag_var (rs_sframe, 1, 0, (relax_substateT) 0,
- make_expr_symbol (&width), 0, (char *) frag_now);
+ make_expr_symbol (&cexp), 0, (char *) frag_now);
#else
- unsigned char func_info;
- func_info = sframe_set_func_info (SFRAME_FDE_TYPE_PCINC,
- SFRAME_FRE_TYPE_ADDR4);
out_one (func_info);
#endif
}