From patchwork Sat Dec 17 19:26:50 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sterling Augustine X-Patchwork-Id: 132020 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id 9ED1EB6FA0 for ; Sun, 18 Dec 2011 06:27:20 +1100 (EST) Received: (qmail 24392 invoked by alias); 17 Dec 2011 19:27:18 -0000 Received: (qmail 24376 invoked by uid 22791); 17 Dec 2011 19:27:15 -0000 X-SWARE-Spam-Status: No, hits=-3.4 required=5.0 tests=AWL, BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, RP_MATCHES_RCVD, TW_CX X-Spam-Check-By: sourceware.org Received: from mail-ee0-f73.google.com (HELO mail-ee0-f73.google.com) (74.125.83.73) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Sat, 17 Dec 2011 19:26:53 +0000 Received: by eekd41 with SMTP id d41so77798eek.2 for ; Sat, 17 Dec 2011 11:26:51 -0800 (PST) Received: by 10.14.120.12 with SMTP id o12mr590364eeh.0.1324150011829; Sat, 17 Dec 2011 11:26:51 -0800 (PST) Received: by 10.14.120.12 with SMTP id o12mr590359eeh.0.1324150011724; Sat, 17 Dec 2011 11:26:51 -0800 (PST) Received: from hpza10.eem.corp.google.com ([74.125.121.33]) by gmr-mx.google.com with ESMTPS id a53si3698483eeg.1.2011.12.17.11.26.51 (version=TLSv1/SSLv3 cipher=AES128-SHA); Sat, 17 Dec 2011 11:26:51 -0800 (PST) Received: from sterling.mtv.corp.google.com (sterling.mtv.corp.google.com [172.18.111.14]) by hpza10.eem.corp.google.com (Postfix) with ESMTP id 3B11A20004E; Sat, 17 Dec 2011 11:26:51 -0800 (PST) Received: by sterling.mtv.corp.google.com (Postfix, from userid 135279) id 736B6160785; Sat, 17 Dec 2011 11:26:50 -0800 (PST) To: reply@codereview.appspotmail.com,gcc-patches@gcc.gnu.org Subject: [Google Debugfission] Add pubnames and pubtypes to google/main (issue5489074) Message-Id: <20111217192650.736B6160785@sterling.mtv.corp.google.com> Date: Sat, 17 Dec 2011 11:26:50 -0800 (PST) From: saugustine@google.com (Sterling Augustine) Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Enclosed for review and inclusion on the google/main and google/4_6 trees is the first patch for the debugfission project. It includes producing a complete and correct set of .debug_pubnames and .debug_pubtypes, as well as switching the default to generate .debug_pubnames and .debug_pubtypes. It further (and the most worth of review), changes certain decl printers (which are used to generate debug info) to be more consistent with the naming conventions used by demanglers. Tested: Via complete bootstap and running the test suite. No new failures found. ChangeLog: 2011-12-17 Sterling Augustine * gcc/dwarf2out.c (is_cu_die, is_namespace_die, is_class_die): New functions. (add_pubname): Call is_namespace_die, is_cu_die, and is_class_die in conditional. (add_enumerator_pubname): New function. (add_pubtype): Call is_namespace_die. Rework name calculation. Call type_tag, lang_hooks.dwarf_name and add_enumerator_pubname. (output_pubnames): Output debug_pubnames_section_label or debug_pubtypes_section_label. (base_type_die): Call add_pubtype. (gen_namespace_die): Call add_pubname_string and lang_hooks.dwarf_name. (dwarf2out_init): Generate debug_pubnames_section_label and debug_pubtypes_section_label. (dwarf2out_finish): Call add_AT_lineptr if pubnames or pubtypes is non-empty. When dealing with pubnames, change assertion to conditional. Call pubtypes_section_empty. Likewise when dealing with pubtypes. Move code checking for empty section to... (pubtypes_section_empty): ...here. New function. * gcc/target.def: Switch default generate pubnames and types to true. cp-family/ChangeLog: 2011-12-17 Sterling Augustine * gcc/c-family/c-pretty-print.c (pp_c_specifier_qualifier_list): Move conditional from beginning to end. cp/ChangeLog 2011-12-17 Sterling Augustine * gcc/cp/error.c (dump_decl): Reformat return value to "(anonymous namespace)". (lang_decl_name): Return "(anonymous namespace)" when appropriate. include/ChangeLog * include/dwarf2.h (enum dwarf_form): Add forms DW_FORM_GNU_ref_index, DW_FORM_GNU_addr_index and DW_FORM_GNU_str_index. (enum dwarf_attribute): Add attributes: Add DW_AT_GNU_dwo_name, DW_AT_GNU_dwo_id, DW_AT_GNU_ref_base, DW_AT_GNU_addr_base, DW_AT_GNU_pubnames and DW_AT_GNU_pubtypes. --- This patch is available for review at http://codereview.appspot.com/5489074 diff --git a/gcc/c-family/c-pretty-print.c b/gcc/c-family/c-pretty-print.c index 621b7f6..55ed41e 100644 --- a/gcc/c-family/c-pretty-print.c +++ b/gcc/c-family/c-pretty-print.c @@ -446,8 +446,6 @@ pp_c_specifier_qualifier_list (c_pretty_printer *pp, tree t) { const enum tree_code code = TREE_CODE (t); - if (TREE_CODE (t) != POINTER_TYPE) - pp_c_type_qualifier_list (pp, t); switch (code) { case REFERENCE_TYPE: @@ -494,6 +492,8 @@ pp_c_specifier_qualifier_list (c_pretty_printer *pp, tree t) pp_simple_type_specifier (pp, t); break; } + if (TREE_CODE (t) != POINTER_TYPE) + pp_c_type_qualifier_list (pp, t); } /* parameter-type-list: diff --git a/gcc/cp/error.c b/gcc/cp/error.c index 52c84cb..194fc76 100644 --- a/gcc/cp/error.c +++ b/gcc/cp/error.c @@ -988,7 +988,7 @@ dump_decl (tree t, int flags) dump_scope (CP_DECL_CONTEXT (t), flags); flags &= ~TFF_UNQUALIFIED_NAME; if (DECL_NAME (t) == NULL_TREE) - pp_cxx_ws_string (cxx_pp, M_("{anonymous}")); + pp_cxx_ws_string (cxx_pp, M_("(anonymous namespace)")); else pp_cxx_tree_identifier (cxx_pp, DECL_NAME (t)); } @@ -2536,6 +2536,8 @@ lang_decl_name (tree decl, int v, bool translate) if (TREE_CODE (decl) == FUNCTION_DECL) dump_function_name (decl, TFF_PLAIN_IDENTIFIER); + else if (DECL_NAME (decl) == NULL && TREE_CODE (decl) == NAMESPACE_DECL) + pp_string (cxx_pp, M_("(anonymous namespace)")); else dump_decl (DECL_NAME (decl), TFF_PLAIN_IDENTIFIER); diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index 844bba3..6512292 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -3343,6 +3343,7 @@ static void output_comp_unit (dw_die_ref, int); static void output_comdat_type_unit (comdat_type_node *); static const char *dwarf2_name (tree, int); static void add_pubname (tree, dw_die_ref); +static void add_enumerator_pubname (const char *, const char *, dw_die_ref); static void add_pubname_string (const char *, dw_die_ref); static void add_pubtype (tree, dw_die_ref); static void output_pubnames (VEC (pubname_entry,gc) *); @@ -3546,6 +3547,12 @@ static void gen_scheduled_generic_parms_dies (void); #ifndef COLD_TEXT_SECTION_LABEL #define COLD_TEXT_SECTION_LABEL "Ltext_cold" #endif +#ifndef DEBUG_PUBNAMES_SECTION_LABEL +#define DEBUG_PUBNAMES_SECTION_LABEL "Ldebug_pubnames" +#endif +#ifndef DEBUG_PUBTYPES_SECTION_LABEL +#define DEBUG_PUBTYPES_SECTION_LABEL "Ldebug_pubtypes" +#endif #ifndef DEBUG_LINE_SECTION_LABEL #define DEBUG_LINE_SECTION_LABEL "Ldebug_line" #endif @@ -3582,6 +3589,8 @@ static char cold_end_label[MAX_ARTIFICIAL_LABEL_BYTES]; static char abbrev_section_label[MAX_ARTIFICIAL_LABEL_BYTES]; static char debug_info_section_label[MAX_ARTIFICIAL_LABEL_BYTES]; static char debug_line_section_label[MAX_ARTIFICIAL_LABEL_BYTES]; +static char debug_pubnames_section_label[MAX_ARTIFICIAL_LABEL_BYTES]; +static char debug_pubtypes_section_label[MAX_ARTIFICIAL_LABEL_BYTES]; static char macinfo_section_label[MAX_ARTIFICIAL_LABEL_BYTES]; static char loc_section_label[MAX_ARTIFICIAL_LABEL_BYTES]; static char ranges_section_label[2 * MAX_ARTIFICIAL_LABEL_BYTES]; @@ -6716,6 +6725,22 @@ is_cu_die (dw_die_ref c) return c && c->die_tag == DW_TAG_compile_unit; } +/* Returns true iff C is a namespace DIE. */ + +static inline bool +is_namespace_die (dw_die_ref c) +{ + return c && c->die_tag == DW_TAG_namespace; +} + +/* Returns true iff C is a class DIE. */ + +static inline bool +is_class_die (dw_die_ref c) +{ + return c && c->die_tag == DW_TAG_class_type; +} + static char * gen_internal_sym (const char *prefix) { @@ -8638,12 +8663,33 @@ add_pubname (tree decl, dw_die_ref die) && targetm.want_debug_pub_sections && TREE_PUBLIC (decl)) { - const char *name = dwarf2_name (decl, 1); - if (name) - add_pubname_string (name, die); + if ((TREE_PUBLIC (decl) && !is_class_die (die->die_parent)) + || is_cu_die (die->die_parent) || is_namespace_die (die->die_parent)) + { + const char *name = dwarf2_name (decl, 1); + if (name) + add_pubname_string (name, die); + } } } +/* Add an enumerator to the pubnames section. */ + +static void +add_enumerator_pubname (const char *scope_name, const char *sep, dw_die_ref die) +{ + const char *name; + pubname_entry e; + + if (scope_name) + name = concat (scope_name, sep, get_AT_string (die, DW_AT_name), NULL); + else + name = xstrdup (get_AT_string (die, DW_AT_name)); + e.name = name; + e.die = die; + VEC_safe_push (pubname_entry, gc, pubtype_table, &e); +} + /* Add a new entry to .debug_pubtypes if appropriate. */ static void @@ -8656,34 +8702,47 @@ add_pubtype (tree decl, dw_die_ref die) e.name = NULL; if ((TREE_PUBLIC (decl) - || is_cu_die (die->die_parent)) + || is_cu_die (die->die_parent) || is_namespace_die (die->die_parent)) && (die->die_tag == DW_TAG_typedef || COMPLETE_TYPE_P (decl))) { - e.die = die; + tree scope = NULL; + const char *scope_name = NULL; + const char *sep = is_cxx () ? "::" : "."; + const char *name = NULL; + if (TYPE_P (decl)) - { - if (TYPE_NAME (decl)) - { - if (TREE_CODE (TYPE_NAME (decl)) == IDENTIFIER_NODE) - e.name = IDENTIFIER_POINTER (TYPE_NAME (decl)); - else if (TREE_CODE (TYPE_NAME (decl)) == TYPE_DECL - && DECL_NAME (TYPE_NAME (decl))) - e.name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (decl))); - else - e.name = xstrdup ((const char *) get_AT_string (die, DW_AT_name)); - } - } + name = type_tag (decl); else - { - e.name = dwarf2_name (decl, 1); - if (e.name) - e.name = xstrdup (e.name); - } + name = lang_hooks.dwarf_name (decl, 1); /* If we don't have a name for the type, there's no point in adding it to the table. */ - if (e.name && e.name[0] != '\0') - VEC_safe_push (pubname_entry, gc, pubtype_table, &e); + if (name == NULL || name[0] == '\0') + return; + + e.die = die; + e.name = xstrdup (name); + + scope = TYPE_P (decl) ? TYPE_CONTEXT (decl) : NULL; + if (scope && TREE_CODE (scope) == NAMESPACE_DECL) + { + scope_name = lang_hooks.dwarf_name (scope, 1); + if (scope_name != NULL) + e.name = concat (scope_name, sep, e.name, NULL); + } + VEC_safe_push (pubname_entry, gc, pubtype_table, &e); + + /* Although it might be more consistent to add the pubinfo for the + enumerators as their dies are created, they should only be added if the + enum type meets the criteria above. So rather than re-check the parent + enum type whenever an enumerator die is created, just output them all + here. */ + if (die->die_tag == DW_TAG_enumeration_type) + { + dw_die_ref c; + + FOR_EACH_CHILD (die, c, add_enumerator_pubname (scope_name, sep, c)); + } } } @@ -8697,6 +8756,10 @@ output_pubnames (VEC (pubname_entry, gc) * names) unsigned long pubnames_length = size_of_pubnames (names); pubname_ref pub; + if (names == pubname_table) + ASM_OUTPUT_LABEL (asm_out_file, debug_pubnames_section_label); + else + 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"); @@ -9608,6 +9671,7 @@ base_type_die (tree type) add_AT_unsigned (base_type_result, DW_AT_byte_size, int_size_in_bytes (type)); add_AT_unsigned (base_type_result, DW_AT_encoding, encoding); + add_pubtype (type, base_type_result); return base_type_result; } @@ -19382,6 +19446,8 @@ gen_namespace_die (tree decl, dw_die_ref context_die) add_AT_die_ref (namespace_die, DW_AT_import, origin_die); equate_decl_number_to_die (decl, namespace_die); } + /* Bypass dwarf2_name's check for DECL_NAMELESS. */ + add_pubname_string (lang_hooks.dwarf_name (decl, 1), namespace_die); } /* Generate Dwarf debug information for a decl described by DECL. @@ -21049,6 +21115,10 @@ dwarf2out_init (const char *filename ATTRIBUTE_UNUSED) ASM_GENERATE_INTERNAL_LABEL (debug_info_section_label, DEBUG_INFO_SECTION_LABEL, 0); + ASM_GENERATE_INTERNAL_LABEL (debug_pubnames_section_label, + DEBUG_PUBNAMES_SECTION_LABEL, 0); + ASM_GENERATE_INTERNAL_LABEL (debug_pubtypes_section_label, + DEBUG_PUBTYPES_SECTION_LABEL, 0); ASM_GENERATE_INTERNAL_LABEL (debug_line_section_label, DEBUG_LINE_SECTION_LABEL, 0); ASM_GENERATE_INTERNAL_LABEL (ranges_section_label, @@ -22391,6 +22461,30 @@ optimize_location_lists (dw_die_ref die) htab_delete (htab); } + +/* Report if the pubtypes_section is either empty or will be pruned to + empty. */ + +static bool +pubtypes_section_empty (void) +{ + if (!VEC_empty (pubname_entry, pubtype_table)) + { + if (flag_eliminate_unused_debug_types) + { + /* The pubtypes table might be emptied by pruning unused items. */ + unsigned i; + pubname_ref p; + FOR_EACH_VEC_ELT (pubname_entry, pubtype_table, i, p) + if (p->die->die_offset != 0) + return false; + } + return true; + } + return false; +} + + /* Output stuff that dwarf requires at the end of every file, and generate the DWARF-2 debugging info. */ @@ -22654,6 +22748,22 @@ dwarf2out_finish (const char *filename) } htab_delete (comdat_type_table); + /* Add the DW_AT_GNU_pubnames and DW_AT_GNU_pubtypes attributes. */ + if (!VEC_empty (pubname_entry, pubname_table)) + { + /* FIXME: Should use add_AT_pubnamesptr. This works because + most targets don't care what the base section is. */ + add_AT_lineptr (comp_unit_die (), DW_AT_GNU_pubnames, + debug_pubnames_section_label); + } + if (!pubtypes_section_empty ()) + { + /* FIXME: Should use add_AT_pubtypesptr. This works because + most targets don't care what the base section is. */ + add_AT_lineptr (comp_unit_die (), DW_AT_GNU_pubtypes, + debug_pubtypes_section_label); + } + /* Output the main compilation unit if non-empty or if .debug_macinfo will be emitted. */ output_comp_unit (comp_unit_die (), debug_info_level >= DINFO_LEVEL_VERBOSE); @@ -22678,9 +22788,8 @@ dwarf2out_finish (const char *filename) } /* Output public names table if necessary. */ - if (!VEC_empty (pubname_entry, pubname_table)) + if (!VEC_empty (pubname_entry, pubname_table) && info_section_emitted) { - gcc_assert (info_section_emitted); switch_to_section (debug_pubnames_section); output_pubnames (pubname_table); } @@ -22689,29 +22798,10 @@ dwarf2out_finish (const char *filename) /* ??? 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. */ - if (!VEC_empty (pubname_entry, pubtype_table)) + if (!pubtypes_section_empty () && info_section_emitted) { - bool empty = false; - - if (flag_eliminate_unused_debug_types) - { - /* The pubtypes table might be emptied by pruning unused items. */ - unsigned i; - pubname_ref p; - empty = true; - FOR_EACH_VEC_ELT (pubname_entry, pubtype_table, i, p) - if (p->die->die_offset != 0) - { - empty = false; - break; - } - } - if (!empty) - { - gcc_assert (info_section_emitted); - switch_to_section (debug_pubtypes_section); - output_pubnames (pubtype_table); - } + switch_to_section (debug_pubtypes_section); + output_pubnames (pubtype_table); } /* Output the address range information if a CU (.debug_info section) diff --git a/gcc/target.def b/gcc/target.def index b72b265..7ce8555 100644 --- a/gcc/target.def +++ b/gcc/target.def @@ -2753,7 +2753,7 @@ DEFHOOKPOD "True if the @code{.debug_pubtypes} and @code{.debug_pubnames} sections\ should be emitted. These sections are not used on most platforms, and\ in particular GDB does not use them.", - bool, false) + bool, true) DEFHOOKPOD (delay_sched2, "True if sched2 is not to be run at its normal place. \ diff --git a/include/dwarf2.h b/include/dwarf2.h index 37cb83f..b93aebf 100644 --- a/include/dwarf2.h +++ b/include/dwarf2.h @@ -188,7 +188,11 @@ enum dwarf_form DW_FORM_sec_offset = 0x17, DW_FORM_exprloc = 0x18, DW_FORM_flag_present = 0x19, - DW_FORM_ref_sig8 = 0x20 + DW_FORM_ref_sig8 = 0x20, + /* Extensions for Fission. */ + DW_FORM_GNU_ref_index = 0x70, + DW_FORM_GNU_addr_index = 0x71, + DW_FORM_GNU_str_index = 0x72 }; /* Attribute names and codes. */ @@ -368,6 +372,13 @@ enum dwarf_attribute DW_AT_GNU_all_source_call_sites = 0x2118, /* Section offset into .debug_macro section. */ DW_AT_GNU_macros = 0x2119, + /* Extensions for Fission. */ + DW_AT_GNU_dwo_name = 0x2130, + DW_AT_GNU_dwo_id = 0x2131, + DW_AT_GNU_ref_base = 0x2132, + DW_AT_GNU_addr_base = 0x2133, + DW_AT_GNU_pubnames = 0x2134, + DW_AT_GNU_pubtypes = 0x2135, /* VMS extensions. */ DW_AT_VMS_rtnbeg_pd_address = 0x2201, /* GNAT extensions. */