Hi,

On Tue, 2020-09-15 at 20:40 +0200, Jakub Jelinek wrote:
> Ok, here it is in patch form.
> I've briefly tested it, with the older binutils I have around (no --gdwarf-N
> support), with latest gas (--gdwarf-N that can be passed to as even when
> compiling C/C++ etc. code and emitting .debug_line) and latest gas with 
> Mark's fix
> reverted (--gdwarf-N support, but can only pass it to as when assembling
> user .s/.S files, not when compiling C/C++ etc.).
> Will bootstrap/regtest (with the older binutils) later tonight.
> 
> 2020-09-15  Jakub Jelinek  <ja...@redhat.com>
> 
>       * configure.ac (HAVE_AS_GDWARF_5_DEBUG_FLAG,
>       HAVE_AS_WORKING_DWARF_4_FLAG): New tests.
>       * gcc.c (ASM_DEBUG_DWARF_OPTION): Define.
>       (ASM_DEBUG_SPEC): Use ASM_DEBUG_DWARF_OPTION instead of
>       "--gdwarf2".  Use %{cond:opt1;:opt2} style.
>       (ASM_DEBUG_OPTION_DWARF_OPT): Define.
>       (ASM_DEBUG_OPTION_SPEC): Define.
>       (asm_debug_option): New variable.
>       (asm_options): Add "%(asm_debug_option)".
>       (static_specs): Add asm_debug_option entry.
>       (static_spec_functions): Add dwarf-version-gt.
>       (debug_level_greater_than_spec_func): New function.
>       * config/darwin.h (ASM_DEBUG_OPTION_SPEC): Define.
>       * config/darwin9.h (ASM_DEBUG_OPTION_SPEC): Redefine.
>       * config.in: Regenerated.
>       * configure: Regenerated.

Once this is in we can more generally emit DW_FORM_line_str for
filepaths in CU DIEs for the name and comp_dir attribute. There
currently is a bit of a hack to do this in dwarf2out_early_finish, but
that only works when the assembler doesn't emit a DWARF5 .debug_line,
but gcc does it itself.

What do you think of the attached patch?
From c31667db57de62c3107a0b2a5e30fbd57a4708a3 Mon Sep 17 00:00:00 2001
From: Mark Wielaard <m...@klomp.org>
Date: Fri, 18 Sep 2020 17:07:03 +0200
Subject: [PATCH] Output filepath strings in .debug_line_str for DWARF5

DWARF5 has a new string table specially for file paths. .debug_line
file and dir tables reference strings in .debug_line_str.  If a
.debug_line_str section is emitted then also place CU DIE file
names and comp dirs there.

gcc/ChangeLog:

	* dwarf2out.c (add_filepath_AT_string): New function.
	(asm_outputs_debug_line_str): Likewise.
	(add_filename_attribute): Likewise.
	(add_comp_dir_attribute): Call add_filepath_AT_string.
	(gen_compile_unit_die): Call add_filename_attribute for name.
	(init_sections_and_labels): Init debug_line_str_section when
	asm_outputs_debug_line_str return true.
	(dwarf2out_early_finish): Remove DW_AT_name and DW_AT_comp_dir
	hack and call add_filename_attribute for the remap_debug_filename.
---
 gcc/dwarf2out.c | 96 ++++++++++++++++++++++++++++++++-----------------
 1 file changed, 64 insertions(+), 32 deletions(-)

diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index 4096c0c0d69f..a43082864a75 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -3347,6 +3347,8 @@ output_asm_line_debug_info (void)
 	      || !debug_variable_location_views));
 }
 
+static bool asm_outputs_debug_line_str (void);
+
 /* Minimum line offset in a special line info. opcode.
    This value was chosen to give a reasonable range of values.  */
 #define DWARF_LINE_BASE  -10
@@ -4731,6 +4733,33 @@ reset_indirect_string (indirect_string_node **h, void *)
   return 1;
 }
 
+static inline void
+add_filepath_AT_string (dw_die_ref die, enum dwarf_attribute attr_kind,
+			const char *str)
+{
+  if (! asm_outputs_debug_line_str ())
+    add_AT_string (die, attr_kind, str);
+  else
+    {
+      dw_attr_node attr;
+      struct indirect_string_node *node;
+
+      if (!debug_line_str_hash)
+	debug_line_str_hash
+	  = hash_table<indirect_string_hasher>::create_ggc (10);
+
+      node = find_AT_string_in_table (str, debug_line_str_hash);
+      set_indirect_string (node);
+      node->form = DW_FORM_line_strp;
+
+      attr.dw_attr = attr_kind;
+      attr.dw_attr_val.val_class = dw_val_class_str;
+      attr.dw_attr_val.val_entry = NULL;
+      attr.dw_attr_val.v.val_str = node;
+      add_dwarf_attr (die, &attr);
+    }
+}
+
 /* Find out whether a string should be output inline in DIE
    or out-of-line in .debug_str section.  */
 
@@ -11839,6 +11868,29 @@ output_ranges (void)
       for -gsplit-dwarf we should use DW_FORM_strx instead.  */	\
    && !dwarf_split_debug_info)
 
+
+/* Returns TRUE if we are outputting DWARF5 and the assembler supports
+   DWARF5 .debug_line tables using .debug_line_str or we generate
+   it ourselves, except for split-dwarf which doesn't have a
+   .debug_line_str.  */
+static bool
+asm_outputs_debug_line_str (void)
+{
+  if (dwarf_version >= 5
+      && ! output_asm_line_debug_info ()
+      && DWARF5_USE_DEBUG_LINE_STR)
+    return true;
+  else
+    {
+#if defined(HAVE_AS_GDWARF_5_DEBUG_FLAG) && defined(HAVE_AS_WORKING_DWARF_4_FLAG)
+      return !dwarf_split_debug_info && dwarf_version >= 5;
+#else
+      return false;
+#endif
+    }
+}
+
+
 /* Assign .debug_rnglists indexes.  */
 
 static void
@@ -20514,6 +20566,13 @@ add_name_attribute (dw_die_ref die, const char *name_string)
     }
 }
 
+static void
+add_filename_attribute (dw_die_ref die, const char *name_string)
+{
+  if (name_string != NULL && *name_string != 0)
+    add_filepath_AT_string (die, DW_AT_name, name_string);
+}
+
 /* Generate a DW_AT_description attribute given some string value to be included
    as the value of the attribute.  */
 
@@ -20640,7 +20699,7 @@ add_comp_dir_attribute (dw_die_ref die)
 {
   const char * wd = comp_dir_string ();
   if (wd != NULL)
-    add_AT_string (die, DW_AT_comp_dir, wd);
+    add_filepath_AT_string (die, DW_AT_comp_dir, wd);
 }
 
 /* Given a tree node VALUE describing a scalar attribute ATTR (i.e. a bound, a
@@ -24482,7 +24541,7 @@ gen_compile_unit_die (const char *filename)
 
   if (filename)
     {
-      add_name_attribute (die, filename);
+      add_filename_attribute (die, filename);
       /* Don't add cwd for <built-in>.  */
       if (filename[0] != '<')
 	add_comp_dir_attribute (die);
@@ -28733,7 +28792,8 @@ init_sections_and_labels (bool early_lto_debug)
 					    SECTION_DEBUG, NULL);
       debug_str_section = get_section (DEBUG_STR_SECTION,
 				       DEBUG_STR_SECTION_FLAGS, NULL);
-      if (!dwarf_split_debug_info && !output_asm_line_debug_info ())
+      if ((!dwarf_split_debug_info && !output_asm_line_debug_info ())
+	  || asm_outputs_debug_line_str ())
 	debug_line_str_section = get_section (DEBUG_LINE_STR_SECTION,
 					      DEBUG_STR_SECTION_FLAGS, NULL);
 
@@ -32020,37 +32080,9 @@ dwarf2out_early_finish (const char *filename)
 
   /* Add the name for the main input file now.  We delayed this from
      dwarf2out_init to avoid complications with PCH.  */
-  add_name_attribute (comp_unit_die (), remap_debug_filename (filename));
+  add_filename_attribute (comp_unit_die (), remap_debug_filename (filename));
   add_comp_dir_attribute (comp_unit_die ());
 
-  /* When emitting DWARF5 .debug_line_str, move DW_AT_name and
-     DW_AT_comp_dir into .debug_line_str section.  */
-  if (!output_asm_line_debug_info ()
-      && dwarf_version >= 5
-      && DWARF5_USE_DEBUG_LINE_STR)
-    {
-      for (int i = 0; i < 2; i++)
-	{
-	  dw_attr_node *a = get_AT (comp_unit_die (),
-				    i ? DW_AT_comp_dir : DW_AT_name);
-	  if (a == NULL
-	      || AT_class (a) != dw_val_class_str
-	      || strlen (AT_string (a)) + 1 <= DWARF_OFFSET_SIZE)
-	    continue;
-
-	  if (! debug_line_str_hash)
-	    debug_line_str_hash
-	      = hash_table<indirect_string_hasher>::create_ggc (10);
-
-	  struct indirect_string_node *node
-	    = find_AT_string_in_table (AT_string (a), debug_line_str_hash);
-	  set_indirect_string (node);
-	  node->form = DW_FORM_line_strp;
-	  a->dw_attr_val.v.val_str->refcount--;
-	  a->dw_attr_val.v.val_str = node;
-	}
-    }
-
   /* With LTO early dwarf was really finished at compile-time, so make
      sure to adjust the phase after annotating the LTRANS CU DIE.  */
   if (in_lto_p)
-- 
2.18.4

Reply via email to