There are many more places that copy an uninitialised expressionS to a
symbol via symbol_set_value_expression and make_expr_symbol. This
patch focuses on general gas code that does that, and a few backends.
Note that unlike the i386 case that oss-fuzz found, it is likely that
the tc-alpha.c, tc-ppc.c and tc-tic54x.c changes are not fixing bugs,
alpha and tic54x because they don't use X_md, ppc because it carefully
handles X_md. Also, as an example an O_constant expression should
only ever have its X_add_number field accessed, therefore the other
fields can stay uninitialised. However, I think that copying
uninitialised struct fields around is not good practice. If nothing
else it can be confusing when examining symbols under gdb.
I also replaced gen-sframe.c "#ifdef SFRAME_FRE_TYPE_SELECTION_OPT"
with "if (SFRAME_FRE_TYPE_SELECTION_OPT)" so code in the false
branches is compiled and thus less likely to bitrot. (As far as I can
see, SFRAME_FRE_TYPE_SELECTION_OPT is always 1.)
* cgen.c (expr_build_binary): Use structure initialiser to
ensure all fields of expression are initialised.
* config/obj-coff.c (obj_coff_val): Likewise.
* config/tc-alpha.c (add_to_link_pool): Likewise.
* config/tc-i386-intel.c (i386_intel_simplify): Likewise.
* config/tc-mips.c (fix_loongson2f_jump, load_register),
(load_address, add_got_offset, add_got_offset_hilo),
(macro_build_branch_likely, macro, mips16_macro),
(s_cpload, s_cpsetup, s_cprestore, s_cpreturn): Likewise.
* config/tc-ppc.c (ppc_function): Likewise.
* config/tc-tic54x.c (tic54x_field): Likewise.
* dw2gencfi.c (output_cfi_insn): Likewise.
* expr.c (expr_build_uconstant): Likewise.
* read.c (s_mri_common): Likewise.
* gen-sframe.c (create_fre_start_addr_exp),
(create_func_info_exp, output_sframe_row_entry): Likewise.
Don't conditionally compile via SFRAME_FRE_TYPE_SELECTION_OPT.
* cgen.c (gas_cgen_parse_operand): Use md_expr_init_rest.
* config/tc-microblaze.c (microblaze_s_weakext): Likewise.
* ecoff.c (ecoff_directive_weakext, ecoff_stab): Likewise.
* read.c (pseudo_set): Likewise.
@@ -294,12 +294,11 @@ gas_cgen_record_fixup_exp (fragS *frag, int where, const CGEN_INSN *insn,
static symbolS *
expr_build_binary (operatorT op, symbolS * s1, symbolS * s2)
{
- expressionS e;
-
- e.X_op = op;
- e.X_add_symbol = s1;
- e.X_op_symbol = s2;
- e.X_add_number = 0;
+ expressionS e = {
+ .X_op = op,
+ .X_add_symbol = s1,
+ .X_op_symbol = s2
+ };
return make_expr_symbol (& e);
}
#endif
@@ -368,6 +367,9 @@ gas_cgen_parse_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
}
expr_jmp_buf_p = 1;
+#ifdef md_expr_init_rest
+ md_expr_init_rest (&exp);
+#endif
expression (&exp);
expr_jmp_buf_p = 0;
errmsg = NULL;
@@ -1015,12 +1015,10 @@ obj_coff_val (int ignore ATTRIBUTE_UNUSED)
}
else if (! streq (S_GET_NAME (def_symbol_in_progress), symbol_name))
{
- expressionS exp;
-
- exp.X_op = O_symbol;
- exp.X_add_symbol = symbol_find_or_make (symbol_name);
- exp.X_op_symbol = NULL;
- exp.X_add_number = 0;
+ expressionS exp = {
+ .X_op = O_symbol,
+ .X_add_symbol = symbol_find_or_make (symbol_name)
+ };
symbol_set_value_expression (def_symbol_in_progress, &exp);
/* If the segment is undefined when the forward reference is
@@ -3355,7 +3355,6 @@ add_to_link_pool (symbolS *sym, offsetT addend)
segment_info_type *seginfo = seg_info (alpha_link_section);
fixS *fixp;
symbolS *linksym, *expsym;
- expressionS e;
basesym = alpha_evax_proc->symbol;
@@ -3385,10 +3384,11 @@ add_to_link_pool (symbolS *sym, offsetT addend)
memset (p, 0, 8);
/* Create a symbol for 'basesym - linksym' (offset of the added entry). */
- e.X_op = O_subtract;
- e.X_add_symbol = linksym;
- e.X_op_symbol = basesym;
- e.X_add_number = 0;
+ expressionS e = {
+ .X_op = O_subtract,
+ .X_add_symbol = linksym,
+ .X_op_symbol = basesym
+ };
expsym = make_expr_symbol (&e);
/* Create a fixup for the entry. */
@@ -483,11 +483,11 @@ i386_intel_simplify (expressionS *e)
intel_state.seg = e->X_add_symbol;
else
{
- expressionS exp;
-
- exp.X_op = O_full_ptr;
- exp.X_add_symbol = e->X_add_symbol;
- exp.X_op_symbol = intel_state.seg;
+ expressionS exp = {
+ .X_op = O_full_ptr,
+ .X_add_symbol = e->X_add_symbol,
+ .X_op_symbol = intel_state.seg
+ };
intel_state.seg = make_expr_symbol (&exp);
}
}
@@ -333,6 +333,9 @@ microblaze_s_weakext (int ignore ATTRIBUTE_UNUSED)
SKIP_WHITESPACE ();
}
+#ifdef md_expr_init_rest
+ md_expr_init_rest (&exp);
+#endif
expression (&exp);
if (exp.X_op != O_symbol)
{
@@ -5312,13 +5312,7 @@ ppc_function (int ignore ATTRIBUTE_UNUSED)
if (ext_sym != lab_sym)
{
- expressionS exp;
-
- exp.X_op = O_symbol;
- exp.X_add_symbol = lab_sym;
- exp.X_op_symbol = NULL;
- exp.X_add_number = 0;
- exp.X_unsigned = 0;
+ expressionS exp = { .X_op = O_symbol, .X_add_symbol = lab_sym };
symbol_set_value_expression (ext_sym, &exp);
}
@@ -1795,10 +1795,10 @@ tic54x_field (int ignore ATTRIBUTE_UNUSED)
struct bit_info *bi = XNEW (struct bit_info);
/* We don't know the previous offset at this time, so store the
info we need and figure it out later. */
- expressionS size_exp;
-
- size_exp.X_op = O_constant;
- size_exp.X_add_number = size;
+ expressionS size_exp = {
+ .X_op = O_constant,
+ .X_add_number = size
+ };
bi->seg = now_seg;
bi->type = TYPE_FIELD;
bi->value = value;
@@ -1694,12 +1694,11 @@ output_cfi_insn (struct cfi_insn_data *insn)
}
else
{
- expressionS exp;
-
- exp.X_op = O_subtract;
- exp.X_add_symbol = to;
- exp.X_op_symbol = from;
- exp.X_add_number = 0;
+ expressionS exp = {
+ .X_op = O_subtract,
+ .X_add_symbol = to,
+ .X_op_symbol = from,
+ };
/* The code in ehopt.c expects that one byte of the encoding
is already allocated to the frag. This comes from the way
@@ -3322,6 +3322,9 @@ ecoff_directive_weakext (int ignore ATTRIBUTE_UNUSED)
SKIP_WHITESPACE ();
if (! is_end_of_stmt (*input_line_pointer))
{
+#ifdef md_expr_init_rest
+ md_expr_init_rest (&exp);
+#endif
expression (&exp);
if (exp.X_op != O_symbol)
{
@@ -3480,6 +3483,9 @@ ecoff_stab (int what,
sc = sc_Nil;
st = st_Nil;
+#ifdef md_expr_init_rest
+ md_expr_init_rest (&exp);
+#endif
expression (&exp);
if (exp.X_op == O_constant)
{
@@ -183,12 +183,11 @@ symbol_lookup_or_make (const char *name, bool start)
symbolS *
expr_build_uconstant (offsetT value)
{
- expressionS e;
-
- e.X_op = O_constant;
- e.X_add_number = value;
- e.X_unsigned = 1;
- e.X_extrabit = 0;
+ expressionS e = {
+ .X_op = O_constant,
+ .X_add_number = value,
+ .X_unsigned = 1
+ };
return make_expr_symbol (&e);
}
@@ -421,8 +421,6 @@ sframe_get_fre_offset_size (const struct sframe_row_entry *sframe_fre)
return fre_offset_size;
}
-#if SFRAME_FRE_TYPE_SELECTION_OPT
-
/* Create a composite expression CEXP (for SFrame FRE start address) such that:
exp = <val> OP_absent <width>, where,
@@ -441,28 +439,28 @@ create_fre_start_addr_exp (expressionS *cexp, symbolS *fre_pc_begin,
symbolS *fde_start_address,
symbolS *fde_end_address)
{
- expressionS val;
- expressionS width;
-
/* val expression stores the FDE start address offset from the start PC
of function. */
- val.X_op = O_subtract;
- val.X_add_symbol = fre_pc_begin;
- val.X_op_symbol = fde_start_address;
- val.X_add_number = 0;
+ expressionS val = {
+ .X_op = O_subtract,
+ .X_add_symbol = fre_pc_begin,
+ .X_op_symbol = fde_start_address,
+ };
/* width expressions stores the size of the function. This is used later
to determine the number of bytes to be used to encode the FRE start
address of each FRE of the function. */
- width.X_op = O_subtract;
- width.X_add_symbol = fde_end_address;
- width.X_op_symbol = fde_start_address;
- width.X_add_number = 0;
+ expressionS width = {
+ .X_op = O_subtract,
+ .X_add_symbol = fde_end_address,
+ .X_op_symbol = fde_start_address,
+ };
- cexp->X_op = O_absent;
- cexp->X_add_symbol = make_expr_symbol (&val);
- cexp->X_op_symbol = make_expr_symbol (&width);
- cexp->X_add_number = 0;
+ *cexp = (expressionS) {
+ .X_op = O_absent,
+ .X_add_symbol = make_expr_symbol (&val),
+ .X_op_symbol = make_expr_symbol (&width)
+ };
}
/* Create a composite expression CEXP (for SFrame FDE function info) such that:
@@ -483,25 +481,24 @@ 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;
+ expressionS width = {
+ .X_op = O_subtract,
+ .X_add_symbol = dw_fde_end_addrS,
+ .X_op_symbol = dw_fde_start_addrS
+ };
- rest_of_func_info.X_op = O_constant;
- rest_of_func_info.X_add_number = func_info;
+ expressionS rest_of_func_info = {
+ .X_op = O_constant,
+ .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;
+ *cexp = (expressionS) {
+ .X_op = O_modulus,
+ .X_add_symbol = make_expr_symbol (&rest_of_func_info),
+ .X_op_symbol = make_expr_symbol (&width)
+ };
}
-#endif
-
static struct sframe_row_entry*
sframe_row_entry_new (void)
{
@@ -564,20 +561,24 @@ output_sframe_row_entry (symbolS *fde_start_addr,
fre_addr_size = 4; /* 4 bytes by default. FIXME tie it to fre_type? */
/* SFrame FRE Start Address. */
-#if SFRAME_FRE_TYPE_SELECTION_OPT
- create_fre_start_addr_exp (&exp, sframe_fre->pc_begin, fde_start_addr,
- fde_end_addr);
- frag_grow (fre_addr_size);
- frag_var (rs_sframe, fre_addr_size, 0, 0,
- make_expr_symbol (&exp), 0, (char *) frag_now);
-#else
- gas_assert (fde_end_addr);
- exp.X_op = O_subtract;
- exp.X_add_symbol = sframe_fre->pc_begin; /* to. */
- exp.X_op_symbol = fde_start_addr; /* from. */
- exp.X_add_number = 0;
- emit_expr (&exp, fre_addr_size);
-#endif
+ if (SFRAME_FRE_TYPE_SELECTION_OPT)
+ {
+ create_fre_start_addr_exp (&exp, sframe_fre->pc_begin, fde_start_addr,
+ fde_end_addr);
+ frag_grow (fre_addr_size);
+ frag_var (rs_sframe, fre_addr_size, 0, 0,
+ make_expr_symbol (&exp), 0, (char *) frag_now);
+ }
+ else
+ {
+ gas_assert (fde_end_addr);
+ exp = (expressionS) {
+ .X_op = O_subtract,
+ .X_add_symbol = sframe_fre->pc_begin, /* to. */
+ .X_op_symbol = fde_start_addr /* from. */
+ };
+ emit_expr (&exp, fre_addr_size);
+ }
/* Create the fre_info using the CFA base register, number of offsets and max
size of offset in this frame row entry. */
@@ -668,16 +669,17 @@ output_sframe_funcdesc (symbolS *start_of_fre_section,
func_info = sframe_set_func_info (SFRAME_FDE_TYPE_PCINC,
SFRAME_FRE_TYPE_ADDR4,
pauth_key);
-#if SFRAME_FRE_TYPE_SELECTION_OPT
- 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, 0, make_expr_symbol (&cexp), 0,
- (char *) frag_now);
-#else
- out_one (func_info);
-#endif
+ if (SFRAME_FRE_TYPE_SELECTION_OPT)
+ {
+ 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, 0, make_expr_symbol (&cexp), 0,
+ (char *) frag_now);
+ }
+ else
+ out_one (func_info);
out_one (0);
out_two (0);
}
@@ -1957,10 +1957,7 @@ s_mri_common (int small ATTRIBUTE_UNUSED)
if (line_label != NULL)
{
- expressionS exp;
- exp.X_op = O_symbol;
- exp.X_add_symbol = sym;
- exp.X_add_number = 0;
+ expressionS exp = { .X_op = O_symbol, .X_add_symbol = sym };
symbol_set_value_expression (line_label, &exp);
symbol_set_frag (line_label, &zero_address_frag);
S_SET_SEGMENT (line_label, expr_section);
@@ -4122,6 +4119,9 @@ pseudo_set (symbolS *symbolP)
know (symbolP); /* NULL pointer is logic error. */
+#ifdef md_expr_init_rest
+ md_expr_init_rest (&exp);
+#endif
if (!S_IS_FORWARD_REF (symbolP))
(void) expression (&exp);
else