diff mbox series

[2/4] Don't output CodeView line numbers for inlined functions

Message ID 20241107043915.2112-2-mark@harmstone.com
State New
Headers show
Series [1/4] Add block parameter to begin_block debug hook | expand

Commit Message

Mark Harmstone Nov. 7, 2024, 4:39 a.m. UTC
If we encounter an inlined function, treat it as another
codeview_function, and skip over these when outputting line numbers.
This information will instead be output as part of the S_INLINESITE
symbols.

gcc/
	* dwarf2codeview.cc (struct codeview_function): Add parent and
	inline_block fields.
	(cur_func): New global variable.
	(new_codeview_function): New function.
	(codeview_source_line): Call new_codeview_function, and use cur_func
	instead of last_func.
	(codeview_begin_block): New function.
	(codeview_end_block): New function.
	(write_line_numbers): No longer free data as we go along.
	(codeview_switch_text_section): Call new_codeview_function, and use
	cur_func instead of last_func.
	(codeview_end_epilogue): Use cur_func instead of last_func.
	(codeview_debug_finish): Free funcs list and its contents.
	* dwarf2codeview.h (codeview_begin_block): Add declaration.
	(codeview_end_block): Add declaration.
	* dwarf2out.cc (dwarf2out_begin_block): Call codeview_begin_block if
	outputting CodeView debug info.
	(dwarf2out_end_block): Call codeview_end_block if outputting CodeView
	debug info.
---
 gcc/dwarf2codeview.cc | 199 ++++++++++++++++++++++++++++--------------
 gcc/dwarf2codeview.h  |   2 +
 gcc/dwarf2out.cc      |  10 +++
 3 files changed, 145 insertions(+), 66 deletions(-)
diff mbox series

Patch

diff --git a/gcc/dwarf2codeview.cc b/gcc/dwarf2codeview.cc
index 5e8a4ab39e7..df59fbcf288 100644
--- a/gcc/dwarf2codeview.cc
+++ b/gcc/dwarf2codeview.cc
@@ -1146,6 +1146,8 @@  struct codeview_function
   function *func;
   unsigned int end_label;
   codeview_line_block *blocks, *last_block;
+  codeview_function *parent;
+  unsigned int inline_block;
 };
 
 struct codeview_symbol
@@ -1417,7 +1419,7 @@  static unsigned int num_files;
 static uint32_t string_offset = 1;
 static hash_table<string_hasher> *strings_htab;
 static codeview_string *strings, *last_string;
-static codeview_function *funcs, *last_func;
+static codeview_function *funcs, *last_func, *cur_func;
 static const char* last_filename;
 static uint32_t last_file_id;
 static codeview_symbol *sym, *last_sym;
@@ -1433,6 +1435,30 @@  static uint32_t get_type_num_subroutine_type (dw_die_ref type, bool in_struct,
 					      int32_t this_adjustment);
 static void write_cv_padding (size_t padding);
 
+/* Allocate and initialize a codeview_function struct.  */
+
+static codeview_function *
+new_codeview_function (void)
+{
+  codeview_function *f = (codeview_function *)
+			    xmalloc (sizeof (codeview_function));
+
+  f->next = NULL;
+  f->func = cfun;
+  f->end_label = 0;
+  f->blocks = f->last_block = NULL;
+  f->inline_block = 0;
+
+  if (!funcs)
+    funcs = f;
+  else
+    last_func->next = f;
+
+  last_func = f;
+
+  return f;
+}
+
 /* Record new line number against the current function.  */
 
 void
@@ -1444,22 +1470,13 @@  codeview_source_line (unsigned int line_no, const char *filename)
 
   targetm.asm_out.internal_label (asm_out_file, LINE_LABEL, label_num);
 
-  if (!last_func || last_func->func != cfun)
+  if (!cur_func || cur_func->func != cfun)
     {
-      codeview_function *f = (codeview_function *)
-				xmalloc (sizeof (codeview_function));
+      codeview_function *f = new_codeview_function ();
 
-      f->next = NULL;
-      f->func = cfun;
-      f->end_label = 0;
-      f->blocks = f->last_block = NULL;
-
-      if (!funcs)
-	funcs = f;
-      else
-	last_func->next = f;
+      f->parent = NULL;
 
-      last_func = f;
+      cur_func = f;
     }
 
   if (filename != last_filename)
@@ -1484,7 +1501,7 @@  codeview_source_line (unsigned int line_no, const char *filename)
 	}
     }
 
-  if (!last_func->last_block || last_func->last_block->file_id != file_id)
+  if (!cur_func->last_block || cur_func->last_block->file_id != file_id)
     {
       codeview_line_block *b;
 
@@ -1495,16 +1512,16 @@  codeview_source_line (unsigned int line_no, const char *filename)
       b->num_lines = 0;
       b->lines = b->last_line = NULL;
 
-      if (!last_func->blocks)
-	last_func->blocks = b;
+      if (!cur_func->blocks)
+	cur_func->blocks = b;
       else
-	last_func->last_block->next = b;
+	cur_func->last_block->next = b;
 
-      last_func->last_block = b;
+      cur_func->last_block = b;
     }
 
-  if (last_func->last_block->last_line
-    && last_func->last_block->last_line->line_no == line_no)
+  if (cur_func->last_block->last_line
+    && cur_func->last_block->last_line->line_no == line_no)
     return;
 
   l = (codeview_line *) xmalloc (sizeof (codeview_line));
@@ -1513,13 +1530,45 @@  codeview_source_line (unsigned int line_no, const char *filename)
   l->line_no = line_no;
   l->label_num = label_num;
 
-  if (!last_func->last_block->lines)
-    last_func->last_block->lines = l;
+  if (!cur_func->last_block->lines)
+    cur_func->last_block->lines = l;
   else
-    last_func->last_block->last_line->next = l;
+    cur_func->last_block->last_line->next = l;
 
-  last_func->last_block->last_line = l;
-  last_func->last_block->num_lines++;
+  cur_func->last_block->last_line = l;
+  cur_func->last_block->num_lines++;
+}
+
+/* We have encountered the beginning of a lexical block.  If this is actually
+   an inlined function, allocate a new codeview_function for this.  */
+
+void
+codeview_begin_block (unsigned int line ATTRIBUTE_UNUSED,
+		      unsigned int blocknum, tree block)
+{
+  if (inlined_function_outer_scope_p (block))
+    {
+      location_t locus = BLOCK_SOURCE_LOCATION (block);
+      expanded_location s = expand_location (locus);
+      codeview_function *f = new_codeview_function ();
+
+      codeview_source_line (s.line, s.file);
+
+      f->parent = cur_func;
+      f->inline_block = blocknum;
+
+      cur_func = f;
+    }
+}
+
+/* We have encountered the end of a lexical block.  If this is the end of an
+   inlined function, change cur_func back to its parent.  */
+
+void
+codeview_end_block (unsigned int line ATTRIBUTE_UNUSED, unsigned int blocknum)
+{
+  if (cur_func && cur_func->inline_block == blocknum)
+    cur_func = cur_func->parent;
 }
 
 /* Adds string to the string table, returning its offset.  If already present,
@@ -1722,11 +1771,19 @@  static void
 write_line_numbers (void)
 {
   unsigned int func_num = 0;
+  codeview_function *f = funcs;
 
-  while (funcs)
+  while (f)
     {
-      codeview_function *next = funcs->next;
+      codeview_function *next_func = f->next;
       unsigned int first_label_num;
+      codeview_line_block *b = f->blocks;
+
+      if (f->inline_block != 0)
+	{
+	  f = next_func;
+	  continue;
+	}
 
       fputs (integer_asm_op (4, false), asm_out_file);
       fprint_whex (asm_out_file, DEBUG_S_LINES);
@@ -1751,26 +1808,27 @@  write_line_numbers (void)
       */
 
       asm_fprintf (asm_out_file, "\t.secrel32\t%L" LINE_LABEL "%u\n",
-		   funcs->blocks->lines->label_num);
+		   b->lines->label_num);
       asm_fprintf (asm_out_file, "\t.secidx\t%L" LINE_LABEL "%u\n",
-		   funcs->blocks->lines->label_num);
+		   b->lines->label_num);
 
       /* flags */
       fputs (integer_asm_op (2, false), asm_out_file);
       fprint_whex (asm_out_file, 0);
       putc ('\n', asm_out_file);
 
-      first_label_num = funcs->blocks->lines->label_num;
+      first_label_num = b->lines->label_num;
 
       /* length */
       fputs (integer_asm_op (4, false), asm_out_file);
       asm_fprintf (asm_out_file,
 		   "%L" END_FUNC_LABEL "%u - %L" LINE_LABEL "%u\n",
-		   funcs->end_label, first_label_num);
+		   f->end_label, first_label_num);
 
-      while (funcs->blocks)
+      while (b)
 	{
-	  codeview_line_block *next = funcs->blocks->next;
+	  codeview_line_block *next_block = b->next;
+	  codeview_line *l = b->lines;
 
 	  /* Next comes the blocks, each block being a part of a function
 	     within the same source file (struct cv_lines_block in binutils or
@@ -1786,23 +1844,23 @@  write_line_numbers (void)
 
 	  /* file ID */
 	  fputs (integer_asm_op (4, false), asm_out_file);
-	  fprint_whex (asm_out_file, funcs->blocks->file_id);
+	  fprint_whex (asm_out_file, b->file_id);
 	  putc ('\n', asm_out_file);
 
 	  /* number of lines */
 	  fputs (integer_asm_op (4, false), asm_out_file);
-	  fprint_whex (asm_out_file, funcs->blocks->num_lines);
+	  fprint_whex (asm_out_file, b->num_lines);
 	  putc ('\n', asm_out_file);
 
 	  /* length of code block: (num_lines * sizeof (struct cv_line)) +
 	     sizeof (struct cv_lines_block) */
 	  fputs (integer_asm_op (4, false), asm_out_file);
-	  fprint_whex (asm_out_file, (funcs->blocks->num_lines * 0x8) + 0xc);
+	  fprint_whex (asm_out_file, (b->num_lines * 0x8) + 0xc);
 	  putc ('\n', asm_out_file);
 
-	  while (funcs->blocks->lines)
+	  while (l)
 	    {
-	      codeview_line *next = funcs->blocks->lines->next;
+	      codeview_line *next_line = l->next;
 
 	      /* Finally comes the line number information (struct cv_line in
 		 binutils or CV_Line_t in Microsoft's cvinfo.h):
@@ -1820,30 +1878,24 @@  write_line_numbers (void)
 	      fputs (integer_asm_op (4, false), asm_out_file);
 	      asm_fprintf (asm_out_file,
 			   "%L" LINE_LABEL "%u - %L" LINE_LABEL "%u\n",
-			   funcs->blocks->lines->label_num, first_label_num);
+			   l->label_num, first_label_num);
 
 	      fputs (integer_asm_op (4, false), asm_out_file);
 	      fprint_whex (asm_out_file,
 			   0x80000000
-			   | (funcs->blocks->lines->line_no & 0xffffff));
+			   | (l->line_no & 0xffffff));
 	      putc ('\n', asm_out_file);
 
-	      free (funcs->blocks->lines);
-
-	      funcs->blocks->lines = next;
+	      l = next_line;
 	    }
 
-	  free (funcs->blocks);
-
-	  funcs->blocks = next;
+	  b = next_block;
 	}
 
-      free (funcs);
-
       asm_fprintf (asm_out_file, "%LLcv_lines%u_end:\n", func_num);
       func_num++;
 
-      funcs = next;
+      f = next_func;
     }
 }
 
@@ -1855,29 +1907,20 @@  codeview_switch_text_section (void)
 {
   codeview_function *f;
 
-  if (last_func && last_func->end_label == 0)
+  if (cur_func && cur_func->end_label == 0)
     {
       unsigned int label_num = ++func_label_num;
 
       targetm.asm_out.internal_label (asm_out_file, END_FUNC_LABEL,
 				      label_num);
 
-      last_func->end_label = label_num;
+      cur_func->end_label = label_num;
     }
 
-  f = (codeview_function *) xmalloc (sizeof (codeview_function));
+  f = new_codeview_function ();
+  f->parent = cur_func ? cur_func->parent : NULL;
 
-  f->next = NULL;
-  f->func = cfun;
-  f->end_label = 0;
-  f->blocks = f->last_block = NULL;
-
-  if (!funcs)
-    funcs = f;
-  else
-    last_func->next = f;
-
-  last_func = f;
+  cur_func = f;
 }
 
 /* Mark the end of the current function.  */
@@ -1885,14 +1928,14 @@  codeview_switch_text_section (void)
 void
 codeview_end_epilogue (void)
 {
-  if (last_func && last_func->end_label == 0)
+  if (cur_func && cur_func->end_label == 0)
     {
       unsigned int label_num = ++func_label_num;
 
       targetm.asm_out.internal_label (asm_out_file, END_FUNC_LABEL,
 				      label_num);
 
-      last_func->end_label = label_num;
+      cur_func->end_label = label_num;
     }
 }
 
@@ -4676,6 +4719,30 @@  codeview_debug_finish (void)
   if (custom_types)
     write_custom_types ();
 
+  while (funcs)
+    {
+      codeview_function *next_func = funcs->next;
+
+      while (funcs->blocks)
+	{
+	  codeview_line_block *next_block = funcs->blocks->next;
+
+	  while (funcs->blocks->lines)
+	    {
+	      codeview_line *next_line = funcs->blocks->lines->next;
+
+	      free (funcs->blocks->lines);
+	      funcs->blocks->lines = next_line;
+	    }
+
+	  free (funcs->blocks);
+	  funcs->blocks = next_block;
+	}
+
+      free (funcs);
+      funcs = next_func;
+    }
+
   if (types_htab)
     delete types_htab;
 
diff --git a/gcc/dwarf2codeview.h b/gcc/dwarf2codeview.h
index 52ffc6cfb99..367334d68cb 100644
--- a/gcc/dwarf2codeview.h
+++ b/gcc/dwarf2codeview.h
@@ -95,5 +95,7 @@  extern void codeview_start_source_file (const char *);
 extern void codeview_switch_text_section ();
 extern void codeview_end_epilogue (void);
 extern void codeview_debug_early_finish (dw_die_ref die);
+extern void codeview_begin_block (unsigned int, unsigned int, tree);
+extern void codeview_end_block (unsigned int, unsigned int);
 
 #endif /* GCC_DWARF2CODEVIEW_H */
diff --git a/gcc/dwarf2out.cc b/gcc/dwarf2out.cc
index 698926b41c0..2efcb52723a 100644
--- a/gcc/dwarf2out.cc
+++ b/gcc/dwarf2out.cc
@@ -27809,6 +27809,11 @@  dwarf2out_begin_block (unsigned int line ATTRIBUTE_UNUSED,
 		       unsigned int blocknum,
 		       tree block ATTRIBUTE_UNUSED)
 {
+#ifdef CODEVIEW_DEBUGGING_INFO
+  if (codeview_debuginfo_p ())
+    codeview_begin_block (line, blocknum, block);
+#endif
+
   switch_to_section (current_function_section ());
   ASM_OUTPUT_DEBUG_LABEL (asm_out_file, BLOCK_BEGIN_LABEL, blocknum);
 }
@@ -27819,6 +27824,11 @@  dwarf2out_begin_block (unsigned int line ATTRIBUTE_UNUSED,
 static void
 dwarf2out_end_block (unsigned int line ATTRIBUTE_UNUSED, unsigned int blocknum)
 {
+#ifdef CODEVIEW_DEBUGGING_INFO
+  if (codeview_debuginfo_p ())
+    codeview_end_block (line, blocknum);
+#endif
+
   switch_to_section (current_function_section ());
   ASM_OUTPUT_DEBUG_LABEL (asm_out_file, BLOCK_END_LABEL, blocknum);
 }