]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
gas/Dwarf: properly skip zero-size functions
authorJan Beulich <jbeulich@suse.com>
Wed, 10 Aug 2022 08:34:22 +0000 (10:34 +0200)
committerJan Beulich <jbeulich@suse.com>
Wed, 10 Aug 2022 08:34:22 +0000 (10:34 +0200)
PR gas/29451

While out_debug_abbrev() properly skips such functions, out_debug_info()
mistakenly didn't. It needs to calculate the high_pc expression ahead of
time, in order to skip emitting any data for the function if the value
is zero.

The one case which would still leave a zero-size entry is when
symbol_get_obj(symp)->size ends up evaluating to zero. I hope we can
expect that to not be the case, otherwise we'd need to have a way to
post-process .debug_info contents between resolving expressions and
actually writing the data out to the file. Even then it wouldn't be
entirely obvious in which way to alter the data.

(cherry picked from commit d7abcbcea5ddd40a3bf28758b62f35933c59f996)

gas/dwarf2dbg.c

index 868ec79ee2cff6262a5ea2857633558936f846af..f346bd6a412e0ac549efee6ee6721c279b0cd581 100644 (file)
@@ -2882,6 +2882,7 @@ out_debug_info (segT info_seg, segT abbrev_seg, segT line_seg, segT str_seg,
        {
          const char *name;
          size_t len;
+         expressionS size = { .X_op = O_constant };
 
          /* Skip warning constructs (see above).  */
          if (symbol_get_bfdsym (symp)->flags & BSF_WARNING)
@@ -2895,6 +2896,18 @@ out_debug_info (segT info_seg, segT abbrev_seg, segT line_seg, segT str_seg,
          if (!S_IS_DEFINED (symp) || !S_IS_FUNCTION (symp))
            continue;
 
+#if defined (OBJ_ELF) /* || defined (OBJ_MAYBE_ELF) */
+         size.X_add_number = S_GET_SIZE (symp);
+         if (size.X_add_number == 0 && IS_ELF
+             && symbol_get_obj (symp)->size != NULL)
+           {
+             size.X_op = O_add;
+             size.X_op_symbol = make_expr_symbol (symbol_get_obj (symp)->size);
+           }
+#endif
+         if (size.X_op == O_constant && size.X_add_number == 0)
+           continue;
+
          subseg_set (str_seg, 0);
          name_sym = symbol_temp_new_now_octets ();
          name = S_GET_NAME (symp);
@@ -2920,29 +2933,17 @@ out_debug_info (segT info_seg, segT abbrev_seg, segT line_seg, segT str_seg,
          emit_expr (&exp, sizeof_address);
 
          /* DW_AT_high_pc */
-         exp.X_op = O_constant;
-#if defined (OBJ_ELF) /* || defined (OBJ_MAYBE_ELF) */
-         exp.X_add_number = S_GET_SIZE (symp);
-         if (exp.X_add_number == 0 && IS_ELF
-             && symbol_get_obj (symp)->size != NULL)
-           {
-             exp.X_op = O_add;
-             exp.X_op_symbol = make_expr_symbol (symbol_get_obj (symp)->size);
-           }
-#else
-         exp.X_add_number = 0;
-#endif
          if (DWARF2_VERSION < 4)
            {
-             if (exp.X_op == O_constant)
-               exp.X_op = O_symbol;
-             exp.X_add_symbol = symp;
-             emit_expr (&exp, sizeof_address);
+             if (size.X_op == O_constant)
+               size.X_op = O_symbol;
+             size.X_add_symbol = symp;
+             emit_expr (&size, sizeof_address);
            }
-         else if (exp.X_op == O_constant)
-           out_uleb128 (exp.X_add_number);
+         else if (size.X_op == O_constant)
+           out_uleb128 (size.X_add_number);
          else
-           emit_leb128_expr (symbol_get_value_expression (exp.X_op_symbol), 0);
+           emit_leb128_expr (symbol_get_value_expression (size.X_op_symbol), 0);
        }
 
       /* End of children.  */