From patchwork Tue Mar 20 01:59:03 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cary Coutant X-Patchwork-Id: 147720 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 63A27B7061 for ; Tue, 20 Mar 2012 12:59:45 +1100 (EST) Comment: DKIM? See http://www.dkim.org DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d=gcc.gnu.org; s=default; x=1332813586; h=Comment: DomainKey-Signature:Received:Received:Received:Received:Received: Received:Received:Received:Received:To:Subject:Message-Id:Date: From:Mailing-List:Precedence:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:Sender:Delivered-To; bh=YSsqidt SxAhVAJRcIELD0ajhjGk=; b=f8jNKrjD3pLn8PX5AXATizAf2+p/jniCDITYvXF F3c9rS7KKDKLQ9JKsdgKtvYTdXSIIC6uDvfaORQmHMdI1ZbWMhbop9y3Zbz/uI9T seEid2g9dK4I8O0tIczeP0tOcg7hn8LhNGGmrcj4XkY+QuSn6xQlcxy98lmA3XGr Qa1o= Comment: DomainKeys? See http://antispam.yahoo.com/domainkeys DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=default; d=gcc.gnu.org; h=Received:Received:X-SWARE-Spam-Status:X-Spam-Check-By:Received:Received:X-Google-DKIM-Signature:Received:Received:Received:Received:Received:To:Subject:Message-Id:Date:From:X-Gm-Message-State:X-IsSubscribed:Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post:List-Help:Sender:Delivered-To; b=CZ1bQDMfs1fkomfPYvZJl9pOh52H9xisuCJPwqVKbIo7Y6Y3PYdhWX0luKkNf0 5i3JjHmQPx8Uee9lU5uId3i/pO/eZLzKIMAbu6znrkPgGNZFeFbdp32hH6s4Z1Bb Jr6Z6Sl/7JOBU4sYY/VK6JmivLhNgz7iQhlMoWjYFQYgY=; Received: (qmail 12754 invoked by alias); 20 Mar 2012 01:59:40 -0000 Received: (qmail 12012 invoked by uid 22791); 20 Mar 2012 01:59:35 -0000 X-SWARE-Spam-Status: No, hits=-2.4 required=5.0 tests=AWL, BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, RCVD_IN_DNSWL_LOW, TW_CP, TW_TM, T_RP_MATCHES_RCVD 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; Tue, 20 Mar 2012 01:59:06 +0000 Received: by eeit10 with SMTP id t10so337155eei.2 for ; Mon, 19 Mar 2012 18:59:05 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=to:subject:message-id:date:from:x-gm-message-state; bh=qeATVUjMZIlDW/F2rsR+32uqDO0CBePhApGdoZQCnxc=; b=JgrQYA1ctqS6upw61jMkPzFH9aihYduVpVP6aA4uI3gVqpc2Ot+8HDX06DmOQ0QGT+ NQ6JYakvogC2nUkmyRtPMHoHsYf7E9td779u4/Z7KfsiEwchdOeNWhRraowfDP+oNBx/ azcoDCEnFAodv5CmWnzulZeGSk/BSzaoxkm+MHu/B8WQtl6kcIvECdCqW94oiN26TH1Q MCHZgBr0K5DcrXTcaPeSBRrLgRx5A/kDD1USk6QMUdP8du05Z1oIHoX++OYbLjGBt+kv /YWalpMU+dwVi+mkr9z6YwKiVNlNFy9utGeIc2ujKGhzyzKPyQBUZo/YxGziCOf6gWXO n06A== Received: by 10.213.9.67 with SMTP id k3mr1041280ebk.14.1332208744998; Mon, 19 Mar 2012 18:59:04 -0700 (PDT) Received: by 10.213.9.67 with SMTP id k3mr1041270ebk.14.1332208744871; Mon, 19 Mar 2012 18:59:04 -0700 (PDT) Received: from hpza9.eem.corp.google.com ([74.125.121.33]) by gmr-mx.google.com with ESMTPS id f5si25496eeo.2.2012.03.19.18.59.04 (version=TLSv1/SSLv3 cipher=AES128-SHA); Mon, 19 Mar 2012 18:59:04 -0700 (PDT) Received: from ccoutant.mtv.corp.google.com (ccoutant.mtv.corp.google.com [172.18.110.42]) by hpza9.eem.corp.google.com (Postfix) with ESMTP id 32D9F5C0050; Mon, 19 Mar 2012 18:59:04 -0700 (PDT) Received: by ccoutant.mtv.corp.google.com (Postfix, from userid 62097) id 7C87AE2847; Mon, 19 Mar 2012 18:59:03 -0700 (PDT) To: reply@codereview.appspotmail.com, saugustine@google.com, gcc-patches@gcc.gnu.org Subject: [google/4.6] Fix problems with -gfission (issue5844043) Message-Id: <20120320015903.7C87AE2847@ccoutant.mtv.corp.google.com> Date: Mon, 19 Mar 2012 18:59:03 -0700 (PDT) From: ccoutant@google.com (Cary Coutant) X-Gm-Message-State: ALoCoQkYNG/sA2Sy3K179hqHNE2yEs8hbYbO2gJv4pEGwOoeqfPq0nERi4WNbQtA7Z5czXNGYnjM59KiBU4lnpjZtQqn016wmajnqlFWj7zMh8YL1dt3Pt09wy9ymAgRhZA4XOVvWuasqIONiAAaRMditnHhz4hK6Wtc65W0rz/cJSPYmFncML0= X-IsSubscribed: yes 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 This is for the google/gcc-4_6 branch only. This revised patch fixes several problems with -gfission: - Bad index for range list in the compile unit DIE. - DW_AT_ranges attribute for compile unit in the wrong file. - Incorrect size for skeleton type unit DIEs. - Wrote location expression using DW_OP_addr to DWO file. - Emitted skeleton debug section even when there is no debug info. It also addresses a problem with the previous patch that resulted in an ICE when a location expression is removed after creating an addr_table entry for it. Tested: bootstrap, core, mantle, crust (in progress). 2012-03-19 Sterling Augustine Cary Coutant * dwarf2out.c (dwarf_stack_op_name): Add DW_OP_GNU_addr_index. (new_loc_descr): Initialize val_index. (size_of_loc_descr): Add DW_OP_GNU_addr_index. (output_loc_operands): Likewise. (output_loc_operands_raw): Likewise. (build_cfa_loc): Initialize val_index. (new_addr_loc_descr): New function. (add_AT_flag): Initialize val_index. (add_AT_int): Likewise. (add_AT_unsigned): Likewise. (add_AT_double): Likewise. (add_AT_vec): Likewise. (add_AT_data8): Likewise. (add_AT_string): Likewise. (add_AT_die_ref): Likewise. (add_AT_fde_ref): Likewise. (add_AT_loc): Likewise. (add_AT_loc_list): Likewise. (add_addr_table_entry): Change if to assert. (remove_addr_table_entry): New function. (add_AT_addr): Add force_direct parameter; adjust all callers. Initialize val_index. (add_AT_file): Initialize val_index. (add_AT_vms_delta): Likewise. (add_AT_lbl_id): Add force_direct parameter; adjust all callers. Initialize val_index. (add_AT_lineptr): Initialize val_index. (add_AT_macptr): Likewise. (add_AT_offset): Likewise. (add_AT_range_list): Add force_direct parameter; adjust all callers. Initialize val_index. (size_of_die): Check for AT_index. (value_format): Likewise. (output_attr_index_or_value): Likewise. (output_die): Fix format warning. (add_top_level_skeleton_die_attrs): Don't add DW_AT_stmt_list here. (get_skeleton_type_unit): New function. (output_skeleton_debug_sections): Add comp_unit parameter; adjust caller; don't generate debug_skeleton_info_section_label or debug_skeleton_abbrev_section_label here; call get_skeleton_type_unit. (output_comdat_type_unit): Remove assert; call get_skeleton_type_unit. (add_ranges_by_labels): Add force_direct parameter; adjust callers. (address_of_int_loc_descriptor): Initialize val_index. (mem_loc_descriptor): Initialize val_index; call new_addr_loc_descr. (implicit_ptr_descriptor): Don't generate DW_OP_GNU_implicit_pointer when splitting debug info. Initialize val_index. (loc_descriptor): Initialize val_index; call new_addr_loc_descr. (loc_list_from_tree): Likewise. (add_const_value_attribute): Likewise. (dwarf2out_init): Generate debug_skeleton_info_section_label and debug_skeleton_abbrev_section_label here. (output_indirect_string): Check for DW_FORM_strp instead of label and refcount. (output_addr_table): Check for removed entries, handle dw_val_class_loc. (resolve_addr_in_expr): Handle DW_OP_GNU_addr_index. (resolve_addr): Remove entry from addr_table if necessary. (hash_loc_operands): Add DW_OP_GNU_addr_index. (compare_loc_operands): Likewise. (dwarf2out_finish): Put DW_AT_low_pc, DW_AT_high_pc, DW_AT_ranges, DW_AT_stmt_list, DW_AT_macptr in skeleton comp_unit DIE; write skeleton debug sections if regular debug section emitted. --- This patch is available for review at http://codereview.appspot.com/5844043 Index: dwarf2out.c =================================================================== --- dwarf2out.c (revision 185555) +++ dwarf2out.c (working copy) @@ -4779,6 +4779,8 @@ dwarf_stack_op_name (unsigned int op) return "DW_OP_GNU_encoded_addr"; case DW_OP_GNU_implicit_pointer: return "DW_OP_GNU_implicit_pointer"; + case DW_OP_GNU_addr_index: + return "DW_OP_GNU_addr_index"; default: return "OP_"; @@ -4797,8 +4799,10 @@ new_loc_descr (enum dwarf_location_atom descr->dw_loc_opc = op; descr->dw_loc_oprnd1.val_class = dw_val_class_unsigned_const; + descr->dw_loc_oprnd1.val_index = -1U; descr->dw_loc_oprnd1.v.val_unsigned = oprnd1; descr->dw_loc_oprnd2.val_class = dw_val_class_unsigned_const; + descr->dw_loc_oprnd2.val_index = -1U; descr->dw_loc_oprnd2.v.val_unsigned = oprnd2; return descr; @@ -4897,6 +4901,9 @@ size_of_loc_descr (dw_loc_descr_ref loc) case DW_OP_addr: size += DWARF2_ADDR_SIZE; break; + case DW_OP_GNU_addr_index: + size += size_of_uleb128 (loc->dw_loc_oprnd1.v.val_unsigned); + break; case DW_OP_const1u: case DW_OP_const1s: size += 1; @@ -5275,6 +5282,11 @@ output_loc_operands (dw_loc_descr_ref lo } break; + case DW_OP_GNU_addr_index: + dw2_asm_output_data_uleb128 (loc->dw_loc_oprnd1.v.val_unsigned, + "(address index)"); + break; + case DW_OP_GNU_implicit_pointer: { char label[MAX_ARTIFICIAL_LABEL_BYTES @@ -5343,6 +5355,7 @@ output_loc_operands_raw (dw_loc_descr_re switch (loc->dw_loc_opc) { case DW_OP_addr: + case DW_OP_GNU_addr_index: case DW_OP_implicit_value: /* We cannot output addresses in .cfi_escape, only bytes. */ gcc_unreachable (); @@ -5573,6 +5586,7 @@ build_cfa_loc (dw_cfa_location *cfa, HOS { head = new_reg_loc_descr (cfa->reg, cfa->base_offset); head->dw_loc_oprnd1.val_class = dw_val_class_const; + head->dw_loc_oprnd1.val_index = -1U; tmp = new_loc_descr (DW_OP_deref, 0, 0); add_loc_descr (&head, tmp); if (offset != 0) @@ -6314,15 +6328,18 @@ static inline dw_loc_descr_ref AT_loc (d static void add_AT_loc_list (dw_die_ref, enum dwarf_attribute, dw_loc_list_ref); static inline dw_loc_list_ref AT_loc_list (dw_attr_ref); -static void add_AT_addr (dw_die_ref, enum dwarf_attribute, rtx); +static unsigned int add_addr_table_entry (dw_attr_node *); +static void remove_addr_table_entry (unsigned int); +static void add_AT_addr (dw_die_ref, enum dwarf_attribute, rtx, bool); static inline rtx AT_addr (dw_attr_ref); -static void add_AT_lbl_id (dw_die_ref, enum dwarf_attribute, const char *); +static void add_AT_lbl_id (dw_die_ref, enum dwarf_attribute, const char *, + bool); static void add_AT_lineptr (dw_die_ref, enum dwarf_attribute, const char *); static void add_AT_macptr (dw_die_ref, enum dwarf_attribute, const char *); static void add_AT_offset (dw_die_ref, enum dwarf_attribute, unsigned HOST_WIDE_INT); static void add_AT_range_list (dw_die_ref, enum dwarf_attribute, - unsigned long); + unsigned long, bool); static inline const char *AT_lbl (dw_attr_ref); static dw_attr_ref get_AT (dw_die_ref, enum dwarf_attribute); static const char *get_AT_low_pc (dw_die_ref); @@ -6432,7 +6449,7 @@ static void output_aranges (unsigned lon static unsigned int add_ranges_num (int); static unsigned int add_ranges (const_tree); static void add_ranges_by_labels (dw_die_ref, const char *, const char *, - bool *); + bool *, bool); static void output_ranges (void); static void output_line_info (bool); static void output_file_names (void); @@ -6571,6 +6588,33 @@ static bool generic_type_p (tree); static void schedule_generic_params_dies_gen (tree t); static void gen_scheduled_generic_parms_dies (void); +/* Return a pointer to a newly allocated address location description. If + dwarf_split_debug_info is true, then record the address with the appropriate + relocation. */ +static inline dw_loc_descr_ref +new_addr_loc_descr (rtx addr, int dtprel) +{ + dw_loc_descr_ref ref = new_loc_descr (DW_OP_addr, 0, 0); + + ref->dw_loc_oprnd1.val_class = dw_val_class_addr; + ref->dw_loc_oprnd1.val_index = -1U; + ref->dw_loc_oprnd1.v.val_addr = addr; + if (dwarf_split_debug_info) + { + dw_attr_node attr; + + attr.dw_attr = DW_AT_location; + attr.dw_attr_val.val_class = (dtprel + ? dw_val_class_loc : dw_val_class_addr); + attr.dw_attr_val.val_index = -1U; + attr.dw_attr_val.v.val_addr = addr; + + ref->dw_loc_opc = DW_OP_GNU_addr_index; + ref->dw_loc_oprnd1.val_index = add_addr_table_entry (&attr); + } + return ref; +} + /* Section names used to hold DWARF debugging information. */ #ifndef DEBUG_INFO_SECTION @@ -7358,7 +7402,7 @@ AT_class (dw_attr_ref a) } /* Return the index for any attribute that will be referenced with a - DW_FORM_GNU_ref_index of DW_FORM_GNU_addr_index. Strings have their + DW_FORM_GNU_ref_index or DW_FORM_GNU_addr_index. Strings have their indices handled differently to account for reference counting pruning. */ @@ -7372,7 +7416,7 @@ AT_index (dw_attr_ref a) } /* Set the index for any attribute that will be referenced with a - DW_FORM_GNU_ref_index of DW_FORM_GNU_addr_index. */ + DW_FORM_GNU_ref_index or DW_FORM_GNU_addr_index. */ static inline void set_AT_index (dw_attr_ref a, unsigned int index) @@ -7392,6 +7436,7 @@ add_AT_flag (dw_die_ref die, enum dwarf_ attr.dw_attr = attr_kind; attr.dw_attr_val.val_class = dw_val_class_flag; + attr.dw_attr_val.val_index = -1U; attr.dw_attr_val.v.val_flag = flag; add_dwarf_attr (die, &attr); } @@ -7412,6 +7457,7 @@ add_AT_int (dw_die_ref die, enum dwarf_a attr.dw_attr = attr_kind; attr.dw_attr_val.val_class = dw_val_class_const; + attr.dw_attr_val.val_index = -1U; attr.dw_attr_val.v.val_int = int_val; add_dwarf_attr (die, &attr); } @@ -7433,6 +7479,7 @@ add_AT_unsigned (dw_die_ref die, enum dw attr.dw_attr = attr_kind; attr.dw_attr_val.val_class = dw_val_class_unsigned_const; + attr.dw_attr_val.val_index = -1U; attr.dw_attr_val.v.val_unsigned = unsigned_val; add_dwarf_attr (die, &attr); } @@ -7454,6 +7501,7 @@ add_AT_double (dw_die_ref die, enum dwar attr.dw_attr = attr_kind; attr.dw_attr_val.val_class = dw_val_class_const_double; + attr.dw_attr_val.val_index = -1U; attr.dw_attr_val.v.val_double.high = high; attr.dw_attr_val.v.val_double.low = low; add_dwarf_attr (die, &attr); @@ -7469,6 +7517,7 @@ add_AT_vec (dw_die_ref die, enum dwarf_a attr.dw_attr = attr_kind; attr.dw_attr_val.val_class = dw_val_class_vec; + attr.dw_attr_val.val_index = -1U; attr.dw_attr_val.v.val_vec.length = length; attr.dw_attr_val.v.val_vec.elt_size = elt_size; attr.dw_attr_val.v.val_vec.array = array; @@ -7485,6 +7534,7 @@ add_AT_data8 (dw_die_ref die, enum dwarf attr.dw_attr = attr_kind; attr.dw_attr_val.val_class = dw_val_class_data8; + attr.dw_attr_val.val_index = -1U; memcpy (attr.dw_attr_val.v.val_data8, data8, 8); add_dwarf_attr (die, &attr); } @@ -7543,6 +7593,7 @@ add_AT_string (dw_die_ref die, enum dwar attr.dw_attr = attr_kind; attr.dw_attr_val.val_class = dw_val_class_str; + attr.dw_attr_val.val_index = -1U; attr.dw_attr_val.v.val_str = node; add_dwarf_attr (die, &attr); } @@ -7656,6 +7707,7 @@ add_AT_die_ref (dw_die_ref die, enum dwa attr.dw_attr = attr_kind; attr.dw_attr_val.val_class = dw_val_class_die_ref; + attr.dw_attr_val.val_index = -1U; attr.dw_attr_val.v.val_die_ref.die = targ_die; attr.dw_attr_val.v.val_die_ref.external = 0; add_dwarf_attr (die, &attr); @@ -7704,6 +7756,7 @@ add_AT_fde_ref (dw_die_ref die, enum dwa attr.dw_attr = attr_kind; attr.dw_attr_val.val_class = dw_val_class_fde_ref; + attr.dw_attr_val.val_index = -1U; attr.dw_attr_val.v.val_fde_index = targ_fde; add_dwarf_attr (die, &attr); } @@ -7717,6 +7770,7 @@ add_AT_loc (dw_die_ref die, enum dwarf_a attr.dw_attr = attr_kind; attr.dw_attr_val.val_class = dw_val_class_loc; + attr.dw_attr_val.val_index = -1U; attr.dw_attr_val.v.val_loc = loc; add_dwarf_attr (die, &attr); } @@ -7735,6 +7789,7 @@ add_AT_loc_list (dw_die_ref die, enum dw attr.dw_attr = attr_kind; attr.dw_attr_val.val_class = dw_val_class_loc_list; + attr.dw_attr_val.val_index = -1U; attr.dw_attr_val.v.val_loc_list = loc_list; add_dwarf_attr (die, &attr); have_location_lists = true; @@ -7761,26 +7816,41 @@ static GTY (()) VEC (dw_attr_node,gc) * static unsigned int add_addr_table_entry (dw_attr_node *attr) { - if (dwarf_split_debug_info) - { - VEC_safe_push (dw_attr_node, gc, addr_index_table, attr); - return VEC_length (dw_attr_node, addr_index_table) - 1; - } - return 0; + gcc_assert (dwarf_split_debug_info); + + VEC_safe_push (dw_attr_node, gc, addr_index_table, attr); + return VEC_length (dw_attr_node, addr_index_table) - 1; +} + +/* Remove an entry from the addr table. Since we have already numbered + all the entries, the best we can do here is null it out. */ + +static void +remove_addr_table_entry (unsigned int i) +{ + dw_attr_node *attr; + + gcc_assert (dwarf_split_debug_info); + gcc_assert (i < VEC_length (dw_attr_node, addr_index_table)); + + attr = VEC_index (dw_attr_node, addr_index_table, i); + attr->dw_attr = (enum dwarf_attribute) 0; } /* Add an address constant attribute value to a DIE. */ static inline void -add_AT_addr (dw_die_ref die, enum dwarf_attribute attr_kind, rtx addr) +add_AT_addr (dw_die_ref die, enum dwarf_attribute attr_kind, rtx addr, + bool force_direct) { dw_attr_node attr; attr.dw_attr = attr_kind; attr.dw_attr_val.val_class = dw_val_class_addr; + attr.dw_attr_val.val_index = -1U; attr.dw_attr_val.v.val_addr = addr; add_dwarf_attr (die, &attr); - if (dwarf_split_debug_info) + if (dwarf_split_debug_info && !force_direct) set_AT_index (get_AT (die, attr_kind), add_addr_table_entry (&attr)); } @@ -7803,6 +7873,7 @@ add_AT_file (dw_die_ref die, enum dwarf_ attr.dw_attr = attr_kind; attr.dw_attr_val.val_class = dw_val_class_file; + attr.dw_attr_val.val_index = -1U; attr.dw_attr_val.v.val_file = fd; add_dwarf_attr (die, &attr); } @@ -7826,6 +7897,7 @@ add_AT_vms_delta (dw_die_ref die, enum d attr.dw_attr = attr_kind; attr.dw_attr_val.val_class = dw_val_class_vms_delta; + attr.dw_attr_val.val_index = -1U; attr.dw_attr_val.v.val_vms_delta.lbl1 = xstrdup (lbl1); attr.dw_attr_val.v.val_vms_delta.lbl2 = xstrdup (lbl2); add_dwarf_attr (die, &attr); @@ -7834,15 +7906,17 @@ add_AT_vms_delta (dw_die_ref die, enum d /* Add a label identifier attribute value to a DIE. */ static inline void -add_AT_lbl_id (dw_die_ref die, enum dwarf_attribute attr_kind, const char *lbl_id) +add_AT_lbl_id (dw_die_ref die, enum dwarf_attribute attr_kind, + const char *lbl_id, bool force_direct) { dw_attr_node attr; attr.dw_attr = attr_kind; attr.dw_attr_val.val_class = dw_val_class_lbl_id; + attr.dw_attr_val.val_index = -1U; attr.dw_attr_val.v.val_lbl_id = xstrdup (lbl_id); add_dwarf_attr (die, &attr); - if (dwarf_split_debug_info) + if (dwarf_split_debug_info && !force_direct) set_AT_index (get_AT (die, attr_kind), add_addr_table_entry (&attr)); } @@ -7857,6 +7931,7 @@ add_AT_lineptr (dw_die_ref die, enum dwa attr.dw_attr = attr_kind; attr.dw_attr_val.val_class = dw_val_class_lineptr; + attr.dw_attr_val.val_index = -1U; attr.dw_attr_val.v.val_lbl_id = xstrdup (label); add_dwarf_attr (die, &attr); } @@ -7872,6 +7947,7 @@ add_AT_macptr (dw_die_ref die, enum dwar attr.dw_attr = attr_kind; attr.dw_attr_val.val_class = dw_val_class_macptr; + attr.dw_attr_val.val_index = -1U; attr.dw_attr_val.v.val_lbl_id = xstrdup (label); add_dwarf_attr (die, &attr); } @@ -7886,6 +7962,7 @@ add_AT_offset (dw_die_ref die, enum dwar attr.dw_attr = attr_kind; attr.dw_attr_val.val_class = dw_val_class_offset; + attr.dw_attr_val.val_index = -1U; attr.dw_attr_val.v.val_offset = offset; add_dwarf_attr (die, &attr); } @@ -7905,25 +7982,27 @@ add_ref_table_entry (dw_attr_node *attr) return 0; } -/* Add an range_list attribute value to a DIE. */ +/* Add a range_list attribute value to a DIE. */ static void add_AT_range_list (dw_die_ref die, enum dwarf_attribute attr_kind, - long unsigned int offset) + long unsigned int offset, bool force_direct) { dw_attr_node attr; attr.dw_attr = attr_kind; attr.dw_attr_val.val_class = dw_val_class_range_list; + attr.dw_attr_val.val_index = -1U; attr.dw_attr_val.v.val_offset = offset; add_dwarf_attr (die, &attr); - if (dwarf_split_debug_info) + if (dwarf_split_debug_info && !force_direct) { + dw_attr_ref a = get_AT (die, DW_AT_ranges); + /* There will be two copies of the attr, one in the die, and one in the - ref table. Substitute the index for the actual offset in the die, and - save the actual offset in the ref table. */ - get_AT (die, DW_AT_ranges)->dw_attr_val.v.val_offset - = add_ref_table_entry (&attr); + ref table. Store the index in the die, and save the actual offset + in the ref table. */ + set_AT_index (a, add_ref_table_entry (&attr)); } } @@ -10880,7 +10959,7 @@ size_of_die (dw_die_ref die) switch (AT_class (a)) { case dw_val_class_addr: - if (dwarf_split_debug_info) + if (dwarf_split_debug_info && AT_index (a) != -1U) size += size_of_uleb128 (AT_index (a)); else size += DWARF2_ADDR_SIZE; @@ -10901,14 +10980,9 @@ size_of_die (dw_die_ref die) } break; case dw_val_class_loc_list: - if (dwarf_split_debug_info) - size += size_of_uleb128 (AT_index (a)); - else - size += DWARF_OFFSET_SIZE; - break; case dw_val_class_range_list: - if (dwarf_split_debug_info) - size += size_of_uleb128 (a->dw_attr_val.v.val_offset); + if (dwarf_split_debug_info && AT_index (a) != -1U) + size += size_of_uleb128 (AT_index (a)); else size += DWARF_OFFSET_SIZE; break; @@ -10970,7 +11044,7 @@ size_of_die (dw_die_ref die) size += DWARF_OFFSET_SIZE; break; case dw_val_class_lbl_id: - if (dwarf_split_debug_info) + if (dwarf_split_debug_info && AT_index (a) != -1U) size += size_of_uleb128 (AT_index (a)); else size += DWARF2_ADDR_SIZE; @@ -11145,7 +11219,8 @@ value_format (dw_attr_ref a) case DW_AT_high_pc: case DW_AT_entry_pc: case DW_AT_trampoline: - return dwarf_split_debug_info ? DW_FORM_GNU_addr_index : DW_FORM_addr; + return (dwarf_split_debug_info && AT_index (a) != -1U + ? DW_FORM_GNU_addr_index : DW_FORM_addr); default: break; } @@ -11164,7 +11239,7 @@ value_format (dw_attr_ref a) } case dw_val_class_range_list: case dw_val_class_loc_list: - if (dwarf_split_debug_info) + if (dwarf_split_debug_info && AT_index (a) != -1U) return DW_FORM_GNU_ref_index; if (dwarf_version >= 4) return DW_FORM_sec_offset; @@ -11263,7 +11338,8 @@ value_format (dw_attr_ref a) case dw_val_class_fde_ref: return DW_FORM_data; case dw_val_class_lbl_id: - return dwarf_split_debug_info ? DW_FORM_GNU_addr_index : DW_FORM_addr; + return (dwarf_split_debug_info && AT_index (a) != -1U + ? DW_FORM_GNU_addr_index : DW_FORM_addr); case dw_val_class_lineptr: case dw_val_class_macptr: return dwarf_version >= 4 ? DW_FORM_sec_offset : DW_FORM_data; @@ -11485,7 +11561,7 @@ output_attr_index_or_value (dw_attr_ref { const char *name = dwarf_attr_name (a->dw_attr); - if (dwarf_split_debug_info) + if (dwarf_split_debug_info && AT_index (a) != -1U) { dw2_asm_output_data_uleb128 (AT_index (a), "%s", name); return; @@ -11612,7 +11688,7 @@ output_die (dw_die_ref die) } dw2_asm_output_data (HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR, - first, name); + first, "%s", name); dw2_asm_output_data (HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR, second, NULL); } @@ -11867,12 +11943,9 @@ add_AT_pubnames (dw_die_ref die) static void add_top_level_skeleton_die_attrs (dw_die_ref die) { - /* The splitter will fill in the file name. It would be good to allocate - a fairly large string here to make it easy for the splitter though. */ const char *dwo_file_name = concat (aux_base_name, ".dwo", NULL); dw_attr_ref attr; - add_AT_lineptr (die, DW_AT_stmt_list, debug_line_section_label); add_comp_dir_attribute (die); add_AT_string (die, DW_AT_GNU_dwo_name, dwo_file_name); /* The specification suggests that these attributes be inline to avoid @@ -11882,17 +11955,31 @@ add_top_level_skeleton_die_attrs (dw_die attr->dw_attr_val.v.val_str->form = DW_FORM_string; attr = get_AT (die, DW_AT_comp_dir); attr->dw_attr_val.v.val_str->form = DW_FORM_string; - /* The post compile splitter will fill in this value. */ + add_AT_pubnames (die); add_AT_lineptr (die, DW_AT_GNU_ref_base, debug_ref_section_label); add_AT_lineptr (die, DW_AT_GNU_addr_base, debug_addr_section_label); } -/* For split_debug_sections with use_type info, all type units int the skeleton - sections have identical dies (but different headers). This single die will - be output many times. */ +/* Return the single type-unit die for skeleton type units. */ + +static dw_die_ref +get_skeleton_type_unit (void) +{ + /* For split_debug_sections with use_type info, all type units int the + skeleton sections have identical dies (but different headers). This single + die will be output many times. */ + + static dw_die_ref skeleton_type_unit = NULL; -static dw_die_ref skeleton_type_unit = NULL; + if (skeleton_type_unit == NULL) + { + skeleton_type_unit = new_die (DW_TAG_type_unit, NULL, NULL); + add_top_level_skeleton_die_attrs (skeleton_type_unit); + skeleton_type_unit->die_abbrev = SKELETON_TYPE_DIE_ABBREV; + } + return skeleton_type_unit; +} /* The splitter will fill in this value. */ @@ -11901,21 +11988,19 @@ unsigned char dwo_id_placeholder[8] = { /* Output skeleton debug sections that point to the dwo file. */ static void -output_skeleton_debug_sections (void) +output_skeleton_debug_sections (dw_die_ref comp_unit) { - dw_die_ref comp_unit = gen_compile_unit_die (NULL); - /* 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); + /* Add attributes common to skeleton compile_units and type_units. */ add_top_level_skeleton_die_attrs (comp_unit); - /* Only the compilation unit gets the dwo_id. */ + + /* The dwo_id is only for compile_units. */ add_AT_data8 (comp_unit, DW_AT_GNU_dwo_id, dwo_id_placeholder); switch_to_section (debug_skeleton_info_section); - ASM_GENERATE_INTERNAL_LABEL (debug_skeleton_info_section_label, - DEBUG_SKELETON_INFO_SECTION_LABEL, 0); ASM_OUTPUT_LABEL (asm_out_file, debug_skeleton_info_section_label); /* Produce the skeleton compilation-unit header. This one differs enough from @@ -11932,8 +12017,6 @@ output_skeleton_debug_sections (void) + size_of_die (comp_unit) + 1, "Length of Compilation Unit Info"); dw2_asm_output_data (2, dwarf_version, "DWARF version number"); - ASM_GENERATE_INTERNAL_LABEL (debug_skeleton_abbrev_section_label, - DEBUG_SKELETON_ABBREV_SECTION_LABEL, 0); dw2_asm_output_offset (DWARF_OFFSET_SIZE, debug_skeleton_abbrev_section_label, debug_abbrev_section, "Offset Into Abbrev. Section"); @@ -11950,14 +12033,7 @@ output_skeleton_debug_sections (void) output_die_abbrevs (SKELETON_COMP_DIE_ABBREV, comp_unit); if (dwarf_version >= 4) - { - /* Because all skeleton type_units have identical dies, just generate - one, and output it repeatedly. */ - skeleton_type_unit = new_die (DW_TAG_type_unit, NULL, NULL); - add_top_level_skeleton_die_attrs (skeleton_type_unit); - skeleton_type_unit->die_abbrev = SKELETON_TYPE_DIE_ABBREV; - output_die_abbrevs (SKELETON_TYPE_DIE_ABBREV, skeleton_type_unit); - } + output_die_abbrevs (SKELETON_TYPE_DIE_ABBREV, get_skeleton_type_unit ()); dw2_asm_output_data (1, 0, "end of skeleton .debug_abbrev"); } @@ -12020,7 +12096,6 @@ output_comdat_type_unit (comdat_type_nod { /* Produce the skeleton type-unit header. */ const char *secname = ".debug_types"; - gcc_assert (skeleton_type_unit); targetm.asm_out.named_section (secname, SECTION_DEBUG | SECTION_LINKONCE, @@ -12033,7 +12108,7 @@ output_comdat_type_unit (comdat_type_nod dw2_asm_output_data (DWARF_OFFSET_SIZE, DWARF_COMPILE_UNIT_HEADER_SIZE - DWARF_INITIAL_LENGTH_SIZE - + size_of_die (skeleton_type_unit) + + size_of_die (get_skeleton_type_unit ()) + DWARF_TYPE_SIGNATURE_SIZE + DWARF_OFFSET_SIZE, "Length of Type Unit Info"); dw2_asm_output_data (2, dwarf_version, "DWARF version number"); @@ -12045,7 +12120,7 @@ output_comdat_type_unit (comdat_type_nod output_signature (node->signature, "Type Signature"); dw2_asm_output_data (DWARF_OFFSET_SIZE, 0, "Offset to Type DIE"); - output_die (skeleton_type_unit); + output_die (get_skeleton_type_unit ()); /* dw2_asm_output_data (1, 0, "end of skeleton .debug_types"); */ } } @@ -12352,7 +12427,7 @@ add_ranges (const_tree block) static void add_ranges_by_labels (dw_die_ref die, const char *begin, const char *end, - bool *added) + bool *added, bool force_direct) { unsigned int in_use = ranges_by_label_in_use; unsigned int offset; @@ -12375,7 +12450,7 @@ add_ranges_by_labels (dw_die_ref die, co offset = add_ranges_num (-(int)in_use - 1); if (!*added) { - add_AT_range_list (die, DW_AT_ranges, offset); + add_AT_range_list (die, DW_AT_ranges, offset, force_direct); *added = true; } } @@ -14076,6 +14151,7 @@ address_of_int_loc_descriptor (int size, loc_result = new_loc_descr (DW_OP_implicit_value, size, 0); loc_result->dw_loc_oprnd2.val_class = dw_val_class_const; + loc_result->dw_loc_oprnd2.val_index = -1U; loc_result->dw_loc_oprnd2.v.val_int = i; return loc_result; } @@ -14464,6 +14540,7 @@ mem_loc_descriptor (rtx rtl, enum machin temp = new_loc_descr (DWARF2_ADDR_SIZE == 4 ? DW_OP_const4u : DW_OP_const8u, 0, 0); temp->dw_loc_oprnd1.val_class = dw_val_class_addr; + temp->dw_loc_oprnd1.val_index = -1U; temp->dw_loc_oprnd1.v.val_addr = rtl; temp->dtprel = true; @@ -14477,9 +14554,7 @@ mem_loc_descriptor (rtx rtl, enum machin break; symref: - mem_loc_result = new_loc_descr (DW_OP_addr, 0, 0); - mem_loc_result->dw_loc_oprnd1.val_class = dw_val_class_addr; - mem_loc_result->dw_loc_oprnd1.v.val_addr = rtl; + mem_loc_result = new_addr_loc_descr (rtl, 0); VEC_safe_push (rtx, gc, used_rtx_array, rtl); break; @@ -14895,6 +14970,7 @@ mem_loc_descriptor (rtx rtl, enum machin drop_node = new_loc_descr (DW_OP_drop, 0, 0); add_loc_descr (&mem_loc_result, drop_node); bra_node->dw_loc_oprnd1.val_class = dw_val_class_loc; + bra_node->dw_loc_oprnd1.val_index = -1U; bra_node->dw_loc_oprnd1.v.val_loc = drop_node; } break; @@ -14961,6 +15037,7 @@ mem_loc_descriptor (rtx rtl, enum machin drop_node = new_loc_descr (DW_OP_drop, 0, 0); add_loc_descr (&mem_loc_result, drop_node); bra_node->dw_loc_oprnd1.val_class = dw_val_class_loc; + bra_node->dw_loc_oprnd1.val_index = -1U; bra_node->dw_loc_oprnd1.v.val_loc = drop_node; } break; @@ -15109,7 +15186,8 @@ implicit_ptr_descriptor (rtx rtl, HOST_W dw_loc_descr_ref ret; dw_die_ref ref; - if (dwarf_strict) + /* TODO: We don't yet support DW_OP_GNU_implicit_pointer with -gfission. */ + if (dwarf_strict || dwarf_split_debug_info) return NULL; gcc_assert (TREE_CODE (DEBUG_IMPLICIT_PTR_DECL (rtl)) == VAR_DECL || TREE_CODE (DEBUG_IMPLICIT_PTR_DECL (rtl)) == PARM_DECL @@ -15117,15 +15195,18 @@ implicit_ptr_descriptor (rtx rtl, HOST_W ref = lookup_decl_die (DEBUG_IMPLICIT_PTR_DECL (rtl)); ret = new_loc_descr (DW_OP_GNU_implicit_pointer, 0, offset); ret->dw_loc_oprnd2.val_class = dw_val_class_const; + ret->dw_loc_oprnd2.val_index = -1U; if (ref) { ret->dw_loc_oprnd1.val_class = dw_val_class_die_ref; + ret->dw_loc_oprnd1.val_index = -1U; ret->dw_loc_oprnd1.v.val_die_ref.die = ref; ret->dw_loc_oprnd1.v.val_die_ref.external = 0; } else { ret->dw_loc_oprnd1.val_class = dw_val_class_decl_ref; + ret->dw_loc_oprnd1.val_index = -1U; ret->dw_loc_oprnd1.v.val_decl_ref = DEBUG_IMPLICIT_PTR_DECL (rtl); } return ret; @@ -15258,6 +15339,7 @@ loc_descriptor (rtx rtl, enum machine_mo insert_float (rtl, array); loc_result->dw_loc_oprnd2.val_class = dw_val_class_vec; + loc_result->dw_loc_oprnd2.val_index = -1U; loc_result->dw_loc_oprnd2.v.val_vec.length = length / 4; loc_result->dw_loc_oprnd2.v.val_vec.elt_size = 4; loc_result->dw_loc_oprnd2.v.val_vec.array = array; @@ -15265,6 +15347,7 @@ loc_descriptor (rtx rtl, enum machine_mo else { loc_result->dw_loc_oprnd2.val_class = dw_val_class_const_double; + loc_result->dw_loc_oprnd2.val_index = -1U; loc_result->dw_loc_oprnd2.v.val_double = rtx_to_double_int (rtl); } @@ -15318,6 +15401,7 @@ loc_descriptor (rtx rtl, enum machine_mo loc_result = new_loc_descr (DW_OP_implicit_value, length * elt_size, 0); loc_result->dw_loc_oprnd2.val_class = dw_val_class_vec; + loc_result->dw_loc_oprnd2.val_index = -1U; loc_result->dw_loc_oprnd2.v.val_vec.length = length; loc_result->dw_loc_oprnd2.v.val_vec.elt_size = elt_size; loc_result->dw_loc_oprnd2.v.val_vec.array = array; @@ -15341,9 +15425,7 @@ loc_descriptor (rtx rtl, enum machine_mo if (mode != VOIDmode && GET_MODE_SIZE (mode) == DWARF2_ADDR_SIZE && (dwarf_version >= 4 || !dwarf_strict)) { - loc_result = new_loc_descr (DW_OP_addr, 0, 0); - loc_result->dw_loc_oprnd1.val_class = dw_val_class_addr; - loc_result->dw_loc_oprnd1.v.val_addr = rtl; + loc_result = new_addr_loc_descr (rtl, 0); add_loc_descr (&loc_result, new_loc_descr (DW_OP_stack_value, 0, 0)); VEC_safe_push (rtx, gc, used_rtx_array, rtl); } @@ -16084,9 +16166,16 @@ loc_list_from_tree (tree loc, int want_a if (! CONSTANT_P (rtl)) return 0; - ret = new_loc_descr (first_op, 0, 0); - ret->dw_loc_oprnd1.val_class = dw_val_class_addr; - ret->dw_loc_oprnd1.v.val_addr = rtl; + if (dwarf_split_debug_info && first_op == DW_OP_addr) + ret = new_addr_loc_descr (rtl, dtprel); + else + { + ret = new_loc_descr (first_op, 0, 0); + ret->dw_loc_oprnd1.val_class = dw_val_class_addr; + ret->dw_loc_oprnd1.val_index = -1U; + ret->dw_loc_oprnd1.v.val_addr = rtl; + } + ret->dtprel = dtprel; ret1 = new_loc_descr (second_op, 0, 0); @@ -16134,11 +16223,7 @@ loc_list_from_tree (tree loc, int want_a return 0; } else if (CONSTANT_P (rtl) && const_ok_for_output (rtl)) - { - ret = new_loc_descr (DW_OP_addr, 0, 0); - ret->dw_loc_oprnd1.val_class = dw_val_class_addr; - ret->dw_loc_oprnd1.v.val_addr = rtl; - } + ret = new_addr_loc_descr (rtl, 0); else { enum machine_mode mode; @@ -16457,12 +16542,14 @@ loc_list_from_tree (tree loc, int want_a add_loc_descr_to_each (list_ret, lhs); bra_node->dw_loc_oprnd1.val_class = dw_val_class_loc; + bra_node->dw_loc_oprnd1.val_index = -1U; bra_node->dw_loc_oprnd1.v.val_loc = lhs; /* ??? Need a node to point the skip at. Use a nop. */ tmp = new_loc_descr (DW_OP_nop, 0, 0); add_loc_descr_to_each (list_ret, tmp); jump_node->dw_loc_oprnd1.val_class = dw_val_class_loc; + jump_node->dw_loc_oprnd1.val_index = -1U; jump_node->dw_loc_oprnd1.v.val_loc = tmp; } break; @@ -17072,9 +17159,7 @@ add_const_value_attribute (dw_die_ref di dw_loc_descr_ref loc_result; resolve_one_addr (&rtl, NULL); rtl_addr: - loc_result = new_loc_descr (DW_OP_addr, 0, 0); - loc_result->dw_loc_oprnd1.val_class = dw_val_class_addr; - loc_result->dw_loc_oprnd1.v.val_addr = rtl; + loc_result = new_addr_loc_descr (rtl, 0); add_loc_descr (&loc_result, new_loc_descr (DW_OP_stack_value, 0, 0)); add_AT_loc (die, DW_AT_location, loc_result); VEC_safe_push (rtx, gc, used_rtx_array, rtl); @@ -18535,7 +18620,7 @@ add_name_and_src_coords_attributes (dw_d if (TREE_CODE (decl) == FUNCTION_DECL && TREE_ASM_WRITTEN (decl)) { add_AT_addr (die, DW_AT_VMS_rtnbeg_pd_address, - XEXP (DECL_RTL (decl), 0)); + XEXP (DECL_RTL (decl), 0), false); VEC_safe_push (rtx, gc, used_rtx_array, XEXP (DECL_RTL (decl), 0)); } #endif /* VMS_DEBUGGING_INFO */ @@ -18556,7 +18641,7 @@ dwarf2out_vms_debug_main_pointer (void) add_name_attribute (die, VMS_DEBUG_MAIN_POINTER); ASM_GENERATE_INTERNAL_LABEL (label, PROLOGUE_END_LABEL, FUNC_LABEL_ID (cfun)); - add_AT_lbl_id (die, DW_AT_entry_pc, label); + add_AT_lbl_id (die, DW_AT_entry_pc, label, false); /* Make it the first child of comp_unit_die (). */ die->die_parent = comp_unit_die (); @@ -19139,7 +19224,7 @@ gen_entry_point_die (tree decl, dw_die_r if (DECL_ABSTRACT (decl)) equate_decl_number_to_die (decl, decl_die); else - add_AT_lbl_id (decl_die, DW_AT_low_pc, decl_start_label (decl)); + add_AT_lbl_id (decl_die, DW_AT_low_pc, decl_start_label (decl), false); } #endif @@ -19801,8 +19886,8 @@ gen_subprogram_die (tree decl, dw_die_re if (fde->dw_fde_begin) { /* We have already generated the labels. */ - add_AT_lbl_id (subr_die, DW_AT_low_pc, fde->dw_fde_begin); - add_AT_lbl_id (subr_die, DW_AT_high_pc, fde->dw_fde_end); + add_AT_lbl_id (subr_die, DW_AT_low_pc, fde->dw_fde_begin, false); + add_AT_lbl_id (subr_die, DW_AT_high_pc, fde->dw_fde_end, false); } else { @@ -19810,10 +19895,10 @@ gen_subprogram_die (tree decl, dw_die_re char label_id[MAX_ARTIFICIAL_LABEL_BYTES]; ASM_GENERATE_INTERNAL_LABEL (label_id, FUNC_BEGIN_LABEL, FUNC_LABEL_ID (cfun)); - add_AT_lbl_id (subr_die, DW_AT_low_pc, label_id); + add_AT_lbl_id (subr_die, DW_AT_low_pc, label_id, false); ASM_GENERATE_INTERNAL_LABEL (label_id, FUNC_END_LABEL, FUNC_LABEL_ID (cfun)); - add_AT_lbl_id (subr_die, DW_AT_high_pc, label_id); + add_AT_lbl_id (subr_die, DW_AT_high_pc, label_id, false); } #if VMS_DEBUGGING_INFO @@ -19857,10 +19942,11 @@ gen_subprogram_die (tree decl, dw_die_re alignment offset. */ bool range_list_added = false; add_ranges_by_labels (subr_die, fde->dw_fde_begin, - fde->dw_fde_end, &range_list_added); + fde->dw_fde_end, &range_list_added, + false); add_ranges_by_labels (subr_die, fde->dw_fde_second_begin, fde->dw_fde_second_end, - &range_list_added); + &range_list_added, false); add_pubname (decl, subr_die); if (range_list_added) add_ranges (NULL); @@ -19880,9 +19966,9 @@ gen_subprogram_die (tree decl, dw_die_re /* Do the 'primary' section. */ add_AT_lbl_id (subr_die, DW_AT_low_pc, - fde->dw_fde_begin); + fde->dw_fde_begin, false); add_AT_lbl_id (subr_die, DW_AT_high_pc, - fde->dw_fde_end); + fde->dw_fde_end, false); /* Add it. */ add_pubname (decl, subr_die); @@ -19909,17 +19995,17 @@ gen_subprogram_die (tree decl, dw_die_re name = concat ("__second_sect_of_", name, NULL); add_AT_lbl_id (seg_die, DW_AT_low_pc, - fde->dw_fde_second_begin); + fde->dw_fde_second_begin, false); add_AT_lbl_id (seg_die, DW_AT_high_pc, - fde->dw_fde_second_end); + fde->dw_fde_second_end, false); add_name_attribute (seg_die, name); add_pubname_string (name, seg_die); } } else { - add_AT_lbl_id (subr_die, DW_AT_low_pc, fde->dw_fde_begin); - add_AT_lbl_id (subr_die, DW_AT_high_pc, fde->dw_fde_end); + add_AT_lbl_id (subr_die, DW_AT_low_pc, fde->dw_fde_begin, false); + add_AT_lbl_id (subr_die, DW_AT_high_pc, fde->dw_fde_end, false); add_pubname (decl, subr_die); } } @@ -20211,7 +20297,7 @@ gen_variable_die (tree decl, tree origin { /* Optimize the common case. */ if (single_element_loc_list_p (loc) - && loc->expr->dw_loc_opc == DW_OP_addr + && loc->expr->dw_loc_opc == DW_OP_addr && loc->expr->dw_loc_next == NULL && GET_CODE (loc->expr->dw_loc_oprnd1.v.val_addr) == SYMBOL_REF) loc->expr->dw_loc_oprnd1.v.val_addr @@ -20395,7 +20481,7 @@ gen_label_die (tree decl, dw_die_ref con gcc_assert (!INSN_DELETED_P (insn)); ASM_GENERATE_INTERNAL_LABEL (label, "L", CODE_LABEL_NUMBER (insn)); - add_AT_lbl_id (lbl_die, DW_AT_low_pc, label); + add_AT_lbl_id (lbl_die, DW_AT_low_pc, label, false); } } } @@ -20434,10 +20520,10 @@ add_high_low_attributes (tree stmt, dw_d { ASM_GENERATE_INTERNAL_LABEL (label, BLOCK_BEGIN_LABEL, BLOCK_NUMBER (stmt)); - add_AT_lbl_id (die, DW_AT_entry_pc, label); + add_AT_lbl_id (die, DW_AT_entry_pc, label, false); } - add_AT_range_list (die, DW_AT_ranges, add_ranges (stmt)); + add_AT_range_list (die, DW_AT_ranges, add_ranges (stmt), false); chain = BLOCK_FRAGMENT_CHAIN (stmt); do @@ -20452,10 +20538,10 @@ add_high_low_attributes (tree stmt, dw_d { ASM_GENERATE_INTERNAL_LABEL (label, BLOCK_BEGIN_LABEL, BLOCK_NUMBER (stmt)); - add_AT_lbl_id (die, DW_AT_low_pc, label); + add_AT_lbl_id (die, DW_AT_low_pc, label, false); ASM_GENERATE_INTERNAL_LABEL (label, BLOCK_END_LABEL, BLOCK_NUMBER (stmt)); - add_AT_lbl_id (die, DW_AT_high_pc, label); + add_AT_lbl_id (die, DW_AT_high_pc, label, false); } } @@ -22956,6 +23042,8 @@ dwarf2out_init (const char *filename ATT SECTION_DEBUG, NULL); debug_skeleton_abbrev_section = get_section (DEBUG_ABBREV_SECTION, SECTION_DEBUG, NULL); + ASM_GENERATE_INTERNAL_LABEL (debug_skeleton_abbrev_section_label, + DEBUG_SKELETON_ABBREV_SECTION_LABEL, 0); /* Somewhat confusing detail: The skeleton_[abbrev|info] sections stay in the main .o, but the skeleton_line goes into the split off dwo. */ @@ -22965,6 +23053,8 @@ dwarf2out_init (const char *filename ATT DEBUG_SKELETON_LINE_SECTION_LABEL, 0); debug_str_offsets_section = get_section (DEBUG_STR_OFFSETS_SECTION, SECTION_DEBUG, NULL); + ASM_GENERATE_INTERNAL_LABEL (debug_skeleton_info_section_label, + DEBUG_SKELETON_INFO_SECTION_LABEL, 0); } debug_aranges_section = get_section (DEBUG_ARANGES_SECTION, SECTION_DEBUG, NULL); @@ -23042,7 +23132,7 @@ output_indirect_string (void **h, void * { struct indirect_string_node *node = (struct indirect_string_node *) *h; - if (node->label && node->refcount) + if (node->form == DW_FORM_strp) { switch_to_section (debug_str_section); ASM_OUTPUT_LABEL (asm_out_file, node->label); @@ -23117,13 +23207,27 @@ output_addr_table (void) switch_to_section (debug_addr_section); for (i = 0; VEC_iterate (dw_attr_node, addr_index_table, i, node); i++) { - const char *name = dwarf_attr_name (node->dw_attr); + const char *name; + + if (node->dw_attr == (enum dwarf_attribute) 0) + { + dw2_asm_output_data (DWARF2_ADDR_SIZE, 0, ""); + continue; + } + + name = dwarf_attr_name (node->dw_attr); switch (AT_class (node)) { case dw_val_class_addr: dw2_asm_output_addr_rtx (DWARF2_ADDR_SIZE, AT_addr (node), "%s", name); break; + case dw_val_class_loc: + gcc_assert (targetm.asm_out.output_dwarf_dtprel); + targetm.asm_out.output_dwarf_dtprel (asm_out_file, + DWARF2_ADDR_SIZE, + AT_addr (node)); + break; case dw_val_class_lbl_id: dw2_asm_output_addr (DWARF2_ADDR_SIZE, AT_lbl (node), "%s", name); break; @@ -23629,23 +23733,33 @@ static bool resolve_addr_in_expr (dw_loc_descr_ref loc) { for (; loc; loc = loc->dw_loc_next) - if (((loc->dw_loc_opc == DW_OP_addr || loc->dtprel) - && resolve_one_addr (&loc->dw_loc_oprnd1.v.val_addr, NULL)) - || (loc->dw_loc_opc == DW_OP_implicit_value - && loc->dw_loc_oprnd2.val_class == dw_val_class_addr - && resolve_one_addr (&loc->dw_loc_oprnd2.v.val_addr, NULL))) - return false; - else if (loc->dw_loc_opc == DW_OP_GNU_implicit_pointer - && loc->dw_loc_oprnd1.val_class == dw_val_class_decl_ref) - { - dw_die_ref ref - = lookup_decl_die (loc->dw_loc_oprnd1.v.val_decl_ref); - if (ref == NULL) - return false; - loc->dw_loc_oprnd1.val_class = dw_val_class_die_ref; - loc->dw_loc_oprnd1.v.val_die_ref.die = ref; - loc->dw_loc_oprnd1.v.val_die_ref.external = 0; - } + { + if (loc->dw_loc_opc == DW_OP_GNU_addr_index) + { + unsigned int idx = loc->dw_loc_oprnd1.val_index; + dw_attr_node *node = VEC_index (dw_attr_node, addr_index_table, idx); + if (resolve_one_addr (&node->dw_attr_val.v.val_addr, NULL)) + return false; + } + else if (((loc->dw_loc_opc == DW_OP_addr || loc->dtprel) + && resolve_one_addr (&loc->dw_loc_oprnd1.v.val_addr, NULL)) + || (loc->dw_loc_opc == DW_OP_implicit_value + && loc->dw_loc_oprnd2.val_class == dw_val_class_addr + && resolve_one_addr (&loc->dw_loc_oprnd2.v.val_addr, NULL))) + return false; + else if (loc->dw_loc_opc == DW_OP_GNU_implicit_pointer + && loc->dw_loc_oprnd1.val_class == dw_val_class_decl_ref) + { + dw_die_ref ref + = lookup_decl_die (loc->dw_loc_oprnd1.v.val_decl_ref); + if (ref == NULL) + return false; + loc->dw_loc_oprnd1.val_class = dw_val_class_die_ref; + loc->dw_loc_oprnd1.val_index = -1U; + loc->dw_loc_oprnd1.v.val_die_ref.die = ref; + loc->dw_loc_oprnd1.v.val_die_ref.external = 0; + } + } return true; } @@ -23716,6 +23830,9 @@ resolve_addr (dw_die_ref die) case dw_val_class_loc: if (!resolve_addr_in_expr (AT_loc (a))) { + dw_loc_descr_ref l = AT_loc (a); + if (l->dw_loc_oprnd1.val_index != -1U) + remove_addr_table_entry (l->dw_loc_oprnd1.val_index); remove_AT (die, a->dw_attr); ix--; } @@ -23724,6 +23841,8 @@ resolve_addr (dw_die_ref die) if (a->dw_attr == DW_AT_const_value && resolve_one_addr (&a->dw_attr_val.v.val_addr, NULL)) { + if (AT_index (a) != -1U) + remove_addr_table_entry (AT_index (a)); remove_AT (die, a->dw_attr); ix--; } @@ -23856,6 +23975,18 @@ hash_loc_operands (dw_loc_descr_ref loc, } hash = iterative_hash_rtx (val1->v.val_addr, hash); break; + case DW_OP_GNU_addr_index: + { + dw_attr_ref attr = VEC_index (dw_attr_node, addr_index_table, + val1->val_index); + if (loc->dtprel) + { + unsigned char dtprel = 0xd1; + hash = iterative_hash_object (dtprel, hash); + } + hash = iterative_hash_rtx (attr->dw_attr_val.v.val_addr, hash); + } + break; case DW_OP_GNU_implicit_pointer: hash = iterative_hash_object (val2->v.val_int, hash); break; @@ -24011,6 +24142,17 @@ compare_loc_operands (dw_loc_descr_ref x case DW_OP_addr: hash_addr: return rtx_equal_p (valx1->v.val_addr, valy1->v.val_addr); + case DW_OP_GNU_addr_index: + { + dw_attr_node *attrx1 = VEC_index (dw_attr_node, + addr_index_table, + valx1->val_index); + dw_attr_node *attry1 = VEC_index (dw_attr_node, + addr_index_table, + valy1->val_index); + return rtx_equal_p (attrx1->dw_attr_val.v.val_addr, + attry1->dw_attr_val.v.val_addr); + } case DW_OP_GNU_implicit_pointer: return valx1->val_class == dw_val_class_die_ref && valx1->val_class == valy1->val_class @@ -24133,6 +24275,7 @@ dwarf2out_finish (const char *filename) comdat_type_node *ctnode; htab_t comdat_type_table; unsigned int i; + dw_die_ref main_comp_unit_die; gen_scheduled_generic_parms_dies (); gen_remaining_tmpl_value_param_die_attribute (); @@ -24273,6 +24416,14 @@ dwarf2out_finish (const char *filename) for (ctnode = comdat_type_list; ctnode != NULL; ctnode = ctnode->next) add_sibling_attributes (ctnode->root_die); + /* When splitting DWARF info, we put some attributes in the + skeleton compile_unit DIE that remains in the .o, while + most attributes go in the DWO compile_unit_die. */ + if (dwarf_split_debug_info) + main_comp_unit_die = gen_compile_unit_die (NULL); + else + main_comp_unit_die = comp_unit_die (); + /* Output a terminator label for the .text section. */ switch_to_section (text_section); targetm.asm_out.internal_label (asm_out_file, TEXT_END_LABEL, 0); @@ -24287,8 +24438,9 @@ dwarf2out_finish (const char *filename) if (!have_multiple_function_sections || (dwarf_version < 3 && dwarf_strict)) { - add_AT_lbl_id (comp_unit_die (), DW_AT_low_pc, text_section_label); - add_AT_lbl_id (comp_unit_die (), DW_AT_high_pc, text_end_label); + add_AT_lbl_id (main_comp_unit_die, DW_AT_low_pc, text_section_label, + true); + add_AT_lbl_id (main_comp_unit_die, DW_AT_high_pc, text_end_label, true); } else @@ -24301,26 +24453,27 @@ dwarf2out_finish (const char *filename) absolute. Historically, we've emitted the unexpected DW_AT_entry_pc instead of DW_AT_low_pc for this purpose. Emit both to give time for other tools to adapt. */ - add_AT_addr (comp_unit_die (), DW_AT_low_pc, const0_rtx); - add_AT_addr (comp_unit_die (), DW_AT_entry_pc, const0_rtx); + add_AT_addr (main_comp_unit_die, DW_AT_low_pc, const0_rtx, true); + add_AT_addr (main_comp_unit_die, DW_AT_entry_pc, const0_rtx, true); if (text_section_used) - add_ranges_by_labels (comp_unit_die (), text_section_label, - text_end_label, &range_list_added); + add_ranges_by_labels (main_comp_unit_die, text_section_label, + text_end_label, &range_list_added, true); if (cold_text_section_used) - add_ranges_by_labels (comp_unit_die (), cold_text_section_label, - cold_end_label, &range_list_added); + add_ranges_by_labels (main_comp_unit_die, cold_text_section_label, + cold_end_label, &range_list_added, true); for (fde_idx = 0; fde_idx < fde_table_in_use; fde_idx++) { dw_fde_ref fde = &fde_table[fde_idx]; if (!fde->in_std_section) - add_ranges_by_labels (comp_unit_die (), fde->dw_fde_begin, - fde->dw_fde_end, &range_list_added); + add_ranges_by_labels (main_comp_unit_die, fde->dw_fde_begin, + fde->dw_fde_end, &range_list_added, true); if (fde->dw_fde_second_begin && !fde->second_in_std_section) - add_ranges_by_labels (comp_unit_die (), fde->dw_fde_second_begin, - fde->dw_fde_second_end, &range_list_added); + add_ranges_by_labels (main_comp_unit_die, fde->dw_fde_second_begin, + fde->dw_fde_second_end, &range_list_added, + true); } if (range_list_added) @@ -24328,11 +24481,11 @@ dwarf2out_finish (const char *filename) } if (generate_debug_line_table) - add_AT_lineptr (comp_unit_die (), DW_AT_stmt_list, + add_AT_lineptr (main_comp_unit_die, DW_AT_stmt_list, debug_line_section_label); if (debug_info_level >= DINFO_LEVEL_VERBOSE) - add_AT_macptr (comp_unit_die (), DW_AT_macro_info, macinfo_section_label); + add_AT_macptr (main_comp_unit_die, DW_AT_macro_info, macinfo_section_label); if (have_location_lists) { @@ -24340,15 +24493,6 @@ dwarf2out_finish (const char *filename) index_location_lists (comp_unit_die ()); } - if (dwarf_split_debug_info) - { - /* Add a place-holder for the dwo_id to the comp-unit die. Similarly, the - skeleton die gets a placeholder inside - output_skeleton_debug_sections. */ - add_AT_data8 (comp_unit_die (), DW_AT_GNU_dwo_id, dwo_id_placeholder); - output_skeleton_debug_sections (); - } - /* Output all of the compilation units. We put the main one last so that the offsets are available to output_pubnames. */ for (node = limbo_die_list; node; node = node->next) @@ -24380,10 +24524,17 @@ dwarf2out_finish (const char *filename) if (!dwarf_split_debug_info) add_AT_pubnames (comp_unit_die ()); + if (dwarf_split_debug_info) + /* Add a place-holder for the dwo_id to the comp-unit die. */ + add_AT_data8 (comp_unit_die (), DW_AT_GNU_dwo_id, dwo_id_placeholder); + /* 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); + if (dwarf_split_debug_info && info_section_emitted) + output_skeleton_debug_sections (main_comp_unit_die); + /* Output the abbreviation table. */ switch_to_section (debug_abbrev_section); ASM_OUTPUT_LABEL (asm_out_file, abbrev_section_label); @@ -24465,7 +24616,7 @@ dwarf2out_finish (const char *filename) dw2_asm_output_data (1, 0, "End compilation unit"); } - if (dwarf_split_debug_info) + if (dwarf_split_debug_info && info_section_emitted) { switch_to_section (debug_skeleton_line_section); ASM_OUTPUT_LABEL (asm_out_file, debug_skeleton_line_section_label);