[patch] More DWARF-4 support

Cary Coutant ccoutant@google.com
Tue Sep 22 20:27:00 GMT 2009


>> I think that for a GNU extension it would be best for the document to be
>> hosted on a GNU site.  That way we have some amount of control over the
>> existence and contents of the document.

I've updated the patch so that dwarf2.h now points to the
ThreadSafetyAnnotation wiki page for the thread safety extensions, and
to the just-created DwarfSeparateTypeInfo wiki page for the
DW_AT_odr_signature attribute.

> I tried translating the document into the wiki markup language, but
> gave up (there's too much non-semantic markup, and the wiki doesn't
> seem to take any HTML markup), so it looks like the best solution will
> be to export the doc as HTML and check it in under wwwdocs/htdocs.

I've added the DWARF extensions document as an HTML page at
wwwdocs/htdocs/projects/thread-annotations.html, which I will send as
a separate patch, then I'll update the ThreadSafetyAnnotation wiki
page to point to that page instead of Google Docs.

OK?

-cary


include/

	* dwarf2.h (DW_TAG_rvalue_reference_type, DW_TAG_template_alias):
	New tags.
	(DW_FORM_ref_sig8): New name for DW_FORM_sig8.
	(DW_AT_main_subprogram, DW_AT_data_bit_offset, DW_AT_const_expr,
	DW_AT_enum_class, DW_AT_linkage_name, DW_AT_GNU_guarded_by,
	DW_AT_GNU_pt_guarded_by, DW_AT_GNU_guarded, DW_AT_GNU_pt_guarded,
	DW_AT_GNU_locks_excluded, DW_AT_GNU_exclusive_locks_required,
	DW_AT_GNU_shared_locks_required, DW_AT_GNU_odr_signature): New
	attributes.
	(DW_LANG_Python): New language.

binutils/

	* dwarf.c (get_TAG_name): Add missing DWARF-3 and new DWARF-4 tags.
	(get_FORM_name): Add new DWARF-4 forms.
	(read_and_display_attr_value): Add DW_FORM_ref_sig8, DW_LANG_Python.
	(get_AT_name): Add new DWARF-4 and GNU-specific attributes.
	(process_debug_info): Add do_types parameter; change all callers.
	Add support for .debug_types sections.
	(display_debug_types): New function.
	(debug_displays): Add .debug_types section.
	* readelf.c (process_section_headers): Add .debug_types section.
	(display_debug_section): Simplify call to streq.
-------------- next part --------------
Index: include/dwarf2.h
===================================================================
RCS file: /cvs/src/src/include/dwarf2.h,v
retrieving revision 1.4
diff -u -p -r1.4 dwarf2.h
--- include/dwarf2.h	31 Aug 2009 23:24:07 -0000	1.4
+++ include/dwarf2.h	22 Sep 2009 20:17:12 -0000
@@ -196,6 +196,8 @@ enum dwarf_tag
     DW_TAG_shared_type = 0x40,
     /* DWARF 4.  */
     DW_TAG_type_unit = 0x41,
+    DW_TAG_rvalue_reference_type = 0x42,
+    DW_TAG_template_alias = 0x43,
 
     DW_TAG_lo_user = 0x4080,
     DW_TAG_hi_user = 0xffff,
@@ -254,7 +256,8 @@ enum dwarf_form
     DW_FORM_sec_offset = 0x17,
     DW_FORM_exprloc = 0x18,
     DW_FORM_flag_present = 0x19,
-    DW_FORM_sig8 = 0x20
+    DW_FORM_ref_sig8 = 0x20
+#define DW_FORM_sig8  DW_FORM_ref_sig8  /* Note: The use of DW_FORM_sig8 is deprecated.  */
   };
 
 /* Attribute names and codes.  */
@@ -353,7 +356,12 @@ enum dwarf_attribute
     DW_AT_pure          = 0x67,
     DW_AT_recursive     = 0x68,
     /* DWARF 4.  */
-    DW_AT_signature     = 0x69,
+    DW_AT_signature       = 0x69,
+    DW_AT_main_subprogram = 0x6a,
+    DW_AT_data_bit_offset = 0x6b,
+    DW_AT_const_expr      = 0x6c,
+    DW_AT_enum_class      = 0x6d,
+    DW_AT_linkage_name    = 0x6e,
 
     DW_AT_lo_user = 0x2000,	/* Implementation-defined range start.  */
     DW_AT_hi_user = 0x3ff0,	/* Implementation-defined range end.  */
@@ -393,6 +401,18 @@ enum dwarf_attribute
     DW_AT_body_begin = 0x2105,
     DW_AT_body_end   = 0x2106,
     DW_AT_GNU_vector = 0x2107,
+    /* Thread-safety annotations.
+       See http://gcc.gnu.org/wiki/ThreadSafetyAnnotation .  */
+    DW_AT_GNU_guarded_by    = 0x2108,
+    DW_AT_GNU_pt_guarded_by = 0x2109,
+    DW_AT_GNU_guarded       = 0x210a,
+    DW_AT_GNU_pt_guarded    = 0x210b,
+    DW_AT_GNU_locks_excluded = 0x210c,
+    DW_AT_GNU_exclusive_locks_required = 0x210d,
+    DW_AT_GNU_shared_locks_required = 0x210e,
+    /* One-definition rule violation detection.
+       See http://gcc.gnu.org/wiki/DwarfSeparateTypeInfo .  */
+    DW_AT_GNU_odr_signature = 0x210f,
     /* Template template argument name.
        See http://gcc.gnu.org/wiki/TemplateParmsDwarf .  */
     DW_AT_GNU_template_name = 0x2110,
@@ -831,6 +851,7 @@ enum dwarf_source_language
     DW_LANG_ObjC_plus_plus = 0x0011,
     DW_LANG_UPC = 0x0012,
     DW_LANG_D = 0x0013,
+    DW_LANG_Python = 0x0014,
 
     DW_LANG_lo_user = 0x8000,	/* Implementation-defined range start.  */
     DW_LANG_hi_user = 0xffff,	/* Implementation-defined range start.  */
Index: binutils/dwarf.c
===================================================================
RCS file: /cvs/src/src/binutils/dwarf.c,v
retrieving revision 1.56
diff -u -p -r1.56 dwarf.c
--- binutils/dwarf.c	10 Sep 2009 13:40:44 -0000	1.56
+++ binutils/dwarf.c	22 Sep 2009 20:17:12 -0000
@@ -628,6 +628,12 @@ get_TAG_name (unsigned long tag)
     case DW_TAG_unspecified_type:	return "DW_TAG_unspecified_type";
     case DW_TAG_partial_unit:		return "DW_TAG_partial_unit";
     case DW_TAG_imported_unit:		return "DW_TAG_imported_unit";
+    case DW_TAG_condition:		return "DW_TAG_condition";
+    case DW_TAG_shared_type:		return "DW_TAG_shared_type";
+      /* DWARF 4 values.  */
+    case DW_TAG_type_unit:		return "DW_TAG_type_unit";
+    case DW_TAG_rvalue_reference_type:	return "DW_TAG_rvalue_reference_type";
+    case DW_TAG_template_alias:		return "DW_TAG_template_alias";
       /* UPC values.  */
     case DW_TAG_upc_shared_type:	return "DW_TAG_upc_shared_type";
     case DW_TAG_upc_strict_type:	return "DW_TAG_upc_strict_type";
@@ -668,6 +674,11 @@ get_FORM_name (unsigned long form)
     case DW_FORM_ref8:		return "DW_FORM_ref8";
     case DW_FORM_ref_udata:	return "DW_FORM_ref_udata";
     case DW_FORM_indirect:	return "DW_FORM_indirect";
+      /* DWARF 4 values.  */
+    case DW_FORM_sec_offset:	return "DW_FORM_sec_offset";
+    case DW_FORM_exprloc:	return "DW_FORM_exprloc";
+    case DW_FORM_flag_present:	return "DW_FORM_flag_present";
+    case DW_FORM_ref_sig8:	return "DW_FORM_ref_sig8";
     default:
       {
 	static char buffer[100];
@@ -1305,6 +1316,21 @@ read_and_display_attr_value (unsigned lo
       /* Handled above.  */
       break;
 
+    case DW_FORM_ref_sig8:
+      if (!do_loc)
+	{
+	  int i;
+	  printf (" signature: ");
+	  for (i = 0; i < 8; i++)
+	    {
+	      printf ("%02x", (unsigned) byte_get (data, 1));
+	      data += 1;
+	    }
+	}
+      else
+        data += 8;
+      break;
+
     default:
       warn (_("Unrecognized form: %lu\n"), form);
       break;
@@ -1432,6 +1458,8 @@ read_and_display_attr_value (unsigned lo
 	case DW_LANG_ObjC_plus_plus:	printf ("(Objective C++)"); break;
 	case DW_LANG_UPC:		printf ("(Unified Parallel C)"); break;
 	case DW_LANG_D:			printf ("(D)"); break;
+	  /* DWARF 4 values.  */
+	case DW_LANG_Python:		printf ("(Python)"); break;
 	  /* MIPS extension.  */
 	case DW_LANG_Mips_Assembler:	printf ("(MIPS assembler)"); break;
 	  /* UPC extension.  */
@@ -1588,6 +1616,9 @@ read_and_display_attr_value (unsigned lo
 
     case DW_AT_import:
       {
+        if (form == DW_FORM_ref_sig8)
+          break;
+
 	if (form == DW_FORM_ref1
 	    || form == DW_FORM_ref2
 	    || form == DW_FORM_ref4)
@@ -1716,6 +1747,13 @@ get_AT_name (unsigned long attribute)
     case DW_AT_elemental:		return "DW_AT_elemental";
     case DW_AT_pure:			return "DW_AT_pure";
     case DW_AT_recursive:		return "DW_AT_recursive";
+      /* DWARF 4 values.  */
+    case DW_AT_signature:		return "DW_AT_signature";
+    case DW_AT_main_subprogram:		return "DW_AT_main_subprogram";
+    case DW_AT_data_bit_offset:		return "DW_AT_data_bit_offset";
+    case DW_AT_const_expr:		return "DW_AT_const_expr";
+    case DW_AT_enum_class:		return "DW_AT_enum_class";
+    case DW_AT_linkage_name:		return "DW_AT_linkage_name";
 
       /* HP and SGI/MIPS extensions.  */
     case DW_AT_MIPS_loop_begin:			return "DW_AT_MIPS_loop_begin";
@@ -1748,13 +1786,21 @@ get_AT_name (unsigned long attribute)
     case DW_AT_MIPS_fde:			return "DW_AT_MIPS_fde or DW_AT_HP_unmodifiable";
 
       /* GNU extensions.  */
-    case DW_AT_sf_names:		return "DW_AT_sf_names";
-    case DW_AT_src_info:		return "DW_AT_src_info";
-    case DW_AT_mac_info:		return "DW_AT_mac_info";
-    case DW_AT_src_coords:		return "DW_AT_src_coords";
-    case DW_AT_body_begin:		return "DW_AT_body_begin";
-    case DW_AT_body_end:		return "DW_AT_body_end";
-    case DW_AT_GNU_vector:		return "DW_AT_GNU_vector";
+    case DW_AT_sf_names:			return "DW_AT_sf_names";
+    case DW_AT_src_info:			return "DW_AT_src_info";
+    case DW_AT_mac_info:			return "DW_AT_mac_info";
+    case DW_AT_src_coords:			return "DW_AT_src_coords";
+    case DW_AT_body_begin:			return "DW_AT_body_begin";
+    case DW_AT_body_end:			return "DW_AT_body_end";
+    case DW_AT_GNU_vector:			return "DW_AT_GNU_vector";
+    case DW_AT_GNU_guarded_by:			return "DW_AT_GNU_guarded_by";
+    case DW_AT_GNU_pt_guarded_by:		return "DW_AT_GNU_pt_guarded_by";
+    case DW_AT_GNU_guarded:			return "DW_AT_GNU_guarded";
+    case DW_AT_GNU_pt_guarded:			return "DW_AT_GNU_pt_guarded";
+    case DW_AT_GNU_locks_excluded:		return "DW_AT_GNU_locks_excluded";
+    case DW_AT_GNU_exclusive_locks_required:	return "DW_AT_GNU_exclusive_locks_required";
+    case DW_AT_GNU_shared_locks_required:	return "DW_AT_GNU_shared_locks_required";
+    case DW_AT_GNU_odr_signature:		return "DW_AT_GNU_odr_signature";
 
       /* UPC extension.  */
     case DW_AT_upc_threads_scaled:	return "DW_AT_upc_threads_scaled";
@@ -1801,12 +1847,14 @@ read_and_display_attr (unsigned long att
 
 /* Process the contents of a .debug_info section.  If do_loc is non-zero
    then we are scanning for location lists and we do not want to display
-   anything to the user.  */
+   anything to the user.  If do_types is non-zero, we are processing
+   a .debug_types section instead of a .debug_info section.  */
 
 static int
 process_debug_info (struct dwarf_section *section,
 		    void *file,
-		    int do_loc)
+		    int do_loc,
+		    int do_types)
 {
   unsigned char *start = section->start;
   unsigned char *end = start + section->size;
@@ -1815,7 +1863,8 @@ process_debug_info (struct dwarf_section
   unsigned int num_units = 0;
 
   if ((do_loc || do_debug_loc || do_debug_ranges)
-      && num_debug_info_entries == 0)
+      && num_debug_info_entries == 0
+      && ! do_types)
     {
       unsigned long length;
 
@@ -1893,6 +1942,8 @@ process_debug_info (struct dwarf_section
       unsigned long cu_offset;
       int offset_size;
       int initial_length_size;
+      unsigned char signature[8];
+      unsigned long type_offset = 0;
 
       hdrptr = start;
 
@@ -1923,8 +1974,24 @@ process_debug_info (struct dwarf_section
 
       compunit.cu_pointer_size = byte_get (hdrptr, 1);
       hdrptr += 1;
+
+      if (do_types)
+        {
+          int i;
+
+          for (i = 0; i < 8; i++)
+            {
+              signature[i] = byte_get (hdrptr, 1);
+              hdrptr += 1;
+            }
+
+          type_offset = byte_get (hdrptr, offset_size);
+          hdrptr += offset_size;
+        }
+
       if ((do_loc || do_debug_loc || do_debug_ranges)
-	  && num_debug_info_entries == 0)
+	  && num_debug_info_entries == 0
+	  && ! do_types)
 	{
 	  debug_information [unit].cu_offset = cu_offset;
 	  debug_information [unit].pointer_size
@@ -1947,6 +2014,15 @@ process_debug_info (struct dwarf_section
 	  printf (_("   Version:       %d\n"), compunit.cu_version);
 	  printf (_("   Abbrev Offset: %ld\n"), compunit.cu_abbrev_offset);
 	  printf (_("   Pointer Size:  %d\n"), compunit.cu_pointer_size);
+	  if (do_types)
+	    {
+	      int i;
+	      printf (_("   Signature:     "));
+	      for (i = 0; i < 8; i++)
+	        printf ("%02x", signature[i]);
+	      printf ("\n");
+	      printf (_("   Type Offset:   0x%lx\n"), type_offset);
+	    }
 	}
 
       if (cu_offset + compunit.cu_length + initial_length_size
@@ -2094,7 +2170,8 @@ process_debug_info (struct dwarf_section
   /* Set num_debug_info_entries here so that it can be used to check if
      we need to process .debug_loc and .debug_ranges sections.  */
   if ((do_loc || do_debug_loc || do_debug_ranges)
-      && num_debug_info_entries == 0)
+      && num_debug_info_entries == 0
+      && ! do_types)
     num_debug_info_entries = num_units;
 
   if (!do_loc)
@@ -2129,7 +2206,7 @@ load_debug_info (void * file)
     return num_debug_info_entries;
 
   if (load_debug_section (info, file)
-      && process_debug_info (&debug_displays [info].section, file, 1))
+      && process_debug_info (&debug_displays [info].section, file, 1, 0))
     return num_debug_info_entries;
 
   num_debug_info_entries = DEBUG_INFO_UNAVAILABLE;
@@ -3360,9 +3437,14 @@ display_debug_str (struct dwarf_section 
 static int
 display_debug_info (struct dwarf_section *section, void *file)
 {
-  return process_debug_info (section, file, 0);
+  return process_debug_info (section, file, 0, 0);
 }
 
+static int
+display_debug_types (struct dwarf_section *section, void *file)
+{
+  return process_debug_info (section, file, 0, 1);
+}
 
 static int
 display_debug_aranges (struct dwarf_section *section,
@@ -4937,7 +5019,7 @@ struct dwarf_section_display debug_displ
   { { ".debug_static_vars",	".zdebug_static_vars",	NULL,	NULL,	0,	0 },
     display_debug_not_supported,	NULL,			0 },
   { { ".debug_types",		".zdebug_types",	NULL,	NULL,	0,	0 },
-    display_debug_not_supported,	NULL,			0 },
+    display_debug_types,		&do_debug_info,		1 },
   { { ".debug_weaknames",	".zdebug_weaknames",	NULL,	NULL,	0,	0 },
     display_debug_not_supported,	NULL,			0 }
 };
Index: binutils/readelf.c
===================================================================
RCS file: /cvs/src/src/binutils/readelf.c,v
retrieving revision 1.459
diff -u -p -r1.459 readelf.c
--- binutils/readelf.c	14 Sep 2009 12:29:50 -0000	1.459
+++ binutils/readelf.c	22 Sep 2009 20:17:12 -0000
@@ -4274,6 +4274,7 @@ process_section_headers (FILE * file)
 
 	  if (do_debugging
 	      || (do_debug_info     && streq (name, "info"))
+	      || (do_debug_info     && streq (name, "types"))
 	      || (do_debug_abbrevs  && streq (name, "abbrev"))
 	      || (do_debug_lines    && streq (name, "line"))
 	      || (do_debug_pubnames && streq (name, "pubnames"))
@@ -8815,7 +8816,7 @@ display_debug_section (Elf_Internal_Shdr
 	if (secondary)
 	  free_debug_section ((enum dwarf_section_display_enum) i);
 
-	if (streq (debug_displays[i].section.uncompressed_name, name))
+	if (streq (sec->uncompressed_name, name))
 	  sec->name = sec->uncompressed_name;
 	else
 	  sec->name = sec->compressed_name;


More information about the Binutils mailing list