public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* PR28149, debug info with wrong file association
@ 2021-09-17  6:56 Alan Modra
  2021-09-17  7:05 ` PR28149 part 2, purge generated line info Alan Modra
  2021-09-17  7:25 ` Eric Botcazou
  0 siblings, 2 replies; 9+ messages in thread
From: Alan Modra @ 2021-09-17  6:56 UTC (permalink / raw)
  To: binutils

gcc-11 and gcc-12 pass -gdwarf-5 to gas, in order to prime gas for
DWARF 5 level debug info.  Unfortunately it seems there are cases
where the compiler does not emit a .file or .loc dwarf debug directive
before any machine instructions.  (Note that the .file directive
typically emitted as the first line of assembly output doesn't count as
a dwarf debug directive.  The dwarf .file has a file number before the
file name string.)

This patch delays allocation of file numbers for gas generated line
debug info until the end of assembly, thus avoiding any clashes with
compiler generated file numbers.  Two fixes for test case source are
necessary;  A .loc can't use a file number that hasn't already been
specified with .file.

A followup patch will remove all the gas generated line info on
seeing a .file directive.

HJ, I'm cc'ing you in case you want to comment on the testcase
source changes.  BTW, the next patch changes .d files all over
again.

	PR 28149
	* dwarf2dbg.c (num_of_auto_assigned): Delete.
	(current): Update initialisation.
	(set_or_check_view): Replace all accesses to view with u.view.
	(dwarf2_consume_line_info): Likewise.
	(dwarf2_directive_loc): Likewise.  Assert that we aren't generating
	line info.
	(dwarf2_gen_line_info_1): Don't call set_or_check_view on
	gas generated line entries.
	(dwarf2_gen_line_info): Set and track filenames for gas generated
	line entries.  Simplify generation of labels.
	(get_directory_table_entry): Use filename_cmp when comparing dirs.
	(do_allocate_filenum): New function.
	(dwarf2_where): Set u.filename and filenum to -1 for gas generated
	line entries.
	(dwarf2_directive_filename): Remove num_of_auto_assigned handling.
	(process_entries): Update view field access.  Call
	do_allocate_filenum.
	* dwarf2dbg.h (struct dwarf2_line_info): Add filename field in
	union aliasing view.
	* testsuite/gas/i386/dwarf2-line-3.s: Add .file directive.
	* testsuite/gas/i386/dwarf2-line-4.s: Likewise.
	* testsuite/gas/i386/dwarf2-line-4.d: Update expected output.
	* testsuite/gas/i386/dwarf4-line-1.d: Likewise.
	* testsuite/gas/i386/dwarf5-line-1.d: Likewise.
	* testsuite/gas/i386/dwarf5-line-2.d: Likewise.

diff --git a/gas/dwarf2dbg.c b/gas/dwarf2dbg.c
index 9e3437b8948..c6303ba94a6 100644
--- a/gas/dwarf2dbg.c
+++ b/gas/dwarf2dbg.c
@@ -207,7 +207,6 @@ struct file_entry
 static struct file_entry *files;
 static unsigned int files_in_use;
 static unsigned int files_allocated;
-static unsigned int num_of_auto_assigned;
 
 /* Table of directories used by .debug_line.  */
 static char **       dirs = NULL;
@@ -233,7 +232,7 @@ static struct dwarf2_line_info current =
 {
   1, 1, 0, 0,
   DWARF2_LINE_DEFAULT_IS_STMT ? DWARF2_FLAG_IS_STMT : 0,
-  0, NULL
+  0, { NULL }
 };
 
 /* This symbol is used to recognize view number forced resets in loc
@@ -342,7 +341,7 @@ set_or_check_view (struct line_entry *e, struct line_entry *p,
   /* First, compute !(E->label > P->label), to tell whether or not
      we're to reset the view number.  If we can't resolve it to a
      constant, keep it symbolic.  */
-  if (!p || (e->loc.view == force_reset_view && force_reset_view))
+  if (!p || (e->loc.u.view == force_reset_view && force_reset_view))
     {
       viewx.X_op = O_constant;
       viewx.X_add_number = 0;
@@ -367,9 +366,9 @@ set_or_check_view (struct line_entry *e, struct line_entry *p,
 	}
     }
 
-  if (S_IS_DEFINED (e->loc.view) && symbol_constant_p (e->loc.view))
+  if (S_IS_DEFINED (e->loc.u.view) && symbol_constant_p (e->loc.u.view))
     {
-      expressionS *value = symbol_get_value_expression (e->loc.view);
+      expressionS *value = symbol_get_value_expression (e->loc.u.view);
       /* We can't compare the view numbers at this point, because in
 	 VIEWX we've only determined whether we're to reset it so
 	 far.  */
@@ -404,16 +403,16 @@ set_or_check_view (struct line_entry *e, struct line_entry *p,
     {
       expressionS incv;
 
-      if (!p->loc.view)
+      if (!p->loc.u.view)
 	{
-	  p->loc.view = symbol_temp_make ();
-	  gas_assert (!S_IS_DEFINED (p->loc.view));
+	  p->loc.u.view = symbol_temp_make ();
+	  gas_assert (!S_IS_DEFINED (p->loc.u.view));
 	}
 
       memset (&incv, 0, sizeof (incv));
       incv.X_unsigned = 1;
       incv.X_op = O_symbol;
-      incv.X_add_symbol = p->loc.view;
+      incv.X_add_symbol = p->loc.u.view;
       incv.X_add_number = 1;
 
       if (viewx.X_op == O_constant)
@@ -430,16 +429,16 @@ set_or_check_view (struct line_entry *e, struct line_entry *p,
 	}
     }
 
-  if (!S_IS_DEFINED (e->loc.view))
+  if (!S_IS_DEFINED (e->loc.u.view))
     {
-      symbol_set_value_expression (e->loc.view, &viewx);
-      S_SET_SEGMENT (e->loc.view, expr_section);
-      symbol_set_frag (e->loc.view, &zero_address_frag);
+      symbol_set_value_expression (e->loc.u.view, &viewx);
+      S_SET_SEGMENT (e->loc.u.view, expr_section);
+      symbol_set_frag (e->loc.u.view, &zero_address_frag);
     }
 
   /* Define and attempt to simplify any earlier views needed to
      compute E's.  */
-  if (h && p && p->loc.view && !S_IS_DEFINED (p->loc.view))
+  if (h && p && p->loc.u.view && !S_IS_DEFINED (p->loc.u.view))
     {
       struct line_entry *h2;
       /* Reverse the list to avoid quadratic behavior going backwards
@@ -459,7 +458,9 @@ set_or_check_view (struct line_entry *e, struct line_entry *p,
 	    break;
 	  set_or_check_view (r, r->next, NULL);
 	}
-      while (r->next && r->next->loc.view && !S_IS_DEFINED (r->next->loc.view)
+      while (r->next
+	     && r->next->loc.u.view
+	     && !S_IS_DEFINED (r->next->loc.u.view)
 	     && (r = r->next));
 
       /* Unreverse the list, so that we can go forward again.  */
@@ -475,14 +476,14 @@ set_or_check_view (struct line_entry *e, struct line_entry *p,
 	     view of the previous subsegment.  */
 	  if (r == h)
 	    continue;
-	  gas_assert (S_IS_DEFINED (r->loc.view));
-	  resolve_expression (symbol_get_value_expression (r->loc.view));
+	  gas_assert (S_IS_DEFINED (r->loc.u.view));
+	  resolve_expression (symbol_get_value_expression (r->loc.u.view));
 	}
       while (r != p && (r = r->next));
 
       /* Now that we've defined and computed all earlier views that might
 	 be needed to compute E's, attempt to simplify it.  */
-      resolve_expression (symbol_get_value_expression (e->loc.view));
+      resolve_expression (symbol_get_value_expression (e->loc.u.view));
     }
 }
 
@@ -518,10 +519,8 @@ dwarf2_gen_line_info_1 (symbolS *label, struct dwarf2_line_info *loc)
 
   /* Subseg heads are chained to previous subsegs in
      dwarf2_finish.  */
-  if (loc->view && lss->head)
-    set_or_check_view (e,
-		       (struct line_entry *)lss->ptail,
-		       lss->head);
+  if (loc->filenum != -1u && loc->u.view && lss->head)
+    set_or_check_view (e, (struct line_entry *) lss->ptail, lss->head);
 
   *lss->ptail = e;
   lss->ptail = &e->next;
@@ -532,9 +531,6 @@ dwarf2_gen_line_info_1 (symbolS *label, struct dwarf2_line_info *loc)
 void
 dwarf2_gen_line_info (addressT ofs, struct dwarf2_line_info *loc)
 {
-  static unsigned int line = -1;
-  static unsigned int filenum = -1;
-
   symbolS *sym;
 
   /* Early out for as-yet incomplete location information.  */
@@ -552,20 +548,35 @@ dwarf2_gen_line_info (addressT ofs, struct dwarf2_line_info *loc)
      symbols apply to assembler code.  It is necessary to emit
      duplicate line symbols when a compiler asks for them, because GDB
      uses them to determine the end of the prologue.  */
-  if (debug_type == DEBUG_DWARF2
-      && line == loc->line && filenum == loc->filenum)
-    return;
+  if (debug_type == DEBUG_DWARF2)
+    {
+      static unsigned int line = -1;
+      static const char *filename = NULL;
+
+      if (line == loc->line)
+	{
+	  if (filename == loc->u.filename)
+	    return;
+	  if (filename_cmp (filename, loc->u.filename) == 0)
+	    {
+	      filename = loc->u.filename;
+	      return;
+	    }
+	}
 
-  line = loc->line;
-  filenum = loc->filenum;
+      line = loc->line;
+      filename = loc->u.filename;
+    }
 
   if (linkrelax)
     {
-      char name[120];
+      static int label_num = 0;
+      char name[32];
 
       /* Use a non-fake name for the line number location,
 	 so that it can be referred to by relocations.  */
-      sprintf (name, ".Loc.%u.%u", line, filenum);
+      sprintf (name, ".Loc.%u", label_num);
+      label_num++;
       sym = symbol_new (name, now_seg, frag_now, ofs);
     }
   else
@@ -624,13 +635,15 @@ get_directory_table_entry (const char *dirname,
 	{
 	  const char * pwd = file0_dirname ? file0_dirname : getpwd ();
 
-	  if (dwarf_level >= 5 && strcmp (dirname, pwd) != 0)
+	  if (dwarf_level >= 5 && filename_cmp (dirname, pwd) != 0)
 	    {
-	      /* In DWARF-5 the 0 entry in the directory table is expected to be
-		 the same as the DW_AT_comp_dir (which is set to the current build
-		 directory).  Since we are about to create a directory entry that
-		 is not the same, allocate the current directory first.
-		 FIXME: Alternatively we could generate an error message here.  */
+	      /* In DWARF-5 the 0 entry in the directory table is
+		 expected to be the same as the DW_AT_comp_dir (which
+		 is set to the current build directory).  Since we are
+		 about to create a directory entry that is not the
+		 same, allocate the current directory first.
+		 FIXME: Alternatively we could generate an error
+		 message here.  */
 	      (void) get_directory_table_entry (pwd, NULL, strlen (pwd),
 						true);
 	      d = 1;
@@ -745,14 +758,30 @@ allocate_filenum (const char * pathname)
   if (!assign_file_to_slot (i, file, dir))
     return -1;
 
-  num_of_auto_assigned++;
-
   last_used = i;
   last_used_dir_len = dir_len;
 
   return i;
 }
 
+/* Run through the list of line entries starting at E, allocating
+   file entries for gas generated debug.  */
+
+static void
+do_allocate_filenum (struct line_entry *e)
+{
+  do
+    {
+      if (e->loc.filenum == -1u)
+	{
+	  e->loc.filenum = allocate_filenum (e->loc.u.filename);
+	  e->loc.u.view = NULL;
+	}
+      e = e->next;
+    }
+  while (e);
+}
+
 /* Allocate slot NUM in the .debug_line file table to FILENAME.
    If DIRNAME is not NULL or there is a directory component to FILENAME
    then this will be stored in the directory table, if not already present.
@@ -929,17 +958,12 @@ dwarf2_where (struct dwarf2_line_info *line)
 {
   if (debug_type == DEBUG_DWARF2)
     {
-      const char *filename;
-
-      memset (line, 0, sizeof (*line));
-      filename = as_where (&line->line);
-      line->filenum = allocate_filenum (filename);
-      /* FIXME: We should check the return value from allocate_filenum.  */
+      line->u.filename = as_where (&line->line);
+      line->filenum = -1u;
       line->column = 0;
       line->flags = DWARF2_FLAG_IS_STMT;
       line->isa = current.isa;
       line->discriminator = current.discriminator;
-      line->view = NULL;
     }
   else
     *line = current;
@@ -1018,7 +1042,7 @@ dwarf2_consume_line_info (void)
 		     | DWARF2_FLAG_PROLOGUE_END
 		     | DWARF2_FLAG_EPILOGUE_BEGIN);
   current.discriminator = 0;
-  current.view = NULL;
+  current.u.view = NULL;
 }
 
 /* Called for each (preferably code) label.  If dwarf2_loc_mark_labels
@@ -1060,7 +1084,6 @@ dwarf2_directive_filename (void)
   char *filename;
   const char * dirname = NULL;
   int filename_len;
-  unsigned int i;
 
   /* Continue to accept a bare string and pass it off.  */
   SKIP_WHITESPACE ();
@@ -1132,18 +1155,6 @@ dwarf2_directive_filename (void)
       return NULL;
     }
 
-  if (num_of_auto_assigned)
-    {
-      /* Clear slots auto-assigned before the first .file <NUMBER>
-	 directive was seen.  */
-      if (files_in_use != (num_of_auto_assigned + 1))
-	abort ();
-      for (i = 1; i < files_in_use; i++)
-	files[i].filename = NULL;
-      files_in_use = 0;
-      num_of_auto_assigned = 0;
-    }
-
   if (! allocate_filename_to_slot (dirname, filename, (unsigned int) num,
 				   with_md5))
     return NULL;
@@ -1191,6 +1202,11 @@ dwarf2_directive_loc (int dummy ATTRIBUTE_UNUSED)
       return;
     }
 
+  /* debug_type will be turned off by dwarf2_directive_filename, and
+     if we don't have a dwarf style .file then files_in_use will be
+     zero and the above error will trigger.  */
+  gas_assert (debug_type == DEBUG_NONE);
+
   current.filenum = filenum;
   current.line = line;
   current.discriminator = 0;
@@ -1333,7 +1349,7 @@ dwarf2_directive_loc (int dummy ATTRIBUTE_UNUSED)
 	      S_SET_VALUE (sym, 0);
 	      symbol_set_frag (sym, &zero_address_frag);
 	    }
-	  current.view = sym;
+	  current.u.view = sym;
 	}
       else
 	{
@@ -1347,10 +1363,9 @@ dwarf2_directive_loc (int dummy ATTRIBUTE_UNUSED)
 
   demand_empty_rest_of_line ();
   dwarf2_any_loc_directive_seen = dwarf2_loc_directive_seen = true;
-  debug_type = DEBUG_NONE;
 
   /* If we were given a view id, emit the row right away.  */
-  if (current.view)
+  if (current.u.view)
     dwarf2_emit_insn (0);
 }
 
@@ -1984,7 +1999,7 @@ process_entries (segT seg, struct line_entry *e)
       frag_ofs = S_GET_VALUE (lab);
 
       if (last_frag == NULL
-	  || (e->loc.view == force_reset_view && force_reset_view
+	  || (e->loc.u.view == force_reset_view && force_reset_view
 	      /* If we're going to reset the view, but we know we're
 		 advancing the PC, we don't have to force with
 		 set_address.  We know we do when we're at the same
@@ -2850,16 +2865,19 @@ dwarf2_finish (void)
       struct line_subseg *lss = s->head;
       struct line_entry **ptail = lss->ptail;
 
+      if (lss->head && SEG_NORMAL (s->seg))
+	do_allocate_filenum (lss->head);
+
       /* Reset the initial view of the first subsection of the
 	 section.  */
-      if (lss->head && lss->head->loc.view)
+      if (lss->head && lss->head->loc.u.view)
 	set_or_check_view (lss->head, NULL, NULL);
 
       while ((lss = lss->next) != NULL)
 	{
 	  /* Link the first view of subsequent subsections to the
 	     previous view.  */
-	  if (lss->head && lss->head->loc.view)
+	  if (lss->head && lss->head->loc.u.view)
 	    set_or_check_view (lss->head,
 			       !s->head ? NULL : (struct line_entry *)ptail,
 			       s->head ? s->head->head : NULL);
diff --git a/gas/dwarf2dbg.h b/gas/dwarf2dbg.h
index 14d770c40dd..700d9dec5cb 100644
--- a/gas/dwarf2dbg.h
+++ b/gas/dwarf2dbg.h
@@ -36,7 +36,12 @@ struct dwarf2_line_info
   unsigned int isa;
   unsigned int flags;
   unsigned int discriminator;
-  symbolS *view;
+  /* filenum == -1u chooses filename, otherwise view.  */
+  union
+  {
+    symbolS *view;
+    const char *filename;
+  } u;
 };
 
 /* Implements the .file FILENO "FILENAME" directive.  FILENO can be 0
diff --git a/gas/testsuite/gas/i386/dwarf2-line-3.s b/gas/testsuite/gas/i386/dwarf2-line-3.s
index 2085ef93940..e933719fbc3 100644
--- a/gas/testsuite/gas/i386/dwarf2-line-3.s
+++ b/gas/testsuite/gas/i386/dwarf2-line-3.s
@@ -7,6 +7,7 @@
 main:
         .cfi_startproc
         nop
+	.file 1 "dwarf2-test.c"
 	.loc 1 1
         ret
         .cfi_endproc
diff --git a/gas/testsuite/gas/i386/dwarf2-line-4.d b/gas/testsuite/gas/i386/dwarf2-line-4.d
index c0c85f4639f..a01fd0540f3 100644
--- a/gas/testsuite/gas/i386/dwarf2-line-4.d
+++ b/gas/testsuite/gas/i386/dwarf2-line-4.d
@@ -33,11 +33,14 @@ Raw dump of debug contents of section \.z?debug_line:
 
  The File Name Table \(offset 0x.*\):
   Entry	Dir	Time	Size	Name
-  1	1	0	0	dwarf2-line-4.s
+  1	0	0	0	dwarf2-test.c
+  2	1	0	0	dwarf2-line-4.s
 
  Line Number Statements:
+  \[0x.*\]  Set File Name to entry 2 in the File Name Table
   \[0x.*\]  Extended opcode 2: set Address to 0x0
   \[0x.*\]  Special opcode 13: advance Address by 0 to 0x0 and Line by 8 to 9
+  \[0x.*\]  Set File Name to entry 1 in the File Name Table
   \[0x.*\]  Advance Line by -8 to 1
   \[0x.*\]  Special opcode 19: advance Address by 1 to 0x1 and Line by 0 to 1
   \[0x.*\]  Advance PC by 1 to 0x2
diff --git a/gas/testsuite/gas/i386/dwarf2-line-4.s b/gas/testsuite/gas/i386/dwarf2-line-4.s
index 89bb62d9db7..7348f4be62c 100644
--- a/gas/testsuite/gas/i386/dwarf2-line-4.s
+++ b/gas/testsuite/gas/i386/dwarf2-line-4.s
@@ -7,6 +7,7 @@
 main:
         .cfi_startproc
         nop
+	.file 1 "dwarf2-test.c"
 	.loc 1 1
         ret
         .cfi_endproc
diff --git a/gas/testsuite/gas/i386/dwarf4-line-1.d b/gas/testsuite/gas/i386/dwarf4-line-1.d
index 4f8321e9bfd..8199efbb0c2 100644
--- a/gas/testsuite/gas/i386/dwarf4-line-1.d
+++ b/gas/testsuite/gas/i386/dwarf4-line-1.d
@@ -36,12 +36,14 @@ Raw dump of debug contents of section \.z?debug_line:
   Entry	Dir	Time	Size	Name
   1	0	0	0	foo.c
   2	0	0	0	foo.h
+  3	1	0	0	dwarf4-line-1.s
 
  Line Number Statements:
+  \[0x.*\]  Set File Name to entry 2 in the File Name Table
   \[0x.*\]  Extended opcode 2: set Address to 0x0
   \[0x.*\]  Advance Line by 81 to 82
   \[0x.*\]  Copy
-  \[0x.*\]  Set File Name to entry 2 in the File Name Table
+  \[0x.*\]  Set File Name to entry 3 in the File Name Table
   \[0x.*\]  Advance Line by -73 to 9
   \[0x.*\]  Special opcode 19: advance Address by 1 to 0x1 and Line by 0 to 9
   \[0x.*\]  Advance PC by 3 to 0x4
diff --git a/gas/testsuite/gas/i386/dwarf5-line-1.d b/gas/testsuite/gas/i386/dwarf5-line-1.d
index f57fc47d269..2c2cf5696c4 100644
--- a/gas/testsuite/gas/i386/dwarf5-line-1.d
+++ b/gas/testsuite/gas/i386/dwarf5-line-1.d
@@ -36,12 +36,14 @@ Raw dump of debug contents of section \.z?debug_line:
   0	\(indirect line string, offset: 0x.*\): .*/gas/testsuite
   1	\(indirect line string, offset: 0x.*\): .*/gas/testsuite/gas/i386
 
- The File Name Table \(offset 0x.*, lines 2, columns 3\):
+ The File Name Table \(offset 0x.*, lines 3, columns 3\):
   Entry	Dir	MD5				Name
   0	0 0xbbd69fc03ce253b2dbaab2522dd519ae	\(indirect line string, offset: 0x.*\): core.c
   1	0 0x0	\(indirect line string, offset: 0x.*\): types.h
+  2	1 0x0	\(indirect line string, offset: 0x.*\): dwarf5-line-1.s
 
  Line Number Statements:
+  \[0x.*\]  Set File Name to entry 2 in the File Name Table
   \[0x.*\]  Extended opcode 2: set Address to 0x0
   \[0x.*\]  Special opcode 8: advance Address by 0 to 0x0 and Line by 3 to 4
   \[0x.*\]  Advance PC by 1 to 0x1
diff --git a/gas/testsuite/gas/i386/dwarf5-line-2.d b/gas/testsuite/gas/i386/dwarf5-line-2.d
index 2f96df510d0..85f98c8ab9c 100644
--- a/gas/testsuite/gas/i386/dwarf5-line-2.d
+++ b/gas/testsuite/gas/i386/dwarf5-line-2.d
@@ -36,9 +36,10 @@ Raw dump of debug contents of section \.z?debug_line:
   0	\(indirect line string, offset: 0x.*\): .*/gas/testsuite
   1	\(indirect line string, offset: 0x.*\): .*/gas/testsuite/gas/i386
 
- The File Name Table \(offset 0x.*, lines 1, columns 3\):
+ The File Name Table \(offset 0x.*, lines 2, columns 3\):
   Entry	Dir	MD5				Name
   0	0 0xbbd69fc03ce253b2dbaab2522dd519ae	\(indirect line string, offset: 0x.*\): core.c
+  1	1 0x0	\(indirect line string, offset: .*\): dwarf5-line-2.s
 
  Line Number Statements:
   \[0x.*\]  Extended opcode 2: set Address to 0x0

-- 
Alan Modra
Australia Development Lab, IBM

^ permalink raw reply	[flat|nested] 9+ messages in thread

* PR28149 part 2, purge generated line info
  2021-09-17  6:56 PR28149, debug info with wrong file association Alan Modra
@ 2021-09-17  7:05 ` Alan Modra
  2021-09-20  2:54   ` PR28149, debug info with wrong file association Alan Modra
  2021-09-17  7:25 ` Eric Botcazou
  1 sibling, 1 reply; 9+ messages in thread
From: Alan Modra @ 2021-09-17  7:05 UTC (permalink / raw)
  To: binutils

Mixing compiler generated line info with gas generated line info is
generally just confusing.  Also .loc directives with non-zero view
fields might reference a previous .loc.  It becomes a little more
tricky to locate that previous .loc if there might be gas generated
line info present too.  Mind you, we turn off gas generation of line
info on seeing compiler generated line info, so any reference back
won't hit gas generated line info.  At least, if the view info is
sane.  Unfortunately, gas needs to handle mangled source.

	PR 28149
	* dwarf2dbg.c (purge_generated_debug): New function.
	(dwarf2_directive_filename): Call the above.
	(out_debug_line): Don't segfault after purging.
	* testsuite/gas/i386/dwarf2-line-4.d: Update expected output.
	* testsuite/gas/i386/dwarf4-line-1.d: Likewise.
	* testsuite/gas/i386/dwarf5-line-1.d: Likewise.
	* testsuite/gas/i386/dwarf5-line-2.d: Likewise.

diff --git a/gas/dwarf2dbg.c b/gas/dwarf2dbg.c
index c6303ba94a6..1250fcef54f 100644
--- a/gas/dwarf2dbg.c
+++ b/gas/dwarf2dbg.c
@@ -782,6 +782,32 @@ do_allocate_filenum (struct line_entry *e)
   while (e);
 }
 
+/* Remove any generated line entries.  These don't live comfortably
+   with compiler generated line info.  */
+
+static void
+purge_generated_debug (void)
+{
+  struct line_seg *s;
+
+  for (s = all_segs; s; s = s->next)
+    {
+      struct line_subseg *lss = s->head;
+      struct line_entry *e, *next;
+
+      for (e = lss->head; e; e = next)
+	{
+	  know (e->loc.filenum == -1u);
+	  next = e->next;
+	  free (e);
+	}
+
+      lss->head = NULL;
+      lss->ptail = &lss->head;
+      lss->pmove_tail = &lss->head;
+    }
+}
+
 /* Allocate slot NUM in the .debug_line file table to FILENAME.
    If DIRNAME is not NULL or there is a directory component to FILENAME
    then this will be stored in the directory table, if not already present.
@@ -1146,6 +1172,8 @@ dwarf2_directive_filename (void)
 
   /* A .file directive implies compiler generated debug information is
      being supplied.  Turn off gas generated debug info.  */
+  if (debug_type == DEBUG_DWARF2)
+    purge_generated_debug ();
   debug_type = DEBUG_NONE;
 
   if (num != (unsigned int) num
@@ -2414,7 +2442,7 @@ out_debug_line (segT line_seg)
   for (s = all_segs; s; s = s->next)
     /* Paranoia - this check should have already have
        been handled in dwarf2_gen_line_info_1().  */
-    if (SEG_NORMAL (s->seg))
+    if (s->head->head && SEG_NORMAL (s->seg))
       process_entries (s->seg, s->head->head);
 
   if (flag_dwarf_sections)
diff --git a/gas/testsuite/gas/i386/dwarf2-line-4.d b/gas/testsuite/gas/i386/dwarf2-line-4.d
index a01fd0540f3..0403c3e2faf 100644
--- a/gas/testsuite/gas/i386/dwarf2-line-4.d
+++ b/gas/testsuite/gas/i386/dwarf2-line-4.d
@@ -28,21 +28,15 @@ Raw dump of debug contents of section \.z?debug_line:
   Opcode 11 has 0 args
   Opcode 12 has 1 arg
 
- The Directory Table \(offset 0x.*\):
-  .*
+ The Directory Table is empty\.
 
  The File Name Table \(offset 0x.*\):
   Entry	Dir	Time	Size	Name
   1	0	0	0	dwarf2-test.c
-  2	1	0	0	dwarf2-line-4.s
 
  Line Number Statements:
-  \[0x.*\]  Set File Name to entry 2 in the File Name Table
-  \[0x.*\]  Extended opcode 2: set Address to 0x0
-  \[0x.*\]  Special opcode 13: advance Address by 0 to 0x0 and Line by 8 to 9
-  \[0x.*\]  Set File Name to entry 1 in the File Name Table
-  \[0x.*\]  Advance Line by -8 to 1
-  \[0x.*\]  Special opcode 19: advance Address by 1 to 0x1 and Line by 0 to 1
+  \[0x.*\]  Extended opcode 2: set Address to 0x1
+  \[0x.*\]  Copy
   \[0x.*\]  Advance PC by 1 to 0x2
   \[0x.*\]  Extended opcode 1: End of Sequence
 
diff --git a/gas/testsuite/gas/i386/dwarf4-line-1.d b/gas/testsuite/gas/i386/dwarf4-line-1.d
index 8199efbb0c2..762bdce9934 100644
--- a/gas/testsuite/gas/i386/dwarf4-line-1.d
+++ b/gas/testsuite/gas/i386/dwarf4-line-1.d
@@ -29,24 +29,11 @@ Raw dump of debug contents of section \.z?debug_line:
   Opcode 11 has 0 args
   Opcode 12 has 1 arg
 
- The Directory Table \(offset 0x.*\):
-  1	.*/gas/testsuite/gas/i386
+ The Directory Table is empty\.
 
  The File Name Table \(offset 0x.*\):
   Entry	Dir	Time	Size	Name
   1	0	0	0	foo.c
   2	0	0	0	foo.h
-  3	1	0	0	dwarf4-line-1.s
-
- Line Number Statements:
-  \[0x.*\]  Set File Name to entry 2 in the File Name Table
-  \[0x.*\]  Extended opcode 2: set Address to 0x0
-  \[0x.*\]  Advance Line by 81 to 82
-  \[0x.*\]  Copy
-  \[0x.*\]  Set File Name to entry 3 in the File Name Table
-  \[0x.*\]  Advance Line by -73 to 9
-  \[0x.*\]  Special opcode 19: advance Address by 1 to 0x1 and Line by 0 to 9
-  \[0x.*\]  Advance PC by 3 to 0x4
-  \[0x.*\]  Extended opcode 1: End of Sequence
-
 
+ No Line Number Statements\.
diff --git a/gas/testsuite/gas/i386/dwarf5-line-1.d b/gas/testsuite/gas/i386/dwarf5-line-1.d
index 2c2cf5696c4..6ec51912dd1 100644
--- a/gas/testsuite/gas/i386/dwarf5-line-1.d
+++ b/gas/testsuite/gas/i386/dwarf5-line-1.d
@@ -31,22 +31,13 @@ Raw dump of debug contents of section \.z?debug_line:
   Opcode 11 has 0 args
   Opcode 12 has 1 arg
 
- The Directory Table \(offset 0x.*, lines 2, columns 1\):
+ The Directory Table \(offset 0x.*, lines 1, columns 1\):
   Entry	Name
   0	\(indirect line string, offset: 0x.*\): .*/gas/testsuite
-  1	\(indirect line string, offset: 0x.*\): .*/gas/testsuite/gas/i386
 
- The File Name Table \(offset 0x.*, lines 3, columns 3\):
+ The File Name Table \(offset 0x.*, lines 2, columns 3\):
   Entry	Dir	MD5				Name
   0	0 0xbbd69fc03ce253b2dbaab2522dd519ae	\(indirect line string, offset: 0x.*\): core.c
   1	0 0x0	\(indirect line string, offset: 0x.*\): types.h
-  2	1 0x0	\(indirect line string, offset: 0x.*\): dwarf5-line-1.s
-
- Line Number Statements:
-  \[0x.*\]  Set File Name to entry 2 in the File Name Table
-  \[0x.*\]  Extended opcode 2: set Address to 0x0
-  \[0x.*\]  Special opcode 8: advance Address by 0 to 0x0 and Line by 3 to 4
-  \[0x.*\]  Advance PC by 1 to 0x1
-  \[0x.*\]  Extended opcode 1: End of Sequence
-
 
+ No Line Number Statements\.
diff --git a/gas/testsuite/gas/i386/dwarf5-line-2.d b/gas/testsuite/gas/i386/dwarf5-line-2.d
index 85f98c8ab9c..4bb849bba34 100644
--- a/gas/testsuite/gas/i386/dwarf5-line-2.d
+++ b/gas/testsuite/gas/i386/dwarf5-line-2.d
@@ -31,20 +31,12 @@ Raw dump of debug contents of section \.z?debug_line:
   Opcode 11 has 0 args
   Opcode 12 has 1 arg
 
- The Directory Table \(offset 0x.*, lines 2, columns 1\):
+ The Directory Table \(offset 0x.*, lines 1, columns 1\):
   Entry	Name
   0	\(indirect line string, offset: 0x.*\): .*/gas/testsuite
-  1	\(indirect line string, offset: 0x.*\): .*/gas/testsuite/gas/i386
 
- The File Name Table \(offset 0x.*, lines 2, columns 3\):
+ The File Name Table \(offset 0x.*, lines 1, columns 3\):
   Entry	Dir	MD5				Name
   0	0 0xbbd69fc03ce253b2dbaab2522dd519ae	\(indirect line string, offset: 0x.*\): core.c
-  1	1 0x0	\(indirect line string, offset: .*\): dwarf5-line-2.s
-
- Line Number Statements:
-  \[0x.*\]  Extended opcode 2: set Address to 0x0
-  \[0x.*\]  Special opcode 8: advance Address by 0 to 0x0 and Line by 3 to 4
-  \[0x.*\]  Advance PC by 1 to 0x1
-  \[0x.*\]  Extended opcode 1: End of Sequence
-
 
+ No Line Number Statements\.

-- 
Alan Modra
Australia Development Lab, IBM

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: PR28149, debug info with wrong file association
  2021-09-17  6:56 PR28149, debug info with wrong file association Alan Modra
  2021-09-17  7:05 ` PR28149 part 2, purge generated line info Alan Modra
@ 2021-09-17  7:25 ` Eric Botcazou
  2021-09-17  8:32   ` Alan Modra
  1 sibling, 1 reply; 9+ messages in thread
From: Eric Botcazou @ 2021-09-17  7:25 UTC (permalink / raw)
  To: Alan Modra; +Cc: binutils

> gcc-11 and gcc-12 pass -gdwarf-5 to gas, in order to prime gas for
> DWARF 5 level debug info.  Unfortunately it seems there are cases
> where the compiler does not emit a .file or .loc dwarf debug directive
> before any machine instructions.  (Note that the .file directive
> typically emitted as the first line of assembly output doesn't count as
> a dwarf debug directive.  The dwarf .file has a file number before the
> file name string.)

That"s no longer true in DWARF 5, as there is always a .file 0 directive now.

-- 
Eric Botcazou



^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: PR28149, debug info with wrong file association
  2021-09-17  7:25 ` Eric Botcazou
@ 2021-09-17  8:32   ` Alan Modra
  2021-09-17  8:49     ` Eric Botcazou
  0 siblings, 1 reply; 9+ messages in thread
From: Alan Modra @ 2021-09-17  8:32 UTC (permalink / raw)
  To: Eric Botcazou; +Cc: binutils

On Fri, Sep 17, 2021 at 09:25:33AM +0200, Eric Botcazou wrote:
> > gcc-11 and gcc-12 pass -gdwarf-5 to gas, in order to prime gas for
> > DWARF 5 level debug info.  Unfortunately it seems there are cases
> > where the compiler does not emit a .file or .loc dwarf debug directive
> > before any machine instructions.  (Note that the .file directive
> > typically emitted as the first line of assembly output doesn't count as
> > a dwarf debug directive.  The dwarf .file has a file number before the
> > file name string.)
> 
> That"s no longer true in DWARF 5, as there is always a .file 0 directive now.

I did check before making that statement.  :-)

A freshly built x86_64-linux mainline gcc compiling this testcase

asm("nop");
int main () 
{
  return 0;
}

~/build/gcc/gcc/xgcc -B ~/build/gcc/gcc/ -g pr28149.c -v -save-temps
shows the assembler being invoked with --gdwarf-5 on the following

	.file	"pr28149.c"
	.text
.Ltext0:
#APP
	nop
#NO_APP
	.globl	main
	.type	main, @function
main:
.LFB0:
	.file 1 "pr28149.c"
	.loc 1 3 1
	.cfi_startproc
[snip rest]

So we have an instruction being emitted before gas generated line info
is turned off at ".file 1 ...".

-- 
Alan Modra
Australia Development Lab, IBM

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: PR28149, debug info with wrong file association
  2021-09-17  8:32   ` Alan Modra
@ 2021-09-17  8:49     ` Eric Botcazou
  2021-09-17  9:02       ` Alan Modra
  0 siblings, 1 reply; 9+ messages in thread
From: Eric Botcazou @ 2021-09-17  8:49 UTC (permalink / raw)
  To: Alan Modra; +Cc: binutils

> A freshly built x86_64-linux mainline gcc compiling this testcase
> 
> asm("nop");
> int main ()
> {
>   return 0;
> }
> 
> ~/build/gcc/gcc/xgcc -B ~/build/gcc/gcc/ -g pr28149.c -v -save-temps
> shows the assembler being invoked with --gdwarf-5 on the following

Your compiler does not seem to be properly configured, here's mine:

	.file	"pr28149.c"
	.text
.Ltext0:
	.file 0 "/home/eric/build/gcc/native" "pr28149.c"
#APP
	nop
#NO_APP
	.globl	main
	.type	main, @function
main:
.LFB0:
	.file 1 "pr28149.c"
	.loc 1 3 1
	.cfi_startproc

Note that there is a fair amount of configury involved on the compiler side to 
detect various binutils quirks:

#if defined(HAVE_AS_GDWARF_5_DEBUG_FLAG) && 
defined(HAVE_AS_WORKING_DWARF_N_FLAG)
  if (output_asm_line_debug_info () && dwarf_version >= 5)

so the assembler must really be detected at configure time.

-- 
Eric Botcazou



^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: PR28149, debug info with wrong file association
  2021-09-17  8:49     ` Eric Botcazou
@ 2021-09-17  9:02       ` Alan Modra
  2021-09-17  9:16         ` Eric Botcazou
  0 siblings, 1 reply; 9+ messages in thread
From: Alan Modra @ 2021-09-17  9:02 UTC (permalink / raw)
  To: Eric Botcazou; +Cc: binutils

On Fri, Sep 17, 2021 at 10:49:20AM +0200, Eric Botcazou wrote:
> > A freshly built x86_64-linux mainline gcc compiling this testcase
> > 
> > asm("nop");
> > int main ()
> > {
> >   return 0;
> > }
> > 
> > ~/build/gcc/gcc/xgcc -B ~/build/gcc/gcc/ -g pr28149.c -v -save-temps
> > shows the assembler being invoked with --gdwarf-5 on the following
> 
> Your compiler does not seem to be properly configured, here's mine:

I'm sorry, I see I had a mainline gcc built from older sources..
Today's build was commit a6aa2458a92f from the top of the gcc-11
branch.  That one does show the problem.  I'll build a fresh gcc from
mainline which will no doubt behave as you say.

-- 
Alan Modra
Australia Development Lab, IBM

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: PR28149, debug info with wrong file association
  2021-09-17  9:02       ` Alan Modra
@ 2021-09-17  9:16         ` Eric Botcazou
  2021-09-17 11:16           ` Alan Modra
  0 siblings, 1 reply; 9+ messages in thread
From: Eric Botcazou @ 2021-09-17  9:16 UTC (permalink / raw)
  To: Alan Modra; +Cc: binutils

> I'm sorry, I see I had a mainline gcc built from older sources..
> Today's build was commit a6aa2458a92f from the top of the gcc-11
> branch.  That one does show the problem.

No, it should generate the same directive:

	.file	"pr28149.c"
	.text
.Ltext0:
	.file 0 "/home/eric/build/gcc/native" "pr28149.c"
#APP
	nop
#NO_APP
	.globl	main
	.type	main, @function
main:
.LFB0:
	.file 1 "pr28149.c"
	.loc 1 3 1
[...]
	.string	"pr28149.c"
	.ident	"GCC: (GNU) 11.2.1 20210903"
	.section	.note.GNU-stack,"",@progbits

and the fix is present in the 11.2 release:

2021-06-24  Eric Botcazou  <ebotcazou@adacore.com>

	* dwarf2out.c (dwarf2out_assembly_start): Emit .file 0 marker here..
	(dwarf2out_finish): ...instead of here.

-- 
Eric Botcazou



^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: PR28149, debug info with wrong file association
  2021-09-17  9:16         ` Eric Botcazou
@ 2021-09-17 11:16           ` Alan Modra
  0 siblings, 0 replies; 9+ messages in thread
From: Alan Modra @ 2021-09-17 11:16 UTC (permalink / raw)
  To: Eric Botcazou; +Cc: binutils

On Fri, Sep 17, 2021 at 11:16:38AM +0200, Eric Botcazou wrote:
> > I'm sorry, I see I had a mainline gcc built from older sources..
> > Today's build was commit a6aa2458a92f from the top of the gcc-11
> > branch.  That one does show the problem.
> 
> No, it should generate the same directive:

Huh.  I was tricked.  The gcc-11 command line I showed was exactly
what I ran, without what I'd normally add, -o pr28149.  So a.out
output.  Under those circumstances it seems gcc writes temp files to
a-pr28149.*, and I looked at the old pr28149.s.

Eh well, I may not have made the gas dwarf cleanup if I'd known the
problem was fixed already by gcc changes..

-- 
Alan Modra
Australia Development Lab, IBM

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: PR28149, debug info with wrong file association
  2021-09-17  7:05 ` PR28149 part 2, purge generated line info Alan Modra
@ 2021-09-20  2:54   ` Alan Modra
  0 siblings, 0 replies; 9+ messages in thread
From: Alan Modra @ 2021-09-20  2:54 UTC (permalink / raw)
  To: binutils

Linaro TCWG CI sent me a love letter.  :)

Fixes segfaults when building aarch64-linux kernel, due to only doing
part of the work necessary when allocating file numbers late.  I'd
missed looping over subsegments, which resulted in some u.filename
entries left around and later interpreted as u.view.

	PR 28149
	* dwarf2dbg.c (purge_generated_debug): Iterate over subsegs too.
	(dwarf2_finish): Call do_allocate_filenum for all subsegs too,
	in a separate loop before subsegs are chained.

diff --git a/gas/dwarf2dbg.c b/gas/dwarf2dbg.c
index 1250fcef54f..e2abe19c88a 100644
--- a/gas/dwarf2dbg.c
+++ b/gas/dwarf2dbg.c
@@ -792,19 +792,23 @@ purge_generated_debug (void)
 
   for (s = all_segs; s; s = s->next)
     {
-      struct line_subseg *lss = s->head;
-      struct line_entry *e, *next;
+      struct line_subseg *lss;
 
-      for (e = lss->head; e; e = next)
+      for (lss = s->head; lss; lss = lss->next)
 	{
-	  know (e->loc.filenum == -1u);
-	  next = e->next;
-	  free (e);
-	}
+	  struct line_entry *e, *next;
+
+	  for (e = lss->head; e; e = next)
+	    {
+	      know (e->loc.filenum == -1u);
+	      next = e->next;
+	      free (e);
+	    }
 
-      lss->head = NULL;
-      lss->ptail = &lss->head;
-      lss->pmove_tail = &lss->head;
+	  lss->head = NULL;
+	  lss->ptail = &lss->head;
+	  lss->pmove_tail = &lss->head;
+	}
     }
 }
 
@@ -2887,15 +2891,21 @@ dwarf2_finish (void)
 			     SEC_READONLY | SEC_DEBUGGING | SEC_OCTETS);
     }
 
+  for (s = all_segs; s; s = s->next)
+    {
+      struct line_subseg *lss;
+
+      for (lss = s->head; lss; lss = lss->next)
+	if (lss->head)
+	  do_allocate_filenum (lss->head);
+    }
+
   /* For each subsection, chain the debug entries together.  */
   for (s = all_segs; s; s = s->next)
     {
       struct line_subseg *lss = s->head;
       struct line_entry **ptail = lss->ptail;
 
-      if (lss->head && SEG_NORMAL (s->seg))
-	do_allocate_filenum (lss->head);
-
       /* Reset the initial view of the first subsection of the
 	 section.  */
       if (lss->head && lss->head->loc.u.view)

-- 
Alan Modra
Australia Development Lab, IBM

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2021-09-20  2:54 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-09-17  6:56 PR28149, debug info with wrong file association Alan Modra
2021-09-17  7:05 ` PR28149 part 2, purge generated line info Alan Modra
2021-09-20  2:54   ` PR28149, debug info with wrong file association Alan Modra
2021-09-17  7:25 ` Eric Botcazou
2021-09-17  8:32   ` Alan Modra
2021-09-17  8:49     ` Eric Botcazou
2021-09-17  9:02       ` Alan Modra
2021-09-17  9:16         ` Eric Botcazou
2021-09-17 11:16           ` Alan Modra

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).