]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
gas: more expression initialisation
authorAlan Modra <amodra@gmail.com>
Fri, 3 Oct 2025 23:07:37 +0000 (08:37 +0930)
committerAlan Modra <amodra@gmail.com>
Sat, 4 Oct 2025 00:09:02 +0000 (09:39 +0930)
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.

12 files changed:
gas/cgen.c
gas/config/obj-coff.c
gas/config/tc-alpha.c
gas/config/tc-i386-intel.c
gas/config/tc-microblaze.c
gas/config/tc-ppc.c
gas/config/tc-tic54x.c
gas/dw2gencfi.c
gas/ecoff.c
gas/expr.c
gas/gen-sframe.c
gas/read.c

index 605dd3cf25112033211ec5d81d5dcfac2a10bb8e..d97107267f52a6e08f83842285073b24097f5f93 100644 (file)
@@ -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;
index be6a96576289a8604ac880588236b183c4befc82..f4fa9c52c5588a0ec5ef399df7167000a784cfca 100644 (file)
@@ -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
index 7ba85a6777021dd4ce4e784c1a4a059be7e3eb8c..f9d18bb8c246d82eb3c830dab4ad1311e3742fa9 100644 (file)
@@ -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.  */
index 2b86f88b8bcb55afc968299da11f06c6f6e3d019..a60b1e94830e5abd2fa073ee73966ac5e446e3bd 100644 (file)
@@ -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);
            }
        }
index 055d9ee22dd030704aca81b3c92034647da795d3..01f322df2b672fff91a318a80b0c509bbd97e38c 100644 (file)
@@ -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)
        {
index 3b2b218bcf34068001389e2332fa498ef2c501b5..e2485a4d79472911880f482b200cb6a7b6ca4ff7 100644 (file)
@@ -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);
     }
 
index 515b8435c505e5faa1eb2e439751438e3b9b52ba..de3d762c2061f72d67e11bfec6727b382379e935 100644 (file)
@@ -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;
index 186dfa667c8b1a61233f24a0baa32b23653f791b..96964c13508a2b1b0a4322f9d398a64170e066ba 100644 (file)
@@ -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
index 97b909364a930ddd40423d01d0ab073a67cb6cba..d09c70ca264f7c524281f4a3df1c881c9cf05b68 100644 (file)
@@ -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)
            {
index b75cce9f7816130271d34443bbff18dd313a449e..4b5a3be06694510f9e52f4cea40931ca7e1c0a59 100644 (file)
@@ -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);
 }
 \f
index ac1427856fab8278c01bc60da6b92fca85154b74..b9db87f6c64c7d03f2629038eeed8e7d7e861f00 100644 (file)
@@ -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);
 }
index 2e7a4accabd20ba5b79d60067b0e06bd642af546..4ba71f99250cb79feaebd78b538eea4cd69d5891 100644 (file)
@@ -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