From: Alan Modra Date: Fri, 3 Oct 2025 23:07:37 +0000 (+0930) Subject: gas: more expression initialisation X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=e3f9c2f90efe233208a75ccf317faad4716bec69;p=thirdparty%2Fbinutils-gdb.git gas: more expression initialisation 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. --- diff --git a/gas/cgen.c b/gas/cgen.c index 605dd3cf251..d97107267f5 100644 --- a/gas/cgen.c +++ b/gas/cgen.c @@ -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; diff --git a/gas/config/obj-coff.c b/gas/config/obj-coff.c index be6a9657628..f4fa9c52c55 100644 --- a/gas/config/obj-coff.c +++ b/gas/config/obj-coff.c @@ -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 diff --git a/gas/config/tc-alpha.c b/gas/config/tc-alpha.c index 7ba85a67770..f9d18bb8c24 100644 --- a/gas/config/tc-alpha.c +++ b/gas/config/tc-alpha.c @@ -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. */ diff --git a/gas/config/tc-i386-intel.c b/gas/config/tc-i386-intel.c index 2b86f88b8bc..a60b1e94830 100644 --- a/gas/config/tc-i386-intel.c +++ b/gas/config/tc-i386-intel.c @@ -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); } } diff --git a/gas/config/tc-microblaze.c b/gas/config/tc-microblaze.c index 055d9ee22dd..01f322df2b6 100644 --- a/gas/config/tc-microblaze.c +++ b/gas/config/tc-microblaze.c @@ -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) { diff --git a/gas/config/tc-ppc.c b/gas/config/tc-ppc.c index 3b2b218bcf3..e2485a4d794 100644 --- a/gas/config/tc-ppc.c +++ b/gas/config/tc-ppc.c @@ -5275,13 +5275,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); } diff --git a/gas/config/tc-tic54x.c b/gas/config/tc-tic54x.c index 515b8435c50..de3d762c206 100644 --- a/gas/config/tc-tic54x.c +++ b/gas/config/tc-tic54x.c @@ -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; diff --git a/gas/dw2gencfi.c b/gas/dw2gencfi.c index 186dfa667c8..96964c13508 100644 --- a/gas/dw2gencfi.c +++ b/gas/dw2gencfi.c @@ -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 diff --git a/gas/ecoff.c b/gas/ecoff.c index 97b909364a9..d09c70ca264 100644 --- a/gas/ecoff.c +++ b/gas/ecoff.c @@ -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) { diff --git a/gas/expr.c b/gas/expr.c index b75cce9f781..4b5a3be0669 100644 --- a/gas/expr.c +++ b/gas/expr.c @@ -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); } diff --git a/gas/gen-sframe.c b/gas/gen-sframe.c index ac1427856fa..b9db87f6c64 100644 --- a/gas/gen-sframe.c +++ b/gas/gen-sframe.c @@ -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 = OP_absent , 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); } diff --git a/gas/read.c b/gas/read.c index 2e7a4accabd..4ba71f99250 100644 --- a/gas/read.c +++ b/gas/read.c @@ -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