277c44e
From b53c44bfe31fb036f212275b6d70edd5eee7b088 Mon Sep 17 00:00:00 2001
277c44e
From: Jan Beulich via Binutils <binutils@sourceware.org>
277c44e
Date: Tue, 9 Aug 2022 13:12:03 +0200
277c44e
Subject: [PATCH] gas/Dwarf: properly skip zero-size functions
277c44e
277c44e
PR gas/29451
277c44e
277c44e
While out_debug_abbrev() properly skips such functions, out_debug_info()
277c44e
mistakenly didn't. It needs to calculate the high_pc expression ahead of
277c44e
time, in order to skip emitting any data for the function if the value
277c44e
is zero.
277c44e
277c44e
The one case which would still leave a zero-size entry is when
277c44e
symbol_get_obj(symp)->size ends up evaluating to zero. I hope we can
277c44e
expect that to not be the case, otherwise we'd need to have a way to
277c44e
post-process .debug_info contents between resolving expressions and
277c44e
actually writing the data out to the file. Even then it wouldn't be
277c44e
entirely obvious in which way to alter the data.
277c44e
---
277c44e
 gas/dwarf2dbg.c | 39 ++++++++++++++++++++-------------------
277c44e
 1 file changed, 20 insertions(+), 19 deletions(-)
277c44e
277c44e
diff --git a/gas/dwarf2dbg.c b/gas/dwarf2dbg.c
277c44e
index 868ec79ee2c..f346bd6a412 100644
277c44e
--- a/gas/dwarf2dbg.c
277c44e
+++ b/gas/dwarf2dbg.c
277c44e
@@ -2882,6 +2882,7 @@ out_debug_info (segT info_seg, segT abbrev_seg, segT line_seg, segT str_seg,
277c44e
 	{
277c44e
 	  const char *name;
277c44e
 	  size_t len;
277c44e
+	  expressionS size = { .X_op = O_constant };
277c44e
 
277c44e
 	  /* Skip warning constructs (see above).  */
277c44e
 	  if (symbol_get_bfdsym (symp)->flags & BSF_WARNING)
277c44e
@@ -2895,6 +2896,18 @@ out_debug_info (segT info_seg, segT abbrev_seg, segT line_seg, segT str_seg,
277c44e
 	  if (!S_IS_DEFINED (symp) || !S_IS_FUNCTION (symp))
277c44e
 	    continue;
277c44e
 
277c44e
+#if defined (OBJ_ELF) /* || defined (OBJ_MAYBE_ELF) */
277c44e
+	  size.X_add_number = S_GET_SIZE (symp);
277c44e
+	  if (size.X_add_number == 0 && IS_ELF
277c44e
+	      && symbol_get_obj (symp)->size != NULL)
277c44e
+	    {
277c44e
+	      size.X_op = O_add;
277c44e
+	      size.X_op_symbol = make_expr_symbol (symbol_get_obj (symp)->size);
277c44e
+	    }
277c44e
+#endif
277c44e
+	  if (size.X_op == O_constant && size.X_add_number == 0)
277c44e
+	    continue;
277c44e
+
277c44e
 	  subseg_set (str_seg, 0);
277c44e
 	  name_sym = symbol_temp_new_now_octets ();
277c44e
 	  name = S_GET_NAME (symp);
277c44e
@@ -2920,29 +2933,17 @@ out_debug_info (segT info_seg, segT abbrev_seg, segT line_seg, segT str_seg,
277c44e
 	  emit_expr (&exp, sizeof_address);
277c44e
 
277c44e
 	  /* DW_AT_high_pc */
277c44e
-	  exp.X_op = O_constant;
277c44e
-#if defined (OBJ_ELF) /* || defined (OBJ_MAYBE_ELF) */
277c44e
-	  exp.X_add_number = S_GET_SIZE (symp);
277c44e
-	  if (exp.X_add_number == 0 && IS_ELF
277c44e
-	      && symbol_get_obj (symp)->size != NULL)
277c44e
-	    {
277c44e
-	      exp.X_op = O_add;
277c44e
-	      exp.X_op_symbol = make_expr_symbol (symbol_get_obj (symp)->size);
277c44e
-	    }
277c44e
-#else
277c44e
-	  exp.X_add_number = 0;
277c44e
-#endif
277c44e
 	  if (DWARF2_VERSION < 4)
277c44e
 	    {
277c44e
-	      if (exp.X_op == O_constant)
277c44e
-		exp.X_op = O_symbol;
277c44e
-	      exp.X_add_symbol = symp;
277c44e
-	      emit_expr (&exp, sizeof_address);
277c44e
+	      if (size.X_op == O_constant)
277c44e
+		size.X_op = O_symbol;
277c44e
+	      size.X_add_symbol = symp;
277c44e
+	      emit_expr (&size, sizeof_address);
277c44e
 	    }
277c44e
-	  else if (exp.X_op == O_constant)
277c44e
-	    out_uleb128 (exp.X_add_number);
277c44e
+	  else if (size.X_op == O_constant)
277c44e
+	    out_uleb128 (size.X_add_number);
277c44e
 	  else
277c44e
-	    emit_leb128_expr (symbol_get_value_expression (exp.X_op_symbol), 0);
277c44e
+	    emit_leb128_expr (symbol_get_value_expression (size.X_op_symbol), 0);
277c44e
 	}
277c44e
 
277c44e
       /* End of children.  */
277c44e
-- 
277c44e
2.37.1
277c44e