From patchwork Wed Dec 13 21:57:31 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Kratochvil X-Patchwork-Id: 24921 Received: (qmail 64564 invoked by alias); 13 Dec 2017 21:57:41 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 64541 invoked by uid 89); 13 Dec 2017 21:57:40 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-26.9 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, SPF_HELO_PASS, T_RP_MATCHES_RCVD autolearn=ham version=3.3.2 spammy= X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Wed, 13 Dec 2017 21:57:38 +0000 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 4DC2280C06; Wed, 13 Dec 2017 21:57:37 +0000 (UTC) Received: from host1.jankratochvil.net (ovpn-117-202.ams2.redhat.com [10.36.117.202]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 72ECD6A519; Wed, 13 Dec 2017 21:57:35 +0000 (UTC) Date: Wed, 13 Dec 2017 22:57:31 +0100 From: Jan Kratochvil To: Pedro Alves Cc: gdb-patches@sourceware.org, Victor Leschuk Subject: [patch] DWARF-5 .debug_names DW_IDX_type_unit fix [Re: [PATCH v3.2 5/5] DWARF-5: .debug_names index consumer] Message-ID: <20171213215731.GA32208@host1.jankratochvil.net> References: <149790572259.20186.14601775821404892582.stgit@host1.jankratochvil.net> <149790576669.20186.17091294504362630191.stgit@host1.jankratochvil.net> <20170628212114.GA23559@host1.jankratochvil.net> <20170702142957.GA22686@host1.jankratochvil.net> <628074a3-b992-1d96-273e-ecdf1e90bd8c@redhat.com> <20171212165221.GA12449@host1.jankratochvil.net> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20171212165221.GA12449@host1.jankratochvil.net> User-Agent: Mutt/1.9.1 (2017-09-22) On Tue, 12 Dec 2017 17:52:21 +0100, Jan Kratochvil wrote: > On Sat, 09 Dec 2017 00:58:47 +0100, Pedro Alves wrote: > > I'm seeing a few regressions compared to .gdb_index, using > > --target_board=dwarf4-gdb-index : > > > > -PASS: gdb.base/enumval.exp: p ZERO > > +FAIL: gdb.base/enumval.exp: p ZERO > ... > > etc. There are a few more. That board has: > > > > set_board_info debug_flags "-gdwarf-4 -fdebug-types-section" > > > > and if I remove "-fdebug-types-section", then the series > > is regression-free compared to .gdb_index. Have you seen this? ... > The .debug_names completely misses its support as it does not even produce > DW_IDX_type_unit. Here you are, could you also verify my regression testing for this patch? Thanks, Jan gdb/ChangeLog 2017-12-13 Jan Kratochvil * dwarf2read.c (dw2_debug_names_iterator::next): Support DW_IDX_type_unit. (debug_names::dwarf5_offset_size, unit_kind): New. (debug_names::insert): Add parameter kind. (debug_names::build): Support DW_IDX_type_unit. (debug_names::recursively_write_psymbols): Update (debug_names::write_psymbols caller. (debug_names::write_one_signatured_type_data) (debug_names::write_one_signatured_type): New. (debug_names::index_key, debug_names::symbol_value) (debug_names::write_psymbols): Add kind. (debug_names::write_one_signatured_type): New. (write_debug_names): Move dwarf5_offset_size to debug_names. Use debug_names::write_one_signatured_type for type units. diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index b4e60a4409..e65eac7acd 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -6192,8 +6192,7 @@ dw2_debug_names_iterator::next () { case DW_IDX_compile_unit: /* Don't crash on bad data. */ - if (ull >= (dwarf2_per_objfile->n_comp_units - + dwarf2_per_objfile->n_type_units)) + if (ull >= dwarf2_per_objfile->n_comp_units) { complaint (&symfile_complaints, _(".debug_names entry has bad CU index %s" @@ -6204,6 +6203,19 @@ dw2_debug_names_iterator::next () } per_cu = dw2_get_cutu (ull); break; + case DW_IDX_type_unit: + /* Don't crash on bad data. */ + if (ull >= dwarf2_per_objfile->n_type_units) + { + complaint (&symfile_complaints, + _(".debug_names entry has bad TU index %s" + " [in module %s]"), + pulongest (ull), + objfile_name (dwarf2_per_objfile->objfile)); + continue; + } + per_cu = dw2_get_cutu (dwarf2_per_objfile->n_comp_units + ull); + break; case DW_IDX_GNU_internal: if (!m_map.augmentation_is_gdb) break; @@ -26012,8 +26024,17 @@ public: m_name_table_entry_offs (m_dwarf.name_table_entry_offs) {} + int dwarf5_offset_size () const { + const bool dwarf5_is_dwarf64 = &m_dwarf == &m_dwarf64; + return dwarf5_is_dwarf64 ? 8 : 4; + } + + /* Is this symbol from DW_TAG_compile_unit or DW_TAG_type_unit? */ + enum class unit_kind { cu, tu }; + /* Insert one symbol. */ - void insert (const partial_symbol *psym, int cu_index, bool is_static) + void insert (const partial_symbol *psym, int cu_index, bool is_static, + unit_kind kind) { const int dwarf_tag = psymbol_tag (psym); if (dwarf_tag == 0) @@ -26023,7 +26044,7 @@ public: = m_name_to_value_set.emplace (c_str_view (name), std::set ()); std::set &value_set = insertpair.first->second; - value_set.emplace (symbol_value (dwarf_tag, cu_index, is_static)); + value_set.emplace (symbol_value (dwarf_tag, cu_index, is_static, kind)); } /* Build all the tables. All symbols must be already inserted. @@ -26088,13 +26109,16 @@ public: for (const symbol_value &value : value_set) { int &idx = m_indexkey_to_idx[index_key (value.dwarf_tag, - value.is_static)]; + value.is_static, + value.kind)]; if (idx == 0) { idx = m_idx_next++; m_abbrev_table.append_unsigned_leb128 (idx); m_abbrev_table.append_unsigned_leb128 (value.dwarf_tag); - m_abbrev_table.append_unsigned_leb128 (DW_IDX_compile_unit); + m_abbrev_table.append_unsigned_leb128 + (value.kind == unit_kind::cu ? DW_IDX_compile_unit + : DW_IDX_type_unit); m_abbrev_table.append_unsigned_leb128 (DW_FORM_udata); m_abbrev_table.append_unsigned_leb128 (value.is_static ? DW_IDX_GNU_internal @@ -26169,10 +26193,10 @@ public: write_psymbols (psyms_seen, &objfile->global_psymbols[psymtab->globals_offset], - psymtab->n_global_syms, cu_index, false); + psymtab->n_global_syms, cu_index, false, unit_kind::cu); write_psymbols (psyms_seen, &objfile->static_psymbols[psymtab->statics_offset], - psymtab->n_static_syms, cu_index, true); + psymtab->n_static_syms, cu_index, true, unit_kind::cu); } /* Return number of bytes the .debug_names section will have. This @@ -26207,6 +26231,30 @@ public: m_debugstrlookup.file_write (file_str); } + /* A helper user data for write_one_signatured_type. */ + class write_one_signatured_type_data + { + public: + write_one_signatured_type_data (debug_names &nametable_, + signatured_type_index_data &&info_) + : nametable (nametable_), info (std::move (info_)) + {} + debug_names &nametable; + struct signatured_type_index_data info; + }; + + /* A helper function to pass write_one_signatured_type to + htab_traverse_noresize. */ + static int + write_one_signatured_type (void **slot, void *d) + { + write_one_signatured_type_data *data = (write_one_signatured_type_data *) d; + struct signatured_type_index_data *info = &data->info; + struct signatured_type *entry = (struct signatured_type *) *slot; + + return data->nametable.write_one_signatured_type (entry, info); + } + private: /* Storage for symbol names mapping them to their .debug_str section @@ -26275,19 +26323,21 @@ private: class index_key { public: - index_key (int dwarf_tag_, bool is_static_) - : dwarf_tag (dwarf_tag_), is_static (is_static_) + index_key (int dwarf_tag_, bool is_static_, unit_kind kind_) + : dwarf_tag (dwarf_tag_), is_static (is_static_), kind (kind_) { } bool operator== (const index_key &other) const { - return dwarf_tag == other.dwarf_tag && is_static == other.is_static; + return (dwarf_tag == other.dwarf_tag && is_static == other.is_static + && kind == other.kind); } const int dwarf_tag; const bool is_static; + const unit_kind kind; }; /* Provide std::unordered_map::hasher for index_key. */ @@ -26307,9 +26357,12 @@ private: public: const int dwarf_tag, cu_index; const bool is_static; + const unit_kind kind; - symbol_value (int dwarf_tag_, int cu_index_, bool is_static_) - : dwarf_tag (dwarf_tag_), cu_index (cu_index_), is_static (is_static_) + symbol_value (int dwarf_tag_, int cu_index_, bool is_static_, + unit_kind kind_) + : dwarf_tag (dwarf_tag_), cu_index (cu_index_), is_static (is_static_), + kind (kind_) {} bool @@ -26326,6 +26379,7 @@ private: while (0) X (dwarf_tag); X (is_static); + X (kind); X (cu_index); #undef X return false; @@ -26471,7 +26525,7 @@ private: /* Call insert for all partial symbols and mark them in PSYMS_SEEN. */ void write_psymbols (std::unordered_set &psyms_seen, struct partial_symbol **psymp, int count, int cu_index, - bool is_static) + bool is_static, unit_kind kind) { for (; count-- > 0; ++psymp) { @@ -26482,10 +26536,35 @@ private: /* Only add a given psymbol once. */ if (psyms_seen.insert (psym).second) - insert (psym, cu_index, is_static); + insert (psym, cu_index, is_static, kind); } } + /* A helper function that writes a single signatured_type to an + debug_names. */ + int + write_one_signatured_type (struct signatured_type *entry, + struct signatured_type_index_data *info) + { + struct partial_symtab *psymtab = entry->per_cu.v.psymtab; + + write_psymbols (info->psyms_seen, + &info->objfile->global_psymbols[psymtab->globals_offset], + psymtab->n_global_syms, info->cu_index, false, + unit_kind::tu); + write_psymbols (info->psyms_seen, + &info->objfile->static_psymbols[psymtab->statics_offset], + psymtab->n_static_syms, info->cu_index, true, + unit_kind::tu); + + info->types_list.append_uint (dwarf5_offset_size (), m_dwarf5_byte_order, + to_underlying (entry->per_cu.sect_off)); + + ++info->cu_index; + + return 1; + } + /* Store value of each symbol. */ std::unordered_map, c_str_view_hasher> m_name_to_value_set; @@ -26685,7 +26764,6 @@ static size_t write_debug_names (struct objfile *objfile, FILE *out_file, FILE *out_file_str) { const bool dwarf5_is_dwarf64 = check_dwarf64_offsets (); - const int dwarf5_offset_size = dwarf5_is_dwarf64 ? 8 : 4; const enum bfd_endian dwarf5_byte_order = gdbarch_byte_order (get_objfile_arch (objfile)); @@ -26709,23 +26787,30 @@ write_debug_names (struct objfile *objfile, FILE *out_file, FILE *out_file_str) if (psymtab->user == NULL) nametable.recursively_write_psymbols (objfile, psymtab, psyms_seen, i); - cu_list.append_uint (dwarf5_offset_size, dwarf5_byte_order, + cu_list.append_uint (nametable.dwarf5_offset_size (), dwarf5_byte_order, to_underlying (per_cu->sect_off)); } - nametable.build (); - - /* No addr_vec - DWARF-5 uses .debug_aranges generated by GCC. */ + /* Write out the .debug_type entries, if any. */ data_buf types_cu_list; - for (int i = 0; i < dwarf2_per_objfile->n_type_units; ++i) + if (dwarf2_per_objfile->signatured_types) { - const signatured_type &sigtype = *dwarf2_per_objfile->all_type_units[i]; - const dwarf2_per_cu_data &per_cu = sigtype.per_cu; + debug_names::write_one_signatured_type_data sig_data (nametable, + signatured_type_index_data (types_cu_list, psyms_seen)); - types_cu_list.append_uint (dwarf5_offset_size, dwarf5_byte_order, - to_underlying (per_cu.sect_off)); + sig_data.info.objfile = objfile; + /* It is used only for gdb_index. */ + sig_data.info.symtab = nullptr; + sig_data.info.cu_index = 0; + htab_traverse_noresize (dwarf2_per_objfile->signatured_types, + debug_names::write_one_signatured_type, + &sig_data); } + nametable.build (); + + /* No addr_vec - DWARF-5 uses .debug_aranges generated by GCC. */ + const offset_type bytes_of_header = ((dwarf5_is_dwarf64 ? 12 : 4) + 2 + 2 + 7 * 4