From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from simark.ca by simark.ca with LMTP id 6LgGNf9RVGjG3hQAWB0awg (envelope-from ) for ; Thu, 19 Jun 2025 14:07:59 -0400 Authentication-Results: simark.ca; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=AYUQRCyE; dkim-atps=neutral Received: by simark.ca (Postfix, from userid 112) id D56C11E11C; Thu, 19 Jun 2025 14:07:59 -0400 (EDT) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-25) on simark.ca X-Spam-Level: X-Spam-Status: No, score=-10.1 required=5.0 tests=ARC_SIGNED,ARC_VALID, BAYES_00,DKIMWL_WL_HIGH,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU, MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED,RCVD_IN_VALIDITY_CERTIFIED, RCVD_IN_VALIDITY_RPBL,RCVD_IN_VALIDITY_SAFE autolearn=ham autolearn_force=no version=4.0.1 Received: from server2.sourceware.org (server2.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) by simark.ca (Postfix) with ESMTPS id E3C1A1E089 for ; Thu, 19 Jun 2025 14:07:58 -0400 (EDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 52A64383BD8B for ; Thu, 19 Jun 2025 18:07:55 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 52A64383BD8B Authentication-Results: sourceware.org; dkim=pass (1024-bit key, unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=AYUQRCyE Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by sourceware.org (Postfix) with ESMTP id 49DF7383E13F for ; Thu, 19 Jun 2025 18:06:02 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 49DF7383E13F Authentication-Results: sourceware.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 49DF7383E13F Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1750356362; cv=none; b=n/GJxAtSe/EyxL3q5wQ/psqpcd3FznAmRdHW4E8KqQHTbfxEd5lAshIo7yWSWh38MgiuICC2s7/tne00VXTS58j/Vdn9Vq1Nti6ZDj8s71zyVTUAjS5YYFf7hUfjEffYOcsnqi3YI3r2l7eNH8AHy0DZXyhHDyr9lCLq04kKUAU= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1750356362; c=relaxed/simple; bh=kcxsQulkbdKGcPatHNGURym5iMRz60GF4W7uu4Y0DkA=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=MbcyQfgFHukuLI4EwkFdXCxGpmGwVA3VMHC95AR0pIqwT67EZjUyUfK0WrYXuSmlYe5MrMxQ4CFVWgbn1V+rEwH113mZ30sRRAq2F+xamNZbjWvbxM6dY3LBDDQ0rWYcL9cZiAKtJE4MKA1F3orcwX6loE+yLCqtmKEzL+MRmBs= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 49DF7383E13F DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1750356362; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=QHyRQpny69pXiO9GfmScmymiMgwRbwO8IqW5aWlW3g4=; b=AYUQRCyEErjuQJzI2fEGjGvUzBMtATx3Raetr1W3g2tnVKs8/d+Jyni2mdPoqWwuDiGFkM Bzt+Za7peLJfdn9AOBekIwaeN4lh7Tc8heO8e7kIND480mdwunYZB99bPlUByCSjhclcIv OjPXOIjURaOnaRACnBv0TIGsAM3XT/M= Received: from mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-343-AZZYSX5mOkmeELwRBcstCQ-1; Thu, 19 Jun 2025 14:06:00 -0400 X-MC-Unique: AZZYSX5mOkmeELwRBcstCQ-1 X-Mimecast-MFC-AGG-ID: AZZYSX5mOkmeELwRBcstCQ_1750356359 Received: from mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.111]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id AAA7419560B1 for ; Thu, 19 Jun 2025 18:05:59 +0000 (UTC) Received: from fedora.redhat.com (unknown [10.96.134.45]) by mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 5853018003FC; Thu, 19 Jun 2025 18:05:58 +0000 (UTC) From: Guinevere Larsen To: gdb-patches@sourceware.org Cc: Guinevere Larsen Subject: [PATCH v3 3/3] gdb: extend the [[N]]::foo syntax for files Date: Thu, 19 Jun 2025 15:05:40 -0300 Message-ID: <20250619180540.2315103-4-guinevere@redhat.com> In-Reply-To: <20250619180540.2315103-1-guinevere@redhat.com> References: <20250619180540.2315103-1-guinevere@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.111 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: NWFSu3nuduBk-o--Yy0xv1h_H1rbjk4S1WfrRno50jI_1750356359 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: 8bit content-type: text/plain; charset="US-ASCII"; x-default=true 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~public-inbox=simark.ca@sourceware.org This commit implements the missing support for [[N]]::'file.c'::var syntax that was skipped on the previous commit. This is done by adding a new value to the global parser_state, so that the classify_name function can restrict its search for file names to the specified linker namespace. It had to be done this way because if the logic was contained on the newly added "block: block COLONCOLON FILENAME" rule, we would not have the name to rerun the search. Because of that, the new rule only exists to make sure this is only used in the intended syntax. This commit also adds a link to the solib_ops relevant to the expression being parsed, as a way to identify if linker namespaces are supported; this could be achieved by guarding the search functions instead, but I think that this is more reliable. The new rule uses "block" rather than a linker namespace specific token, because if we allowed that token to also reduce into block, the new rule would never be triggered as the simple reduction would be preferred. If we didn't allow the linker namespace to reduce into block, the rest of the syntaxes for [[N]]::foo would be more involved, so the option in this commit seemed like the simplest solution. The parser_state changes were not used for the previous commit because the lookup_symbol calls would lead to an even more intrusive change for no real gain, since the search would be rerun any way. There is an argument to be made that the results could be different if only namespace had a type and another had a variable, but a situation where that significantly changes the result is quite unlikely, I think. --- gdb/c-exp.y | 10 +++++++- gdb/linespec.c | 4 +-- gdb/parse.c | 3 ++- gdb/parser-defs.h | 30 +++++++++++++++++++++-- gdb/rust-parse.c | 3 ++- gdb/symtab.c | 24 ++++++++++++++---- gdb/symtab.h | 7 +++++- gdb/testsuite/gdb.base/dlmopen-ns-ids.exp | 7 ++++++ 8 files changed, 75 insertions(+), 13 deletions(-) diff --git a/gdb/c-exp.y b/gdb/c-exp.y index 1de2ee6bfc6..4f4e36c9789 100644 --- a/gdb/c-exp.y +++ b/gdb/c-exp.y @@ -1084,6 +1084,7 @@ block : BLOCKNAME { $$.search_namespace = true; $$.namespace_val = $2.val; + pstate->set_linker_namespace ($2.val); } ; @@ -1106,6 +1107,12 @@ block : block COLONCOLON name $$.b_val = tem.symbol->value_block (); $$.search_namespace = false; } + | block COLONCOLON FILENAME + { + if (!$1.search_namespace) + error (_("Filename must be the first part of the expression")); + $$ = $3; + } ; variable: name_not_typename ENTRY @@ -3116,7 +3123,8 @@ classify_name (struct parser_state *par_state, const struct block *block, || is_quoted_name) { /* See if it's a file name. */ - if (auto symtab = lookup_symtab (current_program_space, copy.c_str ()); + if (auto symtab = lookup_symtab (current_program_space, copy.c_str (), + par_state->get_linker_namespace ()); symtab != nullptr) { yylval.bval.b_val diff --git a/gdb/linespec.c b/gdb/linespec.c index b59c0553c34..9fde76d6c80 100644 --- a/gdb/linespec.c +++ b/gdb/linespec.c @@ -3658,11 +3658,11 @@ collect_symtabs_from_filename (const char *file, if (pspace->executing_startup) continue; - iterate_over_symtabs (pspace, file, collector); + iterate_over_symtabs (pspace, file, -1, collector); } } else - iterate_over_symtabs (search_pspace, file, collector); + iterate_over_symtabs (search_pspace, file, -1, collector); return collector.release_symtabs (); } diff --git a/gdb/parse.c b/gdb/parse.c index 64653c8ae6e..6edd9058dcb 100644 --- a/gdb/parse.c +++ b/gdb/parse.c @@ -421,7 +421,8 @@ parse_exp_in_context (const char **stringptr, CORE_ADDR pc, parser_state ps (lang, get_current_arch (), expression_context_block, expression_context_pc, flags, *stringptr, - completer != nullptr, tracker); + completer != nullptr, tracker, + current_program_space->solib_ops ()); scoped_restore_current_language lang_saver (lang->la_language); diff --git a/gdb/parser-defs.h b/gdb/parser-defs.h index ff4ab6a09de..9de3b6f7d9c 100644 --- a/gdb/parser-defs.h +++ b/gdb/parser-defs.h @@ -26,6 +26,7 @@ #include "expression.h" #include "symtab.h" #include "expop.h" +#include "solib.h" struct block; struct language_defn; @@ -147,7 +148,8 @@ struct parser_state : public expr_builder parser_flags flags, const char *input, bool completion, - innermost_block_tracker *tracker) + innermost_block_tracker *tracker, + solib_ops *ops) : expr_builder (lang, gdbarch), expression_context_block (context_block), expression_context_pc (context_pc), @@ -157,7 +159,8 @@ struct parser_state : public expr_builder comma_terminates ((flags & PARSER_COMMA_TERMINATES) != 0), parse_completion (completion), void_context_p ((flags & PARSER_VOID_CONTEXT) != 0), - debug ((flags & PARSER_DEBUG) != 0) + debug ((flags & PARSER_DEBUG) != 0), + m_solib_ops (ops) { } @@ -263,6 +266,19 @@ struct parser_state : public expr_builder push (expr::make_operation (std::move (lhs), std::move (rhs))); } + void set_linker_namespace (LONGEST ns_id) + { + if (m_solib_ops->supports_namespaces ()) + linker_namespace = ns_id; + else + error (_("Linker namespaces are not supported")); + } + + LONGEST get_linker_namespace () + { + return linker_namespace; + } + /* Function called from the various parsers' yyerror functions to throw an error. The error will include a message identifying the location of the error within the current expression. */ @@ -323,6 +339,16 @@ struct parser_state : public expr_builder /* Stack of operations. */ std::vector m_operations; + + /* If the expression is being restricted to a specific namespace, this is + where that information is stored for the block lookup. It should be + accessed through setter/getters to ensure that the linker namespace is + only set when the gdbarch supports it. */ + LONGEST linker_namespace = -1; + + /* Used to figure out if an inferior is capable of handling linker + namespaces at all. */ + solib_ops *m_solib_ops; }; /* A string token, either a char-string or bit-string. Char-strings are diff --git a/gdb/rust-parse.c b/gdb/rust-parse.c index ef640056051..752b89f4af4 100644 --- a/gdb/rust-parse.c +++ b/gdb/rust-parse.c @@ -2315,7 +2315,8 @@ rust_lex_tests (void) { /* Set up dummy "parser", so that rust_type works. */ parser_state ps (language_def (language_rust), current_inferior ()->arch (), - nullptr, 0, 0, nullptr, 0, nullptr); + nullptr, 0, 0, nullptr, 0, nullptr, + current_program_space->solib_ops ()); rust_parser parser (&ps); rust_lex_test_one (&parser, "", 0); diff --git a/gdb/symtab.c b/gdb/symtab.c index b4db8275580..638142fe633 100644 --- a/gdb/symtab.c +++ b/gdb/symtab.c @@ -703,6 +703,7 @@ iterate_over_some_symtabs (const char *name, void iterate_over_symtabs (program_space *pspace, const char *name, + LONGEST linker_ns, gdb::function_view callback) { gdb::unique_xmalloc_ptr real_path; @@ -715,7 +716,20 @@ iterate_over_symtabs (program_space *pspace, const char *name, gdb_assert (IS_ABSOLUTE_PATH (real_path.get ())); } - for (objfile *objfile : pspace->objfiles ()) + std::vector objfiles_to_search; + if (linker_ns >= 0) + { + gdb_assert (pspace->solib_ops ()->supports_namespaces ()); + objfiles_to_search + = get_objfiles_in_linker_namespace (linker_ns, pspace); + } + else + { + for (objfile *objf : pspace->objfiles ()) + objfiles_to_search.push_back (objf); + } + + for (objfile *objfile : objfiles_to_search) if (iterate_over_some_symtabs (name, real_path.get (), objfile->compunit_symtabs, nullptr, callback)) @@ -723,7 +737,7 @@ iterate_over_symtabs (program_space *pspace, const char *name, /* Same search rules as above apply here, but now we look through the psymtabs. */ - for (objfile *objfile : pspace->objfiles ()) + for (objfile *objfile : objfiles_to_search) if (objfile->map_symtabs_matching_filename (name, real_path.get (), callback)) return; @@ -732,11 +746,11 @@ iterate_over_symtabs (program_space *pspace, const char *name, /* See symtab.h. */ symtab * -lookup_symtab (program_space *pspace, const char *name) +lookup_symtab (program_space *pspace, const char *name, LONGEST linker_ns) { struct symtab *result = NULL; - iterate_over_symtabs (pspace, name, [&] (symtab *symtab) + iterate_over_symtabs (pspace, name, linker_ns, [&] (symtab *symtab) { result = symtab; return true; @@ -6359,7 +6373,7 @@ collect_file_symbol_completion_matches (completion_tracker &tracker, /* Go through symtabs for SRCFILE and check the externs and statics for symbols which match. */ - iterate_over_symtabs (current_program_space, srcfile, [&] (symtab *s) + iterate_over_symtabs (current_program_space, srcfile, -1, [&] (symtab *s) { add_symtab_completions (s->compunit (), tracker, mode, lookup_name, diff --git a/gdb/symtab.h b/gdb/symtab.h index 27acc70bf1d..8ab73e9b73c 100644 --- a/gdb/symtab.h +++ b/gdb/symtab.h @@ -2090,7 +2090,8 @@ const char *multiple_symbols_select_mode (void); /* Lookup a symbol table in PSPACE by source file name. */ -extern symtab *lookup_symtab (program_space *pspace, const char *name); +extern symtab *lookup_symtab (program_space *pspace, const char *name, + LONGEST linker_ns = -1); /* An object of this type is passed as the 'is_a_field_of_this' argument to lookup_symbol and lookup_symbol_in_language. */ @@ -2824,10 +2825,14 @@ bool iterate_over_some_symtabs (const char *name, psymtabs. *If* there is no '/' in the name, a match after a '/' in the symtab filename will also work. + If LINKER_NS is 0 or greater, only the objfiles in the provided linker + namespace will be iterated over. + Call CALLBACK with each symtab that is found. If CALLBACK returns true, the search stops. */ void iterate_over_symtabs (program_space *pspace, const char *name, + LONGEST linker_ns, gdb::function_view callback); std::vector find_pcs_for_symtab_line diff --git a/gdb/testsuite/gdb.base/dlmopen-ns-ids.exp b/gdb/testsuite/gdb.base/dlmopen-ns-ids.exp index 303595faee5..ac6d1c44aa6 100644 --- a/gdb/testsuite/gdb.base/dlmopen-ns-ids.exp +++ b/gdb/testsuite/gdb.base/dlmopen-ns-ids.exp @@ -265,6 +265,7 @@ proc_with_prefix test_print_namespace_symbol {} { gdb_breakpoint "change_global" allow-pending gdb_continue_to_breakpoint "change_global" + set ns0 [ns_id_for_command 0] set ns1 [ns_id_for_command 1] set ns2 [ns_id_for_command 2] @@ -292,6 +293,12 @@ proc_with_prefix test_print_namespace_symbol {} { # returning a random one, we just say we didn't find one. gdb_test "print gdb_dlmopen_glob" \ "No symbol .gdb_dlmopen_glob. in the current linker namespace." + + # Minimal testing for finding files in namespaces. + gdb_test "print ${ns1}::'${::srcfile_lib}'::gdb_dlmopen_glob" \ + ".* = 2" + gdb_test "print ${ns0}::'${::srcfile_lib}'::gdb_dlmopen_glob" \ + "No function .${::srcfile_lib}. in specified context." } test_info_shared -- 2.49.0