From patchwork Tue Mar 11 14:57:19 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dominik Mascherbauer X-Patchwork-Id: 107694 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id D14223857836 for ; Tue, 11 Mar 2025 15:00:05 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org D14223857836 Authentication-Results: sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20230601 header.b=aYBoZUTV X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from mail-ej1-x62e.google.com (mail-ej1-x62e.google.com [IPv6:2a00:1450:4864:20::62e]) by sourceware.org (Postfix) with ESMTPS id DC8343858288 for ; Tue, 11 Mar 2025 14:57:33 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org DC8343858288 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=gmail.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org DC8343858288 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2a00:1450:4864:20::62e ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1741705054; cv=none; b=KMazaU5Mxs/YseZKqDKub3yFejibgQrofx7++SpTY5phQFfUrQB1VvlaN+H/7CkD8UPWmoEJ5YBgnu/i3Gp3qXN5HWkL6lnbM+vmt+XsIZyxK4arSVx069zaHKS8E8w3Y6pnaW54fdM8z+G6d8rW+gO2M8eSif4GuWxtFQpJ+Y8= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1741705054; c=relaxed/simple; bh=ASA6idqfCgZX97lCjq9dCdWlR3g/DbexOMVJPY0KpDk=; h=DKIM-Signature:From:To:Subject:Date:Message-Id:MIME-Version; b=Dobbo/ggqMwjmyHH0FpvxpuR1/3Wo4aDcx5AUJnVD6vs48TQh8JnejPhJ3iXMgMb26kHNk9L50r1d1dR2ZbmnHDjxFgZcUFwEPlSHMFbbXgsyvQbnghiRQMm92qQ81nAoUJvE8HuyJ2z9hIk8eag4NRl5m3TSAGO8zZ0480Xys8= ARC-Authentication-Results: i=1; server2.sourceware.org Received: by mail-ej1-x62e.google.com with SMTP id a640c23a62f3a-aaeec07b705so881306766b.2 for ; Tue, 11 Mar 2025 07:57:33 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741705052; x=1742309852; darn=sourceware.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=0974Xrde6t4so8sdGmPqYwoiutG9hrj1EDL5JBMCb80=; b=aYBoZUTVzaXag3rBp4vbcBSyR4V8l4f8UblmjE1q5PaeBvxYlrn9taVL7pW07uiXUt H1G/40hjNpMBP1J2tbSj1iRcy03P0SyOu90hWYKJHBdOPE59VSVw6BBeJpjLsy3jzYyK Sndr4GhKAW0D3AF5k5PE8hI/xFFVZgrPjNxqpnoce4RTeMhF5YU8PP/fCqar9czR69ah /vz0yBGIk7XsDuarpFEr/pt+rHpRL/zgByxuBbpOBBSsgxbU6INisIIFJF0TEyY0FFKM QUftuENTb95ijj3MSu/e3t+o63EJGSv9G32hxROuJ56XeZTE7SO/mNc2LY0DMU7js+/p WwuA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741705052; x=1742309852; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=0974Xrde6t4so8sdGmPqYwoiutG9hrj1EDL5JBMCb80=; b=C1UVKNbw+gFpPVoE1teb+wC93zWn18q1DICSfHEOGGjkjDH75E64/6Kwne1ud1p33S hjnDVpCTn2QU0bOBqkHh5wvH+zPJpPGR5rtHsvxwwwBhXivCkFP0GuODuncDHSImOjRN DuuJ0oWN5gU8ufCJtq86i2uB5YWNvbIkgQEkL9t0wfUeZ3ECx0oH+d0G47JOp1GHrA1D 1HDRqHk/2AB62LfX5AeSIhDRM3zlGT30JHwqWNJSqTjxv0Iv3n6XJZf4HGwCieQuPKd1 Fbsqz8Cl6H9PqemM8qqb+sMis0m2yQ1h88XD2N/Lp5gyJwDVKCji5nyW1wXtNf2bBuFM UT8A== X-Gm-Message-State: AOJu0Yya/rq76EjxymR0TzJxa3dgyBRsxxyiAoEaVHP7itjXtwqH6kPV +P0xaLsXq6raqVfPg+AmUf722JTXQAeHBXWjsjksvBNRTEJxbxZPiy378w== X-Gm-Gg: ASbGncsNz0B8yX6Vo0t+L5vtQfNyNQK+C5jL6MKREou8RwgaaADeEtKSByiB2tyCxjs LgyB7xkeknIFrz9b0oXLscryDCXlFvQpRezItYGDtWsvAt7AuN7Tdcs999ZNFfhmHmppvqB7IWs gVYeS56/dAVzgedorLm/uUviIjLNOUBYvvAwIr37gStZzhDInSJTb52IjtymlS3V+drSTuNJY7+ XGxls6QyLOK1OjGBYlQJVv6LAt4SjdiXhVTUSD/WtS0OaiAE88o/5NG8j8o7e+H0BbwvjG4j+lw WOeoyQe2oWknaCfRM5QhmWsgK3QHJsT7t+xlmWv55PEad7B6zcELnhQxbuynjUBbAvWCmdIq/qo 523M= X-Google-Smtp-Source: AGHT+IEuIsTfNv6xIeRuWj7wxT8xceifdrvahv9N5mG2wlmh6mBhx6UJCsF7P7gWWzb9VVR+6tbSPw== X-Received: by 2002:a17:907:3f9f:b0:abf:6b14:6cfb with SMTP id a640c23a62f3a-ac2b9db4897mr455136766b.5.1741705051905; Tue, 11 Mar 2025 07:57:31 -0700 (PDT) Received: from pop-os.ssw.jku.at ([140.78.145.202]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-ac239439074sm945195866b.10.2025.03.11.07.57.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Mar 2025 07:57:30 -0700 (PDT) From: dominikmascherbauer X-Google-Original-From: dominikmascherbauer To: gdb-patches@sourceware.org Cc: dominikmascherbauer Subject: [PATCH 2/3] Add type signature fallback and JIT objfile restriction. Date: Tue, 11 Mar 2025 15:57:19 +0100 Message-Id: X-Mailer: git-send-email 2.34.1 In-Reply-To: References: MIME-Version: 1.0 X-Spam-Status: No, score=-11.1 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gdb-patches-bounces~patchwork=sourceware.org@sourceware.org To support type signature fallback, the lookup_signatured_type method is extended. If no type signature was found in the current objfile or in a dwo file, the dwraf-type-signature-fallback option is checked: 'off': return nullptr 'main': only check the current main objfile for the type signature. This reduces the additional load for a fallback as only one additional objfile is checked. The main objfile often contains major parts of the debug info, thus it is also likely that the requested type signature is found there. If the main objfile is linked to dwo/dwp files, those are also checked for the type signature. This should be the same behavior as if the type signature is lookup up without fallback. 'full': check all objfiles in the current prospace. Requires potentially more time than just checking the main objfile, but it will also find a type signature in a loaded shared library. If a type signature was found in a fallback objfile, the per_objfile after lookup_signatured_type is the fallback per_objfile. This ensures that if the type unit still needs to be read, it is read from the correct objfile. Additionally, a flag is added to objfiles that marks an objfile as a JIT objfile. With this information the type signature fallback can be restricted to only work for JIT objfiles. This is a separate option because JIT objfile are self-contained but usually share debug info (especially type information) with some other already loaded objfile. So this leaves loading other objfiles as is to avoid unexpected behavior if needed. --- gdb/dwarf2/read.c | 184 +++++++++++++++++++++++++++++++++++++------- gdb/jit.c | 6 +- gdb/objfile-flags.h | 3 + 3 files changed, 162 insertions(+), 31 deletions(-) diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c index dc8cc7652d9..2c02f17e85a 100644 --- a/gdb/dwarf2/read.c +++ b/gdb/dwarf2/read.c @@ -2668,12 +2668,12 @@ fill_in_sig_entry_from_dwo_entry (dwarf2_per_objfile *per_objfile, to read all the DWOs to build the type unit groups. */ static struct signatured_type * -lookup_dwo_signatured_type (struct dwarf2_cu *cu, ULONGEST sig) +lookup_dwo_signatured_type (struct dwo_unit *dwo_unit, ULONGEST sig, + struct dwarf2_per_objfile *per_objfile) { - dwarf2_per_objfile *per_objfile = cu->per_objfile; dwarf2_per_bfd *per_bfd = per_objfile->per_bfd; - gdb_assert (cu->dwo_unit); + gdb_assert (dwo_unit); /* We only ever need to read in one copy of a signatured type. Use the global signatured_types array to do our own comdat-folding @@ -2696,14 +2696,14 @@ lookup_dwo_signatured_type (struct dwarf2_cu *cu, ULONGEST sig) && (*sig_type_it)->tu_read) return *sig_type_it; - /* Note: cu->dwo_unit is the dwo_unit that references this TU, not the + /* Note: dwo_unit is the dwo_unit that references this TU, not the dwo_unit of the TU itself. */ - dwo_file *dwo_file = cu->dwo_unit->dwo_file; + dwo_file *dwo_file = dwo_unit->dwo_file; auto it = dwo_file->tus.find (sig); if (it == dwo_file->tus.end ()) return nullptr; - dwo_unit *dwo_entry = *it; + struct dwo_unit *dwo_entry = *it; /* If the global table doesn't have an entry for this TU, add one. */ if (sig_type_it == per_bfd->signatured_types.end ()) @@ -2723,13 +2723,12 @@ lookup_dwo_signatured_type (struct dwarf2_cu *cu, ULONGEST sig) it won't be in .gdb_index. */ static struct signatured_type * -lookup_dwp_signatured_type (struct dwarf2_cu *cu, ULONGEST sig) +lookup_dwp_signatured_type (ULONGEST sig, + struct dwarf2_per_objfile *per_objfile) { - dwarf2_per_objfile *per_objfile = cu->per_objfile; dwarf2_per_bfd *per_bfd = per_objfile->per_bfd; struct dwp_file *dwp_file = get_dwp_file (per_objfile); - gdb_assert (cu->dwo_unit); gdb_assert (dwp_file != NULL); auto sig_type_it = per_bfd->signatured_types.find (sig); @@ -2755,34 +2754,133 @@ lookup_dwp_signatured_type (struct dwarf2_cu *cu, ULONGEST sig) return *sig_type_it; } +/* Subroutine of lookup_signatured_type. + Look up the type for signature SIG, from a fallback objfile. + If we don't have a DWO/DWP file or can't find the signature there, check the + fallback object file. + If a signatured type was found, PER_OBJFILE will contain its per_objfile. */ + +static struct signatured_type * +lookup_fallback_signatured_type (struct objfile *fallback_objfile, ULONGEST sig, + struct dwarf2_per_objfile **per_objfile) +{ + struct signatured_type *sig_type = nullptr; + + /* If we have a separate debug objfile, use it for the fallback. */ + if (fallback_objfile->separate_debug_objfile != nullptr) + fallback_objfile = fallback_objfile->separate_debug_objfile; + + struct dwarf2_per_objfile *fallback_per_objfile = get_dwarf2_per_objfile + (fallback_objfile); + + /* The fallback objfile must be different to the current objfile. Otherwise, + this is no fallback so all necessary checks were already performed in + lookup_signatured_type. */ + if (fallback_per_objfile == *per_objfile) + return nullptr; + + /* Do we have a dwp file? */ + if (get_dwp_file (fallback_per_objfile) != nullptr) + { + sig_type = lookup_dwp_signatured_type (sig, fallback_per_objfile); + } + /* Do we have dwo files? */ + else + { + /* Look for dwo_entry that contains the signatured type. */ + for (const dwo_file_up &file : fallback_per_objfile->per_bfd->dwo_files) + { + auto it = file->tus.find (sig); + if (it != file->tus.end ()) + { + /* We found the dwo entry. Check for the signatured type. */ + sig_type = lookup_dwo_signatured_type (*it, sig, + fallback_per_objfile); + break; + } + } + } + + /* Do we still need to check the fallback per_objfile or was the signatured + type found in a DWO/DWP file? */ + if (sig_type == nullptr) + { + auto sig_type_it + = fallback_per_objfile->per_bfd->signatured_types.find (sig); + + if (sig_type_it != fallback_per_objfile->per_bfd->signatured_types.end ()) + sig_type = *sig_type_it; + } + + if (sig_type != nullptr) + /* Ensure we will know where the signature type came from. */ + *per_objfile = fallback_per_objfile; + return sig_type; +} + /* Lookup a signature based type for DW_FORM_ref_sig8. Returns NULL if signature SIG is not present in the table. - It is up to the caller to complain about this. */ + It is up to the caller to complain about this. + If type_signature_fallback is enabled and the signatured type is found, + per_objfile is the objfile where the signatured type was found in. */ static struct signatured_type * -lookup_signatured_type (struct dwarf2_cu *cu, ULONGEST sig) +lookup_signatured_type (struct dwarf2_cu *cu, ULONGEST sig, + struct dwarf2_per_objfile **per_objfile) { - dwarf2_per_objfile *per_objfile = cu->per_objfile; - dwarf2_per_bfd *per_bfd = per_objfile->per_bfd; + struct signatured_type *sig_type = nullptr; + dwarf2_per_bfd *per_bfd = (*per_objfile)->per_bfd; if (cu->dwo_unit) { /* We're in a DWO/DWP file, and we're using .gdb_index. - These cases require special processing. */ - if (get_dwp_file (per_objfile) == NULL) - return lookup_dwo_signatured_type (cu, sig); + These cases require special processing. */ + if (get_dwp_file (*per_objfile) == nullptr) + sig_type = lookup_dwo_signatured_type (cu->dwo_unit, sig, *per_objfile); else - return lookup_dwp_signatured_type (cu, sig); + sig_type = lookup_dwp_signatured_type (sig, *per_objfile); + + /* If we already found the signatured type, return it. */ + if (sig_type != nullptr) + return sig_type; } else { + /* Lookup type signature in the current objfile. */ auto sig_type_it = per_bfd->signatured_types.find (sig); + /* If we already found the signatured type, return it. */ if (sig_type_it != per_bfd->signatured_types.end ()) return *sig_type_it; + } - return nullptr; + /* Handle fallback if type signature lookup fallback is enabled for this + objfile. */ + if (use_type_signature_fallback ((*per_objfile)->objfile)) + { + /* Do a full fallback through all objfiles in the progspace. */ + if (type_signature_fallback == type_signature_fallback_full) + { + for (objfile *objfile: (*per_objfile)->objfile->pspace ()->objfiles ()) + { + sig_type = lookup_fallback_signatured_type (objfile, sig, + per_objfile); + /* If we already found the signatured type, return it. */ + if (sig_type != nullptr) + return sig_type; + } + } + else + { + /* fallback to main symfile objfile. */ + struct objfile *objfile + = (*per_objfile)->objfile->pspace ()->symfile_object_file; + return lookup_fallback_signatured_type (objfile, sig, per_objfile); + } } + + /* We could not find the signatured type. */ + return nullptr; } /* Low level DIE reading support. */ @@ -4332,8 +4430,19 @@ maybe_queue_comp_unit (struct dwarf2_cu *dependent_cu, dwarf2_per_cu *per_cu, bool queued = false; if (!per_objfile->symtab_set_p (per_cu)) { - /* Add it to the queue. */ - queue_comp_unit (per_cu, per_objfile, pretend_language); + if (dependent_cu != nullptr && !per_objfile->queue.has_value () && + type_signature_fallback != type_signature_fallback_off) + { + /* If the signatured type in the fallback objfile references another + signatured type we might end up here with no queue in the fallback + objfile. */ + dw2_instantiate_symtab (per_cu, per_objfile, false); + } + else + { + /* Add it to the queue. */ + queue_comp_unit (per_cu, per_objfile, pretend_language); + } queued = true; dwarf_read_debug_printf ("Queuing CU for expansion: " @@ -8382,7 +8491,7 @@ static int queue_and_load_dwo_tu (dwo_unit *dwo_unit, dwarf2_cu *cu) { ULONGEST signature = dwo_unit->signature; - signatured_type *sig_type = lookup_dwo_signatured_type (cu, signature); + signatured_type *sig_type = lookup_dwo_signatured_type (cu->dwo_unit, signature, cu->per_objfile); if (sig_type != NULL) { @@ -18984,6 +19093,7 @@ dwarf2_get_die_type (cu_offset die_offset, dwarf2_per_cu *per_cu, static struct die_info * follow_die_sig_1 (struct die_info *src_die, struct signatured_type *sig_type, + struct dwarf2_per_objfile *sig_type_per_objfile, struct dwarf2_cu **ref_cu) { struct dwarf2_cu *sig_cu; @@ -18999,12 +19109,14 @@ follow_die_sig_1 (struct die_info *src_die, struct signatured_type *sig_type, Even if maybe_queue_comp_unit doesn't require us to load the CU's DIEs, it doesn't mean they are currently loaded. Since we require them to be loaded, we must check for ourselves. */ - if (maybe_queue_comp_unit (*ref_cu, sig_type, per_objfile, + if (maybe_queue_comp_unit (*ref_cu, sig_type, sig_type_per_objfile, language_minimal) - || per_objfile->get_cu (sig_type) == nullptr) - read_signatured_type (sig_type, per_objfile); + || sig_type_per_objfile->get_cu (sig_type) == nullptr) + { + read_signatured_type (sig_type, sig_type_per_objfile); + } - sig_cu = per_objfile->get_cu (sig_type); + sig_cu = sig_type_per_objfile->get_cu (sig_type); gdb_assert (sig_cu != NULL); gdb_assert (to_underlying (sig_type->type_offset_in_section) != 0); @@ -19040,7 +19152,8 @@ follow_die_sig (struct die_info *src_die, const struct attribute *attr, gdb_assert (attr->form == DW_FORM_ref_sig8); - sig_type = lookup_signatured_type (*ref_cu, signature); + dwarf2_per_objfile *sig_type_per_objfile = (*ref_cu)->per_objfile; + sig_type = lookup_signatured_type (*ref_cu, signature, &sig_type_per_objfile); /* sig_type will be NULL if the signatured type is missing from the debug info. */ if (sig_type == NULL) @@ -19052,7 +19165,7 @@ follow_die_sig (struct die_info *src_die, const struct attribute *attr, objfile_name ((*ref_cu)->per_objfile->objfile)); } - die = follow_die_sig_1 (src_die, sig_type, ref_cu); + die = follow_die_sig_1 (src_die, sig_type, sig_type_per_objfile, ref_cu); if (die == NULL) { src_die->error_dump (); @@ -19079,7 +19192,8 @@ get_signatured_type (struct die_info *die, ULONGEST signature, struct die_info *type_die; struct type *type; - sig_type = lookup_signatured_type (cu, signature); + dwarf2_per_objfile *sig_type_per_objfile = per_objfile; + sig_type = lookup_signatured_type (cu, signature, &sig_type_per_objfile); /* sig_type will be NULL if the signatured type is missing from the debug info. */ if (sig_type == NULL) @@ -19098,7 +19212,7 @@ get_signatured_type (struct die_info *die, ULONGEST signature, return type; type_cu = cu; - type_die = follow_die_sig_1 (die, sig_type, &type_cu); + type_die = follow_die_sig_1 (die, sig_type, sig_type_per_objfile, &type_cu); if (type_die != NULL) { /* N.B. We need to call get_die_type to ensure only one type for this DIE @@ -19125,6 +19239,18 @@ get_signatured_type (struct die_info *die, ULONGEST signature, type = build_error_marker_type (cu, die); } + if (type_signature_fallback != type_signature_fallback_off) + { + /* We might already have read the required signatured type + after looking for it in a fallback objfile */ + struct type *existing_type = per_objfile->get_type_for_signatured_type + (sig_type); + if (existing_type != nullptr) + { + gdb_assert (type == existing_type); + return type; + } + } per_objfile->set_type_for_signatured_type (sig_type, type); return type; diff --git a/gdb/jit.c b/gdb/jit.c index d55e371b02a..ce19591c378 100644 --- a/gdb/jit.c +++ b/gdb/jit.c @@ -664,7 +664,8 @@ jit_object_close_impl (struct gdb_symbol_callbacks *cb, priv_data->entry.symfile_addr)); objfile *objfile = objfile::make (nullptr, current_program_space, - objfile_name.c_str (), OBJF_NOT_FILENAME); + objfile_name.c_str (), + OBJF_NOT_FILENAME | OBJF_JIT); objfile->section_offsets.push_back (0); objfile->sect_index_text = 0; objfile->per_bfd->gdbarch = priv_data->gdbarch; @@ -801,7 +802,8 @@ JITed symbol file is not an object file, ignoring it.\n")); objfile = symbol_file_add_from_bfd (nbfd, bfd_get_filename (nbfd.get ()), 0, &sai, - OBJF_SHARED | OBJF_NOT_FILENAME, NULL); + OBJF_SHARED | OBJF_NOT_FILENAME | + OBJF_JIT, NULL); add_objfile_entry (objfile, entry_addr, code_entry->symfile_addr, code_entry->symfile_size); diff --git a/gdb/objfile-flags.h b/gdb/objfile-flags.h index e0a84bcdc2e..0ad6e4037dd 100644 --- a/gdb/objfile-flags.h +++ b/gdb/objfile-flags.h @@ -56,6 +56,9 @@ enum objfile_flag : unsigned /* User requested that we do not read this objfile's symbolic information. */ OBJF_READNEVER = 1 << 6, + + /* Set if this objfile originates from a JIT compilation */ + OBJF_JIT = 1 << 7, }; DEF_ENUM_FLAGS_TYPE (enum objfile_flag, objfile_flags);