public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [Google 4.7] Generate pubnames compatible with gdb-index version 7. (issue6459099)
@ 2012-08-16 23:53 Sterling Augustine
  2012-08-17  0:33 ` Cary Coutant
  0 siblings, 1 reply; 3+ messages in thread
From: Sterling Augustine @ 2012-08-16 23:53 UTC (permalink / raw)
  To: reply, gcc-patches

The enclosed patch adds a new option -ggnu-pubnames to solve the problem that
current pubnames don't supply enough information for Gold to generate a version
7 gdb index.

The patch encodes the flag byte from gdb-index version 7, and saves it between
the offset and name in the pubtype. We can't generate the index entry directly
because the cu_index is calculated during the link, but we can generate the
flag byte.

Of particular note is the fact that this patch adds include/gdb/gdb-index.h
from the gdb and binutils trees.

OK for google 4.7?

Sterling


2012-08-16  Sterling Augustine  <saugustine@google.com>

gcc/ChangeLog
	* dwarf2out.c (DEBUG_PUBNAMES_SECTION, DEBUG_PUBTYPES_SECTION): Adjust
	macros.
	(is_java, include_pubname_in_output): New functions.
	(size_of_pubnames): Call include_pubname_in_output.  New variable
	space_for_flags.
	(output_pubnames): Refactor, moving most of the logic to...
	(output_pubname): ... here.  New function.
	(dwarf2out_finish): Move output pubtable logic to...
	(output_pubtables): ... here.  New function.
	* common.opt (ggnu-pubnames):  New option.
	* doc/invoke.texi: Document it.

include/ChangeLog:
	* gdb/gdb-index.h: Check in from src.

Index: dwarf2out.c
===================================================================
--- dwarf2out.c	(revision 190448)
+++ dwarf2out.c	(working copy)
@@ -96,6 +96,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "cfglayout.h"
 #include "opts.h"
 #include "l-ipo.h"
+#include "gdb/gdb-index.h"
 
 static void dwarf2out_source_line (unsigned int, const char *, int, bool);
 static rtx last_var_location_insn;
@@ -3634,10 +3635,14 @@ new_addr_loc_descr (rtx addr, int dtprel)
 #define DEBUG_DWO_LOC_SECTION	".debug_loc.dwo"
 #endif
 #ifndef DEBUG_PUBNAMES_SECTION
-#define DEBUG_PUBNAMES_SECTION	".debug_pubnames"
+#define DEBUG_PUBNAMES_SECTION	\
+  ((debug_generate_pub_sections == 2) \
+   ? ".debug_gnu_pubnames" : ".debug_pubnames")
 #endif
 #ifndef DEBUG_PUBTYPES_SECTION
-#define DEBUG_PUBTYPES_SECTION	".debug_pubtypes"
+#define DEBUG_PUBTYPES_SECTION	\
+  ((debug_generate_pub_sections == 2) \
+   ? ".debug_gnu_pubtypes" : ".debug_pubtypes")
 #endif
 #define DEBUG_NORM_STR_OFFSETS_SECTION ".debug_str_offsets"
 #define DEBUG_DWO_STR_OFFSETS_SECTION ".debug_str_offsets.dwo"
@@ -5148,6 +5153,16 @@ is_cxx (void)
   return lang == DW_LANG_C_plus_plus || lang == DW_LANG_ObjC_plus_plus;
 }
 
+/* Return TRUE if the language is Java.  */
+
+static inline bool
+is_java (void)
+{
+  unsigned int lang = get_AT_unsigned (comp_unit_die (), DW_AT_language);
+
+  return lang == DW_LANG_Java;
+}
+
 /* Return TRUE if the language is Fortran.  */
 
 static inline bool
@@ -8257,22 +8272,32 @@ unmark_all_dies (dw_die_ref die)
       unmark_all_dies (AT_ref (a));
 }
 
+/* Calculate if the entry should appear in the final output file.  It may be
+   from a pruned a type.  */
+
+static bool
+include_pubname_in_output (VEC (pubname_entry, gc) *table, pubname_entry *p)
+{
+  return (table != pubtype_table
+          || p->die->die_offset != 0
+          || !flag_eliminate_unused_debug_types);
+}
+
 /* Return the size of the .debug_pubnames or .debug_pubtypes table
    generated for the compilation unit.  */
 
 static unsigned long
-size_of_pubnames (VEC (pubname_entry, gc) * names)
+size_of_pubnames (VEC (pubname_entry, gc) *names)
 {
   unsigned long size;
   unsigned i;
   pubname_ref p;
+  int space_for_flags = (debug_generate_pub_sections == 2) ? 1 : 0;
 
   size = DWARF_PUBNAMES_HEADER_SIZE;
   FOR_EACH_VEC_ELT (pubname_entry, names, i, p)
-    if (names != pubtype_table
-	|| p->die->die_offset != 0
-	|| !flag_eliminate_unused_debug_types)
-      size += strlen (p->name) + DWARF_OFFSET_SIZE + 1;
+    if (include_pubname_in_output (names, p))
+      size += strlen (p->name) + DWARF_OFFSET_SIZE + 1 + space_for_flags;
 
   size += DWARF_OFFSET_SIZE;
   return size;
@@ -9395,6 +9420,71 @@ add_pubtype (tree decl, dw_die_ref die)
     }
 }
 
+/* Output a single entry in the pubnames table.  */
+
+static void
+output_pubname (dw_offset die_offset, pubname_entry *entry)
+{
+  dw_die_ref die = entry->die;
+  int is_static = get_AT_flag (die, DW_AT_external) ? 1 : 0;
+
+  dw2_asm_output_data (DWARF_OFFSET_SIZE, die_offset, "DIE offset");
+
+  if (debug_generate_pub_sections == 2)
+    {
+      uint32_t flags = GDB_INDEX_SYMBOL_KIND_NONE;
+      switch (die->die_tag)
+      {
+        case DW_TAG_typedef:
+        case DW_TAG_base_type:
+        case DW_TAG_subrange_type:
+          GDB_INDEX_SYMBOL_KIND_SET_VALUE(flags, GDB_INDEX_SYMBOL_KIND_TYPE);
+          GDB_INDEX_SYMBOL_STATIC_SET_VALUE(flags, 1);
+          break;
+        case DW_TAG_enumerator:
+          GDB_INDEX_SYMBOL_KIND_SET_VALUE(flags,
+                                          GDB_INDEX_SYMBOL_KIND_VARIABLE);
+          if (!is_cxx () && !is_java ())
+            GDB_INDEX_SYMBOL_STATIC_SET_VALUE(flags, 1);
+          break;
+        case DW_TAG_subprogram:
+          GDB_INDEX_SYMBOL_KIND_SET_VALUE(flags,
+                                          GDB_INDEX_SYMBOL_KIND_FUNCTION);
+          if (!is_ada ())
+            GDB_INDEX_SYMBOL_STATIC_SET_VALUE(flags, is_static);
+          break;
+        case DW_TAG_constant:
+          GDB_INDEX_SYMBOL_KIND_SET_VALUE(flags,
+                                          GDB_INDEX_SYMBOL_KIND_VARIABLE);
+          GDB_INDEX_SYMBOL_STATIC_SET_VALUE(flags, is_static);
+          break;
+        case DW_TAG_variable:
+          GDB_INDEX_SYMBOL_KIND_SET_VALUE(flags,
+                                          GDB_INDEX_SYMBOL_KIND_VARIABLE);
+          GDB_INDEX_SYMBOL_STATIC_SET_VALUE(flags, is_static);
+          break;
+        case DW_TAG_namespace:
+          GDB_INDEX_SYMBOL_KIND_SET_VALUE(flags, GDB_INDEX_SYMBOL_KIND_TYPE);
+          break;
+        case DW_TAG_class_type:
+        case DW_TAG_interface_type:
+        case DW_TAG_structure_type:
+        case DW_TAG_union_type:
+        case DW_TAG_enumeration_type:
+          GDB_INDEX_SYMBOL_KIND_SET_VALUE(flags, GDB_INDEX_SYMBOL_KIND_TYPE);
+          GDB_INDEX_SYMBOL_STATIC_SET_VALUE(flags, 1);
+          break;
+        default:
+          gcc_unreachable ();
+      }
+      dw2_asm_output_data (1, flags >> GDB_INDEX_CU_BITSIZE,
+                           "GDB-index flags");
+    }
+
+  dw2_asm_output_nstring (entry->name, -1, "external name");
+}
+
+
 /* Output the public names table used to speed up access to externally
    visible names; or the public types table used to find type definitions.  */
 
@@ -9405,29 +9495,14 @@ output_pubnames (VEC (pubname_entry, gc) * names)
   unsigned long pubnames_length = size_of_pubnames (names);
   pubname_ref pub;
 
-  if (!want_pubnames () || !info_section_emitted)
-    return;
-  if (names == pubname_table)
-    {
-      switch_to_section (debug_pubnames_section);
-      ASM_OUTPUT_LABEL (asm_out_file, debug_pubnames_section_label);
-    }
-  else
-    {
-      switch_to_section (debug_pubtypes_section);
-      ASM_OUTPUT_LABEL (asm_out_file, debug_pubtypes_section_label);
-    }
   if (DWARF_INITIAL_LENGTH_SIZE - DWARF_OFFSET_SIZE == 4)
     dw2_asm_output_data (4, 0xffffffff,
       "Initial length escape value indicating 64-bit DWARF extension");
-  if (names == pubname_table)
-    dw2_asm_output_data (DWARF_OFFSET_SIZE, pubnames_length,
-			 "Length of Public Names Info");
-  else
-    dw2_asm_output_data (DWARF_OFFSET_SIZE, pubnames_length,
-			 "Length of Public Type Names Info");
-  /* Version number for pubnames/pubtypes is still 2, even in DWARF3.  */
+  dw2_asm_output_data (DWARF_OFFSET_SIZE, pubnames_length, "Pub Info Length");
+
+  /* Version number for pubnames/pubtypes is independent of dwarf version.  */
   dw2_asm_output_data (2, 2, "DWARF Version");
+
   if (dwarf_split_debug_info)
     dw2_asm_output_offset (DWARF_OFFSET_SIZE, debug_skeleton_info_section_label,
                            debug_skeleton_info_section,
@@ -9445,9 +9520,7 @@ output_pubnames (VEC (pubname_entry, gc) * names)
       if (names == pubname_table)
 	gcc_assert (pub->die->die_mark);
 
-      if (names != pubtype_table
-	  || pub->die->die_offset != 0
-	  || !flag_eliminate_unused_debug_types)
+      if (include_pubname_in_output (names, pub))
 	{
 	  dw_offset die_offset = pub->die->die_offset;
 
@@ -9465,15 +9538,33 @@ output_pubnames (VEC (pubname_entry, gc) * names)
 			      : 0);
 	    }
 
-	  dw2_asm_output_data (DWARF_OFFSET_SIZE, die_offset, "DIE offset");
-
-	  dw2_asm_output_nstring (pub->name, -1, "external name");
+          output_pubname (die_offset, pub);
 	}
     }
 
   dw2_asm_output_data (DWARF_OFFSET_SIZE, 0, NULL);
 }
 
+/* Output public names and types tables if necessary.  */
+
+static void
+output_pubtables (void)
+{
+  if (!want_pubnames () || !info_section_emitted)
+    return;
+
+  switch_to_section (debug_pubnames_section);
+  ASM_OUTPUT_LABEL (asm_out_file, debug_pubnames_section_label);
+  output_pubnames (pubname_table);
+  /* ??? Only defined by DWARF3, but emitted by Darwin for DWARF2.
+     It shouldn't hurt to emit it always, since pure DWARF2 consumers
+     simply won't look for the section.  */
+  switch_to_section (debug_pubtypes_section);
+  ASM_OUTPUT_LABEL (asm_out_file, debug_pubtypes_section_label);
+  output_pubnames (pubtype_table);
+}
+
+
 /* Output the information that goes into the .debug_aranges table.
    Namely, define the beginning and ending address range of the
    text section generated for this compilation unit.  */
@@ -23740,12 +23831,7 @@ dwarf2out_finish (const char *filename)
       output_location_lists (comp_unit_die ());
     }
 
-  /* Output public names and types tables if necessary.  */
-  output_pubnames (pubname_table);
-  /* ??? Only defined by DWARF3, but emitted by Darwin for DWARF2.
-     It shouldn't hurt to emit it always, since pure DWARF2 consumers
-     simply won't look for the section.  */
-  output_pubnames (pubtype_table);
+  output_pubtables ();
 
   /* Output the address range information if a CU (.debug_info section)
      was emitted.  We output an empty table even if we had no functions
Index: common.opt
===================================================================
--- common.opt	(revision 190448)
+++ common.opt	(working copy)
@@ -2424,6 +2424,10 @@ gpubnames
 Common RejectNegative Var(debug_generate_pub_sections, 1)
 Generate DWARF pubnames and pubtypes sections.
 
+ggnu-pubnames
+Common RejectNegative Var(debug_generate_pub_sections, 2)
+Generate DWARF pubnames and pubtypes sections.
+
 gno-record-gcc-switches
 Common RejectNegative Var(dwarf_record_gcc_switches,0) Init(0)
 Don't record gcc command line switches in DWARF DW_AT_producer.
Index: doc/invoke.texi
===================================================================
--- doc/invoke.texi	(revision 190448)
+++ doc/invoke.texi	(working copy)
@@ -4973,6 +4973,12 @@
 @opindex gpubnames
 Generate dwarf .debug_pubnames and .debug_pubtypes sections.
 
+@item -ggnu-pubnames
+@opindex ggnu-pubnames
+Generate .debug_pubnames and .debug_pubtypes sections in a format
+suitable for conversion into a GDB@ index.  This option is only useful
+with a linker that can produce GDB@ index version 7.
+
 @item -gstabs
 @opindex gstabs
 Produce debugging information in stabs format (if that is supported),

--
This patch is available for review at http://codereview.appspot.com/6459099

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

* Re: [Google 4.7] Generate pubnames compatible with gdb-index version 7. (issue6459099)
  2012-08-16 23:53 [Google 4.7] Generate pubnames compatible with gdb-index version 7. (issue6459099) Sterling Augustine
@ 2012-08-17  0:33 ` Cary Coutant
  2012-08-20 18:23   ` Sterling Augustine
  0 siblings, 1 reply; 3+ messages in thread
From: Cary Coutant @ 2012-08-17  0:33 UTC (permalink / raw)
  To: Sterling Augustine; +Cc: reply, gcc-patches

> +/* Output a single entry in the pubnames table.  */
> +
> +static void
> +output_pubname (dw_offset die_offset, pubname_entry *entry)

For this function, I'd suggest a comment to the effect that the logic
is lifted from GDB.

> @@ -2424,6 +2424,10 @@ gpubnames
>  Common RejectNegative Var(debug_generate_pub_sections, 1)
>  Generate DWARF pubnames and pubtypes sections.
>
> +ggnu-pubnames
> +Common RejectNegative Var(debug_generate_pub_sections, 2)
> +Generate DWARF pubnames and pubtypes sections.

Instead of "RejectNegative", I think these three options should now
use "Negative(...)" flags (each one naming the next, circularly). Not
sure about that, though. (See the treatment of -gdwarf-, -gstabs,
etc.)

OK for google/gcc-4_7 branch.

-cary

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

* Re: [Google 4.7] Generate pubnames compatible with gdb-index version 7. (issue6459099)
  2012-08-17  0:33 ` Cary Coutant
@ 2012-08-20 18:23   ` Sterling Augustine
  0 siblings, 0 replies; 3+ messages in thread
From: Sterling Augustine @ 2012-08-20 18:23 UTC (permalink / raw)
  To: Cary Coutant; +Cc: reply, gcc-patches

[-- Attachment #1: Type: text/plain, Size: 916 bytes --]

On Thu, Aug 16, 2012 at 5:32 PM, Cary Coutant <ccoutant@google.com> wrote:
>> +/* Output a single entry in the pubnames table.  */
>> +
>> +static void
>> +output_pubname (dw_offset die_offset, pubname_entry *entry)
>
> For this function, I'd suggest a comment to the effect that the logic
> is lifted from GDB.
>
>> @@ -2424,6 +2424,10 @@ gpubnames
>>  Common RejectNegative Var(debug_generate_pub_sections, 1)
>>  Generate DWARF pubnames and pubtypes sections.
>>
>> +ggnu-pubnames
>> +Common RejectNegative Var(debug_generate_pub_sections, 2)
>> +Generate DWARF pubnames and pubtypes sections.
>
> Instead of "RejectNegative", I think these three options should now
> use "Negative(...)" flags (each one naming the next, circularly). Not
> sure about that, though. (See the treatment of -gdwarf-, -gstabs,
> etc.)
>
> OK for google/gcc-4_7 branch.

Committed with your recommended changes, as attached.

Sterling

[-- Attachment #2: patch.diff --]
[-- Type: application/octet-stream, Size: 16158 bytes --]

2012-08-20  Sterling Augustine  <saugustine@google.com>

gcc/ChangeLog.google-4_7
	* dwarf2out.c (DEBUG_PUBNAMES_SECTION, DEBUG_PUBTYPES_SECTION): Adjust
	macros.
	(is_java, include_pubname_in_output): New functions.
	(size_of_pubnames): Call include_pubname_in_output.  New variable
	space_for_flags.
	(output_pubnames): Refactor, moving most of the logic to...
	(output_pubname): ... here.  New function.
	(dwarf2out_finish): Move output pubtable logic to...
	(output_pubtables): ... here.  New function.
	* common.opt (ggnu-pubnames):  New option.
	(gpubnames, gno-pubnames): Adjust.
	* doc/invoke.texi: Document -ggnu-pubnames.

include/ChangeLog.google-4_7:
	* gdb/gdb-index.h: Check in from src.

Index: include/gdb/gdb-index.h
===================================================================
--- include/gdb/gdb-index.h	(revision 0)
+++ include/gdb/gdb-index.h	(revision 0)
@@ -0,0 +1,99 @@
+/* Public attributes of the .gdb_index section.
+   Copyright 2012 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+/* This file contains values for understanding the .gdb_index section
+   needed by more than just GDB, e.g. readelf.  */
+
+#ifndef GDB_INDEX_H
+#define GDB_INDEX_H
+
+/* Each symbol in .gdb_index refers to a set of CUs that defines the symbol.
+   Each CU is represented by a 32 bit number that is the index of the CU in
+   the CU table, plus some attributes of the use of the symbol in that CU.
+
+   The values are defined such that if all the bits are zero, then no
+   special meaning is assigned to any of them.  This is done to preserve
+   compatibility with older indices.  The way this is done is to specify
+   that if the GDB_INDEX_SYMBOL_KIND value is zero then all other attribute
+   bits must be zero.
+
+    0-23  CU index
+   24-27  reserved
+   28-30  symbol kind
+   31     0 == global, 1 == static
+
+   Bits 24-27 are reserved because it's easier to relax restrictions than
+   it is to impose them after the fact.  At present 24 bits to represent
+   the CU index is plenty.  If we need more bits for the CU index or for
+   attributes then we have them.  */
+
+/* Whether the symbol is in GLOBAL_BLOCK (== 0) or STATIC_BLOCK (== 1).  */
+#define GDB_INDEX_SYMBOL_STATIC_SHIFT 31
+#define GDB_INDEX_SYMBOL_STATIC_MASK 1
+#define GDB_INDEX_SYMBOL_STATIC_VALUE(cu_index) \
+  (((cu_index) >> GDB_INDEX_SYMBOL_STATIC_SHIFT) & GDB_INDEX_SYMBOL_STATIC_MASK)
+#define GDB_INDEX_SYMBOL_STATIC_SET_VALUE(cu_index, value) \
+  do { \
+    (cu_index) |= (((value) & GDB_INDEX_SYMBOL_STATIC_MASK) \
+		   << GDB_INDEX_SYMBOL_STATIC_SHIFT); \
+  } while (0)
+
+/* The kind of the symbol.
+   We don't use GDB's internal values as these numbers are published
+   so that other tools can build and read .gdb_index.  */
+
+typedef enum {
+  /* Special value to indicate no attributes are present.  */
+  GDB_INDEX_SYMBOL_KIND_NONE = 0,
+  GDB_INDEX_SYMBOL_KIND_TYPE = 1,
+  GDB_INDEX_SYMBOL_KIND_VARIABLE = 2,
+  GDB_INDEX_SYMBOL_KIND_FUNCTION = 3,
+  GDB_INDEX_SYMBOL_KIND_OTHER = 4,
+  /* We currently allocate 3 bits to record the symbol kind.
+     Give the unused bits a value so gdb will print them sensibly.  */
+  GDB_INDEX_SYMBOL_KIND_UNUSED5 = 5,
+  GDB_INDEX_SYMBOL_KIND_UNUSED6 = 6,
+  GDB_INDEX_SYMBOL_KIND_UNUSED7 = 7,
+} gdb_index_symbol_kind;
+
+#define GDB_INDEX_SYMBOL_KIND_SHIFT 28
+#define GDB_INDEX_SYMBOL_KIND_MASK 7
+#define GDB_INDEX_SYMBOL_KIND_VALUE(cu_index) \
+  ((gdb_index_symbol_kind) (((cu_index) >> GDB_INDEX_SYMBOL_KIND_SHIFT) \
+			    & GDB_INDEX_SYMBOL_KIND_MASK))
+#define GDB_INDEX_SYMBOL_KIND_SET_VALUE(cu_index, value) \
+  do { \
+    (cu_index) |= (((value) & GDB_INDEX_SYMBOL_KIND_MASK) \
+		   << GDB_INDEX_SYMBOL_KIND_SHIFT); \
+  } while (0)
+
+#define GDB_INDEX_RESERVED_SHIFT 24
+#define GDB_INDEX_RESERVED_MASK 15
+#define GDB_INDEX_RESERVED_VALUE(cu_index) \
+  (((cu_index) >> GDB_INDEX_RESERVED_SHIFT) & GDB_INDEX_RESERVED_MASK)
+
+/* CU index.  */
+#define GDB_INDEX_CU_BITSIZE 24
+#define GDB_INDEX_CU_MASK ((1 << GDB_INDEX_CU_BITSIZE) - 1)
+#define GDB_INDEX_CU_VALUE(cu_index) ((cu_index) & GDB_INDEX_CU_MASK)
+#define GDB_INDEX_CU_SET_VALUE(cu_index, value) \
+  do { \
+    (cu_index) |= (value) & GDB_INDEX_CU_MASK; \
+  } while (0)
+
+#endif /* GDB_INDEX_H */
Index: gcc/doc/invoke.texi
===================================================================
--- gcc/doc/invoke.texi	(revision 190537)
+++ gcc/doc/invoke.texi	(working copy)
@@ -4973,6 +4973,12 @@ possible.
 @opindex gpubnames
 Generate dwarf .debug_pubnames and .debug_pubtypes sections.
 
+@item -ggnu-pubnames
+@opindex ggnu-pubnames
+Generate .debug_pubnames and .debug_pubtypes sections in a format
+suitable for conversion into a GDB@ index.  This option is only useful
+with a linker that can produce GDB@ index version 7.
+
 @item -gstabs
 @opindex gstabs
 Produce debugging information in stabs format (if that is supported),
Index: gcc/dwarf2out.c
===================================================================
--- gcc/dwarf2out.c	(revision 190537)
+++ gcc/dwarf2out.c	(working copy)
@@ -96,6 +96,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "cfglayout.h"
 #include "opts.h"
 #include "l-ipo.h"
+#include "gdb/gdb-index.h"
 
 static void dwarf2out_source_line (unsigned int, const char *, int, bool);
 static rtx last_var_location_insn;
@@ -3634,10 +3635,14 @@ new_addr_loc_descr (rtx addr, int dtprel)
 #define DEBUG_DWO_LOC_SECTION	".debug_loc.dwo"
 #endif
 #ifndef DEBUG_PUBNAMES_SECTION
-#define DEBUG_PUBNAMES_SECTION	".debug_pubnames"
+#define DEBUG_PUBNAMES_SECTION	\
+  ((debug_generate_pub_sections == 2) \
+   ? ".debug_gnu_pubnames" : ".debug_pubnames")
 #endif
 #ifndef DEBUG_PUBTYPES_SECTION
-#define DEBUG_PUBTYPES_SECTION	".debug_pubtypes"
+#define DEBUG_PUBTYPES_SECTION	\
+  ((debug_generate_pub_sections == 2) \
+   ? ".debug_gnu_pubtypes" : ".debug_pubtypes")
 #endif
 #define DEBUG_NORM_STR_OFFSETS_SECTION ".debug_str_offsets"
 #define DEBUG_DWO_STR_OFFSETS_SECTION ".debug_str_offsets.dwo"
@@ -5148,6 +5153,16 @@ is_cxx (void)
   return lang == DW_LANG_C_plus_plus || lang == DW_LANG_ObjC_plus_plus;
 }
 
+/* Return TRUE if the language is Java.  */
+
+static inline bool
+is_java (void)
+{
+  unsigned int lang = get_AT_unsigned (comp_unit_die (), DW_AT_language);
+
+  return lang == DW_LANG_Java;
+}
+
 /* Return TRUE if the language is Fortran.  */
 
 static inline bool
@@ -8248,22 +8263,32 @@ unmark_all_dies (dw_die_ref die)
       unmark_all_dies (AT_ref (a));
 }
 
+/* Calculate if the entry should appear in the final output file.  It may be
+   from a pruned a type.  */
+
+static bool
+include_pubname_in_output (VEC (pubname_entry, gc) *table, pubname_entry *p)
+{
+  return (table != pubtype_table
+          || p->die->die_offset != 0
+          || !flag_eliminate_unused_debug_types);
+}
+
 /* Return the size of the .debug_pubnames or .debug_pubtypes table
    generated for the compilation unit.  */
 
 static unsigned long
-size_of_pubnames (VEC (pubname_entry, gc) * names)
+size_of_pubnames (VEC (pubname_entry, gc) *names)
 {
   unsigned long size;
   unsigned i;
   pubname_ref p;
+  int space_for_flags = (debug_generate_pub_sections == 2) ? 1 : 0;
 
   size = DWARF_PUBNAMES_HEADER_SIZE;
   FOR_EACH_VEC_ELT (pubname_entry, names, i, p)
-    if (names != pubtype_table
-	|| p->die->die_offset != 0
-	|| !flag_eliminate_unused_debug_types)
-      size += strlen (p->name) + DWARF_OFFSET_SIZE + 1;
+    if (include_pubname_in_output (names, p))
+      size += strlen (p->name) + DWARF_OFFSET_SIZE + 1 + space_for_flags;
 
   size += DWARF_OFFSET_SIZE;
   return size;
@@ -9386,6 +9411,73 @@ add_pubtype (tree decl, dw_die_ref die)
     }
 }
 
+/* Output a single entry in the pubnames table.  */
+
+static void
+output_pubname (dw_offset die_offset, pubname_entry *entry)
+{
+  dw_die_ref die = entry->die;
+  int is_static = get_AT_flag (die, DW_AT_external) ? 1 : 0;
+
+  dw2_asm_output_data (DWARF_OFFSET_SIZE, die_offset, "DIE offset");
+
+  if (debug_generate_pub_sections == 2)
+    {
+      /* This logic follows gdb's method for determining the value of the flag
+         byte.  */
+      uint32_t flags = GDB_INDEX_SYMBOL_KIND_NONE;
+      switch (die->die_tag)
+      {
+        case DW_TAG_typedef:
+        case DW_TAG_base_type:
+        case DW_TAG_subrange_type:
+          GDB_INDEX_SYMBOL_KIND_SET_VALUE(flags, GDB_INDEX_SYMBOL_KIND_TYPE);
+          GDB_INDEX_SYMBOL_STATIC_SET_VALUE(flags, 1);
+          break;
+        case DW_TAG_enumerator:
+          GDB_INDEX_SYMBOL_KIND_SET_VALUE(flags,
+                                          GDB_INDEX_SYMBOL_KIND_VARIABLE);
+          if (!is_cxx () && !is_java ())
+            GDB_INDEX_SYMBOL_STATIC_SET_VALUE(flags, 1);
+          break;
+        case DW_TAG_subprogram:
+          GDB_INDEX_SYMBOL_KIND_SET_VALUE(flags,
+                                          GDB_INDEX_SYMBOL_KIND_FUNCTION);
+          if (!is_ada ())
+            GDB_INDEX_SYMBOL_STATIC_SET_VALUE(flags, is_static);
+          break;
+        case DW_TAG_constant:
+          GDB_INDEX_SYMBOL_KIND_SET_VALUE(flags,
+                                          GDB_INDEX_SYMBOL_KIND_VARIABLE);
+          GDB_INDEX_SYMBOL_STATIC_SET_VALUE(flags, is_static);
+          break;
+        case DW_TAG_variable:
+          GDB_INDEX_SYMBOL_KIND_SET_VALUE(flags,
+                                          GDB_INDEX_SYMBOL_KIND_VARIABLE);
+          GDB_INDEX_SYMBOL_STATIC_SET_VALUE(flags, is_static);
+          break;
+        case DW_TAG_namespace:
+          GDB_INDEX_SYMBOL_KIND_SET_VALUE(flags, GDB_INDEX_SYMBOL_KIND_TYPE);
+          break;
+        case DW_TAG_class_type:
+        case DW_TAG_interface_type:
+        case DW_TAG_structure_type:
+        case DW_TAG_union_type:
+        case DW_TAG_enumeration_type:
+          GDB_INDEX_SYMBOL_KIND_SET_VALUE(flags, GDB_INDEX_SYMBOL_KIND_TYPE);
+          GDB_INDEX_SYMBOL_STATIC_SET_VALUE(flags, 1);
+          break;
+        default:
+          gcc_unreachable ();
+      }
+      dw2_asm_output_data (1, flags >> GDB_INDEX_CU_BITSIZE,
+                           "GDB-index flags");
+    }
+
+  dw2_asm_output_nstring (entry->name, -1, "external name");
+}
+
+
 /* Output the public names table used to speed up access to externally
    visible names; or the public types table used to find type definitions.  */
 
@@ -9396,29 +9488,14 @@ output_pubnames (VEC (pubname_entry, gc) * names)
   unsigned long pubnames_length = size_of_pubnames (names);
   pubname_ref pub;
 
-  if (!want_pubnames () || !info_section_emitted)
-    return;
-  if (names == pubname_table)
-    {
-      switch_to_section (debug_pubnames_section);
-      ASM_OUTPUT_LABEL (asm_out_file, debug_pubnames_section_label);
-    }
-  else
-    {
-      switch_to_section (debug_pubtypes_section);
-      ASM_OUTPUT_LABEL (asm_out_file, debug_pubtypes_section_label);
-    }
   if (DWARF_INITIAL_LENGTH_SIZE - DWARF_OFFSET_SIZE == 4)
     dw2_asm_output_data (4, 0xffffffff,
       "Initial length escape value indicating 64-bit DWARF extension");
-  if (names == pubname_table)
-    dw2_asm_output_data (DWARF_OFFSET_SIZE, pubnames_length,
-			 "Length of Public Names Info");
-  else
-    dw2_asm_output_data (DWARF_OFFSET_SIZE, pubnames_length,
-			 "Length of Public Type Names Info");
-  /* Version number for pubnames/pubtypes is still 2, even in DWARF3.  */
+  dw2_asm_output_data (DWARF_OFFSET_SIZE, pubnames_length, "Pub Info Length");
+
+  /* Version number for pubnames/pubtypes is independent of dwarf version.  */
   dw2_asm_output_data (2, 2, "DWARF Version");
+
   if (dwarf_split_debug_info)
     dw2_asm_output_offset (DWARF_OFFSET_SIZE, debug_skeleton_info_section_label,
                            debug_skeleton_info_section,
@@ -9436,9 +9513,7 @@ output_pubnames (VEC (pubname_entry, gc) * names)
       if (names == pubname_table)
 	gcc_assert (pub->die->die_mark);
 
-      if (names != pubtype_table
-	  || pub->die->die_offset != 0
-	  || !flag_eliminate_unused_debug_types)
+      if (include_pubname_in_output (names, pub))
 	{
 	  dw_offset die_offset = pub->die->die_offset;
 
@@ -9456,15 +9531,33 @@ output_pubnames (VEC (pubname_entry, gc) * names)
 			      : 0);
 	    }
 
-	  dw2_asm_output_data (DWARF_OFFSET_SIZE, die_offset, "DIE offset");
-
-	  dw2_asm_output_nstring (pub->name, -1, "external name");
+          output_pubname (die_offset, pub);
 	}
     }
 
   dw2_asm_output_data (DWARF_OFFSET_SIZE, 0, NULL);
 }
 
+/* Output public names and types tables if necessary.  */
+
+static void
+output_pubtables (void)
+{
+  if (!want_pubnames () || !info_section_emitted)
+    return;
+
+  switch_to_section (debug_pubnames_section);
+  ASM_OUTPUT_LABEL (asm_out_file, debug_pubnames_section_label);
+  output_pubnames (pubname_table);
+  /* ??? Only defined by DWARF3, but emitted by Darwin for DWARF2.
+     It shouldn't hurt to emit it always, since pure DWARF2 consumers
+     simply won't look for the section.  */
+  switch_to_section (debug_pubtypes_section);
+  ASM_OUTPUT_LABEL (asm_out_file, debug_pubtypes_section_label);
+  output_pubnames (pubtype_table);
+}
+
+
 /* Output the information that goes into the .debug_aranges table.
    Namely, define the beginning and ending address range of the
    text section generated for this compilation unit.  */
@@ -23731,12 +23824,7 @@ dwarf2out_finish (const char *filename)
       output_location_lists (comp_unit_die ());
     }
 
-  /* Output public names and types tables if necessary.  */
-  output_pubnames (pubname_table);
-  /* ??? Only defined by DWARF3, but emitted by Darwin for DWARF2.
-     It shouldn't hurt to emit it always, since pure DWARF2 consumers
-     simply won't look for the section.  */
-  output_pubnames (pubtype_table);
+  output_pubtables ();
 
   /* Output the address range information if a CU (.debug_info section)
      was emitted.  We output an empty table even if we had no functions
Index: gcc/opts.c
===================================================================
--- gcc/opts.c	(revision 190537)
+++ gcc/opts.c	(working copy)
@@ -866,9 +866,9 @@ finish_options (struct gcc_options *opts, struct g
   if (opts->x_flag_reorder_functions > 1)
     opts->x_flag_function_sections = 1;
 
-  /* The -gsplit-dwarf option requires -gpubnames.  */
+  /* The -gsplit-dwarf option requires -ggnu-pubnames.  */
   if (opts->x_dwarf_split_debug_info)
-    opts->x_debug_generate_pub_sections = 1;
+    opts->x_debug_generate_pub_sections = 2;
 }
 
 #define LEFT_COLUMN	27
Index: gcc/common.opt
===================================================================
--- gcc/common.opt	(revision 190537)
+++ gcc/common.opt	(working copy)
@@ -2417,13 +2417,17 @@ Common RejectNegative
 Generate debug information at level 1 with minimal line table
 
 gno-pubnames
-Common RejectNegative Var(debug_generate_pub_sections, 0) Init(-1)
+Common Negative(gpubnames) Var(debug_generate_pub_sections, 0) Init(-1)
 Don't generate DWARF pubnames and pubtypes sections.
 
 gpubnames
-Common RejectNegative Var(debug_generate_pub_sections, 1)
+Common Negative(ggnu-pubnames) Var(debug_generate_pub_sections, 1)
 Generate DWARF pubnames and pubtypes sections.
 
+ggnu-pubnames
+Common Negative(gno-pubnames) Var(debug_generate_pub_sections, 2)
+Generate DWARF pubnames and pubtypes sections with GNU extensions.
+
 gno-record-gcc-switches
 Common RejectNegative Var(dwarf_record_gcc_switches,0) Init(0)
 Don't record gcc command line switches in DWARF DW_AT_producer.

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

end of thread, other threads:[~2012-08-20 18:23 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-08-16 23:53 [Google 4.7] Generate pubnames compatible with gdb-index version 7. (issue6459099) Sterling Augustine
2012-08-17  0:33 ` Cary Coutant
2012-08-20 18:23   ` Sterling Augustine

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).