From patchwork Sun Jan 12 22:30:33 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tom Tromey X-Patchwork-Id: 37339 Received: (qmail 62583 invoked by alias); 12 Jan 2020 22:30:44 -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 62562 invoked by uid 89); 12 Jan 2020 22:30:42 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-21.1 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_NONE, SPF_HELO_PASS autolearn=ham version=3.3.1 spammy=Verify, alternative, subroutine, Replace X-HELO: gateway32.websitewelcome.com Received: from gateway32.websitewelcome.com (HELO gateway32.websitewelcome.com) (192.185.145.184) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Sun, 12 Jan 2020 22:30:37 +0000 Received: from cm11.websitewelcome.com (cm11.websitewelcome.com [100.42.49.5]) by gateway32.websitewelcome.com (Postfix) with ESMTP id 9CD4BB1A8F8 for ; Sun, 12 Jan 2020 16:30:35 -0600 (CST) Received: from box5379.bluehost.com ([162.241.216.53]) by cmsmtp with SMTP id qlkhitt9tiJ43qlkhiAtpA; Sun, 12 Jan 2020 16:30:35 -0600 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=tromey.com; s=default; h=Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To:MIME-Version :Content-Type:Content-Transfer-Encoding:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: In-Reply-To:References:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=t/stSP9POFWvkBDcOptpPLe7qGYp/N9ju3J/K0H3jr8=; b=JmmQySonjcppI48sDIRUkeARLk j2hSbOWz9RQ9kB/qakuuMd4AQYMj3K3gwFfU4NOS60m5yL3f+KrVPixOCKoCWLLFDsILnRWfRdlOs yPxOst+IgMQhFzaIgVH58nmjX; Received: from 75-166-123-50.hlrn.qwest.net ([75.166.123.50]:45998 helo=bapiya.Home) by box5379.bluehost.com with esmtpsa (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.92) (envelope-from ) id 1iqlkh-001tcb-6U; Sun, 12 Jan 2020 15:30:35 -0700 From: Tom Tromey To: gdb-patches@sourceware.org Cc: Tom Tromey Subject: [PATCH] Replace init_cutu_and_read_dies with a class Date: Sun, 12 Jan 2020 15:30:33 -0700 Message-Id: <20200112223033.22856-1-tom@tromey.com> init_cutu_and_read_dies takes a callback function, which I've always found somewhat difficult to follow. This patch replaces this function with a class, and changes the callers to use it. In some cases this allows for the removal of a helper struct and helper function as well. Tested by the buildbot. gdb/ChangeLog 2020-01-12 Tom Tromey * dwarf2read.c (abbrev_table_up): Move typedef earlier. (die_reader_func_ftype): Remove. (cutu_reader): New class. (dw2_get_file_names_reader): Remove "data" parameter. (dw2_get_file_names): Use cutu_reader. (create_debug_type_hash_table): Update. (read_cutu_die_from_dwo): Update comment. (lookup_dwo_unit): Add dwo_name parameter. (cutu_reader::init_tu_and_read_dwo_dies): Now a method. Remove die_reader_func_ftype and data parameters. (cutu_reader::cutu_reader): Rename from init_cutu_and_read_dies. Remove die_reader_func_ftype and data parameters. (~cutu_reader): New; from init_cutu_and_read_dies. (cutu_reader::cutu_reader): Rename from init_cutu_and_read_dies_no_follow. Remove die_reader_func_ftype and data parameters. (init_cutu_and_read_dies_simple): Remove. (struct process_psymtab_comp_unit_data): Remove. (process_psymtab_comp_unit_reader): Remove data parameter; add want_partial_unit and pretend_language parameters. (process_psymtab_comp_unit): Use cutu_reader. (build_type_psymtabs_reader): Remove data parameter. (build_type_psymtabs_1): Use cutu_reader. (process_skeletonless_type_unit): Likewise. (load_partial_comp_unit_reader): Remove. (load_partial_comp_unit): Use cutu_reader. (load_full_comp_unit_reader): Remove. (load_full_comp_unit): Use cutu_reader. (struct create_dwo_cu_data): Remove. (create_dwo_cu_reader): Remove datap parameter; add dwo_file and dwo_unit parameters. (create_cus_hash_table): Use cutu_reader. (struct dwarf2_read_addr_index_data): Remove. (dwarf2_read_addr_index_reader): Remove. (dwarf2_read_addr_index): Use cutu_reader. (read_signatured_type_reader): Remove. (read_signatured_type): Use cutu_reader. Change-Id: I4ef2f29e73108ce94bfe97799f8f638ed272212d --- gdb/ChangeLog | 40 ++++ gdb/dwarf2read.c | 543 +++++++++++++++++++---------------------------- 2 files changed, 263 insertions(+), 320 deletions(-) diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index 04979f3d12f..94dcf8ac314 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -869,6 +869,9 @@ struct dwp_file asection **elf_sections = nullptr; }; +struct abbrev_table; +typedef std::unique_ptr abbrev_table_up; + /* Struct used to pass misc. parameters to read_die_and_children, et al. which are used for both .debug_info and .debug_types dies. All parameters here are unchanging for the life of the call. This @@ -902,12 +905,44 @@ struct die_reader_specs struct abbrev_table *abbrev_table; }; -/* Type of function passed to init_cutu_and_read_dies, et.al. */ -typedef void (die_reader_func_ftype) (const struct die_reader_specs *reader, - const gdb_byte *info_ptr, - struct die_info *comp_unit_die, - int has_children, - void *data); +/* A subclass of die_reader_specs that holds storage and has complex + constructor and destructor behavior. */ + +class cutu_reader : public die_reader_specs +{ +public: + + cutu_reader (struct dwarf2_per_cu_data *this_cu, + struct abbrev_table *abbrev_table, + int use_existing_cu, int keep, + bool skip_partial); + + explicit cutu_reader (struct dwarf2_per_cu_data *this_cu, + struct dwo_file *dwo_file = nullptr); + + ~cutu_reader (); + + DISABLE_COPY_AND_ASSIGN (cutu_reader); + + const gdb_byte *info_ptr = nullptr; + struct die_info *comp_unit_die = nullptr; + int has_children = 0; + bool dummy_p = false; + +private: + void init_tu_and_read_dwo_dies (struct dwarf2_per_cu_data *this_cu, + int use_existing_cu, int keep); + + struct dwarf2_per_cu_data *m_this_cu; + int m_keep = 0; + std::unique_ptr m_new_cu; + + /* The ordinary abbreviation table. */ + abbrev_table_up m_abbrev_table_holder; + + /* The DWO abbreviation table. */ + abbrev_table_up m_dwo_abbrev_table; +}; /* dir_index is 1-based in DWARF 4 and before, and is 0-based in DWARF 5 and later. */ @@ -1259,8 +1294,6 @@ private: struct abbrev_info **m_abbrevs; }; -typedef std::unique_ptr abbrev_table_up; - /* Attributes have a name and a value. */ struct attribute { @@ -1447,7 +1480,7 @@ static struct partial_symtab *create_partial_symtab static void build_type_psymtabs_reader (const struct die_reader_specs *reader, const gdb_byte *info_ptr, struct die_info *type_unit_die, - int has_children, void *data); + int has_children); static void dwarf2_build_psymtabs_hard (struct dwarf2_per_objfile *dwarf2_per_objfile); @@ -1977,15 +2010,6 @@ static const gdb_byte *read_and_check_comp_unit_head struct dwarf2_section_info *abbrev_section, const gdb_byte *info_ptr, rcuh_kind section_kind); -static void init_cutu_and_read_dies - (struct dwarf2_per_cu_data *this_cu, struct abbrev_table *abbrev_table, - int use_existing_cu, int keep, bool skip_partial, - die_reader_func_ftype *die_reader_func, void *data); - -static void init_cutu_and_read_dies_simple - (struct dwarf2_per_cu_data *this_cu, - die_reader_func_ftype *die_reader_func, void *data); - static htab_t allocate_signatured_type_table (struct objfile *objfile); static htab_t allocate_dwo_unit_table (struct objfile *objfile); @@ -3645,8 +3669,7 @@ static void dw2_get_file_names_reader (const struct die_reader_specs *reader, const gdb_byte *info_ptr, struct die_info *comp_unit_die, - int has_children, - void *data) + int has_children) { struct dwarf2_cu *cu = reader->cu; struct dwarf2_per_cu_data *this_cu = cu->per_cu; @@ -3742,7 +3765,10 @@ dw2_get_file_names (struct dwarf2_per_cu_data *this_cu) if (this_cu->v.quick->no_file_data) return NULL; - init_cutu_and_read_dies_simple (this_cu, dw2_get_file_names_reader, NULL); + cutu_reader reader (this_cu); + if (!reader.dummy_p) + dw2_get_file_names_reader (&reader, reader.info_ptr, reader.comp_unit_die, + reader.has_children); if (this_cu->v.quick->no_file_data) return NULL; @@ -6777,9 +6803,8 @@ create_debug_type_hash_table (struct dwarf2_per_objfile *dwarf2_per_objfile, not present, in which case the bfd is unknown. */ abfd = get_section_bfd_owner (section); - /* We don't use init_cutu_and_read_dies_simple, or some such, here - because we don't need to read any dies: the signature is in the - header. */ + /* We don't use cutu_reader here because we don't need to read + any dies: the signature is in the header. */ end_ptr = info_ptr + section->size; while (info_ptr < end_ptr) @@ -7194,9 +7219,9 @@ init_cu_die_reader (struct die_reader_specs *reader, reader->abbrev_table = abbrev_table; } -/* Subroutine of init_cutu_and_read_dies to simplify it. +/* Subroutine of cutu_reader to simplify it. Read in the rest of a CU/TU top level DIE from DWO_UNIT. - There's just a lot of work to do, and init_cutu_and_read_dies is big enough + There's just a lot of work to do, and cutu_reader is big enough already. STUB_COMP_UNIT_DIE is for the stub DIE, we copy over certain attributes @@ -7412,17 +7437,18 @@ lookup_dwo_id (struct dwarf2_cu *cu, struct die_info* comp_unit_die) return DW_UNSND (attr); } -/* Subroutine of init_cutu_and_read_dies to simplify it. +/* Subroutine of cutu_reader to simplify it. Look up the DWO unit specified by COMP_UNIT_DIE of THIS_CU. Returns NULL if the specified DWO unit cannot be found. */ static struct dwo_unit * lookup_dwo_unit (struct dwarf2_per_cu_data *this_cu, - struct die_info *comp_unit_die) + struct die_info *comp_unit_die, + const char *dwo_name) { struct dwarf2_cu *cu = this_cu->cu; struct dwo_unit *dwo_unit; - const char *comp_dir, *dwo_name; + const char *comp_dir; gdb_assert (cu != NULL); @@ -7453,23 +7479,16 @@ lookup_dwo_unit (struct dwarf2_per_cu_data *this_cu, return dwo_unit; } -/* Subroutine of init_cutu_and_read_dies to simplify it. +/* Subroutine of cutu_reader to simplify it. See it for a description of the parameters. Read a TU directly from a DWO file, bypassing the stub. */ -static void -init_tu_and_read_dwo_dies (struct dwarf2_per_cu_data *this_cu, - int use_existing_cu, int keep, - die_reader_func_ftype *die_reader_func, - void *data) +void +cutu_reader::init_tu_and_read_dwo_dies (struct dwarf2_per_cu_data *this_cu, + int use_existing_cu, int keep) { - std::unique_ptr new_cu; struct signatured_type *sig_type; struct die_reader_specs reader; - const gdb_byte *info_ptr; - struct die_info *comp_unit_die; - int has_children; - struct dwarf2_per_objfile *dwarf2_per_objfile = this_cu->dwarf2_per_objfile; /* Verify we can do the following downcast, and that we have the data we need. */ @@ -7481,48 +7500,28 @@ init_tu_and_read_dwo_dies (struct dwarf2_per_cu_data *this_cu, { gdb_assert (this_cu->cu->dwo_unit == sig_type->dwo_unit); /* There's no need to do the rereading_dwo_cu handling that - init_cutu_and_read_dies does since we don't read the stub. */ + cutu_reader does since we don't read the stub. */ } else { /* If !use_existing_cu, this_cu->cu must be NULL. */ gdb_assert (this_cu->cu == NULL); - new_cu.reset (new dwarf2_cu (this_cu)); + m_new_cu.reset (new dwarf2_cu (this_cu)); } /* A future optimization, if needed, would be to use an existing abbrev table. When reading DWOs with skeletonless TUs, all the TUs could share abbrev tables. */ - /* The abbreviation table used by READER, this must live at least as long as - READER. */ - abbrev_table_up dwo_abbrev_table; - if (read_cutu_die_from_dwo (this_cu, sig_type->dwo_unit, NULL /* stub_comp_unit_die */, sig_type->dwo_unit->dwo_file->comp_dir, &reader, &info_ptr, &comp_unit_die, &has_children, - &dwo_abbrev_table) == 0) + &m_dwo_abbrev_table) == 0) { /* Dummy die. */ - return; - } - - /* All the "real" work is done here. */ - die_reader_func (&reader, info_ptr, comp_unit_die, has_children, data); - - /* This duplicates the code in init_cutu_and_read_dies, - but the alternative is making the latter more complex. - This function is only for the special case of using DWO files directly: - no point in overly complicating the general case just to handle this. */ - if (new_cu != NULL && keep) - { - /* Link this CU into read_in_chain. */ - this_cu->cu->read_in_chain = dwarf2_per_objfile->read_in_chain; - dwarf2_per_objfile->read_in_chain = this_cu; - /* The chain owns it now. */ - new_cu.release (); + dummy_p = true; } } @@ -7537,28 +7536,23 @@ init_tu_and_read_dwo_dies (struct dwarf2_per_cu_data *this_cu, Otherwise, a new CU is allocated with xmalloc. If KEEP is non-zero, then if we allocated a dwarf2_cu we add it to - read_in_chain. Otherwise the dwarf2_cu data is freed at the end. - - WARNING: If THIS_CU is a "dummy CU" (used as filler by the incremental - linker) then DIE_READER_FUNC will not get called. */ + read_in_chain. Otherwise the dwarf2_cu data is freed at the + end. */ -static void -init_cutu_and_read_dies (struct dwarf2_per_cu_data *this_cu, - struct abbrev_table *abbrev_table, - int use_existing_cu, int keep, - bool skip_partial, - die_reader_func_ftype *die_reader_func, - void *data) +cutu_reader::cutu_reader (struct dwarf2_per_cu_data *this_cu, + struct abbrev_table *abbrev_table, + int use_existing_cu, int keep, + bool skip_partial) + : die_reader_specs {}, + m_this_cu (this_cu), + m_keep (keep) { struct dwarf2_per_objfile *dwarf2_per_objfile = this_cu->dwarf2_per_objfile; struct objfile *objfile = dwarf2_per_objfile->objfile; struct dwarf2_section_info *section = this_cu->section; bfd *abfd = get_section_bfd_owner (section); struct dwarf2_cu *cu; - const gdb_byte *begin_info_ptr, *info_ptr; - struct die_reader_specs reader; - struct die_info *comp_unit_die; - int has_children; + const gdb_byte *begin_info_ptr; struct signatured_type *sig_type = NULL; struct dwarf2_section_info *abbrev_section; /* Non-zero if CU currently points to a DWO file and we need to @@ -7581,8 +7575,7 @@ init_cutu_and_read_dies (struct dwarf2_per_cu_data *this_cu, /* Narrow down the scope of possibilities to have to understand. */ gdb_assert (this_cu->is_debug_types); gdb_assert (abbrev_table == NULL); - init_tu_and_read_dwo_dies (this_cu, use_existing_cu, keep, - die_reader_func, data); + init_tu_and_read_dwo_dies (this_cu, use_existing_cu, keep); return; } @@ -7593,7 +7586,6 @@ init_cutu_and_read_dies (struct dwarf2_per_cu_data *this_cu, abbrev_section = get_abbrev_section_for_cu (this_cu); - std::unique_ptr new_cu; if (use_existing_cu && this_cu->cu != NULL) { cu = this_cu->cu; @@ -7610,8 +7602,8 @@ init_cutu_and_read_dies (struct dwarf2_per_cu_data *this_cu, { /* If !use_existing_cu, this_cu->cu must be NULL. */ gdb_assert (this_cu->cu == NULL); - new_cu.reset (new dwarf2_cu (this_cu)); - cu = new_cu.get (); + m_new_cu.reset (new dwarf2_cu (this_cu)); + cu = m_new_cu.get (); } /* Get the header. */ @@ -7664,28 +7656,33 @@ init_cutu_and_read_dies (struct dwarf2_per_cu_data *this_cu, /* Skip dummy compilation units. */ if (info_ptr >= begin_info_ptr + this_cu->length || peek_abbrev_code (abfd, info_ptr) == 0) - return; + { + dummy_p = true; + return; + } /* If we don't have them yet, read the abbrevs for this compilation unit. And if we need to read them now, make sure they're freed when we're - done (own the table through ABBREV_TABLE_HOLDER). */ - abbrev_table_up abbrev_table_holder; + done. */ if (abbrev_table != NULL) gdb_assert (cu->header.abbrev_sect_off == abbrev_table->sect_off); else { - abbrev_table_holder + m_abbrev_table_holder = abbrev_table_read_table (dwarf2_per_objfile, abbrev_section, cu->header.abbrev_sect_off); - abbrev_table = abbrev_table_holder.get (); + abbrev_table = m_abbrev_table_holder.get (); } /* Read the top level CU/TU die. */ - init_cu_die_reader (&reader, cu, section, NULL, abbrev_table); - info_ptr = read_full_die (&reader, &comp_unit_die, info_ptr, &has_children); + init_cu_die_reader (this, cu, section, NULL, abbrev_table); + info_ptr = read_full_die (this, &comp_unit_die, info_ptr, &has_children); if (skip_partial && comp_unit_die->tag == DW_TAG_partial_unit) - return; + { + dummy_p = true; + return; + } /* If we are in a DWO stub, process it and then read in the "real" CU/TU from the DWO file. read_cutu_die_from_dwo will allocate the abbreviation @@ -7696,7 +7693,6 @@ init_cutu_and_read_dies (struct dwarf2_per_cu_data *this_cu, Note that if USE_EXISTING_OK != 0, and THIS_CU->cu already contains a DWO CU, that this test will fail (the attribute will not be present). */ const char *dwo_name = dwarf2_dwo_name (comp_unit_die, cu); - abbrev_table_up dwo_abbrev_table; if (dwo_name != nullptr) { struct dwo_unit *dwo_unit; @@ -7709,16 +7705,17 @@ init_cutu_and_read_dies (struct dwarf2_per_cu_data *this_cu, sect_offset_str (this_cu->sect_off), bfd_get_filename (abfd)); } - dwo_unit = lookup_dwo_unit (this_cu, comp_unit_die); + dwo_unit = lookup_dwo_unit (this_cu, comp_unit_die, dwo_name); if (dwo_unit != NULL) { if (read_cutu_die_from_dwo (this_cu, dwo_unit, comp_unit_die, NULL, - &reader, &info_ptr, + this, &info_ptr, &dwo_comp_unit_die, &has_children, - &dwo_abbrev_table) == 0) + &m_dwo_abbrev_table) == 0) { /* Dummy die. */ + dummy_p = true; return; } comp_unit_die = dwo_comp_unit_die; @@ -7732,18 +7729,20 @@ init_cutu_and_read_dies (struct dwarf2_per_cu_data *this_cu, debug info. */ } } +} - /* All of the above is setup for this call. Yikes. */ - die_reader_func (&reader, info_ptr, comp_unit_die, has_children, data); - +cutu_reader::~cutu_reader () +{ /* Done, clean up. */ - if (new_cu != NULL && keep) + if (m_new_cu != NULL && m_keep && !dummy_p) { + struct dwarf2_per_objfile *dwarf2_per_objfile + = m_this_cu->dwarf2_per_objfile; /* Link this CU into read_in_chain. */ - this_cu->cu->read_in_chain = dwarf2_per_objfile->read_in_chain; - dwarf2_per_objfile->read_in_chain = this_cu; + m_this_cu->cu->read_in_chain = dwarf2_per_objfile->read_in_chain; + dwarf2_per_objfile->read_in_chain = m_this_cu; /* The chain owns it now. */ - new_cu.release (); + m_new_cu.release (); } } @@ -7756,18 +7755,14 @@ init_cutu_and_read_dies (struct dwarf2_per_cu_data *this_cu, We fill in THIS_CU->length. - WARNING: If THIS_CU is a "dummy CU" (used as filler by the incremental - linker) then DIE_READER_FUNC will not get called. - THIS_CU->cu is always freed when done. This is done in order to not leave THIS_CU->cu in a state where we have to care whether it refers to the "main" CU or the DWO CU. */ -static void -init_cutu_and_read_dies_no_follow (struct dwarf2_per_cu_data *this_cu, - struct dwo_file *dwo_file, - die_reader_func_ftype *die_reader_func, - void *data) +cutu_reader::cutu_reader (struct dwarf2_per_cu_data *this_cu, + struct dwo_file *dwo_file) + : die_reader_specs {}, + m_this_cu (this_cu) { struct dwarf2_per_objfile *dwarf2_per_objfile = this_cu->dwarf2_per_objfile; struct objfile *objfile = dwarf2_per_objfile->objfile; @@ -7775,8 +7770,6 @@ init_cutu_and_read_dies_no_follow (struct dwarf2_per_cu_data *this_cu, bfd *abfd = get_section_bfd_owner (section); struct dwarf2_section_info *abbrev_section; const gdb_byte *begin_info_ptr, *info_ptr; - struct die_reader_specs reader; - struct die_info *comp_unit_die; int has_children; if (dwarf_die_debug) @@ -7793,49 +7786,35 @@ init_cutu_and_read_dies_no_follow (struct dwarf2_per_cu_data *this_cu, /* This is cheap if the section is already read in. */ dwarf2_read_section (objfile, section); - struct dwarf2_cu cu (this_cu); + m_new_cu.reset (new dwarf2_cu (this_cu)); begin_info_ptr = info_ptr = section->buffer + to_underlying (this_cu->sect_off); info_ptr = read_and_check_comp_unit_head (dwarf2_per_objfile, - &cu.header, section, + &m_new_cu->header, section, abbrev_section, info_ptr, (this_cu->is_debug_types ? rcuh_kind::TYPE : rcuh_kind::COMPILE)); - this_cu->length = get_cu_length (&cu.header); + this_cu->length = get_cu_length (&m_new_cu->header); /* Skip dummy compilation units. */ if (info_ptr >= begin_info_ptr + this_cu->length || peek_abbrev_code (abfd, info_ptr) == 0) - return; + { + dummy_p = true; + return; + } - abbrev_table_up abbrev_table + m_abbrev_table_holder = abbrev_table_read_table (dwarf2_per_objfile, abbrev_section, - cu.header.abbrev_sect_off); - - init_cu_die_reader (&reader, &cu, section, dwo_file, abbrev_table.get ()); - info_ptr = read_full_die (&reader, &comp_unit_die, info_ptr, &has_children); + m_new_cu->header.abbrev_sect_off); - die_reader_func (&reader, info_ptr, comp_unit_die, has_children, data); + init_cu_die_reader (this, m_new_cu.get (), section, dwo_file, + m_abbrev_table_holder.get ()); + info_ptr = read_full_die (this, &comp_unit_die, info_ptr, &has_children); } -/* Read a CU/TU, except that this does not look for DW_AT_GNU_dwo_name and - does not lookup the specified DWO file. - This cannot be used to read DWO files. - - THIS_CU->cu is always freed when done. - This is done in order to not leave THIS_CU->cu in a state where we have - to care whether it refers to the "main" CU or the DWO CU. - We can revisit this if the data shows there's a performance issue. */ - -static void -init_cutu_and_read_dies_simple (struct dwarf2_per_cu_data *this_cu, - die_reader_func_ftype *die_reader_func, - void *data) -{ - init_cutu_and_read_dies_no_follow (this_cu, NULL, die_reader_func, data); -} /* Type Unit Groups. @@ -8013,29 +7992,15 @@ create_partial_symtab (struct dwarf2_per_cu_data *per_cu, const char *name) return pst; } -/* The DATA object passed to process_psymtab_comp_unit_reader has this - type. */ - -struct process_psymtab_comp_unit_data -{ - /* True if we are reading a DW_TAG_partial_unit. */ - - int want_partial_unit; - - /* The "pretend" language that is used if the CU doesn't declare a - language. */ - - enum language pretend_language; -}; - -/* die_reader_func for process_psymtab_comp_unit. */ +/* DIE reader function for process_psymtab_comp_unit. */ static void process_psymtab_comp_unit_reader (const struct die_reader_specs *reader, const gdb_byte *info_ptr, struct die_info *comp_unit_die, int has_children, - void *data) + int want_partial_unit, + enum language pretend_language) { struct dwarf2_cu *cu = reader->cu; struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile; @@ -8046,15 +8011,13 @@ process_psymtab_comp_unit_reader (const struct die_reader_specs *reader, struct partial_symtab *pst; enum pc_bounds_kind cu_bounds_kind; const char *filename; - struct process_psymtab_comp_unit_data *info - = (struct process_psymtab_comp_unit_data *) data; - if (comp_unit_die->tag == DW_TAG_partial_unit && !info->want_partial_unit) + if (comp_unit_die->tag == DW_TAG_partial_unit && !want_partial_unit) return; gdb_assert (! per_cu->is_debug_types); - prepare_one_comp_unit (cu, comp_unit_die, info->pretend_language); + prepare_one_comp_unit (cu, comp_unit_die, pretend_language); /* Allocate a new partial symbol table structure. */ filename = dwarf2_string_attr (comp_unit_die, DW_AT_name, cu); @@ -8176,17 +8139,21 @@ process_psymtab_comp_unit (struct dwarf2_per_cu_data *this_cu, if (this_cu->cu != NULL) free_one_cached_comp_unit (this_cu); - if (this_cu->is_debug_types) - init_cutu_and_read_dies (this_cu, NULL, 0, 0, false, - build_type_psymtabs_reader, NULL); - else + cutu_reader reader (this_cu, NULL, 0, 0, false); + + if (reader.dummy_p) { - process_psymtab_comp_unit_data info; - info.want_partial_unit = want_partial_unit; - info.pretend_language = pretend_language; - init_cutu_and_read_dies (this_cu, NULL, 0, 0, false, - process_psymtab_comp_unit_reader, &info); + /* Nothing. */ } + else if (this_cu->is_debug_types) + build_type_psymtabs_reader (&reader, reader.info_ptr, reader.comp_unit_die, + reader.has_children); + else + process_psymtab_comp_unit_reader (&reader, reader.info_ptr, + reader.comp_unit_die, + reader.has_children, + want_partial_unit, + pretend_language); /* Age out any secondary CUs. */ age_cached_comp_units (this_cu->dwarf2_per_objfile); @@ -8198,8 +8165,7 @@ static void build_type_psymtabs_reader (const struct die_reader_specs *reader, const gdb_byte *info_ptr, struct die_info *type_unit_die, - int has_children, - void *data) + int has_children) { struct dwarf2_per_objfile *dwarf2_per_objfile = reader->cu->per_cu->dwarf2_per_objfile; @@ -8213,7 +8179,6 @@ build_type_psymtabs_reader (const struct die_reader_specs *reader, CORE_ADDR lowpc, highpc; struct partial_symtab *pst; - gdb_assert (data == NULL); gdb_assert (per_cu->is_debug_types); sig_type = (struct signatured_type *) per_cu; @@ -8344,8 +8309,12 @@ build_type_psymtabs_1 (struct dwarf2_per_objfile *dwarf2_per_objfile) ++tu_stats->nr_uniq_abbrev_tables; } - init_cutu_and_read_dies (&tu.sig_type->per_cu, abbrev_table.get (), - 0, 0, false, build_type_psymtabs_reader, NULL); + cutu_reader reader (&tu.sig_type->per_cu, abbrev_table.get (), + 0, 0, false); + if (!reader.dummy_p) + build_type_psymtabs_reader (&reader, reader.info_ptr, + reader.comp_unit_die, + reader.has_children); } } @@ -8450,8 +8419,10 @@ process_skeletonless_type_unit (void **slot, void *info) *slot = entry; /* This does the job that build_type_psymtabs_1 would have done. */ - init_cutu_and_read_dies (&entry->per_cu, NULL, 0, 0, false, - build_type_psymtabs_reader, NULL); + cutu_reader reader (&entry->per_cu, NULL, 0, 0, false); + if (!reader.dummy_p) + build_type_psymtabs_reader (&reader, reader.info_ptr, + reader.comp_unit_die, reader.has_children); return 1; } @@ -8573,34 +8544,25 @@ dwarf2_build_psymtabs_hard (struct dwarf2_per_objfile *dwarf2_per_objfile) objfile_name (objfile)); } -/* die_reader_func for load_partial_comp_unit. */ - -static void -load_partial_comp_unit_reader (const struct die_reader_specs *reader, - const gdb_byte *info_ptr, - struct die_info *comp_unit_die, - int has_children, - void *data) -{ - struct dwarf2_cu *cu = reader->cu; - - prepare_one_comp_unit (cu, comp_unit_die, language_minimal); - - /* Check if comp unit has_children. - If so, read the rest of the partial symbols from this comp unit. - If not, there's no more debug_info for this comp unit. */ - if (has_children) - load_partial_dies (reader, info_ptr, 0); -} - /* Load the partial DIEs for a secondary CU into memory. This is also used when rereading a primary CU with load_all_dies. */ static void load_partial_comp_unit (struct dwarf2_per_cu_data *this_cu) { - init_cutu_and_read_dies (this_cu, NULL, 1, 1, false, - load_partial_comp_unit_reader, NULL); + cutu_reader reader (this_cu, NULL, 1, 1, false); + + if (!reader.dummy_p) + { + prepare_one_comp_unit (reader.cu, reader.comp_unit_die, + language_minimal); + + /* Check if comp unit has_children. + If so, read the rest of the partial symbols from this comp unit. + If not, there's no more debug_info for this comp unit. */ + if (reader.has_children) + load_partial_dies (&reader, reader.info_ptr, 0); + } } static void @@ -9738,19 +9700,21 @@ die_eq (const void *item_lhs, const void *item_rhs) return die_lhs->sect_off == die_rhs->sect_off; } -/* die_reader_func for load_full_comp_unit. - This is identical to read_signatured_type_reader, - but is kept separate for now. */ +/* Load the DIEs associated with PER_CU into memory. */ static void -load_full_comp_unit_reader (const struct die_reader_specs *reader, - const gdb_byte *info_ptr, - struct die_info *comp_unit_die, - int has_children, - void *data) +load_full_comp_unit (struct dwarf2_per_cu_data *this_cu, + bool skip_partial, + enum language pretend_language) { - struct dwarf2_cu *cu = reader->cu; - enum language *language_ptr = (enum language *) data; + gdb_assert (! this_cu->is_debug_types); + + cutu_reader reader (this_cu, NULL, 1, 1, skip_partial); + if (reader.dummy_p) + return; + + struct dwarf2_cu *cu = reader.cu; + const gdb_byte *info_ptr = reader.info_ptr; gdb_assert (cu->die_hash == NULL); cu->die_hash = @@ -9762,10 +9726,11 @@ load_full_comp_unit_reader (const struct die_reader_specs *reader, hashtab_obstack_allocate, dummy_obstack_deallocate); - if (has_children) - comp_unit_die->child = read_die_and_siblings (reader, info_ptr, - &info_ptr, comp_unit_die); - cu->dies = comp_unit_die; + if (reader.has_children) + reader.comp_unit_die->child + = read_die_and_siblings (&reader, reader.info_ptr, + &info_ptr, reader.comp_unit_die); + cu->dies = reader.comp_unit_die; /* comp_unit_die is not stored in die_hash, no need. */ /* We try not to read any attributes in this function, because not @@ -9774,20 +9739,7 @@ load_full_comp_unit_reader (const struct die_reader_specs *reader, or we won't be able to build types correctly. Similarly, if we do not read the producer, we can not apply producer-specific interpretation. */ - prepare_one_comp_unit (cu, cu->dies, *language_ptr); -} - -/* Load the DIEs associated with PER_CU into memory. */ - -static void -load_full_comp_unit (struct dwarf2_per_cu_data *this_cu, - bool skip_partial, - enum language pretend_language) -{ - gdb_assert (! this_cu->is_debug_types); - - init_cutu_and_read_dies (this_cu, NULL, 1, 1, skip_partial, - load_full_comp_unit_reader, &pretend_language); + prepare_one_comp_unit (cu, cu->dies, pretend_language); } /* Add a DIE to the delayed physname list. */ @@ -11924,14 +11876,6 @@ allocate_dwo_unit_table (struct objfile *objfile) dummy_obstack_deallocate); } -/* Structure used to pass data to create_dwo_debug_info_hash_table_reader. */ - -struct create_dwo_cu_data -{ - struct dwo_file *dwo_file; - struct dwo_unit dwo_unit; -}; - /* die_reader_func for create_dwo_cu. */ static void @@ -11939,14 +11883,12 @@ create_dwo_cu_reader (const struct die_reader_specs *reader, const gdb_byte *info_ptr, struct die_info *comp_unit_die, int has_children, - void *datap) + struct dwo_file *dwo_file, + struct dwo_unit *dwo_unit) { struct dwarf2_cu *cu = reader->cu; sect_offset sect_off = cu->per_cu->sect_off; struct dwarf2_section_info *section = cu->per_cu->section; - struct create_dwo_cu_data *data = (struct create_dwo_cu_data *) datap; - struct dwo_file *dwo_file = data->dwo_file; - struct dwo_unit *dwo_unit = &data->dwo_unit; gdb::optional signature = lookup_dwo_id (cu, comp_unit_die); if (!signature.has_value ()) @@ -11997,33 +11939,32 @@ create_cus_hash_table (struct dwarf2_per_objfile *dwarf2_per_objfile, while (info_ptr < end_ptr) { struct dwarf2_per_cu_data per_cu; - struct create_dwo_cu_data create_dwo_cu_data; + struct dwo_unit read_unit {}; struct dwo_unit *dwo_unit; void **slot; sect_offset sect_off = (sect_offset) (info_ptr - section.buffer); - memset (&create_dwo_cu_data.dwo_unit, 0, - sizeof (create_dwo_cu_data.dwo_unit)); memset (&per_cu, 0, sizeof (per_cu)); per_cu.dwarf2_per_objfile = dwarf2_per_objfile; per_cu.is_debug_types = 0; per_cu.sect_off = sect_offset (info_ptr - section.buffer); per_cu.section = §ion; - create_dwo_cu_data.dwo_file = &dwo_file; - init_cutu_and_read_dies_no_follow ( - &per_cu, &dwo_file, create_dwo_cu_reader, &create_dwo_cu_data); + cutu_reader reader (&per_cu, &dwo_file); + if (!reader.dummy_p) + create_dwo_cu_reader (&reader, reader.info_ptr, reader.comp_unit_die, + reader.has_children, &dwo_file, &read_unit); info_ptr += per_cu.length; // If the unit could not be parsed, skip it. - if (create_dwo_cu_data.dwo_unit.dwo_file == NULL) + if (read_unit.dwo_file == NULL) continue; if (cus_htab == NULL) cus_htab = allocate_dwo_unit_table (objfile); dwo_unit = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct dwo_unit); - *dwo_unit = create_dwo_cu_data.dwo_unit; + *dwo_unit = read_unit; slot = htab_find_slot (cus_htab, dwo_unit, INSERT); gdb_assert (slot != NULL); if (*slot != NULL) @@ -20161,32 +20102,6 @@ read_addr_index_from_leb128 (struct dwarf2_cu *cu, const gdb_byte *info_ptr, return read_addr_index (cu, addr_index); } -/* Data structure to pass results from dwarf2_read_addr_index_reader - back to dwarf2_read_addr_index. */ - -struct dwarf2_read_addr_index_data -{ - ULONGEST addr_base; - int addr_size; -}; - -/* die_reader_func for dwarf2_read_addr_index. */ - -static void -dwarf2_read_addr_index_reader (const struct die_reader_specs *reader, - const gdb_byte *info_ptr, - struct die_info *comp_unit_die, - int has_children, - void *data) -{ - struct dwarf2_cu *cu = reader->cu; - struct dwarf2_read_addr_index_data *aidata = - (struct dwarf2_read_addr_index_data *) data; - - aidata->addr_base = cu->addr_base; - aidata->addr_size = cu->header.addr_size; -} - /* Given an index in .debug_addr, fetch the value. NOTE: This can be called during dwarf expression evaluation, long after the debug information has been read, and thus per_cu->cu @@ -20224,14 +20139,9 @@ dwarf2_read_addr_index (struct dwarf2_per_cu_data *per_cu, } else { - struct dwarf2_read_addr_index_data aidata; - - /* Note: We can't use init_cutu_and_read_dies_simple here, - we need addr_base. */ - init_cutu_and_read_dies (per_cu, NULL, 0, 0, false, - dwarf2_read_addr_index_reader, &aidata); - addr_base = aidata.addr_base; - addr_size = aidata.addr_size; + cutu_reader reader (per_cu, NULL, 0, 0, false); + addr_base = reader.cu->addr_base; + addr_size = reader.cu->header.addr_size; } return read_addr_index_1 (dwarf2_per_objfile, addr_index, addr_base, @@ -24075,44 +23985,6 @@ load_full_type_unit (struct dwarf2_per_cu_data *per_cu) gdb_assert (per_cu->cu != NULL); } -/* die_reader_func for read_signatured_type. - This is identical to load_full_comp_unit_reader, - but is kept separate for now. */ - -static void -read_signatured_type_reader (const struct die_reader_specs *reader, - const gdb_byte *info_ptr, - struct die_info *comp_unit_die, - int has_children, - void *data) -{ - struct dwarf2_cu *cu = reader->cu; - - gdb_assert (cu->die_hash == NULL); - cu->die_hash = - htab_create_alloc_ex (cu->header.length / 12, - die_hash, - die_eq, - NULL, - &cu->comp_unit_obstack, - hashtab_obstack_allocate, - dummy_obstack_deallocate); - - if (has_children) - comp_unit_die->child = read_die_and_siblings (reader, info_ptr, - &info_ptr, comp_unit_die); - cu->dies = comp_unit_die; - /* comp_unit_die is not stored in die_hash, no need. */ - - /* We try not to read any attributes in this function, because not - all CUs needed for references have been loaded yet, and symbol - table processing isn't initialized. But we have to set the CU language, - or we won't be able to build types correctly. - Similarly, if we do not read the producer, we can not apply - producer-specific interpretation. */ - prepare_one_comp_unit (cu, cu->dies, language_minimal); -} - /* Read in a signatured type and build its CU and DIEs. If the type is a stub for the real type in a DWO file, read in the real type from the DWO file as well. */ @@ -24125,8 +23997,39 @@ read_signatured_type (struct signatured_type *sig_type) gdb_assert (per_cu->is_debug_types); gdb_assert (per_cu->cu == NULL); - init_cutu_and_read_dies (per_cu, NULL, 0, 1, false, - read_signatured_type_reader, NULL); + cutu_reader reader (per_cu, NULL, 0, 1, false); + + if (!reader.dummy_p) + { + struct dwarf2_cu *cu = reader.cu; + const gdb_byte *info_ptr = reader.info_ptr; + + gdb_assert (cu->die_hash == NULL); + cu->die_hash = + htab_create_alloc_ex (cu->header.length / 12, + die_hash, + die_eq, + NULL, + &cu->comp_unit_obstack, + hashtab_obstack_allocate, + dummy_obstack_deallocate); + + if (reader.has_children) + reader.comp_unit_die->child + = read_die_and_siblings (&reader, info_ptr, &info_ptr, + reader.comp_unit_die); + cu->dies = reader.comp_unit_die; + /* comp_unit_die is not stored in die_hash, no need. */ + + /* We try not to read any attributes in this function, because + not all CUs needed for references have been loaded yet, and + symbol table processing isn't initialized. But we have to + set the CU language, or we won't be able to build types + correctly. Similarly, if we do not read the producer, we can + not apply producer-specific interpretation. */ + prepare_one_comp_unit (cu, cu->dies, language_minimal); + } + sig_type->per_cu.tu_read = 1; }