diff mbox

DWARF5 .debug_info headers, .debug_types -> .debug_info DW_UT_type

Message ID 20161021193242.GS7282@tucnak.redhat.com
State New
Headers show

Commit Message

Jakub Jelinek Oct. 21, 2016, 7:32 p.m. UTC
Hi!

This patch changes the .debug_info headers to follow the current
specification (I still hope the useless padding1/padding2 fields will be
removed), and also changes the -gsplit-dwarf stuff to move dwo_id into
the header and use DW_UT_{skeleton,split_*}.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2016-10-21  Jakub Jelinek  <jakub@redhat.com>

	* dwarf2out.c (dwarf_AT): Handle DW_AT_dwo_name.
	(use_debug_types): Adjust comment for DWARF5 DW_UT_type units.
	(new_die): Handle DW_TAG_skeleton_unit like DW_TAG_compile_unit.
	(is_cu_die, is_unit_die): Likewise.
	(should_move_die_to_comdat, break_out_comdat_types): Adjust
	comments for DWARF5 DW_UT_type units.
	(output_compilation_unit_header): Add UT argument, output
	start of DWARF5 .debug_info section header.
	(output_comp_unit): Add dwo_id argument.  Adjust
	output_compilation_unit_header caller, for DW_UT_split_compile
	emit dwo_id field, otherwise padding1.  Emit padding2 field.
	(add_top_level_skeleton_die_attrs): Add DW_AT_dwo_name
	rather than DW_AT_GNU_dwo_name attr for -gdwarf-5.
	(output_skeleton_debug_sections): Add dwo_id argument, for
	-gdwarf-5 emit DWARF 5 DW_UT_skeleton header.
	(output_comdat_type_unit): For -gdwarf-5 emit .debug_info
	DW_UT_type or DW_UT_split_type units rather than .debug_types.
	(dwarf2out_finish): Use DW_TAG_skeleton_unit rather than
	DW_TAG_compile_unit for skeleton unit die.  Don't add
	DW_AT_GNU_dwo_id attributes for -gdwarf-5, instead pass checksum
	address to output_comp_unit and output_skeleton_debug_sections.


	Jakub
diff mbox

Patch

--- gcc/dwarf2out.c.jj	2016-10-21 18:10:55.380302806 +0200
+++ gcc/dwarf2out.c	2016-10-21 18:40:34.433237109 +0200
@@ -1634,6 +1634,11 @@  dwarf_AT (enum dwarf_attribute at)
 	return DW_AT_GNU_all_tail_call_sites;
       break;
 
+    case DW_AT_dwo_name:
+      if (dwarf_version < 5)
+	return DW_AT_GNU_dwo_name;
+      break;
+
     default:
       break;
     }
@@ -2758,7 +2763,8 @@  const struct gcc_debug_hooks dwarf2_line
    -fno-debug-types-section.  It is more efficient to put them in a
    separate comdat sections since the linker will then be able to
    remove duplicates.  But not all tools support .debug_types sections
-   yet.  */
+   yet.  For Dwarf V5 or higher .debug_types doesn't exist any more,
+   it is DW_UT_type unit type in .debug_info section.  */
 
 #define use_debug_types (dwarf_version >= 4 && flag_debug_types_section)
 
@@ -3422,8 +3428,8 @@  static void output_abbrev_section (void)
 static void output_die_abbrevs (unsigned long, dw_die_ref);
 static void output_die_symbol (dw_die_ref);
 static void output_die (dw_die_ref);
-static void output_compilation_unit_header (void);
-static void output_comp_unit (dw_die_ref, int);
+static void output_compilation_unit_header (enum dwarf_unit_type);
+static void output_comp_unit (dw_die_ref, int, const unsigned char *);
 static void output_comdat_type_unit (comdat_type_node *);
 static const char *dwarf2_name (tree, int);
 static void add_pubname (tree, dw_die_ref);
@@ -5229,6 +5235,7 @@  new_die (enum dwarf_tag tag_value, dw_di
 	  /* These are allowed because they're generated while
 	     breaking out COMDAT units late.  */
 	  && tag_value != DW_TAG_type_unit
+	  && tag_value != DW_TAG_skeleton_unit
 	  && !early_dwarf
 	  /* Allow nested functions to live in limbo because they will
 	     only temporarily live there, as decls_for_scope will fix
@@ -7257,7 +7264,8 @@  is_symbol_die (dw_die_ref c)
 static inline bool
 is_cu_die (dw_die_ref c)
 {
-  return c && c->die_tag == DW_TAG_compile_unit;
+  return c && (c->die_tag == DW_TAG_compile_unit
+	       || c->die_tag == DW_TAG_skeleton_unit);
 }
 
 /* Returns true iff C is a unit DIE of some sort.  */
@@ -7267,7 +7275,8 @@  is_unit_die (dw_die_ref c)
 {
   return c && (c->die_tag == DW_TAG_compile_unit
 	       || c->die_tag == DW_TAG_partial_unit
-	       || c->die_tag == DW_TAG_type_unit);
+	       || c->die_tag == DW_TAG_type_unit
+	       || c->die_tag == DW_TAG_skeleton_unit);
 }
 
 /* Returns true iff C is a namespace DIE.  */
@@ -7552,7 +7561,8 @@  contains_subprogram_definition (dw_die_r
 }
 
 /* Return non-zero if this is a type DIE that should be moved to a
-   COMDAT .debug_types section.  */
+   COMDAT .debug_types section or .debug_info section with DW_UT_*type
+   unit type.  */
 
 static int
 should_move_die_to_comdat (dw_die_ref die)
@@ -8069,8 +8079,9 @@  copy_dwarf_procs_ref_in_dies (dw_die_ref
 							copied_dwarf_procs));
 }
 
-/* Traverse the DIE and set up additional .debug_types sections for each
-   type worthy of being placed in a COMDAT section.  */
+/* Traverse the DIE and set up additional .debug_types or .debug_info
+   DW_UT_*type sections for each type worthy of being placed in a COMDAT
+   section.  */
 
 static void
 break_out_comdat_types (dw_die_ref die)
@@ -10150,12 +10161,8 @@  output_die (dw_die_ref die)
    .debug_info section, and precedes the DIE descriptions.  */
 
 static void
-output_compilation_unit_header (void)
+output_compilation_unit_header (enum dwarf_unit_type ut)
 {
-  /* We don't support actual DWARFv5 units yet, we just use some
-     DWARFv5 draft DIE tags in DWARFv4 format.  */
-  int ver = dwarf_version < 5 ? dwarf_version : 4;
-
   if (!XCOFF_DEBUGGING_INFO)
     {
       if (DWARF_INITIAL_LENGTH_SIZE - DWARF_OFFSET_SIZE == 4)
@@ -10166,17 +10173,33 @@  output_compilation_unit_header (void)
 			   "Length of Compilation Unit Info");
     }
 
-  dw2_asm_output_data (2, ver, "DWARF version number");
+  dw2_asm_output_data (2, dwarf_version, "DWARF version number");
+  if (dwarf_version >= 5)
+    {
+      const char *name;
+      switch (ut)
+	{
+	case DW_UT_compile: name = "DW_UT_compile"; break;
+	case DW_UT_type: name = "DW_UT_type"; break;
+	case DW_UT_split_compile: name = "DW_UT_split_compile"; break;
+	case DW_UT_split_type: name = "DW_UT_split_type"; break;
+	default: gcc_unreachable ();
+	}
+      dw2_asm_output_data (1, ut, name);
+      dw2_asm_output_data (1, DWARF2_ADDR_SIZE, "Pointer Size (in bytes)");
+    }
   dw2_asm_output_offset (DWARF_OFFSET_SIZE, abbrev_section_label,
 			 debug_abbrev_section,
 			 "Offset Into Abbrev. Section");
-  dw2_asm_output_data (1, DWARF2_ADDR_SIZE, "Pointer Size (in bytes)");
+  if (dwarf_version < 5)
+    dw2_asm_output_data (1, DWARF2_ADDR_SIZE, "Pointer Size (in bytes)");
 }
 
 /* Output the compilation unit DIE and its children.  */
 
 static void
-output_comp_unit (dw_die_ref die, int output_if_empty)
+output_comp_unit (dw_die_ref die, int output_if_empty,
+		  const unsigned char *dwo_id)
 {
   const char *secname, *oldsym;
   char *tmp;
@@ -10228,7 +10251,20 @@  output_comp_unit (dw_die_ref die, int ou
     }
 
   /* Output debugging information.  */
-  output_compilation_unit_header ();
+  output_compilation_unit_header (dwo_id
+				  ? DW_UT_split_compile : DW_UT_compile);
+  if (dwarf_version >= 5)
+    {
+      if (dwo_id != NULL)
+	for (int i = 0; i < 8; i++)
+	  dw2_asm_output_data (1, dwo_id[i], i == 0 ? "DWO id" : NULL);
+      else
+	/* Hope all the padding will be removed for DWARF 5 final for
+	   DW_AT_compile and DW_AT_partial.  */
+	dw2_asm_output_data (8, 0, "Padding 1");
+
+      dw2_asm_output_data (DWARF_OFFSET_SIZE, 0, "Padding 2");
+    }
   output_die (die);
 
   /* Leave the marks on the main CU, so we can check them in
@@ -10297,7 +10333,7 @@  add_top_level_skeleton_die_attrs (dw_die
   const char *dwo_file_name = concat (aux_base_name, ".dwo", NULL);
   const char *comp_dir = comp_dir_string ();
 
-  add_skeleton_AT_string (die, DW_AT_GNU_dwo_name, dwo_file_name);
+  add_skeleton_AT_string (die, dwarf_AT (DW_AT_dwo_name), dwo_file_name);
   if (comp_dir != NULL)
     add_skeleton_AT_string (die, DW_AT_comp_dir, comp_dir);
   add_AT_pubnames (die);
@@ -10307,12 +10343,9 @@  add_top_level_skeleton_die_attrs (dw_die
 /* Output skeleton debug sections that point to the dwo file.  */
 
 static void
-output_skeleton_debug_sections (dw_die_ref comp_unit)
+output_skeleton_debug_sections (dw_die_ref comp_unit,
+				const unsigned char *dwo_id)
 {
-  /* We don't support actual DWARFv5 units yet, we just use some
-     DWARFv5 draft DIE tags in DWARFv4 format.  */
-  int ver = dwarf_version < 5 ? dwarf_version : 4;
-
   /* These attributes will be found in the full debug_info section.  */
   remove_AT (comp_unit, DW_AT_producer);
   remove_AT (comp_unit, DW_AT_language);
@@ -10332,11 +10365,24 @@  output_skeleton_debug_sections (dw_die_r
                        - DWARF_INITIAL_LENGTH_SIZE
                        + size_of_die (comp_unit),
                       "Length of Compilation Unit Info");
-  dw2_asm_output_data (2, ver, "DWARF version number");
+  dw2_asm_output_data (2, dwarf_version, "DWARF version number");
+  if (dwarf_version >= 5)
+    {
+      dw2_asm_output_data (1, DW_UT_skeleton, "DW_UT_skeleton");
+      dw2_asm_output_data (1, DWARF2_ADDR_SIZE, "Pointer Size (in bytes)");
+    }
   dw2_asm_output_offset (DWARF_OFFSET_SIZE, debug_skeleton_abbrev_section_label,
-                         debug_abbrev_section,
+			 debug_skeleton_abbrev_section,
                          "Offset Into Abbrev. Section");
-  dw2_asm_output_data (1, DWARF2_ADDR_SIZE, "Pointer Size (in bytes)");
+  if (dwarf_version < 5)
+    dw2_asm_output_data (1, DWARF2_ADDR_SIZE, "Pointer Size (in bytes)");
+  else
+    {
+      for (int i = 0; i < 8; i++)
+	dw2_asm_output_data (1, dwo_id[i], i == 0 ? "DWO id" : NULL);
+
+      dw2_asm_output_data (DWARF_OFFSET_SIZE, 0, "Padding 2");
+    }
 
   comp_unit->die_abbrev = SKELETON_COMP_DIE_ABBREV;
   output_die (comp_unit);
@@ -10377,13 +10423,20 @@  output_comdat_type_unit (comdat_type_nod
   calc_die_sizes (node->root_die);
 
 #if defined (OBJECT_FORMAT_ELF)
-  if (!dwarf_split_debug_info)
+  if (dwarf_version >= 5)
+    {
+      if (!dwarf_split_debug_info)
+	secname = ".debug_info";
+      else
+	secname = ".debug_info.dwo";
+    }
+  else if (!dwarf_split_debug_info)
     secname = ".debug_types";
   else
     secname = ".debug_types.dwo";
 
   tmp = XALLOCAVEC (char, 4 + DWARF_TYPE_SIGNATURE_SIZE * 2);
-  sprintf (tmp, "wt.");
+  sprintf (tmp, dwarf_version >= 5 ? "wi." : "wt.");
   for (i = 0; i < DWARF_TYPE_SIGNATURE_SIZE; i++)
     sprintf (tmp + 3 + i * 2, "%02x", node->signature[i] & 0xff);
   comdat_key = get_identifier (tmp);
@@ -10392,7 +10445,8 @@  output_comdat_type_unit (comdat_type_nod
                                  comdat_key);
 #else
   tmp = XALLOCAVEC (char, 18 + DWARF_TYPE_SIGNATURE_SIZE * 2);
-  sprintf (tmp, ".gnu.linkonce.wt.");
+  sprintf (tmp, (dwarf_version >= 5
+		 ? ".gnu.linkonce.wi." : ".gnu.linkonce.wt."));
   for (i = 0; i < DWARF_TYPE_SIGNATURE_SIZE; i++)
     sprintf (tmp + 17 + i * 2, "%02x", node->signature[i] & 0xff);
   secname = tmp;
@@ -10400,7 +10454,8 @@  output_comdat_type_unit (comdat_type_nod
 #endif
 
   /* Output debugging information.  */
-  output_compilation_unit_header ();
+  output_compilation_unit_header (dwarf_split_debug_info
+				  ? DW_UT_split_type : DW_UT_type);
   output_signature (node->signature, "Type Signature");
   dw2_asm_output_data (DWARF_OFFSET_SIZE, node->type_die->die_offset,
 		       "Offset to Type DIE");
@@ -29021,6 +29076,7 @@  dwarf2out_finish (const char *)
 {
   comdat_type_node *ctnode;
   dw_die_ref main_comp_unit_die;
+  unsigned char checksum[16];
 
   /* Flush out any latecomers to the limbo party.  */
   flush_limbo_die_list ();
@@ -29066,6 +29122,8 @@  dwarf2out_finish (const char *)
     {
       limbo_die_node *cu;
       main_comp_unit_die = gen_compile_unit_die (NULL);
+      if (dwarf_version >= 5)
+	main_comp_unit_die->die_tag = DW_TAG_skeleton_unit;
       cu = limbo_die_list;
       gcc_assert (cu->die == main_comp_unit_die);
       limbo_die_list = limbo_die_list->next;
@@ -29197,7 +29255,7 @@  dwarf2out_finish (const char *)
   /* Output all of the compilation units.  We put the main one last so that
      the offsets are available to output_pubnames.  */
   for (node = cu_die_list; node; node = node->next)
-    output_comp_unit (node->die, 0);
+    output_comp_unit (node->die, 0, NULL);
 
   hash_table<comdat_type_hasher> comdat_type_table (100);
   for (ctnode = comdat_type_list; ctnode != NULL; ctnode = ctnode->next)
@@ -29231,7 +29289,6 @@  dwarf2out_finish (const char *)
   if (dwarf_split_debug_info)
     {
       int mark;
-      unsigned char checksum[16];
       struct md5_ctx ctx;
 
       if (!vec_safe_is_empty (rnglist_table))
@@ -29244,10 +29301,13 @@  dwarf2out_finish (const char *)
       unmark_all_dies (comp_unit_die ());
       md5_finish_ctx (&ctx, checksum);
 
-      /* Use the first 8 bytes of the checksum as the dwo_id,
-        and add it to both comp-unit DIEs.  */
-      add_AT_data8 (main_comp_unit_die, DW_AT_GNU_dwo_id, checksum);
-      add_AT_data8 (comp_unit_die (), DW_AT_GNU_dwo_id, checksum);
+      if (dwarf_version < 5)
+	{
+	  /* Use the first 8 bytes of the checksum as the dwo_id,
+	     and add it to both comp-unit DIEs.  */
+	  add_AT_data8 (main_comp_unit_die, DW_AT_GNU_dwo_id, checksum);
+	  add_AT_data8 (comp_unit_die (), DW_AT_GNU_dwo_id, checksum);
+	}
 
       /* Add the base offset of the ranges table to the skeleton
         comp-unit DIE.  */
@@ -29265,10 +29325,11 @@  dwarf2out_finish (const char *)
 
   /* Output the main compilation unit if non-empty or if .debug_macinfo
      or .debug_macro will be emitted.  */
-  output_comp_unit (comp_unit_die (), have_macinfo);
+  output_comp_unit (comp_unit_die (), have_macinfo,
+		    dwarf_split_debug_info ? checksum : NULL);
 
   if (dwarf_split_debug_info && info_section_emitted)
-    output_skeleton_debug_sections (main_comp_unit_die);
+    output_skeleton_debug_sections (main_comp_unit_die, checksum);
 
   /* Output the abbreviation table.  */
   if (vec_safe_length (abbrev_die_table) != 1)