This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
[patch] DWARF-5 .debug_names DW_IDX_type_unit fix [Re: [PATCH v3.2 5/5] DWARF-5: .debug_names index consumer]
- From: Jan Kratochvil <jan dot kratochvil at redhat dot com>
- To: Pedro Alves <palves at redhat dot com>
- Cc: gdb-patches at sourceware dot org, Victor Leschuk <vleschuk at accesssoftek dot com>
- Date: Wed, 13 Dec 2017 22:57:31 +0100
- Subject: [patch] DWARF-5 .debug_names DW_IDX_type_unit fix [Re: [PATCH v3.2 5/5] DWARF-5: .debug_names index consumer]
- Authentication-results: sourceware.org; auth=none
- 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>
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 <jan.kratochvil@redhat.com>
* 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<symbol_value> ());
std::set<symbol_value> &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<partial_symbol *> &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, std::set<symbol_value>, 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