Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
* [PATCH v3 0/3] Introduce syntax for linker-namespace specific symbols
@ 2025-06-19 18:05 Guinevere Larsen
  2025-06-19 18:05 ` [PATCH v3 1/3] gdb: make lookup_minimal_symbol_linkage work with linker namespaces Guinevere Larsen
                   ` (3 more replies)
  0 siblings, 4 replies; 12+ messages in thread
From: Guinevere Larsen @ 2025-06-19 18:05 UTC (permalink / raw)
  To: gdb-patches; +Cc: Guinevere Larsen

This series adds support for the syntax [[N]]::foo to find symbols that
belong to specific namespaces, while also making GDB's behavior more
consistent when a namespace is not specified. This needs one preparatory
patch and 2 patches actually implementing this feature

Patch 1 is an essential fix, updating how we calculate a variable's copy
relocation to take linker namespaces into account.

Patches 2 and 3 implement the new syntax, adding the necessary
supporting code and updating error messages when symbols can't be found
- where it made sense.

Do note that this series is built on top Simon's recent C++ification of
the solib_ops class, since it has better solutions to some problems than
my old versions.  It should be reviewed with that series in mind.

Changes for v3:
* Removed previous patches 1 and 2, as Simon's recently merged patches
  already did those in a better way.
* parser_state now also takes the current solib_ops, since that can't be
  obtained from gdbarch anymore.

Changes for v2:
* solib_supports_linker_namespaces now always expects a pointer.
* Previous patches 2 and 3 were dropped.
* lookup_minimal_symbol_linkage now takes an array_view.
* created new tokens for [[ and ]], to ensure that [[N]] looks like
  that.
* Fixed formatting nits from Eli.

Guinevere Larsen (3):
  gdb: make lookup_minimal_symbol_linkage work with linker namespaces
  gdb: Make the parser recognize the [[N]] syntax for variables
  gdb: extend the [[N]]::foo syntax for files

 gdb/NEWS                                     |   6 +
 gdb/c-exp.y                                  |  82 ++++++++---
 gdb/doc/gdb.texinfo                          |   6 +
 gdb/dwarf2/ada-imported.c                    |   8 +-
 gdb/linespec.c                               |   4 +-
 gdb/minsyms.c                                | 135 ++++++++++++-------
 gdb/minsyms.h                                |  17 ++-
 gdb/parse.c                                  |   3 +-
 gdb/parser-defs.h                            |  37 ++++-
 gdb/rust-parse.c                             |   3 +-
 gdb/solib-svr4.c                             |  20 ---
 gdb/solib.c                                  |  82 ++++++++++-
 gdb/solib.h                                  |  19 +++
 gdb/symtab.c                                 |  74 +++++++++-
 gdb/symtab.h                                 |  15 ++-
 gdb/testsuite/gdb.base/dlmopen-ns-ids-lib.c  |  14 ++
 gdb/testsuite/gdb.base/dlmopen-ns-ids-main.c |   3 +
 gdb/testsuite/gdb.base/dlmopen-ns-ids.exp    |  54 ++++++++
 18 files changed, 473 insertions(+), 109 deletions(-)

-- 
2.49.0


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH v3 1/3] gdb: make lookup_minimal_symbol_linkage work with linker namespaces
  2025-06-19 18:05 [PATCH v3 0/3] Introduce syntax for linker-namespace specific symbols Guinevere Larsen
@ 2025-06-19 18:05 ` Guinevere Larsen
  2025-06-19 18:05 ` [PATCH v3 2/3] gdb: Make the parser recognize the [[N]] syntax for variables Guinevere Larsen
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 12+ messages in thread
From: Guinevere Larsen @ 2025-06-19 18:05 UTC (permalink / raw)
  To: gdb-patches; +Cc: Guinevere Larsen

When a symbol found by GDB may have copy relocation, GDB calculates the
address of the symbol by checking all the objfiles in the current
program space for another instance of the same symbol, and returns the
address of the first instance found.

This works well when linker namespaces are not involved, but fails when
a symbol is present in more than one namespace. That's because copy
relocations respect linker namespace boundaries, and so if we're trying
to find the symbol in namespace N, the symbol from a different namespace
M may be returned, if the SO containing the symbol was loaded in M
before N.

To make the search work correctly, lookup_minimal_symbol_linkage would
need to also respect linker namespace boundaries. However, to avoid
leaking solib knowledge to minsyms, and because of how little
information is passed to the function, this commit instead makes the
function take a vector of objfiles to search, in place of the program
space. This makes it so symbol::get_maybe_copied_address (and the
equivalent of minimal_symbol) need to request the objfiles for the
correct namespace, since they have enough context to figure out the
namespace. Creating the vector is left as a function in solib.c

Since minimal_symbol::get_maybe_copied_address only searches main_file
objfiles, if we can guarantee that only one is loaded for each program
space, we could avoid the work of constructing an std::vector that will
be mostly ignored. However, I couldn't convince myself that that is the
case, so I decided to keep the behavior exactly as is.

Ideally, lookup_minimal_symbol_linkage would receive an iterator instead
of a vector, but as of now it isn't possible to do forward declarations
of nested types (we'd need program_space::objfiles_range) and
progspace.h can't be included into minsyms.h, so we're stuck
constructing a vector for it.

Finally, as some minor refactoring, find_solib_for_objfile is moved to
solib.c to simplify looking for which namespace contains the objfile
where we found the symbol the user was looking for.
---
 gdb/dwarf2/ada-imported.c |  8 +++-
 gdb/minsyms.c             | 11 ++++--
 gdb/minsyms.h             |  9 +++--
 gdb/solib-svr4.c          | 20 ----------
 gdb/solib.c               | 82 ++++++++++++++++++++++++++++++++++++++-
 gdb/solib.h               | 19 +++++++++
 gdb/symtab.c              | 13 ++++++-
 7 files changed, 130 insertions(+), 32 deletions(-)

diff --git a/gdb/dwarf2/ada-imported.c b/gdb/dwarf2/ada-imported.c
index 1e259663279..b883d735971 100644
--- a/gdb/dwarf2/ada-imported.c
+++ b/gdb/dwarf2/ada-imported.c
@@ -35,9 +35,13 @@ static struct value *
 ada_imported_read_variable (struct symbol *symbol, const frame_info_ptr &frame)
 {
   const char *name = get_imported_name (symbol);
+
+  std::vector<objfile *> objfiles_to_search;
+  for (auto objf : symbol->objfile ()->pspace ()->objfiles ())
+    objfiles_to_search.push_back (objf);
+
   bound_minimal_symbol minsym
-    = lookup_minimal_symbol_linkage (symbol->objfile ()->pspace (), name,
-				     true, false);
+    = lookup_minimal_symbol_linkage (objfiles_to_search, name, true, false);
   if (minsym.minsym == nullptr)
     error (_("could not find imported name %s"), name);
   return value_at (symbol->type (), minsym.value_address ());
diff --git a/gdb/minsyms.c b/gdb/minsyms.c
index 4a6459a6f2d..3ac2bdf697a 100644
--- a/gdb/minsyms.c
+++ b/gdb/minsyms.c
@@ -55,6 +55,7 @@
 #include "gdbsupport/gdb-safe-ctype.h"
 #include "gdbsupport/parallel-for.h"
 #include "inferior.h"
+#include "solib.h"
 
 #if CXX_STD_THREAD
 #include <mutex>
@@ -589,12 +590,14 @@ lookup_minimal_symbol_linkage (const char *name, struct objfile *objf,
 /* See minsyms.h.  */
 
 bound_minimal_symbol
-lookup_minimal_symbol_linkage (program_space *pspace, const char *name,
-			       bool match_static_type, bool only_main)
+lookup_minimal_symbol_linkage (gdb::array_view<objfile *> objfiles_to_search,
+			       const char *name, bool match_static_type,
+			       bool only_main)
 {
-  for (objfile *objfile : pspace->objfiles ())
+  for (objfile *objfile : objfiles_to_search)
     {
-      if (objfile->separate_debug_objfile_backlink != nullptr)
+      if (objfile == nullptr
+	  || objfile->separate_debug_objfile_backlink != nullptr)
 	continue;
 
       if (only_main && (objfile->flags & OBJF_MAINLINE) == 0)
diff --git a/gdb/minsyms.h b/gdb/minsyms.h
index 709faa5e8f4..4bb2aca0b4c 100644
--- a/gdb/minsyms.h
+++ b/gdb/minsyms.h
@@ -237,11 +237,14 @@ extern bound_minimal_symbol lookup_minimal_symbol_linkage
 
 /* A variant of lookup_minimal_symbol_linkage that iterates over all
    objfiles of PSPACE.  If ONLY_MAIN is true, then only an objfile with
-   OBJF_MAINLINE will be considered.  */
+   OBJF_MAINLINE will be considered.  This function should receive a
+   program_space::objfile_ranges instead, but we can't include progspace.h
+   here, nor can we do forward declarations of nested types, so std::vector
+   will waste a bit of memory to work around that issue.  */
 
 extern bound_minimal_symbol lookup_minimal_symbol_linkage
-  (program_space *pspace, const char *name, bool match_static_type,
-   bool only_main) ATTRIBUTE_NONNULL (1);
+  (gdb::array_view<objfile *> objfiles_to_search, const char *name,
+   bool match_static_type, bool only_main);
 
 /* Look through all the current minimal symbol tables and find the
    first minimal symbol that matches NAME and PC.  If OBJF is non-NULL,
diff --git a/gdb/solib-svr4.c b/gdb/solib-svr4.c
index e9430281bca..86cefc174d2 100644
--- a/gdb/solib-svr4.c
+++ b/gdb/solib-svr4.c
@@ -3549,26 +3549,6 @@ lp64_svr4_solib_ops::fetch_link_map_offsets () const
 }
 \f
 
-/* Return the DSO matching OBJFILE or nullptr if none can be found.  */
-
-static const solib *
-find_solib_for_objfile (struct objfile *objfile)
-{
-  if (objfile == nullptr)
-    return nullptr;
-
-  /* If OBJFILE is a separate debug object file, look for the original
-     object file.  */
-  if (objfile->separate_debug_objfile_backlink != nullptr)
-    objfile = objfile->separate_debug_objfile_backlink;
-
-  for (const solib &so : current_program_space->solibs ())
-    if (so.objfile == objfile)
-      return &so;
-
-  return nullptr;
-}
-
 /* Return the address of the r_debug object for the namespace containing
    SOLIB or zero if it cannot be found.  This may happen when symbol files
    are added manually, for example, or with the main executable.
diff --git a/gdb/solib.c b/gdb/solib.c
index bea0534cb50..9eb961e8b52 100644
--- a/gdb/solib.c
+++ b/gdb/solib.c
@@ -1808,8 +1808,88 @@ remove_user_added_objfile (struct objfile *objfile)
     }
 }
 
-/* Implementation of the linker_namespace convenience variable.
+/* See solib.h.  */
+
+const solib *
+find_solib_for_objfile (struct objfile *objfile)
+{
+  if (objfile == nullptr)
+    return nullptr;
+
+  /* If OBJFILE is a separate debug object file, look for the original
+     object file.  */
+  if (objfile->separate_debug_objfile_backlink != nullptr)
+    objfile = objfile->separate_debug_objfile_backlink;
+
+  for (const solib &so : objfile->pspace ()->solibs ())
+    if (so.objfile == objfile)
+      return &so;
+
+  return nullptr;
+}
+
+/* See solib.h.  */
+
+std::vector<objfile *>
+get_objfiles_in_linker_namespace (int nsid, program_space *pspace)
+{
+  std::vector<objfile *> objfiles_in_ns;
+  const solib_ops *ops = pspace->solib_ops ();
+
+  gdb_assert (ops->supports_namespaces ());
+
+  /* If we're looking at the default namespace, we also need
+     to add the mainline objfiles by hand, since there is no
+     solib associated with those files.  We add them first
+     because if we're searching for copy relocations, they
+     should be in the main file, so we'll find it faster.  */
+  if (nsid == 0)
+    for (objfile *objf : pspace->objfiles ())
+      if ((objf->flags & OBJF_MAINLINE) != 0)
+	objfiles_in_ns.push_back (objf);
+
+  std::vector<const solib *> solibs = ops->get_solibs_in_ns (nsid);
+  /* Reserve for efficiency.  */
+  objfiles_in_ns.reserve (solibs.size () + objfiles_in_ns.size ());
+  for (const solib *so : solibs)
+    objfiles_in_ns.push_back (so->objfile);
+
+  return objfiles_in_ns;
+}
+
+/* See solib.h.  */
+
+std::vector<objfile *>
+get_objfiles_in_linker_namespace (objfile *objfile)
+{
+  program_space *pspace = objfile->pspace ();
+  const solib_ops *ops = pspace->solib_ops ();
+  const solib *so = find_solib_for_objfile (objfile);
+
+  if (ops->supports_namespaces ()
+      /* If we're searching for a symbol from the linker, we'll reach here
+	 before having any namespaces.  Return all objfiles since the
+	 boundaries haven't been setup yet.  */
+      && ops->num_active_namespaces () > 0
+      /* When trying to load libthread_db, we can search for a symbol in an
+	 objfile with no associated solib.  In that case, again, we should
+	 return all objfiles.  */
+      && so != nullptr)
+    {
+      return get_objfiles_in_linker_namespace (ops->find_solib_ns (*so),
+					       pspace);
+    }
+
+  /* If any of the previous conditions isn't satisfied, we return
+     the full list of objfiles in the inferior.  */
+  std::vector<struct objfile *> found_objfiles;
+  for (struct objfile *objf : objfile->pspace ()->objfiles ())
+    found_objfiles.push_back (objf);
 
+  return found_objfiles;
+}
+
+/* Implementation of the linker_namespace convenience variable.
    This returns the GDB internal identifier of the linker namespace,
    for the selected frame, as an integer.  If the inferior doesn't support
    linker namespaces, this always returns 0.  */
diff --git a/gdb/solib.h b/gdb/solib.h
index a3104e47e40..0c5b26c7ad0 100644
--- a/gdb/solib.h
+++ b/gdb/solib.h
@@ -20,6 +20,9 @@
 #ifndef GDB_SOLIB_H
 #define GDB_SOLIB_H
 
+/* Forward decl's for prototypes */
+struct objfile;
+
 #include "gdb_bfd.h"
 #include "gdbsupport/function-view.h"
 #include "gdbsupport/intrusive_list.h"
@@ -373,4 +376,20 @@ extern void update_solib_breakpoints (void);
 
 extern void handle_solib_event (void);
 
+/* Return a vector with pointers of all objfiles in the namespace
+   NSID.  This version assumes that the inferior supports namespaces.  */
+
+std::vector<objfile *> get_objfiles_in_linker_namespace
+  (int nsid, program_space *pspace);
+
+/* Return a vector with pointers of all objfiles in the same namespace
+   as OBJFILE.  If the inferior doesn't support namespaces, return all
+   objfiles in the program_space.  */
+
+std::vector<objfile *> get_objfiles_in_linker_namespace (objfile *objfile);
+
+/* Return the DSO matching OBJFILE or nullptr if none can be found.  */
+
+const solib *find_solib_for_objfile (struct objfile *objfile);
+
 #endif /* GDB_SOLIB_H */
diff --git a/gdb/symtab.c b/gdb/symtab.c
index b2de990143d..7b125bfd006 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -75,6 +75,7 @@
 #include "gdbsupport/common-utils.h"
 #include <optional>
 #include "gdbsupport/unordered_set.h"
+#include "solib.h"
 
 /* Forward declarations for local functions.  */
 
@@ -6779,8 +6780,12 @@ symbol::get_maybe_copied_address () const
   gdb_assert (this->aclass () == LOC_STATIC);
 
   const char *linkage_name = this->linkage_name ();
+
+  std::vector<struct objfile *> objfiles_to_search
+    (get_objfiles_in_linker_namespace (this->objfile ()));
+
   bound_minimal_symbol minsym
-    = lookup_minimal_symbol_linkage (this->objfile ()->pspace (), linkage_name,
+    = lookup_minimal_symbol_linkage (objfiles_to_search, linkage_name,
 				     false, false);
   if (minsym.minsym != nullptr)
     return minsym.value_address ();
@@ -6797,8 +6802,12 @@ minimal_symbol::get_maybe_copied_address (objfile *objf) const
   gdb_assert ((objf->flags & OBJF_MAINLINE) == 0);
 
   const char *linkage_name = this->linkage_name ();
+
+  std::vector<struct objfile *> objfiles_to_search
+    (get_objfiles_in_linker_namespace (objf));
+
   bound_minimal_symbol found
-    = lookup_minimal_symbol_linkage (objf->pspace (), linkage_name,
+    = lookup_minimal_symbol_linkage (objfiles_to_search, linkage_name,
 				     false, true);
   if (found.minsym != nullptr)
     return found.value_address ();
-- 
2.49.0


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH v3 2/3] gdb: Make the parser recognize the [[N]] syntax for variables
  2025-06-19 18:05 [PATCH v3 0/3] Introduce syntax for linker-namespace specific symbols Guinevere Larsen
  2025-06-19 18:05 ` [PATCH v3 1/3] gdb: make lookup_minimal_symbol_linkage work with linker namespaces Guinevere Larsen
@ 2025-06-19 18:05 ` Guinevere Larsen
  2025-06-20  6:57   ` Eli Zaretskii
  2025-06-19 18:05 ` [PATCH v3 3/3] gdb: extend the [[N]]::foo syntax for files Guinevere Larsen
  2025-07-07 19:01 ` [PING][PATCH v3 0/3] Introduce syntax for linker-namespace specific symbols Guinevere Larsen
  3 siblings, 1 reply; 12+ messages in thread
From: Guinevere Larsen @ 2025-06-19 18:05 UTC (permalink / raw)
  To: gdb-patches; +Cc: Guinevere Larsen

This commit adds a couple new rules to the YACC parser, that will allow
GDB to recognize expressions like [[N]]::var.

This new syntax re-uses the existing rules for searching for "block"s,
because it allows, with minimal changes to the .y file as a whole, while
also allowing [[N]]::function::symbol work. Notably, [[N]]::'file.c'::var
does not work yet, as this code change is also involved and would pollute
the current commit, so will be done in a separate one in the same series.

To restrict the search to a desired namespace, a new function is
introduced,  lookup_symbol_in_linker_namespace.  This function will only
perform the symbol lookup in the objfiles that belong to the requested
namespace.

This commit also changes the error message when "print var" if "var" is
only present in namespaces other than the current one. Before this commit,
lookup_minimal_symbol would find them as "external" symbols with
incomplete information - outputting "<symbol> has incomplete
information, cast it to it's defined type." - which could be confusing for
the users. This commit changes the parser rule "variable: name_not_typename"
so that, if multiple namespaces are active, we'll look for minimal symbols
only in the current namespace.

Known limitations:
* When using [[N]]::foo::var, if that specific foo version is not on the
  stack, the error will be unable to include the linker namespace
  requested.  So if a user sees "foo" in the stack this could be
  confusing, but it should be mitigated when a future patch adds the
  namespace ID to the backtrace where applicable.
* Completion is not supported.  That's because the function used to
  complete symbols expects only text in the form "file.c:symbol", so
  can't handle the double colon.  This isn't unique to linker
  namespaces, though, since func::var will also not complete, it is just
  a quirk of how :: completion work at this point.
* The expression that parses [[N]] only takes an integer.  That's
  because there aren't many expressions that would make sense in there,
  and the work of accepting an arbitrary expression felt too much for
  little gain.
---
 gdb/NEWS                                     |   6 +
 gdb/c-exp.y                                  |  72 ++++++++---
 gdb/doc/gdb.texinfo                          |   6 +
 gdb/minsyms.c                                | 124 ++++++++++++-------
 gdb/minsyms.h                                |   8 ++
 gdb/parser-defs.h                            |   7 ++
 gdb/symtab.c                                 |  37 ++++++
 gdb/symtab.h                                 |   8 ++
 gdb/testsuite/gdb.base/dlmopen-ns-ids-lib.c  |  14 +++
 gdb/testsuite/gdb.base/dlmopen-ns-ids-main.c |   3 +
 gdb/testsuite/gdb.base/dlmopen-ns-ids.exp    |  47 +++++++
 11 files changed, 268 insertions(+), 64 deletions(-)

diff --git a/gdb/NEWS b/gdb/NEWS
index d180c49c834..adedb21e6e0 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -102,6 +102,12 @@ info threads [-gid] [-stopped] [-running] [ID]...
   These new flags can be useful to get a reduced list when there is a
   large number of threads.
 
+print
+  The print command now accepts the following syntax to print values
+  from a specific linker namespace: `[[N]]::foo'.  N is the namespace
+  identifier as understood by GDB.
+
+
 * GDB-internal Thread Local Storage (TLS) support
 
   ** Linux targets for the x86_64, aarch64, ppc64, s390x, and riscv
diff --git a/gdb/c-exp.y b/gdb/c-exp.y
index 14d4b704ff1..1de2ee6bfc6 100644
--- a/gdb/c-exp.y
+++ b/gdb/c-exp.y
@@ -144,7 +144,7 @@ using namespace expr;
     struct ttype tsym;
     struct symtoken ssym;
     int voidval;
-    const struct block *bval;
+    struct bval_type bval;
     enum exp_opcode opcode;
 
     struct stoken_vector svec;
@@ -230,6 +230,7 @@ static void c_print_token (FILE *file, int type, YYSTYPE value);
 %token TYPEOF
 %token DECLTYPE
 %token TYPEID
+%token DOUBLESQUAREOPEN DOUBLESQUARECLOSE
 
 /* Special type cases, put in to allow the parser to distinguish different
    legal basetypes.  */
@@ -1069,30 +1070,42 @@ exp     :       FALSEKEYWORD
 
 block	:	BLOCKNAME
 			{
-			  if ($1.sym.symbol)
-			    $$ = $1.sym.symbol->value_block ();
-			  else
+			  if (!$1.sym.symbol)
 			    error (_("No file or function \"%s\"."),
 				   copy_name ($1.stoken).c_str ());
+			  $$.search_namespace = false;
+			  $$.b_val = $1.sym.symbol->value_block ();
 			}
 	|	FILENAME
 			{
 			  $$ = $1;
 			}
+	|	DOUBLESQUAREOPEN INT DOUBLESQUARECLOSE
+			{
+			    $$.search_namespace = true;
+			    $$.namespace_val = $2.val;
+			}
 	;
 
 block	:	block COLONCOLON name
 			{
 			  std::string copy = copy_name ($3);
-			  struct symbol *tem
-			    = lookup_symbol (copy.c_str (), $1,
-					     SEARCH_FUNCTION_DOMAIN,
-					     nullptr).symbol;
+			  struct block_symbol tem;
 
-			  if (tem == nullptr)
+			  if ($1.search_namespace)
+			    tem = lookup_symbol_in_linker_namespace
+				(copy.c_str (), $1.namespace_val, SEARCH_VFT);
+			  else
+			    tem = lookup_symbol (copy.c_str (), $1.b_val,
+						 SEARCH_FUNCTION_DOMAIN,
+						 nullptr);
+
+			  if (tem.symbol == nullptr)
 			    error (_("No function \"%s\" in specified context."),
 				   copy.c_str ());
-			  $$ = tem->value_block (); }
+			  $$.b_val = tem.symbol->value_block ();
+			  $$.search_namespace = false;
+			}
 	;
 
 variable:	name_not_typename ENTRY
@@ -1111,9 +1124,15 @@ variable:	name_not_typename ENTRY
 variable:	block COLONCOLON name
 			{
 			  std::string copy = copy_name ($3);
-			  struct block_symbol sym
-			    = lookup_symbol (copy.c_str (), $1,
-					     SEARCH_VFT, NULL);
+			  struct block_symbol sym;
+
+			  if ($1.search_namespace)
+			    sym = lookup_symbol_in_linker_namespace
+				    (copy.c_str (), $1.namespace_val,
+				     SEARCH_VFT);
+			  else
+			    sym = lookup_symbol (copy.c_str (), $1.b_val,
+						 SEARCH_VFT, NULL);
 
 			  if (sym.symbol == 0)
 			    error (_("No symbol \"%s\" in specified context."),
@@ -1209,13 +1228,25 @@ variable:	name_not_typename
 			    {
 			      std::string arg = copy_name ($1.stoken);
 
-			      bound_minimal_symbol msymbol
-				= lookup_minimal_symbol (current_program_space, arg.c_str ());
+			      LONGEST active_linker_nss;
+			      get_internalvar_integer (lookup_internalvar ("_active_linker_namespaces"),
+						       &active_linker_nss);
+			      bound_minimal_symbol msymbol;
+
+			      if (active_linker_nss > 1)
+				msymbol = lookup_minimal_symbol_in_linker_namespace
+				  (current_program_space, arg.c_str ());
+			      else
+				msymbol = lookup_minimal_symbol
+				  (current_program_space, arg.c_str ());
 			      if (msymbol.minsym == NULL)
 				{
 				  if (!have_full_symbols (current_program_space)
 				      && !have_partial_symbols (current_program_space))
 				    error (_("No symbol table is loaded.  Use the \"file\" command."));
+				  else if (active_linker_nss > 1)
+				    error (_("No symbol \"%s\" in the current linker namespace."),
+					   arg.c_str ());
 				  else
 				    error (_("No symbol \"%s\" in current context."),
 					   arg.c_str ());
@@ -2483,7 +2514,9 @@ static const struct c_token tokentab2[] =
     {"!=", NOTEQUAL, OP_NULL, 0},
     {"<=", LEQ, OP_NULL, 0},
     {">=", GEQ, OP_NULL, 0},
-    {".*", DOT_STAR, OP_NULL, FLAG_CXX}
+    {".*", DOT_STAR, OP_NULL, FLAG_CXX},
+    {"[[", DOUBLESQUAREOPEN, OP_NULL, 0},
+    {"]]", DOUBLESQUARECLOSE, OP_NULL, 0},
   };
 
 /* Identifier-like tokens.  Only type-specifiers than can appear in
@@ -3086,8 +3119,9 @@ classify_name (struct parser_state *par_state, const struct block *block,
 	  if (auto symtab = lookup_symtab (current_program_space, copy.c_str ());
 	      symtab != nullptr)
 	    {
-	      yylval.bval
+	      yylval.bval.b_val
 		= symtab->compunit ()->blockvector ()->static_block ();
+	      yylval.bval.search_namespace = false;
 
 	      return FILENAME;
 	    }
@@ -3291,7 +3325,7 @@ yylex (void)
   name_obstack.clear ();
   checkpoint = 0;
   if (current.token == FILENAME)
-    search_block = current.value.bval;
+    search_block = current.value.bval.b_val;
   else if (current.token == COLONCOLON)
     search_block = NULL;
   else
@@ -3469,7 +3503,7 @@ c_print_token (FILE *file, int type, YYSTYPE value)
       break;
 
     case FILENAME:
-      parser_fprintf (file, "bval<%s>", host_address_to_string (value.bval));
+      parser_fprintf (file, "bval<%s>", host_address_to_string (value.bval.b_val));
       break;
     }
 }
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 6139bc33d2e..d82bb84a845 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -10565,6 +10565,12 @@ you can choose a different format by specifying @samp{/@var{f}}, where
 @var{f} is a letter specifying the format; see @ref{Output Formats,,Output
 Formats}.
 
+Additionally, if the inferior supports linker namespaces, @value{GDBN}
+has implemented the following syntax to allow users to resolve symbols
+to a specific namespace: @code{[[@var{n}]]::@var{symbol}}.  Here @var{n}
+is @value{GDBN}'s namespace identifier, which may be different to the
+inferior's identifier.
+
 @anchor{print options}
 The @code{print} command supports a number of options that allow
 overriding relevant global print settings as set by @code{set print}
diff --git a/gdb/minsyms.c b/gdb/minsyms.c
index 3ac2bdf697a..a9636258b35 100644
--- a/gdb/minsyms.c
+++ b/gdb/minsyms.c
@@ -340,7 +340,10 @@ lookup_minimal_symbol_demangled (const lookup_name_info &lookup_name,
     }
 }
 
-/* Look through all the current minimal symbol tables and find the
+/* Main implementation for the lookup_minimal_symbol function.
+   Receives a list of objfiles in which to look for the symbol.
+
+   Look through all the current minimal symbol tables and find the
    first minimal symbol that matches NAME.  If OBJF is non-NULL, limit
    the search to that objfile.  If SFILE is non-NULL, the only file-scope
    symbols considered will be from that source file (global symbols are
@@ -360,9 +363,9 @@ lookup_minimal_symbol_demangled (const lookup_name_info &lookup_name,
    Obviously, there must be distinct mangled names for each of these,
    but the demangled names are all the same: S::S or S::~S.  */
 
-bound_minimal_symbol
-lookup_minimal_symbol (program_space *pspace, const char *name, objfile *objf,
-		       const char *sfile)
+static bound_minimal_symbol
+lookup_minimal_symbol_in_objfiles (std::vector<objfile *> objfile_list,
+				   const char *name, const char *sfile)
 {
   found_minimal_symbols found;
 
@@ -378,53 +381,48 @@ lookup_minimal_symbol (program_space *pspace, const char *name, objfile *objf,
 
   lookup_name_info lookup_name (name, symbol_name_match_type::FULL);
 
-  for (objfile *objfile : pspace->objfiles ())
+  for (objfile *objfile : objfile_list)
     {
       if (found.external_symbol.minsym != NULL)
 	break;
 
-      if (objf == NULL || objf == objfile
-	  || objf == objfile->separate_debug_objfile_backlink)
+      symbol_lookup_debug_printf ("lookup_minimal_symbol (%s, %s, %s)",
+				  name, sfile != NULL ? sfile : "NULL",
+				  objfile_debug_name (objfile));
+
+      /* Do two passes: the first over the ordinary hash table,
+	 and the second over the demangled hash table.  */
+      lookup_minimal_symbol_mangled (name, sfile, objfile,
+				     objfile->per_bfd->msymbol_hash,
+				     mangled_hash, mangled_cmp, found);
+
+      /* If not found, try the demangled hash table.  */
+      if (found.external_symbol.minsym == NULL)
 	{
-	  symbol_lookup_debug_printf ("lookup_minimal_symbol (%s, %s, %s, %s)",
-				      host_address_to_string (pspace),
-				      name, sfile != NULL ? sfile : "NULL",
-				      objfile_debug_name (objfile));
-
-	  /* Do two passes: the first over the ordinary hash table,
-	     and the second over the demangled hash table.  */
-	  lookup_minimal_symbol_mangled (name, sfile, objfile,
-					 objfile->per_bfd->msymbol_hash,
-					 mangled_hash, mangled_cmp, found);
-
-	  /* If not found, try the demangled hash table.  */
-	  if (found.external_symbol.minsym == NULL)
+	  /* Once for each language in the demangled hash names
+	     table (usually just zero or one languages).  */
+	  for (unsigned iter = 0; iter < nr_languages; ++iter)
 	    {
-	      /* Once for each language in the demangled hash names
-		 table (usually just zero or one languages).  */
-	      for (unsigned iter = 0; iter < nr_languages; ++iter)
-		{
-		  if (!objfile->per_bfd->demangled_hash_languages.test (iter))
-		    continue;
-		  enum language lang = (enum language) iter;
-
-		  unsigned int hash
-		    = (lookup_name.search_name_hash (lang)
-		       % MINIMAL_SYMBOL_HASH_SIZE);
-
-		  symbol_name_matcher_ftype *match
-		    = language_def (lang)->get_symbol_name_matcher
-							(lookup_name);
-		  struct minimal_symbol **msymbol_demangled_hash
-		    = objfile->per_bfd->msymbol_demangled_hash;
-
-		  lookup_minimal_symbol_demangled (lookup_name, sfile, objfile,
-						   msymbol_demangled_hash,
-						   hash, match, found);
-
-		  if (found.external_symbol.minsym != NULL)
-		    break;
-		}
+	      if (!objfile->per_bfd->demangled_hash_languages.test (iter))
+		continue;
+	      enum language lang = (enum language) iter;
+
+	      unsigned int hash
+		= (lookup_name.search_name_hash (lang)
+		   % MINIMAL_SYMBOL_HASH_SIZE);
+
+	      symbol_name_matcher_ftype *match
+		= language_def (lang)->get_symbol_name_matcher
+						    (lookup_name);
+	      struct minimal_symbol **msymbol_demangled_hash
+		= objfile->per_bfd->msymbol_demangled_hash;
+
+	      lookup_minimal_symbol_demangled (lookup_name, sfile, objfile,
+					       msymbol_demangled_hash,
+					       hash, match, found);
+
+	      if (found.external_symbol.minsym != NULL)
+		break;
 	    }
 	}
     }
@@ -477,6 +475,42 @@ lookup_minimal_symbol (program_space *pspace, const char *name, objfile *objf,
   return {};
 }
 
+/* See minsyms.h.  */
+
+bound_minimal_symbol
+lookup_minimal_symbol (program_space *pspace, const char *name, objfile *objf,
+		       const char *sfile)
+{
+  std::vector<objfile *> search_objfiles;
+  if (objf != nullptr)
+    {
+      search_objfiles.push_back (objf);
+      if (objf->separate_debug_objfile_backlink != nullptr)
+	search_objfiles.push_back (objf->separate_debug_objfile_backlink);
+    }
+  else
+    {
+      for (objfile *objfile : pspace->objfiles ())
+	search_objfiles.push_back (objfile);
+    }
+
+  return lookup_minimal_symbol_in_objfiles (search_objfiles, name, sfile);
+}
+
+/* See minsyms.h.  */
+
+bound_minimal_symbol
+lookup_minimal_symbol_in_linker_namespace (program_space *pspace,
+					   const char *name)
+{
+  LONGEST curr_namespace;
+  get_internalvar_integer (lookup_internalvar ("_linker_namespace"),
+			   &curr_namespace);
+  return lookup_minimal_symbol_in_objfiles
+      (get_objfiles_in_linker_namespace (curr_namespace, pspace),
+       name, nullptr);
+}
+
 /* See gdbsupport/symbol.h.  */
 
 int
diff --git a/gdb/minsyms.h b/gdb/minsyms.h
index 4bb2aca0b4c..b2fe4cebb38 100644
--- a/gdb/minsyms.h
+++ b/gdb/minsyms.h
@@ -211,6 +211,14 @@ bound_minimal_symbol lookup_minimal_symbol (program_space *pspace,
 					    objfile *obj = nullptr,
 					    const char *sfile = nullptr);
 
+/* Same as above, but only look for a minimal symbol in the objfiles that
+   belong to the current linker namespace.  This function is only meant to
+   be called when attempting to resolve a symbol from a user command, and
+   there are multiple linker namespaces available to resolve it in.  */
+
+bound_minimal_symbol lookup_minimal_symbol_in_linker_namespace
+  (program_space *pspace, const char *name);
+
 /* Look through all the minimal symbol tables in PSPACE and find the
    first minimal symbol that matches NAME and has text type.  If OBJF
    is non-NULL, limit the search to that objfile.  Returns a bound
diff --git a/gdb/parser-defs.h b/gdb/parser-defs.h
index f5618f3a9ce..ff4ab6a09de 100644
--- a/gdb/parser-defs.h
+++ b/gdb/parser-defs.h
@@ -358,6 +358,13 @@ struct ttype
     struct type *type;
   };
 
+struct bval_type
+  {
+    bool search_namespace;
+    const struct block *b_val;
+    LONGEST namespace_val;
+  };
+
 struct symtoken
   {
     struct stoken stoken;
diff --git a/gdb/symtab.c b/gdb/symtab.c
index 7b125bfd006..b4db8275580 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -2684,6 +2684,43 @@ lookup_static_symbol (const char *name, const domain_search_flags domain)
 
 /* See symtab.h.  */
 
+struct block_symbol
+lookup_symbol_in_linker_namespace (const char *name, int nsid,
+				   const domain_search_flags domain)
+{
+  if (!current_program_space->solib_ops ()->supports_namespaces ())
+    error (_("Linker namespaces are not supported by the inferior."));
+
+  std::vector<objfile *> objfiles_in_namespace
+    = get_objfiles_in_linker_namespace (nsid, current_program_space);
+
+  if (objfiles_in_namespace.size() == 0)
+    error (_("Namespace [[%d]] is inactive"), nsid);
+
+  symbol_lookup_debug_printf ("lookup_symbol_in_linker_namespace (%d, %s, %s)",
+			      nsid, name, domain_name (domain).c_str ());
+
+  /* We look for both global and static symbols in here.  There is no reason
+     to pick one over the other to my knowledge, so we go alphabetical.  */
+  for (objfile *objf : objfiles_in_namespace)
+    {
+      struct block_symbol bsym
+	= lookup_global_symbol_from_objfile (objf, GLOBAL_BLOCK,
+					     name, domain);
+      if (bsym.symbol != nullptr)
+	return bsym;
+
+      bsym = lookup_global_symbol_from_objfile (objf, STATIC_BLOCK,
+						name, domain);
+      if (bsym.symbol != nullptr)
+	return bsym;
+    }
+
+  return {};
+}
+
+/* See symtab.h.  */
+
 struct block_symbol
 lookup_global_symbol (const char *name,
 		      const struct block *block,
diff --git a/gdb/symtab.h b/gdb/symtab.h
index 0a57be5ed80..27acc70bf1d 100644
--- a/gdb/symtab.h
+++ b/gdb/symtab.h
@@ -2750,6 +2750,14 @@ extern struct block_symbol
 				     const char *name,
 				     const domain_search_flags domain);
 
+/* Lookup symbol NAME from DOMAIN in the linker namespace NSID.
+   This generates a list of all objfiles in NSID, then searches
+   those objfiles for the given symbol.  Searches for both global or
+   static symbols.  */
+extern struct block_symbol
+  lookup_symbol_in_linker_namespace (const char *name, int nsid,
+				     const domain_search_flags domain);
+
 extern unsigned int symtab_create_debug;
 
 /* Print a "symtab-create" debug statement.  */
diff --git a/gdb/testsuite/gdb.base/dlmopen-ns-ids-lib.c b/gdb/testsuite/gdb.base/dlmopen-ns-ids-lib.c
index 86cbb0f4e38..cc35ce0080e 100644
--- a/gdb/testsuite/gdb.base/dlmopen-ns-ids-lib.c
+++ b/gdb/testsuite/gdb.base/dlmopen-ns-ids-lib.c
@@ -26,3 +26,17 @@ inc (int n)
   int amount = gdb_dlmopen_glob;
   return n + amount;  /* bp.inc.  */
 }
+
+static int
+change_global (int n)
+{
+  gdb_dlmopen_glob += n;
+  return n;
+}
+
+__attribute__((visibility ("default")))
+int
+func_with_other_call (int n)
+{
+  return change_global (n + 1);
+}
diff --git a/gdb/testsuite/gdb.base/dlmopen-ns-ids-main.c b/gdb/testsuite/gdb.base/dlmopen-ns-ids-main.c
index c7c038a08d1..459ae547842 100644
--- a/gdb/testsuite/gdb.base/dlmopen-ns-ids-main.c
+++ b/gdb/testsuite/gdb.base/dlmopen-ns-ids-main.c
@@ -47,6 +47,9 @@ main (void)
       fun (dl);
     }
 
+  fun = dlsym (handle[0], "func_with_other_call");
+  fun (0);
+
   dlclose (handle[0]); /* TAG: first dlclose */
   dlclose (handle[1]); /* TAG: second dlclose */
   dlclose (handle[2]); /* TAG: third dlclose */
diff --git a/gdb/testsuite/gdb.base/dlmopen-ns-ids.exp b/gdb/testsuite/gdb.base/dlmopen-ns-ids.exp
index 4d3e8eba2ab..303595faee5 100644
--- a/gdb/testsuite/gdb.base/dlmopen-ns-ids.exp
+++ b/gdb/testsuite/gdb.base/dlmopen-ns-ids.exp
@@ -59,6 +59,10 @@ proc get_first_so_ns {} {
     return $ns
 }
 
+proc ns_id_for_command {ns} {
+    return "\[\[$ns\]\]"
+}
+
 # Run the tests relating to the command "info sharedlibrary", to
 # verify that the namespace ID is consistent.
 proc test_info_shared {} {
@@ -248,6 +252,49 @@ proc test_info_linker_namespaces {} {
 		    ".*" ] "print namespaces with no argument"
 }
 
+# Test that we can use the [[N]]::symbol syntax, and it's variations
+# like [[N]]::func::symbol.
+proc_with_prefix test_print_namespace_symbol {} {
+    clean_restart $::binfile
+
+    if { ![runto_main] } {
+	return
+    }
+
+    gdb_breakpoint [gdb_get_line_number "TAG: first dlclose"]
+    gdb_breakpoint "change_global" allow-pending
+    gdb_continue_to_breakpoint "change_global"
+
+    set ns1 [ns_id_for_command 1]
+    set ns2 [ns_id_for_command 2]
+
+    # Test finding location of variables.
+    gdb_test "print ${ns1}::gdb_dlmopen_glob" ".* = 0" "before changing"
+    gdb_test_no_output "set ${ns1}::gdb_dlmopen_glob = 1"
+    gdb_test "print ${ns1}::gdb_dlmopen_glob" ".* = 1" "after changing"
+    gdb_test "print ${ns2}::gdb_dlmopen_glob" ".* = 0" "other namespace"
+
+    gdb_test "print gdb_dlmopen_glob" ".* = 1" "changed the right variable"
+
+    # Test finding functions in specific namespaces.
+    gdb_test "print ${ns1}::inc (2)" ".* = 3"
+    gdb_test "print ${ns2}::inc (2)" ".* = 2"
+
+    # Test finding a specific block in the backtrace.
+    gdb_test "print n" ".* = 1"
+    gdb_test "print ${ns1}::func_with_other_call::n" ".* = 0"
+    gdb_test "print ${ns2}::func_with_other_call::n" \
+	"No frame is currently executing in block func_with_other_call."
+
+    # Leave to default namespace.
+    gdb_continue_to_breakpoint "TAG: first dlclose"
+    # This global doesn't exist in the default namespace.  Rather than
+    # 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."
+}
+
 test_info_shared
 test_conv_vars
 test_info_linker_namespaces
+test_print_namespace_symbol
-- 
2.49.0


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH v3 3/3] gdb: extend the [[N]]::foo syntax for files
  2025-06-19 18:05 [PATCH v3 0/3] Introduce syntax for linker-namespace specific symbols Guinevere Larsen
  2025-06-19 18:05 ` [PATCH v3 1/3] gdb: make lookup_minimal_symbol_linkage work with linker namespaces Guinevere Larsen
  2025-06-19 18:05 ` [PATCH v3 2/3] gdb: Make the parser recognize the [[N]] syntax for variables Guinevere Larsen
@ 2025-06-19 18:05 ` Guinevere Larsen
  2025-07-10  2:02   ` Kevin Buettner
  2025-07-10  2:27   ` Kevin Buettner
  2025-07-07 19:01 ` [PING][PATCH v3 0/3] Introduce syntax for linker-namespace specific symbols Guinevere Larsen
  3 siblings, 2 replies; 12+ messages in thread
From: Guinevere Larsen @ 2025-06-19 18:05 UTC (permalink / raw)
  To: gdb-patches; +Cc: Guinevere Larsen

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<T> (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<expr::operation_up> 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<bool (symtab *)> callback)
 {
   gdb::unique_xmalloc_ptr<char> 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<objfile *> 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<bool (symtab *)> callback);
 
 std::vector<CORE_ADDR> 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


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v3 2/3] gdb: Make the parser recognize the [[N]] syntax for variables
  2025-06-19 18:05 ` [PATCH v3 2/3] gdb: Make the parser recognize the [[N]] syntax for variables Guinevere Larsen
@ 2025-06-20  6:57   ` Eli Zaretskii
  2025-07-07 19:18     ` Guinevere Larsen
  0 siblings, 1 reply; 12+ messages in thread
From: Eli Zaretskii @ 2025-06-20  6:57 UTC (permalink / raw)
  To: Guinevere Larsen; +Cc: gdb-patches

> From: Guinevere Larsen <guinevere@redhat.com>
> Cc: Guinevere Larsen <guinevere@redhat.com>
> Date: Thu, 19 Jun 2025 15:05:39 -0300
> 
> This commit adds a couple new rules to the YACC parser, that will allow
> GDB to recognize expressions like [[N]]::var.
> 
> This new syntax re-uses the existing rules for searching for "block"s,
> because it allows, with minimal changes to the .y file as a whole, while
> also allowing [[N]]::function::symbol work. Notably, [[N]]::'file.c'::var
> does not work yet, as this code change is also involved and would pollute
> the current commit, so will be done in a separate one in the same series.
> 
> To restrict the search to a desired namespace, a new function is
> introduced,  lookup_symbol_in_linker_namespace.  This function will only
> perform the symbol lookup in the objfiles that belong to the requested
> namespace.
> 
> This commit also changes the error message when "print var" if "var" is
> only present in namespaces other than the current one. Before this commit,
> lookup_minimal_symbol would find them as "external" symbols with
> incomplete information - outputting "<symbol> has incomplete
> information, cast it to it's defined type." - which could be confusing for
> the users. This commit changes the parser rule "variable: name_not_typename"
> so that, if multiple namespaces are active, we'll look for minimal symbols
> only in the current namespace.
> 
> Known limitations:
> * When using [[N]]::foo::var, if that specific foo version is not on the
>   stack, the error will be unable to include the linker namespace
>   requested.  So if a user sees "foo" in the stack this could be
>   confusing, but it should be mitigated when a future patch adds the
>   namespace ID to the backtrace where applicable.
> * Completion is not supported.  That's because the function used to
>   complete symbols expects only text in the form "file.c:symbol", so
>   can't handle the double colon.  This isn't unique to linker
>   namespaces, though, since func::var will also not complete, it is just
>   a quirk of how :: completion work at this point.
> * The expression that parses [[N]] only takes an integer.  That's
>   because there aren't many expressions that would make sense in there,
>   and the work of accepting an arbitrary expression felt too much for
>   little gain.
> ---
>  gdb/NEWS                                     |   6 +
>  gdb/c-exp.y                                  |  72 ++++++++---
>  gdb/doc/gdb.texinfo                          |   6 +
>  gdb/minsyms.c                                | 124 ++++++++++++-------
>  gdb/minsyms.h                                |   8 ++
>  gdb/parser-defs.h                            |   7 ++
>  gdb/symtab.c                                 |  37 ++++++
>  gdb/symtab.h                                 |   8 ++
>  gdb/testsuite/gdb.base/dlmopen-ns-ids-lib.c  |  14 +++
>  gdb/testsuite/gdb.base/dlmopen-ns-ids-main.c |   3 +
>  gdb/testsuite/gdb.base/dlmopen-ns-ids.exp    |  47 +++++++
>  11 files changed, 268 insertions(+), 64 deletions(-)

Thanks.

> --- a/gdb/NEWS
> +++ b/gdb/NEWS
> @@ -102,6 +102,12 @@ info threads [-gid] [-stopped] [-running] [ID]...
>    These new flags can be useful to get a reduced list when there is a
>    large number of threads.
>  
> +print
> +  The print command now accepts the following syntax to print values
> +  from a specific linker namespace: `[[N]]::foo'.  N is the namespace
> +  identifier as understood by GDB.

This part is okay.

> --- a/gdb/doc/gdb.texinfo
> +++ b/gdb/doc/gdb.texinfo
> @@ -10565,6 +10565,12 @@ you can choose a different format by specifying @samp{/@var{f}}, where
>  @var{f} is a letter specifying the format; see @ref{Output Formats,,Output
>  Formats}.
>  
> +Additionally, if the inferior supports linker namespaces, @value{GDBN}
> +has implemented the following syntax to allow users to resolve symbols
> +to a specific namespace: @code{[[@var{n}]]::@var{symbol}}.  Here @var{n}
> +is @value{GDBN}'s namespace identifier, which may be different to the
> +inferior's identifier.

This part is also okay, but please say "different from" in the last
sentence.

Reviewed-By: Eli Zaretskii <eliz@gnu.org>

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PING][PATCH v3 0/3] Introduce syntax for linker-namespace specific symbols
  2025-06-19 18:05 [PATCH v3 0/3] Introduce syntax for linker-namespace specific symbols Guinevere Larsen
                   ` (2 preceding siblings ...)
  2025-06-19 18:05 ` [PATCH v3 3/3] gdb: extend the [[N]]::foo syntax for files Guinevere Larsen
@ 2025-07-07 19:01 ` Guinevere Larsen
  3 siblings, 0 replies; 12+ messages in thread
From: Guinevere Larsen @ 2025-07-07 19:01 UTC (permalink / raw)
  To: Guinevere Larsen, gdb-patches

On 6/19/25 3:05 PM, Guinevere Larsen wrote:
> This series adds support for the syntax [[N]]::foo to find symbols that
> belong to specific namespaces, while also making GDB's behavior more
> consistent when a namespace is not specified. This needs one preparatory
> patch and 2 patches actually implementing this feature
>
> Patch 1 is an essential fix, updating how we calculate a variable's copy
> relocation to take linker namespaces into account.
>
> Patches 2 and 3 implement the new syntax, adding the necessary
> supporting code and updating error messages when symbols can't be found
> - where it made sense.
>
> Do note that this series is built on top Simon's recent C++ification of
> the solib_ops class, since it has better solutions to some problems than
> my old versions.  It should be reviewed with that series in mind.

Ping!

Since Simon's c++ification went through before branching, it would be 
nice to get this merged in time for branching as well

-- 
Cheers,
Guinevere Larsen
She/Her/Hers


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v3 2/3] gdb: Make the parser recognize the [[N]] syntax for variables
  2025-06-20  6:57   ` Eli Zaretskii
@ 2025-07-07 19:18     ` Guinevere Larsen
  0 siblings, 0 replies; 12+ messages in thread
From: Guinevere Larsen @ 2025-07-07 19:18 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: gdb-patches

On 6/20/25 3:57 AM, Eli Zaretskii wrote:
>> From: Guinevere Larsen <guinevere@redhat.com>
>> Cc: Guinevere Larsen <guinevere@redhat.com>
>> Date: Thu, 19 Jun 2025 15:05:39 -0300
>>
>> This commit adds a couple new rules to the YACC parser, that will allow
>> GDB to recognize expressions like [[N]]::var.
>>
>> This new syntax re-uses the existing rules for searching for "block"s,
>> because it allows, with minimal changes to the .y file as a whole, while
>> also allowing [[N]]::function::symbol work. Notably, [[N]]::'file.c'::var
>> does not work yet, as this code change is also involved and would pollute
>> the current commit, so will be done in a separate one in the same series.
>>
>> To restrict the search to a desired namespace, a new function is
>> introduced,  lookup_symbol_in_linker_namespace.  This function will only
>> perform the symbol lookup in the objfiles that belong to the requested
>> namespace.
>>
>> This commit also changes the error message when "print var" if "var" is
>> only present in namespaces other than the current one. Before this commit,
>> lookup_minimal_symbol would find them as "external" symbols with
>> incomplete information - outputting "<symbol> has incomplete
>> information, cast it to it's defined type." - which could be confusing for
>> the users. This commit changes the parser rule "variable: name_not_typename"
>> so that, if multiple namespaces are active, we'll look for minimal symbols
>> only in the current namespace.
>>
>> Known limitations:
>> * When using [[N]]::foo::var, if that specific foo version is not on the
>>    stack, the error will be unable to include the linker namespace
>>    requested.  So if a user sees "foo" in the stack this could be
>>    confusing, but it should be mitigated when a future patch adds the
>>    namespace ID to the backtrace where applicable.
>> * Completion is not supported.  That's because the function used to
>>    complete symbols expects only text in the form "file.c:symbol", so
>>    can't handle the double colon.  This isn't unique to linker
>>    namespaces, though, since func::var will also not complete, it is just
>>    a quirk of how :: completion work at this point.
>> * The expression that parses [[N]] only takes an integer.  That's
>>    because there aren't many expressions that would make sense in there,
>>    and the work of accepting an arbitrary expression felt too much for
>>    little gain.
>> ---
>>   gdb/NEWS                                     |   6 +
>>   gdb/c-exp.y                                  |  72 ++++++++---
>>   gdb/doc/gdb.texinfo                          |   6 +
>>   gdb/minsyms.c                                | 124 ++++++++++++-------
>>   gdb/minsyms.h                                |   8 ++
>>   gdb/parser-defs.h                            |   7 ++
>>   gdb/symtab.c                                 |  37 ++++++
>>   gdb/symtab.h                                 |   8 ++
>>   gdb/testsuite/gdb.base/dlmopen-ns-ids-lib.c  |  14 +++
>>   gdb/testsuite/gdb.base/dlmopen-ns-ids-main.c |   3 +
>>   gdb/testsuite/gdb.base/dlmopen-ns-ids.exp    |  47 +++++++
>>   11 files changed, 268 insertions(+), 64 deletions(-)
> Thanks.
>
>> --- a/gdb/NEWS
>> +++ b/gdb/NEWS
>> @@ -102,6 +102,12 @@ info threads [-gid] [-stopped] [-running] [ID]...
>>     These new flags can be useful to get a reduced list when there is a
>>     large number of threads.
>>   
>> +print
>> +  The print command now accepts the following syntax to print values
>> +  from a specific linker namespace: `[[N]]::foo'.  N is the namespace
>> +  identifier as understood by GDB.
> This part is okay.
>
>> --- a/gdb/doc/gdb.texinfo
>> +++ b/gdb/doc/gdb.texinfo
>> @@ -10565,6 +10565,12 @@ you can choose a different format by specifying @samp{/@var{f}}, where
>>   @var{f} is a letter specifying the format; see @ref{Output Formats,,Output
>>   Formats}.
>>   
>> +Additionally, if the inferior supports linker namespaces, @value{GDBN}
>> +has implemented the following syntax to allow users to resolve symbols
>> +to a specific namespace: @code{[[@var{n}]]::@var{symbol}}.  Here @var{n}
>> +is @value{GDBN}'s namespace identifier, which may be different to the
>> +inferior's identifier.
> This part is also okay, but please say "different from" in the last
> sentence.
>
> Reviewed-By: Eli Zaretskii <eliz@gnu.org>
>
Thanks for the review (and sorry for the delay). I fixed this locally

-- 
Cheers,
Guinevere Larsen
She/Her/Hers


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v3 3/3] gdb: extend the [[N]]::foo syntax for files
  2025-06-19 18:05 ` [PATCH v3 3/3] gdb: extend the [[N]]::foo syntax for files Guinevere Larsen
@ 2025-07-10  2:02   ` Kevin Buettner
  2025-07-10 14:47     ` Guinevere Larsen
  2025-07-10  2:27   ` Kevin Buettner
  1 sibling, 1 reply; 12+ messages in thread
From: Kevin Buettner @ 2025-07-10  2:02 UTC (permalink / raw)
  To: Guinevere Larsen; +Cc: gdb-patches

Hi Gwen,

On Thu, 19 Jun 2025 15:05:40 -0300
Guinevere Larsen <guinevere@redhat.com> wrote:

> 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);
>  

I'm seeing a build error related to the bit above:

/mesquite2/sourceware-git/worktree-review/gdb/parse.c: In function
‘expression_up parse_exp_in_context(const char**, CORE_ADDR, const block*,
parser_flags, innermost_block_tracker*,
std::unique_ptr<expr_completion_base>*)’:
/mesquite2/sourceware-git/worktree-review/gdb/parse.c:425:53: error:
invalid conversion from ‘const solib_ops*’ to ‘solib_ops*’ [-fpermissive]
425 |                    current_program_space->solib_ops ()); |
        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~ |
                      | |
  const solib_ops* In file included from
/mesquite2/sourceware-git/worktree-review/gdb/parse.c:41:
/mesquite2/sourceware-git/worktree-review/gdb/parser-defs.h:152:28: note:
initializing argument 9 of ‘parser_state::parser_state(const
language_defn*, gdbarch*, const block*, CORE_ADDR, parser_flags, const
char*, bool, innermost_block_tracker*, solib_ops*)’ 152 |
solib_ops *ops) |                 ~~~~~~~~~~~^~~

Kevin


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v3 3/3] gdb: extend the [[N]]::foo syntax for files
  2025-06-19 18:05 ` [PATCH v3 3/3] gdb: extend the [[N]]::foo syntax for files Guinevere Larsen
  2025-07-10  2:02   ` Kevin Buettner
@ 2025-07-10  2:27   ` Kevin Buettner
  2025-07-10 15:07     ` Guinevere Larsen
  1 sibling, 1 reply; 12+ messages in thread
From: Kevin Buettner @ 2025-07-10  2:27 UTC (permalink / raw)
  To: Guinevere Larsen; +Cc: gdb-patches

On Thu, 19 Jun 2025 15:05:40 -0300
Guinevere Larsen <guinevere@redhat.com> wrote:

> +    gdb_test "print ${ns0}::'${::srcfile_lib}'::gdb_dlmopen_glob" \
> +	"No function .${::srcfile_lib}. in specified context."

I'm wondering about this test.  ${::srcfile_lib} refers to a file, right?
If so, why does the message say "function"?

Kevin


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v3 3/3] gdb: extend the [[N]]::foo syntax for files
  2025-07-10  2:02   ` Kevin Buettner
@ 2025-07-10 14:47     ` Guinevere Larsen
  0 siblings, 0 replies; 12+ messages in thread
From: Guinevere Larsen @ 2025-07-10 14:47 UTC (permalink / raw)
  To: Kevin Buettner; +Cc: gdb-patches

On 7/9/25 11:02 PM, Kevin Buettner wrote:
> Hi Gwen,
>
> On Thu, 19 Jun 2025 15:05:40 -0300
> Guinevere Larsen <guinevere@redhat.com> wrote:
>
>> 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);
>>   
> I'm seeing a build error related to the bit above:
>
> /mesquite2/sourceware-git/worktree-review/gdb/parse.c: In function
> ‘expression_up parse_exp_in_context(const char**, CORE_ADDR, const block*,
> parser_flags, innermost_block_tracker*,
> std::unique_ptr<expr_completion_base>*)’:
> /mesquite2/sourceware-git/worktree-review/gdb/parse.c:425:53: error:
> invalid conversion from ‘const solib_ops*’ to ‘solib_ops*’ [-fpermissive]
> 425 |                    current_program_space->solib_ops ()); |
>          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~ |
>                        | |
>    const solib_ops* In file included from
> /mesquite2/sourceware-git/worktree-review/gdb/parse.c:41:
> /mesquite2/sourceware-git/worktree-review/gdb/parser-defs.h:152:28: note:
> initializing argument 9 of ‘parser_state::parser_state(const
> language_defn*, gdbarch*, const block*, CORE_ADDR, parser_flags, const
> char*, bool, innermost_block_tracker*, solib_ops*)’ 152 |
> solib_ops *ops) |                 ~~~~~~~~~~~^~~
>
> Kevin
>
Ah, thanks for reporting this, I must have not redone a build when I 
sent this (sorry, it was pre-vacation rush).

This is trivially solved by making all solib_ops pointers in 
parser_state const, I fixed it locally

-- 
Cheers,
Guinevere Larsen
She/Her/Hers


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v3 3/3] gdb: extend the [[N]]::foo syntax for files
  2025-07-10  2:27   ` Kevin Buettner
@ 2025-07-10 15:07     ` Guinevere Larsen
  2025-07-10 21:56       ` Kevin Buettner
  0 siblings, 1 reply; 12+ messages in thread
From: Guinevere Larsen @ 2025-07-10 15:07 UTC (permalink / raw)
  To: Kevin Buettner; +Cc: gdb-patches

On 7/9/25 11:27 PM, Kevin Buettner wrote:
> On Thu, 19 Jun 2025 15:05:40 -0300
> Guinevere Larsen <guinevere@redhat.com> wrote:
>
>> +    gdb_test "print ${ns0}::'${::srcfile_lib}'::gdb_dlmopen_glob" \
>> +	"No function .${::srcfile_lib}. in specified context."
> I'm wondering about this test.  ${::srcfile_lib} refers to a file, right?
> If so, why does the message say "function"?

This is an annoying case to work with... The error "No function %s in 
specified context" comes from the "block: block COLONCOLON name" rule, 
around line 1105 in my tree.

The issue here is that the function "classify_name" couldn't find a file 
named ${::srcfile_lib} in the specified namespace, and so it classified 
that string as a generic name, rather than a file name. It's not even a 
factor of not having enough information to differentiate, the issue is 
that the name is miscategorized it would be impossible for us to even 
know when it was meant as a file or a function.

At present, this error can only refer to a file if the user is searching 
for something in a namespace, so I could make that error checking 
slightly more thorough, and keep the current message when no namespace 
ID was used, and have a new "No function or file %s in specified 
context" message. Would that be better, in your opinion?

-- 
Cheers,
Guinevere Larsen
She/Her/Hers


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v3 3/3] gdb: extend the [[N]]::foo syntax for files
  2025-07-10 15:07     ` Guinevere Larsen
@ 2025-07-10 21:56       ` Kevin Buettner
  0 siblings, 0 replies; 12+ messages in thread
From: Kevin Buettner @ 2025-07-10 21:56 UTC (permalink / raw)
  To: Guinevere Larsen; +Cc: gdb-patches

On Thu, 10 Jul 2025 12:07:48 -0300
Guinevere Larsen <guinevere@redhat.com> wrote:

> On 7/9/25 11:27 PM, Kevin Buettner wrote:
> > On Thu, 19 Jun 2025 15:05:40 -0300
> > Guinevere Larsen <guinevere@redhat.com> wrote:
> >  
> >> +    gdb_test "print ${ns0}::'${::srcfile_lib}'::gdb_dlmopen_glob" \
> >> +	"No function .${::srcfile_lib}. in specified context."  
> > I'm wondering about this test.  ${::srcfile_lib} refers to a file,
> > right? If so, why does the message say "function"?  
> 
> This is an annoying case to work with... The error "No function %s in 
> specified context" comes from the "block: block COLONCOLON name" rule, 
> around line 1105 in my tree.
> 
> The issue here is that the function "classify_name" couldn't find a file 
> named ${::srcfile_lib} in the specified namespace, and so it classified 
> that string as a generic name, rather than a file name. It's not even a 
> factor of not having enough information to differentiate, the issue is 
> that the name is miscategorized it would be impossible for us to even 
> know when it was meant as a file or a function.
> 
> At present, this error can only refer to a file if the user is searching 
> for something in a namespace, so I could make that error checking 
> slightly more thorough, and keep the current message when no namespace 
> ID was used, and have a new "No function or file %s in specified 
> context" message. Would that be better, in your opinion?

While it would be nice to use "file" to refer to files and "function"
for functions, if we really can't differentiate, then I think using
"No function or file %s..." is better than the current situation.

Kevin


^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2025-07-10 21:57 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-06-19 18:05 [PATCH v3 0/3] Introduce syntax for linker-namespace specific symbols Guinevere Larsen
2025-06-19 18:05 ` [PATCH v3 1/3] gdb: make lookup_minimal_symbol_linkage work with linker namespaces Guinevere Larsen
2025-06-19 18:05 ` [PATCH v3 2/3] gdb: Make the parser recognize the [[N]] syntax for variables Guinevere Larsen
2025-06-20  6:57   ` Eli Zaretskii
2025-07-07 19:18     ` Guinevere Larsen
2025-06-19 18:05 ` [PATCH v3 3/3] gdb: extend the [[N]]::foo syntax for files Guinevere Larsen
2025-07-10  2:02   ` Kevin Buettner
2025-07-10 14:47     ` Guinevere Larsen
2025-07-10  2:27   ` Kevin Buettner
2025-07-10 15:07     ` Guinevere Larsen
2025-07-10 21:56       ` Kevin Buettner
2025-07-07 19:01 ` [PING][PATCH v3 0/3] Introduce syntax for linker-namespace specific symbols Guinevere Larsen

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox