This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
Re: [RFC PATCH] Introduce dwarf2_cu::get_builder
- From: Keith Seitz <keiths at redhat dot com>
- To: gdb-patches at sourceware dot org
- Date: Tue, 6 Nov 2018 13:33:55 -0800
- Subject: Re: [RFC PATCH] Introduce dwarf2_cu::get_builder
- References: <20181023185715.23082-1-keiths@redhat.com>
On 10/23/18 11:57 AM, Keith Seitz wrote:
> I'm submitting this as an RFC rather than an actual patch because of the
> lack of coverage testing for all the places where get_builder() is used.
Would any maintainer like to comment on this?
Keith
> gdb/ChangeLog:
>
> PR gdb/23773
> * dwarf2read.c (dwarf2_cu) <ancestor>: New field.
> (dwarf2_cu::get_builder): New method. Change all users of
> `builder' to use this method.
> (follow_die_offset): Record the ancestor CU if it is different
> from the followed DIE's CU.
> (follow_die_sig_1): Likewise.
>
> gdb/testsuite/ChangeLog:
>
> PR gdb/23773
> * gdb.dwarf2/inline_subroutine-inheritance.exp: New file.
> ---
> gdb/ChangeLog | 10 +
> gdb/dwarf2read.c | 154 ++++++++-----
> gdb/testsuite/ChangeLog | 5 +
> .../inline_subroutine-inheritance.exp | 213 ++++++++++++++++++
> 4 files changed, 321 insertions(+), 61 deletions(-)
> create mode 100644 gdb/testsuite/gdb.dwarf2/inline_subroutine-inheritance.exp
>
> diff --git a/gdb/ChangeLog b/gdb/ChangeLog
> index 0e9b0a1a5f..bfc2554688 100644
> --- a/gdb/ChangeLog
> +++ b/gdb/ChangeLog
> @@ -1,3 +1,13 @@
> +YYYY-MM-DD Keith Seitz <keiths@redhat.com>
> +
> + PR gdb/23773
> + * dwarf2read.c (dwarf2_cu) <ancestor>: New field.
> + (dwarf2_cu::get_builder): New method. Change all users of
> + `builder' to use this method.
> + (follow_die_offset): Record the ancestor CU if it is different
> + from the followed DIE's CU.
> + (follow_die_sig_1): Likewise.
> +
> 2018-10-21 Simon Marchi <simon.marchi@ericsson.com>
>
> * gdbarch.sh (gdbarch_num_cooked_regs): New.
> diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
> index 2a1b805c9a..8981bbbedf 100644
> --- a/gdb/dwarf2read.c
> +++ b/gdb/dwarf2read.c
> @@ -561,6 +561,24 @@ struct dwarf2_cu
> unsigned int processing_has_namespace_info : 1;
>
> struct partial_die_info *find_partial_die (sect_offset sect_off);
> +
> + /* If this CU was inherited by another CU (via specification,
> + abstract_origin, etc), this is the ancestor CU. */
> + dwarf2_cu *ancestor;
> +
> + /* Get the buildsym_compunit for this CU. */
> + buildsym_compunit *get_builder ()
> + {
> + /* If this CU has a builder associated with it, use that. */
> + if (builder != nullptr)
> + return builder.get ();
> +
> + /* Otherwise, search ancestors for a valid builder. */
> + if (ancestor != nullptr)
> + return ancestor->get_builder ();
> +
> + return nullptr;
> + }
> };
>
> /* A struct that can be used as a hash key for tables based on DW_AT_stmt_list.
> @@ -9822,7 +9840,7 @@ fixup_go_packaging (struct dwarf2_cu *cu)
> struct pending *list;
> int i;
>
> - for (list = *cu->builder->get_global_symbols ();
> + for (list = *cu->get_builder ()->get_global_symbols ();
> list != NULL;
> list = list->next)
> {
> @@ -10377,7 +10395,7 @@ process_full_comp_unit (struct dwarf2_per_cu_data *per_cu,
> get_scope_pc_bounds (cu->dies, &lowpc, &highpc, cu);
>
> addr = gdbarch_adjust_dwarf2_addr (gdbarch, highpc + baseaddr);
> - static_block = cu->builder->end_symtab_get_static_block (addr, 0, 1);
> + static_block = cu->get_builder ()->end_symtab_get_static_block (addr, 0, 1);
>
> /* If the comp unit has DW_AT_ranges, it may have discontiguous ranges.
> Also, DW_AT_ranges may record ranges not belonging to any child DIEs
> @@ -10386,7 +10404,7 @@ process_full_comp_unit (struct dwarf2_per_cu_data *per_cu,
> this comp unit. */
> dwarf2_record_block_ranges (cu->dies, static_block, baseaddr, cu);
>
> - cust = cu->builder->end_symtab_from_static_block (static_block,
> + cust = cu->get_builder ()->end_symtab_from_static_block (static_block,
> SECT_OFF_TEXT (objfile),
> 0);
>
> @@ -10481,7 +10499,8 @@ process_full_type_unit (struct dwarf2_per_cu_data *per_cu,
> this TU's symbols to the existing symtab. */
> if (sig_type->type_unit_group->compunit_symtab == NULL)
> {
> - cust = cu->builder->end_expandable_symtab (0, SECT_OFF_TEXT (objfile));
> + buildsym_compunit *builder = cu->get_builder ();
> + cust = builder->end_expandable_symtab (0, SECT_OFF_TEXT (objfile));
> sig_type->type_unit_group->compunit_symtab = cust;
>
> if (cust != NULL)
> @@ -10497,7 +10516,7 @@ process_full_type_unit (struct dwarf2_per_cu_data *per_cu,
> }
> else
> {
> - cu->builder->augment_type_symtab ();
> + cu->get_builder ()->augment_type_symtab ();
> cust = sig_type->type_unit_group->compunit_symtab;
> }
>
> @@ -11206,10 +11225,11 @@ read_namespace_alias (struct die_info *die, struct dwarf2_cu *cu)
> static struct using_direct **
> using_directives (struct dwarf2_cu *cu)
> {
> - if (cu->language == language_ada && cu->builder->outermost_context_p ())
> - return cu->builder->get_global_using_directives ();
> + if (cu->language == language_ada
> + && cu->get_builder ()->outermost_context_p ())
> + return cu->get_builder ()->get_global_using_directives ();
> else
> - return cu->builder->get_local_using_directives ();
> + return cu->get_builder ()->get_local_using_directives ();
> }
>
> /* Read the import statement specified by the given die and record it. */
> @@ -11681,20 +11701,20 @@ setup_type_unit_groups (struct die_info *die, struct dwarf2_cu *cu)
> file_entry &fe = cu->line_header->file_names[i];
>
> dwarf2_start_subfile (cu, fe.name, fe.include_dir (cu->line_header));
> -
> - if (cu->builder->get_current_subfile ()->symtab == NULL)
> + buildsym_compunit *builder = cu->get_builder ();
> + if (builder->get_current_subfile ()->symtab == NULL)
> {
> /* NOTE: start_subfile will recognize when it's been
> passed a file it has already seen. So we can't
> assume there's a simple mapping from
> cu->line_header->file_names to subfiles, plus
> cu->line_header->file_names may contain dups. */
> - cu->builder->get_current_subfile ()->symtab
> + builder->get_current_subfile ()->symtab
> = allocate_symtab (cust,
> - cu->builder->get_current_subfile ()->name);
> + builder->get_current_subfile ()->name);
> }
>
> - fe.symtab = cu->builder->get_current_subfile ()->symtab;
> + fe.symtab = builder->get_current_subfile ()->symtab;
> tu_group->symtabs[i] = fe.symtab;
> }
> }
> @@ -13731,7 +13751,7 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu)
> }
> }
>
> - newobj = cu->builder->push_context (0, lowpc);
> + newobj = cu->get_builder ()->push_context (0, lowpc);
> newobj->name = new_symbol (die, read_type_die (die, cu), cu,
> (struct symbol *) templ_func);
>
> @@ -13751,7 +13771,7 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu)
> attr_to_dynamic_prop (attr, die, cu, newobj->static_link);
> }
>
> - cu->list_in_scope = cu->builder->get_local_symbols ();
> + cu->list_in_scope = cu->get_builder ()->get_local_symbols ();
>
> if (die->child != NULL)
> {
> @@ -13799,9 +13819,9 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu)
> }
> }
>
> - struct context_stack cstk = cu->builder->pop_context ();
> + struct context_stack cstk = cu->get_builder ()->pop_context ();
> /* Make a block for the local symbols within. */
> - block = cu->builder->finish_block (cstk.name, cstk.old_blocks,
> + block = cu->get_builder ()->finish_block (cstk.name, cstk.old_blocks,
> cstk.static_link, lowpc, highpc);
>
> /* For C++, set the block's scope. */
> @@ -13843,13 +13863,13 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu)
> a function declares a class that has methods). This means that
> when we finish processing a function scope, we may need to go
> back to building a containing block's symbol lists. */
> - *cu->builder->get_local_symbols () = cstk.locals;
> - cu->builder->set_local_using_directives (cstk.local_using_directives);
> + *cu->get_builder ()->get_local_symbols () = cstk.locals;
> + cu->get_builder ()->set_local_using_directives (cstk.local_using_directives);
>
> /* If we've finished processing a top-level function, subsequent
> symbols go in the file symbol list. */
> - if (cu->builder->outermost_context_p ())
> - cu->list_in_scope = cu->builder->get_file_symbols ();
> + if (cu->get_builder ()->outermost_context_p ())
> + cu->list_in_scope = cu->get_builder ()->get_file_symbols ();
> }
>
> /* Process all the DIES contained within a lexical block scope. Start
> @@ -13888,7 +13908,7 @@ read_lexical_block_scope (struct die_info *die, struct dwarf2_cu *cu)
> lowpc = gdbarch_adjust_dwarf2_addr (gdbarch, lowpc + baseaddr);
> highpc = gdbarch_adjust_dwarf2_addr (gdbarch, highpc + baseaddr);
>
> - cu->builder->push_context (0, lowpc);
> + cu->get_builder ()->push_context (0, lowpc);
> if (die->child != NULL)
> {
> child_die = die->child;
> @@ -13899,13 +13919,13 @@ read_lexical_block_scope (struct die_info *die, struct dwarf2_cu *cu)
> }
> }
> inherit_abstract_dies (die, cu);
> - struct context_stack cstk = cu->builder->pop_context ();
> + struct context_stack cstk = cu->get_builder ()->pop_context ();
>
> - if (*cu->builder->get_local_symbols () != NULL
> - || (*cu->builder->get_local_using_directives ()) != NULL)
> + if (*cu->get_builder ()->get_local_symbols () != NULL
> + || (*cu->get_builder ()->get_local_using_directives ()) != NULL)
> {
> struct block *block
> - = cu->builder->finish_block (0, cstk.old_blocks, NULL,
> + = cu->get_builder ()->finish_block (0, cstk.old_blocks, NULL,
> cstk.start_addr, highpc);
>
> /* Note that recording ranges after traversing children, as we
> @@ -13920,8 +13940,8 @@ read_lexical_block_scope (struct die_info *die, struct dwarf2_cu *cu)
> to do. */
> dwarf2_record_block_ranges (die, block, baseaddr, cu);
> }
> - *cu->builder->get_local_symbols () = cstk.locals;
> - cu->builder->set_local_using_directives (cstk.local_using_directives);
> + *cu->get_builder ()->get_local_symbols () = cstk.locals;
> + cu->get_builder ()->set_local_using_directives (cstk.local_using_directives);
> }
>
> /* Read in DW_TAG_call_site and insert it to CU->call_site_htab. */
> @@ -14844,7 +14864,7 @@ dwarf2_record_block_ranges (struct die_info *die, struct block *block,
>
> low = gdbarch_adjust_dwarf2_addr (gdbarch, low + baseaddr);
> high = gdbarch_adjust_dwarf2_addr (gdbarch, high + baseaddr);
> - cu->builder->record_block_range (block, low, high - 1);
> + cu->get_builder ()->record_block_range (block, low, high - 1);
> }
> }
>
> @@ -14869,7 +14889,7 @@ dwarf2_record_block_ranges (struct die_info *die, struct block *block,
> end += baseaddr;
> start = gdbarch_adjust_dwarf2_addr (gdbarch, start);
> end = gdbarch_adjust_dwarf2_addr (gdbarch, end);
> - cu->builder->record_block_range (block, start, end - 1);
> + cu->get_builder ()->record_block_range (block, start, end - 1);
> blockvec.emplace_back (start, end);
> });
>
> @@ -20666,7 +20686,7 @@ lnp_state_machine::handle_set_file (file_name_index file)
> {
> const char *dir = fe->include_dir (m_line_header);
>
> - m_last_subfile = m_cu->builder->get_current_subfile ();
> + m_last_subfile = m_cu->get_builder ()->get_current_subfile ();
> m_line_has_non_zero_discriminator = m_discriminator != 0;
> dwarf2_start_subfile (m_cu, fe->name, dir);
> }
> @@ -20724,7 +20744,7 @@ dwarf_record_line_p (struct dwarf2_cu *cu,
> int line_has_non_zero_discriminator,
> struct subfile *last_subfile)
> {
> - if (cu->builder->get_current_subfile () != last_subfile)
> + if (cu->get_builder ()->get_current_subfile () != last_subfile)
> return 1;
> if (line != last_line)
> return 1;
> @@ -20755,7 +20775,7 @@ dwarf_record_line_1 (struct gdbarch *gdbarch, struct subfile *subfile,
> }
>
> if (cu != nullptr)
> - cu->builder->record_line (subfile, line, addr);
> + cu->get_builder ()->record_line (subfile, line, addr);
> }
>
> /* Subroutine of dwarf_decode_lines_1 to simplify it.
> @@ -20806,7 +20826,7 @@ lnp_state_machine::record_line (bool end_sequence)
> fe->included_p = 1;
> if (m_record_lines_p && (producer_is_codewarrior (m_cu) || m_is_stmt))
> {
> - if (m_last_subfile != m_cu->builder->get_current_subfile ()
> + if (m_last_subfile != m_cu->get_builder ()->get_current_subfile ()
> || end_sequence)
> {
> dwarf_finish_line (m_gdbarch, m_last_subfile, m_address,
> @@ -20819,12 +20839,13 @@ lnp_state_machine::record_line (bool end_sequence)
> m_line_has_non_zero_discriminator,
> m_last_subfile))
> {
> + buildsym_compunit *builder = m_cu->get_builder ();
> dwarf_record_line_1 (m_gdbarch,
> - m_cu->builder->get_current_subfile (),
> + builder->get_current_subfile (),
> m_line, m_address,
> m_currently_recording_lines ? m_cu : nullptr);
> }
> - m_last_subfile = m_cu->builder->get_current_subfile ();
> + m_last_subfile = m_cu->get_builder ()->get_current_subfile ();
> m_last_line = m_line;
> }
> }
> @@ -21147,7 +21168,8 @@ dwarf_decode_lines (struct line_header *lh, const char *comp_dir,
> /* Make sure a symtab is created for every file, even files
> which contain only variables (i.e. no code with associated
> line numbers). */
> - struct compunit_symtab *cust = cu->builder->get_compunit_symtab ();
> + buildsym_compunit *builder = cu->get_builder ();
> + struct compunit_symtab *cust = builder->get_compunit_symtab ();
> int i;
>
> for (i = 0; i < lh->file_names.size (); i++)
> @@ -21156,13 +21178,13 @@ dwarf_decode_lines (struct line_header *lh, const char *comp_dir,
>
> dwarf2_start_subfile (cu, fe.name, fe.include_dir (lh));
>
> - if (cu->builder->get_current_subfile ()->symtab == NULL)
> + if (builder->get_current_subfile ()->symtab == NULL)
> {
> - cu->builder->get_current_subfile ()->symtab
> + builder->get_current_subfile ()->symtab
> = allocate_symtab (cust,
> - cu->builder->get_current_subfile ()->name);
> + builder->get_current_subfile ()->name);
> }
> - fe.symtab = cu->builder->get_current_subfile ()->symtab;
> + fe.symtab = builder->get_current_subfile ()->symtab;
> }
> }
> }
> @@ -21209,7 +21231,7 @@ dwarf2_start_subfile (struct dwarf2_cu *cu, const char *filename,
> filename = copy;
> }
>
> - cu->builder->start_subfile (filename);
> + cu->get_builder ()->start_subfile (filename);
>
> if (copy != NULL)
> xfree (copy);
> @@ -21228,14 +21250,14 @@ dwarf2_start_symtab (struct dwarf2_cu *cu,
> (cu->per_cu->dwarf2_per_objfile->objfile,
> name, comp_dir, cu->language, low_pc));
>
> - cu->list_in_scope = cu->builder->get_file_symbols ();
> + cu->list_in_scope = cu->get_builder ()->get_file_symbols ();
>
> - cu->builder->record_debugformat ("DWARF 2");
> - cu->builder->record_producer (cu->producer);
> + cu->get_builder ()->record_debugformat ("DWARF 2");
> + cu->get_builder ()->record_producer (cu->producer);
>
> cu->processing_has_namespace_info = 0;
>
> - return cu->builder->get_compunit_symtab ();
> + return cu->get_builder ()->get_compunit_symtab ();
> }
>
> static void
> @@ -21421,7 +21443,7 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
> access them globally. For instance, we want to be able
> to break on a nested subprogram without having to
> specify the context. */
> - list_to_add = cu->builder->get_global_symbols ();
> + list_to_add = cu->get_builder ()->get_global_symbols ();
> }
> else
> {
> @@ -21464,7 +21486,7 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
> if (!suppress_add)
> {
> if (attr2 && (DW_UNSND (attr2) != 0))
> - list_to_add = cu->builder->get_global_symbols ();
> + list_to_add = cu->get_builder ()->get_global_symbols ();
> else
> list_to_add = cu->list_in_scope;
> }
> @@ -21510,8 +21532,9 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
> /* A variable with DW_AT_external is never static,
> but it may be block-scoped. */
> list_to_add
> - = (cu->list_in_scope == cu->builder->get_file_symbols ()
> - ? cu->builder->get_global_symbols ()
> + = ((cu->list_in_scope
> + == cu->get_builder ()->get_file_symbols ())
> + ? cu->get_builder ()->get_global_symbols ()
> : cu->list_in_scope);
> }
> else
> @@ -21543,8 +21566,9 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
> /* A variable with DW_AT_external is never static, but it
> may be block-scoped. */
> list_to_add
> - = (cu->list_in_scope == cu->builder->get_file_symbols ()
> - ? cu->builder->get_global_symbols ()
> + = ((cu->list_in_scope
> + == cu->get_builder ()->get_file_symbols ())
> + ? cu->get_builder ()->get_global_symbols ()
> : cu->list_in_scope);
>
> SYMBOL_ACLASS_INDEX (sym) = LOC_UNRESOLVED;
> @@ -21566,7 +21590,7 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
> pretend it's a local variable in that case so that the user can
> still see it. */
> struct context_stack *curr
> - = cu->builder->get_current_context_stack ();
> + = cu->get_builder ()->get_current_context_stack ();
> if (curr != nullptr && curr->name != nullptr)
> SYMBOL_IS_ARGUMENT (sym) = 1;
> attr = dwarf2_attr (die, DW_AT_location, cu);
> @@ -21611,10 +21635,11 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
>
> if (!suppress_add)
> {
> + buildsym_compunit *builder = cu->get_builder ();
> list_to_add
> - = (cu->list_in_scope == cu->builder->get_file_symbols ()
> + = (cu->list_in_scope == builder->get_file_symbols ()
> && cu->language == language_cplus
> - ? cu->builder->get_global_symbols ()
> + ? builder->get_global_symbols ()
> : cu->list_in_scope);
>
> /* The semantics of C++ state that "struct foo {
> @@ -21655,21 +21680,21 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
> DW_TAG_class_type, etc. block. */
>
> list_to_add
> - = (cu->list_in_scope == cu->builder->get_file_symbols ()
> + = (cu->list_in_scope == cu->get_builder ()->get_file_symbols ()
> && cu->language == language_cplus
> - ? cu->builder->get_global_symbols ()
> + ? cu->get_builder ()->get_global_symbols ()
> : cu->list_in_scope);
> }
> break;
> case DW_TAG_imported_declaration:
> case DW_TAG_namespace:
> SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
> - list_to_add = cu->builder->get_global_symbols ();
> + list_to_add = cu->get_builder ()->get_global_symbols ();
> break;
> case DW_TAG_module:
> SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
> SYMBOL_DOMAIN (sym) = MODULE_DOMAIN;
> - list_to_add = cu->builder->get_global_symbols ();
> + list_to_add = cu->get_builder ()->get_global_symbols ();
> break;
> case DW_TAG_common_block:
> SYMBOL_ACLASS_INDEX (sym) = LOC_COMMON_BLOCK;
> @@ -23001,6 +23026,10 @@ follow_die_offset (sect_offset sect_off, int offset_in_dwz,
>
> *ref_cu = target_cu;
> temp_die.sect_off = sect_off;
> +
> + if (target_cu != cu)
> + target_cu->ancestor = cu;
> +
> return (struct die_info *) htab_find_with_hash (target_cu->die_hash,
> &temp_die,
> to_underlying (sect_off));
> @@ -23335,7 +23364,7 @@ follow_die_sig_1 (struct die_info *src_die, struct signatured_type *sig_type,
> struct dwarf2_cu **ref_cu)
> {
> struct die_info temp_die;
> - struct dwarf2_cu *sig_cu;
> + struct dwarf2_cu *sig_cu, *cu = *ref_cu;
> struct die_info *die;
>
> /* While it might be nice to assert sig_type->type == NULL here,
> @@ -23369,6 +23398,9 @@ follow_die_sig_1 (struct die_info *src_die, struct signatured_type *sig_type,
> }
>
> *ref_cu = sig_cu;
> + if (sig_cu != cu)
> + sig_cu->ancestor = cu;
> +
> return die;
> }
>
> @@ -23945,7 +23977,7 @@ macro_start_file (struct dwarf2_cu *cu,
> {
> /* Note: We don't create a macro table for this compilation unit
> at all until we actually get a filename. */
> - struct macro_table *macro_table = cu->builder->get_macro_table ();
> + struct macro_table *macro_table = cu->get_builder ()->get_macro_table ();
>
> /* If we have no current file, then this must be the start_file
> directive for the compilation unit's main source file. */
> diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
> index a917a6d04c..15a2fbaf8c 100644
> --- a/gdb/testsuite/ChangeLog
> +++ b/gdb/testsuite/ChangeLog
> @@ -1,3 +1,8 @@
> +YYYY-MM-DD Keith Seitz <keiths@redhat.com>
> +
> + PR gdb/23773
> + * gdb.dwarf2/inline_subroutine-inheritance.exp: New file.
> +
> 2018-10-19 Alan Hayward <alan.hayward@arm.com>
>
> * gdb.python/py-cmd.exp: Check for gdb_prompt.
> diff --git a/gdb/testsuite/gdb.dwarf2/inline_subroutine-inheritance.exp b/gdb/testsuite/gdb.dwarf2/inline_subroutine-inheritance.exp
> new file mode 100644
> index 0000000000..92c5d0529b
> --- /dev/null
> +++ b/gdb/testsuite/gdb.dwarf2/inline_subroutine-inheritance.exp
> @@ -0,0 +1,213 @@
> +# Copyright 2018 Free Software Foundation, Inc.
> +
> +# 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 tests a segfault that occurs when reading inline_subroutine DIEs
> +# with abstract_origins pointing to DIEs in other CUs.
> +#
> +# See https://bugzilla.redhat.com/show_bug.cgi?id=1638798 .
> +
> +load_lib dwarf.exp
> +
> +# This test can only be run on targets which support DWARF.
> +if {![dwarf2_support]} {
> + return 0
> +}
> +
> +standard_testfile main.c .S
> +
> +# Create the DWARF. This is derived from the reproducer in the Fedora
> +# bugzila mentioned above. For clarity, some "superfluous" DIES have
> +# been left instead of simplifying/pruning the test further.
> +set asm_file [standard_output_file $srcfile2]
> +Dwarf::assemble $asm_file {
> + declare_labels Db D72f8 D736e
> + declare_labels D266465 D266477 D266483 D266496 D266498 D266ad3 D266ad9 \
> + D266ade D26b227 D26b237
> + declare_labels D26d8b1 D26d8c3 D26d8cf D26d944 D26d946 D26e103 D26e145 \
> + D26e415 D26e48c D26df00 D26df06 D26df0b D272519 D274c1a D274c42
> +
> + cu {} {
> + Db: compile_unit {
> + {language @DW_LANG_C99}
> + {name "<artificial>"}
> + } {
> + D72f8: subprogram {
> + {abstract_origin :$D272519}
> + {low_pc 0xb9e20 addr}
> + {high_pc 0x1f5 data4}
> + } {
> + D736e: inlined_subroutine {
> + {abstract_origin :$D26b227}
> + {low_pc 0xb9efc addr}
> + {high_pc 0xc data4}
> + } {
> + formal_parameter {
> + {abstract_origin :$D274c42}
> + }
> + }
> + }
> + }
> + }
> +
> + cu {} {
> + D266465: compile_unit {
> + {language @DW_LANG_C99}
> + } {
> + D266477: typedef {
> + {name "size_t"}
> + {type :$D266483}
> + }
> +
> + D266483: base_type {
> + {byte_size 8 sdata}
> + {encoding @DW_ATE_unsigned}
> + }
> +
> + D266496: pointer_type {
> + {byte_size 8 sdata}
> + }
> +
> + D266498: restrict_type {
> + {type :$D266496}
> + }
> +
> + D266ad3: pointer_type {
> + {byte_size 8 sdata}
> + {type :$D266ade}
> + }
> +
> + D266ad9: restrict_type {
> + {type :$D266ad3}
> + }
> +
> + D266ade: const_type {}
> +
> + D26b227: subprogram {
> + {external 1 flag}
> + {name "memcpy"}
> + {type :$D266496}
> + } {
> + D26b237: formal_parameter {
> + {name "__dest"}
> + {type :$D266498}
> + }
> + formal_parameter {
> + {name "__src"}
> + {type :$D266ad9}
> + }
> + formal_parameter {
> + {name "__len"}
> + {type :$D266477}
> + }
> + }
> + }
> + }
> +
> + cu {} {
> + D26d8b1: compile_unit {
> + {language @DW_LANG_C99}
> + } {
> + D26d8c3: typedef {
> + {name "size_t"}
> + {type :$D26d8cf}
> + }
> +
> + D26d8cf: base_type {
> + {byte_size 8 sdata}
> + {encoding @DW_ATE_unsigned}
> + {name "long unsigned int"}
> + }
> +
> + D26d944: pointer_type {
> + {byte_size 8 sdata}
> + }
> +
> + D26d946: restrict_type {
> + {type :$D26d944}
> + }
> +
> + D26e103: structure_type {
> + {name "__object"}
> + {byte_size 12 sdata}
> + } {
> + member {
> + {name "__ob_next"}
> + {type :$D26e145}
> + {data_member_location 0 sdata}
> + }
> + }
> +
> + D26e145: pointer_type {
> + {byte_size 8 sdata}
> + {type :$D26e103}
> + }
> +
> + D26e415: typedef {
> + {name "PyObject"}
> + {type :$D26e103}
> + }
> +
> + D26e48c: pointer_type {
> + {byte_size 8 sdata}
> + {type :$D26e415}
> + }
> +
> + D26df00: pointer_type {
> + {byte_size 8 sdata}
> + {type :$D26df0b}
> + }
> +
> + D26df06: restrict_type {
> + {type :$D26df00}
> + }
> +
> + D26df0b: const_type {}
> +
> + D272519: subprogram {
> + {name "bytes_repeat"}
> + {type :$D26e48c}
> + }
> +
> + D274c1a: subprogram {
> + {external 1 flag}
> + {name "memcpy"}
> + {type :$D26d944}
> + } {
> + formal_parameter {
> + {name "__dest"}
> + {type :$D26d946}
> + }
> + formal_parameter {
> + {name "__src"}
> + {type :$D26df06}
> + }
> + D274c42: formal_parameter {
> + {name "__len"}
> + {type :$D26d8c3}
> + }
> + }
> + }
> + }
> +}
> +
> +if {[prepare_for_testing "failed to prepare" $testfile \
> + "${asm_file} ${srcfile}" {}]} {
> + return -1
> +}
> +
> +# All we need to do is set a breakpoint, which causes the DWARF
> +# info to be read, to demonstrate the problem.
> +
> +gdb_breakpoint "bytes_repeat" message
>