public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
* [PATCH v5 00/15] basic linker namespace support
@ 2022-06-02 13:24 Markus Metzger
  2022-06-02 13:25 ` [PATCH v5 01/15] gdb, testsuite: extend gdb_test_multiple checks Markus Metzger
                   ` (15 more replies)
  0 siblings, 16 replies; 52+ messages in thread
From: Markus Metzger @ 2022-06-02 13:24 UTC (permalink / raw)
  To: gdb-patches

This series adds basic support for SVR4 linker namespaces.

It makes GDB read DSOs from all namespaces and makes breakpoints bind in
all namespaces.  Symbol lookup (from debug info) is restricted to the
namespace of the current location (expressed by the CURRENT_OBJFILE
argument to gdbarch_iterate_over_objfiles_in_search_order) and defaults to
the initial namespace.

There are known issues (see below) and there are stil many places in GDB
that iterate over objfiles and that are not aware of namespaces, including
minimal symbol lookup.

Since minimal symbol lookup is part of get_symbol_address (), we may
accidentally overwrite a symbol that was resolved to an objfile in the
correct namespace with one from a different namespace.  I believe that
get_symbol_address () should just return the address of that symbol, but
then we need to find another way of handling copy relocations (see below).

Namespaces are hidden in solib-svr4.c; the rest of GDB is not aware of
them.  Hence, they do not show up in 'info shared' or anywhere else on the
user interface.

Ben Woodard and Kevin Buettner requested namespaces to become part of the
user interface to allow setting namespace-specific breakpoints or simply
to show which libraries or breakpoint instances belong to which namespace.

Lacking access to the namespace id that dlinfo(3) would provide, we use
the address of the r_debug object as identifier and also pass it over RSP.
The respective interface was defined as 'lmid', however, to allow changing
it once we get access.

The bulk of this series is changing direct objfiles iterations to use
gdbarch_iterate_over_objfiles_in_search_order ().  There are three cases
that I did not handle and they are listed as known issues below.  The
rest, I either changed or convinced myself that it doesn't need changing.

Expected fails:

  - gdb.base/non-lazy-array-index.exp: the expression parser may lookup
    global symbols, which may result in xfers to read auxv for determining
    the debug base as part of svr4_iterate_over_objfiles_in_search_order().

  - gdb.server/non-lazy-array-index.exp: symbol lookup may access the
    target to read AUXV in order to determine the debug base for SVR4
    linker namespaces.

Known issues:

  - get_symbol_address() and get_msymbol_address() search objfiles for a
    'better' match.  This was introduced by

        4b610737f02 Handle copy relocations

    to handle copy relocations but it now causes a wrong address to be
    read after symbol lookup actually found the correct symbol.  This can
    be seen, for example, with gdb.base/dlmopen.exp when compiled with
    clang.

  - gnu ifuncs are only looked up in the initial namespace.

  - lookup_minimal_symbol() and lookup_minimal_symbol_text() directly
    iterate over objfiles and are not aware of linker namespaces.


Regression-tested on x86-64 on a non-glibc-enabled system.  The dlmopen
part was tested (just gdb.base/dlmopen.exp) with an enabled glibc.

The initial work was done by H.J. Lu.

See also users/mmetzger/dlmopen.

Markus Metzger (15):
  gdb, testsuite: extend gdb_test_multiple checks
  gdb, solib-svr4: remove locate_base()
  gdb, gdbserver: support dlmopen()
  gdbserver: move main_lm handling into caller
  gdb, gdbserver: extend RSP to support namespaces
  gdb, compile: unlink objfile stored in module
  gdb, python: use gdbarch_iterate_over_objfiles_in_search_order
  gdb, ada: collect standard exceptions in all objfiles
  gdb, ada: update ada_lookup_simple_minsym
  gdb, ada: update ada_add_all_symbols
  gdb, cp: update add_symbol_overload_list_qualified
  gdb, hppa: remove unused hppa_lookup_stub_minimal_symbol
  gdb, symtab: inline find_quick_global_symbol_language
  gdb: update gnu ifunc resolve
  gdb, solib-svr4: support namespaces in DSO iteration

 gdb/ada-exp.y                                 |   9 +-
 gdb/ada-lang.c                                | 128 ++--
 gdb/ada-lang.h                                |   3 +-
 gdb/compile/compile-object-run.c              |  21 +-
 gdb/cp-support.c                              |  48 +-
 gdb/doc/gdb.texinfo                           |  16 +-
 gdb/elfread.c                                 | 153 ++---
 gdb/features/library-list-svr4.dtd            |   4 +
 gdb/hppa-tdep.c                               |  31 -
 gdb/hppa-tdep.h                               |   4 -
 gdb/linux-tdep.c                              |   2 +
 gdb/mips-fbsd-tdep.c                          |   2 +
 gdb/mips-netbsd-tdep.c                        |   2 +
 gdb/python/py-objfile.c                       | 116 ++--
 gdb/python/python.c                           |   7 +-
 gdb/python/python.h                           |   6 +
 gdb/solib-svr4.c                              | 553 +++++++++++++-----
 gdb/solib-svr4.h                              |   3 +
 gdb/symtab.c                                  |  43 +-
 gdb/testsuite/gdb.base/dlmopen-lib-dep.c      |  21 +
 gdb/testsuite/gdb.base/dlmopen-lib.c          |  28 +
 gdb/testsuite/gdb.base/dlmopen.c              |  65 ++
 gdb/testsuite/gdb.base/dlmopen.exp            | 174 ++++++
 .../gdb.base/non-lazy-array-index.exp         |  18 +-
 .../gdb.server/bkpt-other-inferior.exp        |  13 +-
 gdb/testsuite/lib/gdb.exp                     | 108 ++++
 gdbserver/linux-low.cc                        | 273 +++++----
 27 files changed, 1324 insertions(+), 527 deletions(-)
 create mode 100644 gdb/testsuite/gdb.base/dlmopen-lib-dep.c
 create mode 100644 gdb/testsuite/gdb.base/dlmopen-lib.c
 create mode 100644 gdb/testsuite/gdb.base/dlmopen.c
 create mode 100644 gdb/testsuite/gdb.base/dlmopen.exp

-- 
2.35.3

Intel Deutschland GmbH
Registered Address: Am Campeon 10, 85579 Neubiberg, Germany
Tel: +49 89 99 8853-0, www.intel.de <http://www.intel.de>
Managing Directors: Christin Eisenschmid, Sharon Heck, Tiffany Doon Silva  
Chairperson of the Supervisory Board: Nicole Lau
Registered Office: Munich
Commercial Register: Amtsgericht Muenchen HRB 186928


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

* [PATCH v5 01/15] gdb, testsuite: extend gdb_test_multiple checks
  2022-06-02 13:24 [PATCH v5 00/15] basic linker namespace support Markus Metzger
@ 2022-06-02 13:25 ` Markus Metzger
  2022-06-13  1:28   ` Kevin Buettner
  2022-06-02 13:25 ` [PATCH v5 02/15] gdb, solib-svr4: remove locate_base() Markus Metzger
                   ` (14 subsequent siblings)
  15 siblings, 1 reply; 52+ messages in thread
From: Markus Metzger @ 2022-06-02 13:25 UTC (permalink / raw)
  To: gdb-patches

Check for

    warning: Corrupted shared library list

and for

    warning: while parsing target library list: .*

and for

    Invalid cast.
    warning: Probes-based dynamic linker interface failed.
    Reverting to original interface.

in gdb_test_multiple.
---
 gdb/testsuite/lib/gdb.exp | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp
index 402450152ac..6aef39e5e02 100644
--- a/gdb/testsuite/lib/gdb.exp
+++ b/gdb/testsuite/lib/gdb.exp
@@ -1129,6 +1129,18 @@ proc gdb_test_multiple { command message args } {
 	    }
 	    set result -1
 	}
+	-re "Corrupted shared library list.*$prompt_regexp" {
+	    fail "$message (shared library list corrupted)"
+	    set result -1
+	}
+	-re "warning: while parsing target library list:.*$prompt_regexp" {
+	    fail "$message (shared library list parsing)"
+	    set result -1
+	}
+	-re "Invalid cast\.\r\nwarning: Probes-based dynamic linker interface failed.*$prompt_regexp" {
+	    fail "$message (probes interface failure)"
+	    set result -1
+	}
     }
     append code $processed_code
 
-- 
2.35.3

Intel Deutschland GmbH
Registered Address: Am Campeon 10, 85579 Neubiberg, Germany
Tel: +49 89 99 8853-0, www.intel.de <http://www.intel.de>
Managing Directors: Christin Eisenschmid, Sharon Heck, Tiffany Doon Silva  
Chairperson of the Supervisory Board: Nicole Lau
Registered Office: Munich
Commercial Register: Amtsgericht Muenchen HRB 186928


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

* [PATCH v5 02/15] gdb, solib-svr4: remove locate_base()
  2022-06-02 13:24 [PATCH v5 00/15] basic linker namespace support Markus Metzger
  2022-06-02 13:25 ` [PATCH v5 01/15] gdb, testsuite: extend gdb_test_multiple checks Markus Metzger
@ 2022-06-02 13:25 ` Markus Metzger
  2022-06-02 23:04   ` Kevin Buettner
  2022-06-02 13:25 ` [PATCH v5 03/15] gdb, gdbserver: support dlmopen() Markus Metzger
                   ` (13 subsequent siblings)
  15 siblings, 1 reply; 52+ messages in thread
From: Markus Metzger @ 2022-06-02 13:25 UTC (permalink / raw)
  To: gdb-patches

Whenever we call locate_base(), we clear info->debug_base directly before
the call.  Thus, we never cache the base location as locate_base() had
intended.

Move the svr4_have_link_map_offsets() check into elf_locate_base(), inline
locate_base() at all call sites, and remove it.
---
 gdb/solib-svr4.c | 62 +++++++++---------------------------------------
 1 file changed, 11 insertions(+), 51 deletions(-)

diff --git a/gdb/solib-svr4.c b/gdb/solib-svr4.c
index 5c046d3fab5..6222f79a7a0 100644
--- a/gdb/solib-svr4.c
+++ b/gdb/solib-svr4.c
@@ -662,6 +662,9 @@ elf_locate_base (void)
   struct bound_minimal_symbol msymbol;
   CORE_ADDR dyn_ptr, dyn_ptr_addr;
 
+  if (!svr4_have_link_map_offsets ())
+    return 0;
+
   /* Look for DT_MIPS_RLD_MAP first.  MIPS executables use this
      instead of DT_DEBUG, although they sometimes contain an unused
      DT_DEBUG.  */
@@ -719,45 +722,6 @@ elf_locate_base (void)
   return 0;
 }
 
-/* Locate the base address of dynamic linker structs.
-
-   For both the SunOS and SVR4 shared library implementations, if the
-   inferior executable has been linked dynamically, there is a single
-   address somewhere in the inferior's data space which is the key to
-   locating all of the dynamic linker's runtime structures.  This
-   address is the value of the debug base symbol.  The job of this
-   function is to find and return that address, or to return 0 if there
-   is no such address (the executable is statically linked for example).
-
-   For SunOS, the job is almost trivial, since the dynamic linker and
-   all of it's structures are statically linked to the executable at
-   link time.  Thus the symbol for the address we are looking for has
-   already been added to the minimal symbol table for the executable's
-   objfile at the time the symbol file's symbols were read, and all we
-   have to do is look it up there.  Note that we explicitly do NOT want
-   to find the copies in the shared library.
-
-   The SVR4 version is a bit more complicated because the address
-   is contained somewhere in the dynamic info section.  We have to go
-   to a lot more work to discover the address of the debug base symbol.
-   Because of this complexity, we cache the value we find and return that
-   value on subsequent invocations.  Note there is no copy in the
-   executable symbol tables.  */
-
-static CORE_ADDR
-locate_base (struct svr4_info *info)
-{
-  /* Check to see if we have a currently valid address, and if so, avoid
-     doing all this work again and just return the cached address.  If
-     we have no cached address, try to locate it in the dynamic info
-     section for ELF executables.  There's no point in doing any of this
-     though if we don't have some link map offsets to work with.  */
-
-  if (info->debug_base == 0 && svr4_have_link_map_offsets ())
-    info->debug_base = elf_locate_base ();
-  return info->debug_base;
-}
-
 /* Find the first element in the inferior's dynamic link map, and
    return its address in the inferior.  Return zero if the address
    could not be determined.
@@ -845,9 +809,8 @@ svr4_keep_data_in_core (CORE_ADDR vaddr, unsigned long size)
 
   info = get_svr4_info (current_program_space);
 
-  info->debug_base = 0;
-  locate_base (info);
-  if (!info->debug_base)
+  info->debug_base = elf_locate_base ();
+  if (info->debug_base == 0)
     return 0;
 
   ldsomap = solib_svr4_r_ldsomap (info);
@@ -881,8 +844,8 @@ open_symbol_file_object (int from_tty)
       return 0;
 
   /* Always locate the debug struct, in case it has moved.  */
-  info->debug_base = 0;
-  if (locate_base (info) == 0)
+  info->debug_base = elf_locate_base ();
+  if (info->debug_base == 0)
     return 0;	/* failed somehow...  */
 
   /* First link map member should be the executable.  */
@@ -1298,13 +1261,10 @@ svr4_current_sos_direct (struct svr4_info *info)
       return library_list.head ? library_list.head : svr4_default_sos (info);
     }
 
-  /* Always locate the debug struct, in case it has moved.  */
-  info->debug_base = 0;
-  locate_base (info);
-
   /* If we can't find the dynamic linker's base structure, this
      must not be a dynamically linked executable.  Hmm.  */
-  if (! info->debug_base)
+  info->debug_base = elf_locate_base ();
+  if (info->debug_base == 0)
     return svr4_default_sos (info);
 
   /* Assume that everything is a library if the dynamic loader was loaded
@@ -1840,8 +1800,8 @@ svr4_handle_solib_event (void)
       return;
 
     /* Always locate the debug struct, in case it moved.  */
-    info->debug_base = 0;
-    if (locate_base (info) == 0)
+    info->debug_base = elf_locate_base ();
+    if (info->debug_base == 0)
       {
 	/* It's possible for the reloc_complete probe to be triggered before
 	   the linker has set the DT_DEBUG pointer (for example, when the
-- 
2.35.3

Intel Deutschland GmbH
Registered Address: Am Campeon 10, 85579 Neubiberg, Germany
Tel: +49 89 99 8853-0, www.intel.de <http://www.intel.de>
Managing Directors: Christin Eisenschmid, Sharon Heck, Tiffany Doon Silva  
Chairperson of the Supervisory Board: Nicole Lau
Registered Office: Munich
Commercial Register: Amtsgericht Muenchen HRB 186928


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

* [PATCH v5 03/15] gdb, gdbserver: support dlmopen()
  2022-06-02 13:24 [PATCH v5 00/15] basic linker namespace support Markus Metzger
  2022-06-02 13:25 ` [PATCH v5 01/15] gdb, testsuite: extend gdb_test_multiple checks Markus Metzger
  2022-06-02 13:25 ` [PATCH v5 02/15] gdb, solib-svr4: remove locate_base() Markus Metzger
@ 2022-06-02 13:25 ` Markus Metzger
  2022-06-19  4:02   ` Kevin Buettner
  2022-06-02 13:25 ` [PATCH v5 04/15] gdbserver: move main_lm handling into caller Markus Metzger
                   ` (12 subsequent siblings)
  15 siblings, 1 reply; 52+ messages in thread
From: Markus Metzger @ 2022-06-02 13:25 UTC (permalink / raw)
  To: gdb-patches; +Cc: Lu, Hongjiu

In glibc, the r_debug structure contains (amongst others) the following
fields:

  int r_version:
    Version number for this protocol.  It should be greater than 0.

If r_version is 2, struct r_debug is extended to struct r_debug_extended
with one additional field:

  struct r_debug_extended *r_next;
    Link to the next r_debug_extended structure.  Each r_debug_extended
    structure represents a different namespace.  The first r_debug_extended
    structure is for the default namespace.

1. Change solib_svr4_r_map argument to take the debug base.
2. Add solib_svr4_r_next to find the link map in the next namespace from
the r_next field.
3. Update svr4_current_sos_direct to get the link map in the next namespace
from the r_next field.
4. Don't check shared libraries in other namespaces when updating shared
libraries in a new namespace.
5. Update svr4_same to check the load offset in addition to the name
6. Update svr4_default_sos to also set l_addr_inferior
7. Change the flat solib_list into a per-namespace list using the
namespace's r_debug address to identify the namespace.

Add gdb.base/dlmopen.exp to test this.

To remain backwards compatible with older gdbserver, we reserve the
namespace zero for a flat list of solibs from all namespaces.  Subsequent
patches will extend RSP to allow listing libraries grouped by namespace.

This fixes PR 11839.

Co-authored-by: Lu, Hongjiu  <hongjiu.lu@intel.com>
---
 gdb/linux-tdep.c                     |   2 +
 gdb/mips-fbsd-tdep.c                 |   2 +
 gdb/mips-netbsd-tdep.c               |   2 +
 gdb/solib-svr4.c                     | 377 ++++++++++++++++++++-------
 gdb/solib-svr4.h                     |   3 +
 gdb/testsuite/gdb.base/dlmopen-lib.c |  25 ++
 gdb/testsuite/gdb.base/dlmopen.c     |  65 +++++
 gdb/testsuite/gdb.base/dlmopen.exp   | 150 +++++++++++
 gdb/testsuite/lib/gdb.exp            |  96 +++++++
 gdbserver/linux-low.cc               | 247 +++++++++++-------
 10 files changed, 784 insertions(+), 185 deletions(-)
 create mode 100644 gdb/testsuite/gdb.base/dlmopen-lib.c
 create mode 100644 gdb/testsuite/gdb.base/dlmopen.c
 create mode 100644 gdb/testsuite/gdb.base/dlmopen.exp

diff --git a/gdb/linux-tdep.c b/gdb/linux-tdep.c
index 4e728a06e7e..a0e319f9395 100644
--- a/gdb/linux-tdep.c
+++ b/gdb/linux-tdep.c
@@ -2775,6 +2775,7 @@ linux_ilp32_fetch_link_map_offsets ()
       lmo.r_map_offset = 4;
       lmo.r_brk_offset = 8;
       lmo.r_ldsomap_offset = -1;
+      lmo.r_next_offset = 20;
 
       /* Everything we need is in the first 20 bytes.  */
       lmo.link_map_size = 20;
@@ -2803,6 +2804,7 @@ linux_lp64_fetch_link_map_offsets ()
       lmo.r_map_offset = 8;
       lmo.r_brk_offset = 16;
       lmo.r_ldsomap_offset = -1;
+      lmo.r_next_offset = 40;
 
       /* Everything we need is in the first 40 bytes.  */
       lmo.link_map_size = 40;
diff --git a/gdb/mips-fbsd-tdep.c b/gdb/mips-fbsd-tdep.c
index 05043d93e74..ecee4cdde50 100644
--- a/gdb/mips-fbsd-tdep.c
+++ b/gdb/mips-fbsd-tdep.c
@@ -495,6 +495,7 @@ mips_fbsd_ilp32_fetch_link_map_offsets (void)
       lmo.r_map_offset = 4;
       lmo.r_brk_offset = 8;
       lmo.r_ldsomap_offset = -1;
+      lmo.r_next_offset = -1;
 
       lmo.link_map_size = 24;
       lmo.l_addr_offset = 0;
@@ -522,6 +523,7 @@ mips_fbsd_lp64_fetch_link_map_offsets (void)
       lmo.r_map_offset = 8;
       lmo.r_brk_offset = 16;
       lmo.r_ldsomap_offset = -1;
+      lmo.r_next_offset = -1;
 
       lmo.link_map_size = 48;
       lmo.l_addr_offset = 0;
diff --git a/gdb/mips-netbsd-tdep.c b/gdb/mips-netbsd-tdep.c
index 2179ca0bf5a..b7a68ffe81b 100644
--- a/gdb/mips-netbsd-tdep.c
+++ b/gdb/mips-netbsd-tdep.c
@@ -308,6 +308,7 @@ mipsnbsd_ilp32_fetch_link_map_offsets (void)
       lmo.r_map_offset = 4;
       lmo.r_brk_offset = 8;
       lmo.r_ldsomap_offset = -1;
+      lmo.r_next_offset = -1;
 
       /* Everything we need is in the first 24 bytes.  */
       lmo.link_map_size = 24;
@@ -336,6 +337,7 @@ mipsnbsd_lp64_fetch_link_map_offsets (void)
       lmo.r_map_offset = 8;
       lmo.r_brk_offset = 16;
       lmo.r_ldsomap_offset = -1;
+      lmo.r_next_offset = -1;
 
       /* Everything we need is in the first 40 bytes.  */
       lmo.link_map_size = 48;
diff --git a/gdb/solib-svr4.c b/gdb/solib-svr4.c
index 6222f79a7a0..1f2abcf16ef 100644
--- a/gdb/solib-svr4.c
+++ b/gdb/solib-svr4.c
@@ -46,10 +46,12 @@
 #include "gdb_bfd.h"
 #include "probe.h"
 
+#include <map>
+
 static struct link_map_offsets *svr4_fetch_link_map_offsets (void);
 static int svr4_have_link_map_offsets (void);
 static void svr4_relocate_main_executable (void);
-static void svr4_free_library_list (void *p_list);
+static void svr4_free_library_list (so_list *solist);
 static void probes_table_remove_objfile_probes (struct objfile *objfile);
 static void svr4_iterate_over_objfiles_in_search_order
   (gdbarch *gdbarch, iterate_over_objfiles_in_search_order_cb_ftype cb,
@@ -174,7 +176,16 @@ svr4_same_1 (const char *gdb_so_name, const char *inferior_so_name)
 static int
 svr4_same (struct so_list *gdb, struct so_list *inferior)
 {
-  return (svr4_same_1 (gdb->so_original_name, inferior->so_original_name));
+  if (!svr4_same_1 (gdb->so_original_name, inferior->so_original_name))
+    return false;
+
+  /* There may be different instances of the same library, in different
+     namespaces.  Each instance, however, must have been loaded at a
+     different address so its relocation offset would be different.  */
+  const lm_info_svr4 *lmg = (const lm_info_svr4 *) gdb->lm_info;
+  const lm_info_svr4 *lmi = (const lm_info_svr4 *) inferior->lm_info;
+
+  return (lmg->l_addr_inferior == lmi->l_addr_inferior);
 }
 
 static std::unique_ptr<lm_info_svr4>
@@ -329,7 +340,7 @@ struct svr4_info
   svr4_info () = default;
   ~svr4_info ();
 
-  /* Base of dynamic linker structures.  */
+  /* Base of dynamic linker structures in default namespace.  */
   CORE_ADDR debug_base = 0;
 
   /* Validity flag for debug_loader_offset.  */
@@ -341,7 +352,7 @@ struct svr4_info
   /* Name of the dynamic linker, valid if debug_loader_offset_p.  */
   char *debug_loader_name = nullptr;
 
-  /* Load map address for the main executable.  */
+  /* Load map address for the main executable in default namespace.  */
   CORE_ADDR main_lm_addr = 0;
 
   CORE_ADDR interp_text_sect_low = 0;
@@ -349,9 +360,9 @@ struct svr4_info
   CORE_ADDR interp_plt_sect_low = 0;
   CORE_ADDR interp_plt_sect_high = 0;
 
-  /* Nonzero if the list of objects was last obtained from the target
+  /* True if the list of objects was last obtained from the target
      via qXfer:libraries-svr4:read.  */
-  int using_xfer = 0;
+  bool using_xfer = false;
 
   /* Table of struct probe_and_action instances, used by the
      probes-based interface to map breakpoint addresses to probes
@@ -359,14 +370,35 @@ struct svr4_info
      probe_and_action->prob->address.  */
   htab_up probes_table;
 
-  /* List of objects loaded into the inferior, used by the probes-
-     based interface.  */
-  struct so_list *solib_list = nullptr;
+  /* List of objects loaded into the inferior per namespace, used by the
+     probes-based interface.
+
+     The namespace is represented by the address of its corresponding
+     r_debug[_ext] object.  We get the namespace id as agrument to the
+     'reloc_complete' probe but we don't get it when scanning the load map
+     on attach.
+
+     The r_debug[_ext] objects may move when ld.so itself moves.  In that
+     case, we expect also the global _r_debug to move so we can detect
+     this and reload everything.  The r_debug[_ext] objects are not
+     expected to move individually.
+
+     The special entry zero is reserved for a linear list to support
+     gdbstubs that do not support namespaces.  */
+  std::map<CORE_ADDR, so_list *> solib_lists;
 };
 
 /* Per-program-space data key.  */
 static const struct program_space_key<svr4_info> solib_svr4_pspace_data;
 
+/* Return whether DEBUG_BASE is the default namespace of INFO.  */
+
+static bool
+svr4_is_default_namespace (const svr4_info *info, CORE_ADDR debug_base)
+{
+  return (debug_base == info->debug_base);
+}
+
 /* Free the probes table.  */
 
 static void
@@ -375,18 +407,21 @@ free_probes_table (struct svr4_info *info)
   info->probes_table.reset (nullptr);
 }
 
-/* Free the solib list.  */
+/* Free the solib lists for all namespaces.  */
 
 static void
-free_solib_list (struct svr4_info *info)
+free_solib_lists (svr4_info *info)
 {
-  svr4_free_library_list (&info->solib_list);
-  info->solib_list = NULL;
+  for (const std::pair<CORE_ADDR, so_list *> tuple
+	 : info->solib_lists)
+    svr4_free_library_list (tuple.second);
+
+  info->solib_lists.clear ();
 }
 
 svr4_info::~svr4_info ()
 {
-  free_solib_list (this);
+  free_solib_lists (this);
 }
 
 /* Get the svr4 data for program space PSPACE.  If none is found yet, add it now.
@@ -731,7 +766,7 @@ elf_locate_base (void)
    RT_CONSISTENT.  */
 
 static CORE_ADDR
-solib_svr4_r_map (struct svr4_info *info)
+solib_svr4_r_map (CORE_ADDR debug_base)
 {
   struct link_map_offsets *lmo = svr4_fetch_link_map_offsets ();
   struct type *ptr_type = builtin_type (target_gdbarch ())->builtin_data_ptr;
@@ -739,7 +774,7 @@ solib_svr4_r_map (struct svr4_info *info)
 
   try
     {
-      addr = read_memory_typed_address (info->debug_base + lmo->r_map_offset,
+      addr = read_memory_typed_address (debug_base + lmo->r_map_offset,
 					ptr_type);
     }
   catch (const gdb_exception_error &ex)
@@ -793,6 +828,35 @@ solib_svr4_r_ldsomap (struct svr4_info *info)
 				    ptr_type);
 }
 
+/* Find the next namespace from the r_next field.  */
+
+static CORE_ADDR
+solib_svr4_r_next (CORE_ADDR debug_base)
+{
+  link_map_offsets *lmo = svr4_fetch_link_map_offsets ();
+  type *ptr_type = builtin_type (target_gdbarch ())->builtin_data_ptr;
+  bfd_endian byte_order = type_byte_order (ptr_type);
+  ULONGEST version = 0;
+
+  try
+    {
+      version
+	= read_memory_unsigned_integer (debug_base + lmo->r_version_offset,
+					lmo->r_version_size, byte_order);
+    }
+  catch (const gdb_exception_error &ex)
+    {
+      exception_print (gdb_stderr, ex);
+    }
+
+  /* The r_next field is added with r_version == 2.  */
+  if (version < 2 || lmo->r_next_offset == -1)
+    return 0;
+
+  return read_memory_typed_address (debug_base + lmo->r_next_offset,
+				    ptr_type);
+}
+
 /* On Solaris systems with some versions of the dynamic linker,
    ld.so's l_name pointer points to the SONAME in the string table
    rather than into writable memory.  So that GDB can find shared
@@ -849,7 +913,7 @@ open_symbol_file_object (int from_tty)
     return 0;	/* failed somehow...  */
 
   /* First link map member should be the executable.  */
-  lm = solib_svr4_r_map (info);
+  lm = solib_svr4_r_map (info->debug_base);
   if (lm == 0)
     return 0;	/* failed somehow...  */
 
@@ -883,11 +947,19 @@ open_symbol_file_object (int from_tty)
 
 struct svr4_library_list
 {
-  struct so_list *head, **tailp;
+  /* The tail pointer of the current namespace.  This is internal to XML
+     parsing.  */
+  so_list **tailp;
 
   /* Inferior address of struct link_map used for the main executable.  It is
      NULL if not known.  */
   CORE_ADDR main_lm;
+
+  /* List of objects loaded into the inferior per namespace.  This does
+     not include any default sos.
+
+     See comment on struct svr4_info.solib_lists.  */
+  std::map<CORE_ADDR, so_list *> solib_lists;
 };
 
 /* This module's 'free_objfile' observer.  */
@@ -919,13 +991,11 @@ svr4_clear_so (struct so_list *so)
     li->l_addr_p = 0;
 }
 
-/* Free so_list built so far (called via cleanup).  */
+/* Free so_list built so far.  */
 
 static void
-svr4_free_library_list (void *p_list)
+svr4_free_library_list (so_list *list)
 {
-  struct so_list *list = *(struct so_list **) p_list;
-
   while (list != NULL)
     {
       struct so_list *next = list->next;
@@ -1022,6 +1092,12 @@ svr4_library_list_start_list (struct gdb_xml_parser *parser,
 
   if (main_lm)
     list->main_lm = *(ULONGEST *) main_lm->value.get ();
+
+  /* Older gdbserver do not support namespaces.  We use the special
+     namespace zero for a linear list of libraries.  */
+  so_list **solist = &list->solib_lists[0];
+  *solist = nullptr;
+  list->tailp = solist;
 }
 
 /* The allowed elements and attributes for an XML library list.
@@ -1069,13 +1145,16 @@ static const struct gdb_xml_element svr4_library_list_elements[] =
 static int
 svr4_parse_libraries (const char *document, struct svr4_library_list *list)
 {
-  auto cleanup = make_scope_exit ([&] ()
+  auto cleanup = make_scope_exit ([list] ()
     {
-      svr4_free_library_list (&list->head);
+      for (const std::pair<CORE_ADDR, so_list *> tuple
+	     : list->solib_lists)
+	svr4_free_library_list (tuple.second);
     });
 
-  memset (list, 0, sizeof (*list));
-  list->tailp = &list->head;
+  list->tailp = nullptr;
+  list->main_lm = 0;
+  list->solib_lists.clear ();
   if (gdb_xml_parse_quick (_("target library list"), "library-list-svr4.dtd",
 			   svr4_library_list_elements, document, list) == 0)
     {
@@ -1141,7 +1220,7 @@ svr4_default_sos (svr4_info *info)
   newobj->lm_info = li;
 
   /* Nothing will ever check the other fields if we set l_addr_p.  */
-  li->l_addr = info->debug_loader_offset;
+  li->l_addr = li->l_addr_inferior = info->debug_loader_offset;
   li->l_addr_p = 1;
 
   strncpy (newobj->so_name, info->debug_loader_name, SO_NAME_MAX_PATH_SIZE - 1);
@@ -1232,17 +1311,18 @@ svr4_read_so_list (svr4_info *info, CORE_ADDR lm, CORE_ADDR prev_lm,
 /* Read the full list of currently loaded shared objects directly
    from the inferior, without referring to any libraries read and
    stored by the probes interface.  Handle special cases relating
-   to the first elements of the list.  */
+   to the first elements of the list in default namespace.  */
 
-static struct so_list *
+static void
 svr4_current_sos_direct (struct svr4_info *info)
 {
   CORE_ADDR lm;
-  struct so_list *head = NULL;
-  struct so_list **link_ptr = &head;
-  int ignore_first;
+  bool ignore_first;
   struct svr4_library_list library_list;
 
+  /* Remove any old libraries.  We're going to read them back in again.  */
+  free_solib_lists (info);
+
   /* Fall back to manual examination of the target if the packet is not
      supported or gdbserver failed to find DT_DEBUG.  gdb.server/solib-list.exp
      tests a case where gdbserver cannot find the shared libraries list while
@@ -1258,49 +1338,110 @@ svr4_current_sos_direct (struct svr4_info *info)
       if (library_list.main_lm)
 	info->main_lm_addr = library_list.main_lm;
 
-      return library_list.head ? library_list.head : svr4_default_sos (info);
+      /* Remove an empty special zero namespace so we know that when there
+	 is one, it is actually used, and we have a flat list without
+	 namespace information.  */
+      if ((library_list.solib_lists.find (0)
+	   != library_list.solib_lists.end ())
+	  && (library_list.solib_lists[0] == nullptr))
+	library_list.solib_lists.erase (0);
+
+      std::swap (info->solib_lists, library_list.solib_lists);
+      return;
     }
 
   /* If we can't find the dynamic linker's base structure, this
      must not be a dynamically linked executable.  Hmm.  */
   info->debug_base = elf_locate_base ();
   if (info->debug_base == 0)
-    return svr4_default_sos (info);
+    return;
 
   /* Assume that everything is a library if the dynamic loader was loaded
      late by a static executable.  */
   if (current_program_space->exec_bfd ()
       && bfd_get_section_by_name (current_program_space->exec_bfd (),
 				  ".dynamic") == NULL)
-    ignore_first = 0;
+    ignore_first = false;
   else
-    ignore_first = 1;
+    ignore_first = true;
 
-  auto cleanup = make_scope_exit ([&] ()
+  auto cleanup = make_scope_exit ([info] ()
     {
-      svr4_free_library_list (&head);
+      free_solib_lists (info);
     });
 
-  /* Walk the inferior's link map list, and build our list of
-     `struct so_list' nodes.  */
-  lm = solib_svr4_r_map (info);
-  if (lm)
-    svr4_read_so_list (info, lm, 0, &link_ptr, ignore_first);
+  /* Collect the sos in each namespace.  */
+  CORE_ADDR debug_base = info->debug_base;
+  for (; debug_base != 0;
+       ignore_first = false, debug_base = solib_svr4_r_next (debug_base))
+    {
+      /* Walk the inferior's link map list, and build our so_list list.  */
+      lm = solib_svr4_r_map (debug_base);
+      if (lm != 0)
+	{
+	  so_list **sos = &info->solib_lists[debug_base];
+	  *sos = nullptr;
+
+	  svr4_read_so_list (info, lm, 0, &sos, ignore_first);
+	}
+    }
 
   /* On Solaris, the dynamic linker is not in the normal list of
      shared objects, so make sure we pick it up too.  Having
      symbol information for the dynamic linker is quite crucial
-     for skipping dynamic linker resolver code.  */
-  lm = solib_svr4_r_ldsomap (info);
-  if (lm)
-    svr4_read_so_list (info, lm, 0, &link_ptr, 0);
+     for skipping dynamic linker resolver code.
+
+     Note that we interpret the ldsomap load map address as 'virtual'
+     r_debug object.  If we added it to the default namespace (as it was),
+     we would probably run into inconsistencies with the load map's
+     prev/next links (I wonder if we did).  */
+  debug_base = solib_svr4_r_ldsomap (info);
+  if (debug_base != 0)
+    {
+      /* Add the dynamic linker's namespace unless we already did.  */
+      if (info->solib_lists.find (debug_base) == info->solib_lists.end ())
+	{
+	  so_list **sos = &info->solib_lists[debug_base];
+	  *sos = nullptr;
+	  svr4_read_so_list (info, debug_base, 0, &sos, 0);
+	}
+    }
 
   cleanup.release ();
+}
 
-  if (head == NULL)
-    return svr4_default_sos (info);
+/* Collect sos read and stored by the probes interface.  */
 
-  return head;
+static so_list *
+svr4_collect_probes_sos (svr4_info *info)
+{
+  so_list *sos = nullptr;
+  so_list **pnext = &sos;
+
+  for (const std::pair<CORE_ADDR, so_list *> tuple
+	 : info->solib_lists)
+    {
+      so_list *solist = tuple.second;
+
+      /* Allow the linker to report empty namespaces.  */
+      if (solist == nullptr)
+	continue;
+
+      *pnext = svr4_copy_library_list (solist);
+
+      /* Update PNEXT to point to the next member of the last element.  */
+      gdb_assert (*pnext != nullptr);
+      for (;;)
+	{
+	  so_list *next = *pnext;
+	  if (next == nullptr)
+	    break;
+
+	  pnext = &next->next;
+	}
+    }
+
+  return sos;
 }
 
 /* Implement the main part of the "current_sos" target_so_ops
@@ -1309,13 +1450,26 @@ svr4_current_sos_direct (struct svr4_info *info)
 static struct so_list *
 svr4_current_sos_1 (svr4_info *info)
 {
-  /* If the solib list has been read and stored by the probes
-     interface then we return a copy of the stored list.  */
-  if (info->solib_list != NULL)
-    return svr4_copy_library_list (info->solib_list);
+  so_list *sos = nullptr;
+
+  /* If we're using the probes interface, we can use the cache as it will
+     be maintained by probe update/reload actions.  */
+  if (info->probes_table != nullptr)
+    sos = svr4_collect_probes_sos (info);
 
-  /* Otherwise obtain the solib list directly from the inferior.  */
-  return svr4_current_sos_direct (info);
+  /* If we're not using the probes interface or if we didn't cache
+     anything, read the sos to fill the cache, then collect them from the
+     cache.  */
+  if (sos == nullptr)
+    {
+      svr4_current_sos_direct (info);
+
+      sos = svr4_collect_probes_sos (info);
+      if (sos == nullptr)
+	sos = svr4_default_sos (info);
+    }
+
+  return sos;
 }
 
 /* Implement the "current_sos" target_so_ops method.  */
@@ -1649,8 +1803,7 @@ solib_event_probe_action (struct probe_and_action *pa)
 static int
 solist_update_full (struct svr4_info *info)
 {
-  free_solib_list (info);
-  info->solib_list = svr4_current_sos_direct (info);
+  svr4_current_sos_direct (info);
 
   return 1;
 }
@@ -1661,29 +1814,51 @@ solist_update_full (struct svr4_info *info)
    failure.  */
 
 static int
-solist_update_incremental (struct svr4_info *info, CORE_ADDR lm)
+solist_update_incremental (svr4_info *info, CORE_ADDR debug_base,
+			   CORE_ADDR lm)
 {
-  struct so_list *tail;
-  CORE_ADDR prev_lm;
-
-  /* svr4_current_sos_direct contains logic to handle a number of
-     special cases relating to the first elements of the list.  To
-     avoid duplicating this logic we defer to solist_update_full
-     if the list is empty.  */
-  if (info->solib_list == NULL)
-    return 0;
-
   /* Fall back to a full update if we are using a remote target
      that does not support incremental transfers.  */
   if (info->using_xfer && !target_augmented_libraries_svr4_read ())
     return 0;
 
-  /* Walk to the end of the list.  */
-  for (tail = info->solib_list; tail->next != NULL; tail = tail->next)
-    /* Nothing.  */;
+  /* Fall back to a full update if we used the special namespace zero.  We
+     wouldn't be able to find the last item in the DEBUG_BASE namespace
+     and hence get the prev link wrong.  */
+  if (info->solib_lists.find (0) != info->solib_lists.end ())
+    return 0;
+
+  /* Ensure that the element is actually initialized.  */
+  if (info->solib_lists.find (debug_base) == info->solib_lists.end ())
+    info->solib_lists[debug_base] = nullptr;
+
+  so_list **psolist = &info->solib_lists[debug_base];
+  so_list **pnext = nullptr;
+  so_list *solist = *psolist;
+  CORE_ADDR prev_lm;
+
+  if (solist == nullptr)
+    {
+      /* svr4_current_sos_direct contains logic to handle a number of
+	 special cases relating to the first elements of the list in
+	 default namespace.  To avoid duplicating this logic we defer to
+	 solist_update_full in this case.  */
+      if (svr4_is_default_namespace (info, debug_base))
+	return 0;
+
+      prev_lm = 0;
+      pnext = psolist;
+    }
+  else
+    {
+      /* Walk to the end of the list.  */
+      for (; solist->next != nullptr; solist = solist->next)
+	/* Nothing.  */;
 
-  lm_info_svr4 *li = (lm_info_svr4 *) tail->lm_info;
-  prev_lm = li->lm_addr;
+      lm_info_svr4 *li = (lm_info_svr4 *) solist->lm_info;
+      prev_lm = li->lm_addr;
+      pnext = &solist->next;
+    }
 
   /* Read the new objects.  */
   if (info->using_xfer)
@@ -1697,17 +1872,34 @@ solist_update_incremental (struct svr4_info *info, CORE_ADDR lm)
       if (!svr4_current_sos_via_xfer_libraries (&library_list, annex))
 	return 0;
 
-      tail->next = library_list.head;
+      /* We expect gdbserver to provide updates for the namespace that
+	 contains LM, which whould be this namespace...  */
+      so_list *sos = nullptr;
+      if (library_list.solib_lists.find (debug_base)
+	  != library_list.solib_lists.end ())
+	std::swap (sos, library_list.solib_lists[debug_base]);
+      if (sos == nullptr)
+	{
+	  /* ...or for the special zero namespace for earlier versions...  */
+	  if (library_list.solib_lists.find (0)
+	      != library_list.solib_lists.end ())
+	    std::swap (sos, library_list.solib_lists[0]);
+	}
+
+      /* ...but nothing else.  */
+      for (const std::pair<CORE_ADDR, so_list *> tuple
+	     : library_list.solib_lists)
+	gdb_assert (tuple.second == nullptr);
+
+      *pnext = sos;
     }
   else
     {
-      struct so_list **link = &tail->next;
-
       /* IGNORE_FIRST may safely be set to zero here because the
 	 above check and deferral to solist_update_full ensures
 	 that this call to svr4_read_so_list will never see the
 	 first element.  */
-      if (!svr4_read_so_list (info, lm, prev_lm, &link, 0))
+      if (!svr4_read_so_list (info, lm, prev_lm, &pnext, 0))
 	return 0;
     }
 
@@ -1725,7 +1917,7 @@ disable_probes_interface (svr4_info *info)
 	     "Reverting to original interface."));
 
   free_probes_table (info);
-  free_solib_list (info);
+  free_solib_lists (info);
 }
 
 /* Update the solib list as appropriate when using the
@@ -1799,8 +1991,16 @@ svr4_handle_solib_event (void)
     if (debug_base == 0)
       return;
 
-    /* Always locate the debug struct, in case it moved.  */
-    info->debug_base = elf_locate_base ();
+    /* If the global _r_debug object moved, we need to reload everything
+       since we cannot identify namespaces (by the location of their
+       r_debug_ext object) anymore.  */
+    CORE_ADDR global_debug_base = elf_locate_base ();
+    if (global_debug_base != info->debug_base)
+      {
+	info->debug_base = global_debug_base;
+	action = FULL_RELOAD;
+      }
+
     if (info->debug_base == 0)
       {
 	/* It's possible for the reloc_complete probe to be triggered before
@@ -1824,13 +2024,6 @@ svr4_handle_solib_event (void)
 	  return;
       }
 
-    /* GDB does not currently support libraries loaded via dlmopen
-       into namespaces other than the initial one.  We must ignore
-       any namespace other than the initial namespace here until
-       support for this is added to GDB.  */
-    if (debug_base != info->debug_base)
-      action = DO_NOTHING;
-
     if (action == UPDATE_OR_RELOAD)
       {
 	try
@@ -1856,7 +2049,7 @@ svr4_handle_solib_event (void)
 
   if (action == UPDATE_OR_RELOAD)
     {
-      if (!solist_update_incremental (info, lm))
+      if (!solist_update_incremental (info, debug_base, lm))
 	action = FULL_RELOAD;
     }
 
@@ -2091,7 +2284,7 @@ enable_break (struct svr4_info *info, int from_tty)
 
   solib_add (NULL, from_tty, auto_solib_add);
   sym_addr = 0;
-  if (info->debug_base && solib_svr4_r_map (info) != 0)
+  if (info->debug_base && solib_svr4_r_map (info->debug_base) != 0)
     sym_addr = solib_svr4_r_brk (info);
 
   if (sym_addr != 0)
@@ -2887,7 +3080,7 @@ svr4_solib_create_inferior_hook (int from_tty)
 
   /* Clear the probes-based interface's state.  */
   free_probes_table (info);
-  free_solib_list (info);
+  free_solib_lists (info);
 
   /* Relocate the main executable if necessary.  */
   svr4_relocate_main_executable ();
@@ -3042,6 +3235,7 @@ svr4_ilp32_fetch_link_map_offsets (void)
       lmo.r_map_offset = 4;
       lmo.r_brk_offset = 8;
       lmo.r_ldsomap_offset = 20;
+      lmo.r_next_offset = -1;
 
       /* Everything we need is in the first 20 bytes.  */
       lmo.link_map_size = 20;
@@ -3073,6 +3267,7 @@ svr4_lp64_fetch_link_map_offsets (void)
       lmo.r_map_offset = 8;
       lmo.r_brk_offset = 16;
       lmo.r_ldsomap_offset = 40;
+      lmo.r_next_offset = -1;
 
       /* Everything we need is in the first 40 bytes.  */
       lmo.link_map_size = 40;
diff --git a/gdb/solib-svr4.h b/gdb/solib-svr4.h
index 8b4968509f2..c7ea156989b 100644
--- a/gdb/solib-svr4.h
+++ b/gdb/solib-svr4.h
@@ -66,6 +66,9 @@ struct link_map_offsets
     /* Offset of r_debug.r_ldsomap.  */
     int r_ldsomap_offset;
 
+    /* Offset of r_debug_extended.r_next.  */
+    int r_next_offset;
+
     /* Size of struct link_map (or equivalent), or at least enough of it
        to be able to obtain the fields below.  */
     int link_map_size;
diff --git a/gdb/testsuite/gdb.base/dlmopen-lib.c b/gdb/testsuite/gdb.base/dlmopen-lib.c
new file mode 100644
index 00000000000..616bf97b4f5
--- /dev/null
+++ b/gdb/testsuite/gdb.base/dlmopen-lib.c
@@ -0,0 +1,25 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2021-2022 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+__attribute__((visibility ("default")))
+int
+inc (int n)
+{
+  return n + 1;  /* bp.inc.  */
+}
diff --git a/gdb/testsuite/gdb.base/dlmopen.c b/gdb/testsuite/gdb.base/dlmopen.c
new file mode 100644
index 00000000000..2dc2f2e6d03
--- /dev/null
+++ b/gdb/testsuite/gdb.base/dlmopen.c
@@ -0,0 +1,65 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2021 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#define _GNU_SOURCE
+#include <dlfcn.h>
+#include <stddef.h>
+#include <assert.h>
+#include <unistd.h>
+
+volatile int wait_for_gdb = 1;
+
+int
+main (void)
+{
+  void *handle[4];
+  int (*fun) (int);
+  Lmid_t lmid;
+  int dl;
+
+  handle[0] = dlmopen (LM_ID_NEWLM, DSO1_NAME, RTLD_LAZY | RTLD_LOCAL);
+  assert (handle[0] != NULL);
+
+  dlinfo (handle[0], RTLD_DI_LMID, &lmid);
+
+  handle[1] = dlopen (DSO1_NAME, RTLD_LAZY | RTLD_LOCAL);
+  assert (handle[1] != NULL);
+
+  handle[2] = dlmopen (LM_ID_NEWLM, DSO1_NAME, RTLD_LAZY | RTLD_LOCAL);
+  assert (handle[2] != NULL);
+
+  handle[3] = dlmopen (lmid, DSO2_NAME, RTLD_LAZY | RTLD_LOCAL);
+  assert (handle[3] != NULL);
+
+  alarm (20);
+  while (wait_for_gdb != 0)
+    usleep (1);
+
+  for (dl = 0; dl < 4; ++dl)
+    {
+      fun = dlsym (handle[dl], "inc");
+      assert (fun != NULL);
+
+      fun (42);
+
+      dlclose (handle[dl]);
+    }
+
+  return 0;  /* bp.main  */
+}
diff --git a/gdb/testsuite/gdb.base/dlmopen.exp b/gdb/testsuite/gdb.base/dlmopen.exp
new file mode 100644
index 00000000000..8e86d5d5ccc
--- /dev/null
+++ b/gdb/testsuite/gdb.base/dlmopen.exp
@@ -0,0 +1,150 @@
+# This testcase is part of GDB, the GNU debugger.
+#
+# Copyright 2021-2022 Free Software Foundation, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+#
+# Test shared libraries loaded into different namespaces with dlmopen().
+#
+# We test that GDB shows the correct number of instances of the libraries
+# the test loaded while unloading them one-by-one.
+
+if { [skip_dlmopen_tests] } {
+    unsupported "target does not support dlmopen debugging"
+    return -1
+}
+
+standard_testfile
+
+set basename_lib dlmopen-lib
+set srcfile_lib $srcdir/$subdir/$basename_lib.c
+set binfile_lib1 [standard_output_file $basename_lib.1.so]
+set binfile_lib2 [standard_output_file $basename_lib.2.so]
+
+if { [gdb_compile_shlib $srcfile_lib $binfile_lib1 {debug}] != "" } {
+    untested "failed to prepare shlib"
+    return -1
+}
+
+if { [gdb_compile_shlib $srcfile_lib $binfile_lib2 {debug}] != "" } {
+    untested "failed to prepare shlib"
+    return -1
+}
+
+if { [prepare_for_testing "failed to prepare" $testfile $srcfile \
+	  [list additional_flags=-DDSO1_NAME=\"$binfile_lib1\" \
+	       additional_flags=-DDSO2_NAME=\"$binfile_lib2\" \
+	       libs=-ldl debug]] } {
+    return -1
+}
+
+if { ![runto_main] } {
+    return -1
+}
+
+# Check that 'info shared' show NUM occurrences of DSO.
+proc check_dso_count { dso num } {
+    global gdb_prompt hex
+
+    set count 0
+    gdb_test_multiple "info shared" "info shared" {
+	-re "$hex  $hex  Yes \[^\r\n\]*$dso\r\n" {
+	    # use longer form so debug remote does not interfere
+	    set count [expr $count + 1]
+	    exp_continue
+	}
+	-re "$gdb_prompt " {
+	    verbose -log "library: $dso, expected: $num, found: $count"
+	    gdb_assert {$count == $num} "$gdb_test_name"
+	}
+    }
+}
+
+# The DSO part of the test.  We run it once per DSO call.
+proc test_dlmopen_one { ndso1 ndso2 } {
+    global srcfile_lib srcfile_lib basename_lib bp_inc
+
+    # Try to reach the breakpoint in the dynamically loaded library.
+    gdb_continue_to_breakpoint "cont to bp.inc" \
+	".*$srcfile_lib:$bp_inc\r\n.*"
+
+    # We opened all DSOs initially and close them one by one.
+    with_test_prefix "dso 1" { check_dso_count $basename_lib.1.so $ndso1 }
+    with_test_prefix "dso 2" { check_dso_count $basename_lib.2.so $ndso2 }
+
+    # This might help debugging.
+    gdb_test "info breakpoints" ".*"
+    gdb_test "print \$pc" ".*"
+}
+
+# The actual test.  We run it twice.
+proc test_dlmopen {} {
+    global srcfile basename_lib bp_main
+
+    with_test_prefix "dlmopen 1" { test_dlmopen_one 3 1 }
+    with_test_prefix "dlmopen 2" { test_dlmopen_one 2 1 }
+    with_test_prefix "dlmopen 3" { test_dlmopen_one 1 1 }
+    with_test_prefix "dlmopen 4" { test_dlmopen_one 0 1 }
+
+    with_test_prefix "main" {
+	# Try to reach the breakpoint in the dynamically loaded library.
+	gdb_continue_to_breakpoint "cont to bp.main" \
+	    ".*$srcfile:$bp_main\r\n.*"
+
+	# The library should not be listed.
+	with_test_prefix "dso 1" { check_dso_count $basename_lib.1.so 0 }
+	with_test_prefix "dso 2" { check_dso_count $basename_lib.2.so 0 }
+    }
+}
+
+# Remove the pause.  We only need it for the attach test.
+gdb_test "print wait_for_gdb = 0" "\\\$1 = 0"
+
+# Break in the to-be-loaded library and at the end of main.
+set bp_inc [gdb_get_line_number "bp.inc" $srcfile_lib]
+set bp_main [gdb_get_line_number "bp.main" $srcfile]
+
+delete_breakpoints
+gdb_breakpoint $srcfile_lib:$bp_inc allow-pending
+gdb_breakpoint $srcfile:$bp_main
+
+test_dlmopen
+
+# Try the same again when attaching after dlmopen().
+if { ![can_spawn_for_attach] } {
+    unsupported "target does not support attach"
+    return -1
+}
+
+clean_restart $binfile
+
+# Start the test program.
+set test_spawn_id [spawn_wait_for_attach $binfile]
+set testpid [spawn_id_get_pid $test_spawn_id]
+
+# Attach.
+gdb_test "attach $testpid" "Attaching to program.*, process $testpid.*"
+
+with_test_prefix "attach" {
+    # Remove the pause.  We no longer need it.
+    gdb_test "print wait_for_gdb = 0" "\\\$1 = 0"
+
+    # Set the same breakpoints again.  This time, however, we do not allow the
+    # breakpoint to be pending since the library has already been loaded.
+    gdb_breakpoint $srcfile_lib:$bp_inc
+    gdb_breakpoint $srcfile:$bp_main
+
+    test_dlmopen
+}
diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp
index 6aef39e5e02..98715fdc87e 100644
--- a/gdb/testsuite/lib/gdb.exp
+++ b/gdb/testsuite/lib/gdb.exp
@@ -2451,6 +2451,102 @@ proc skip_shlib_tests {} {
     return 1
 }
 
+# Return 1 if we should skip dlmopen tests, 0 if we should not.
+
+proc skip_dlmopen_tests {} {
+    global srcdir subdir gdb_prompt inferior_exited_re
+
+    # We need shared library support.
+    if { [skip_shlib_tests] } {
+	return 1
+    }
+
+    set me "skip_dlmopen_tests"
+    set lib {
+	int foo (void) {
+	    return 42;
+	}
+    }
+    set src {
+	#define _GNU_SOURCE
+	#include <dlfcn.h>
+	#include <link.h>
+	#include <stdio.h>
+	#include <errno.h>
+
+	int  main (void) {
+	    struct r_debug *r_debug;
+	    ElfW(Dyn) *dyn;
+	    void *handle;
+
+	    /* The version is kept at 1 until we create a new namespace.  */
+	    handle = dlmopen (LM_ID_NEWLM, DSO_NAME, RTLD_LAZY | RTLD_LOCAL);
+	    if (!handle) {
+		printf ("dlmopen failed: %s.\n", dlerror ());
+		return 1;
+	    }
+
+	    r_debug = 0;
+	    /* Taken from /usr/include/link.h.  */
+	    for (dyn = _DYNAMIC; dyn->d_tag != DT_NULL; ++dyn)
+	        if (dyn->d_tag == DT_DEBUG)
+	            r_debug = (struct r_debug *) dyn->d_un.d_ptr;
+
+	    if (!r_debug) {
+	        printf ("r_debug not found.\n");
+		return 1;
+	    }
+	    if (r_debug->r_version < 2) {
+	        printf ("dlmopen debug not supported.\n");
+		return 1;
+	    }
+	    printf ("dlmopen debug supported.\n");
+	    return 0;
+	}
+    }
+
+    set libsrc [standard_temp_file "libfoo.c"]
+    set libout [standard_temp_file "libfoo.so"]
+    gdb_produce_source $libsrc $lib
+
+    if { [gdb_compile_shlib $libsrc $libout {debug}] != "" } {
+	verbose -log "failed to build library"
+	return 1
+    }
+    if { ![gdb_simple_compile $me $src executable \
+	       [list shlib_load debug \
+		    additional_flags=-DDSO_NAME=\"$libout\"]] } {
+	verbose -log "failed to build executable"
+        return 1
+    }
+
+    gdb_exit
+    gdb_start
+    gdb_reinitialize_dir $srcdir/$subdir
+    gdb_load $obj
+
+    if { [gdb_run_cmd] != 0 } {
+	verbose -log "failed to start skip test"
+	return 1
+    }
+    gdb_expect {
+        -re "$inferior_exited_re normally.*${gdb_prompt} $" {
+            set skip_dlmopen_tests 0
+        }
+        -re "$inferior_exited_re with code.*${gdb_prompt} $" {
+            set skip_dlmopen_tests 1
+        }
+        default {
+	    warning "\n$me: default case taken"
+            set skip_dlmopen_tests 1
+        }
+    }
+    gdb_exit
+
+    verbose "$me:  returning $skip_dlmopen_tests" 2
+    return $skip_dlmopen_tests
+}
+
 # Return 1 if we should skip tui related tests.
 
 proc skip_tui_tests {} {
diff --git a/gdbserver/linux-low.cc b/gdbserver/linux-low.cc
index 8b8614f6ed4..d765139e816 100644
--- a/gdbserver/linux-low.cc
+++ b/gdbserver/linux-low.cc
@@ -6435,6 +6435,9 @@ struct link_map_offsets
     /* Offset and size of r_debug.r_map.  */
     int r_map_offset;
 
+    /* Offset of r_debug_extended.r_next.  */
+    int r_next_offset;
+
     /* Offset to l_addr field in struct link_map.  */
     int l_addr_offset;
 
@@ -6451,6 +6454,98 @@ struct link_map_offsets
     int l_prev_offset;
   };
 
+static const link_map_offsets lmo_32bit_offsets =
+  {
+    0,     /* r_version offset.  */
+    4,     /* r_debug.r_map offset.  */
+    20,    /* r_debug_extended.r_next.  */
+    0,     /* l_addr offset in link_map.  */
+    4,     /* l_name offset in link_map.  */
+    8,     /* l_ld offset in link_map.  */
+    12,    /* l_next offset in link_map.  */
+    16     /* l_prev offset in link_map.  */
+  };
+
+static const link_map_offsets lmo_64bit_offsets =
+  {
+    0,     /* r_version offset.  */
+    8,     /* r_debug.r_map offset.  */
+    40,    /* r_debug_extended.r_next.  */
+    0,     /* l_addr offset in link_map.  */
+    8,     /* l_name offset in link_map.  */
+    16,    /* l_ld offset in link_map.  */
+    24,    /* l_next offset in link_map.  */
+    32     /* l_prev offset in link_map.  */
+  };
+
+/* Get the loaded shared libraries from one namespace.  */
+
+static void
+read_link_map (std::string &document, CORE_ADDR lm_addr, CORE_ADDR lm_prev,
+	       int ptr_size, const link_map_offsets *lmo, bool ignore_first,
+	       int &header_done)
+{
+  CORE_ADDR l_name, l_addr, l_ld, l_next, l_prev;
+
+  while (lm_addr
+	 && read_one_ptr (lm_addr + lmo->l_name_offset,
+			  &l_name, ptr_size) == 0
+	 && read_one_ptr (lm_addr + lmo->l_addr_offset,
+			  &l_addr, ptr_size) == 0
+	 && read_one_ptr (lm_addr + lmo->l_ld_offset,
+			  &l_ld, ptr_size) == 0
+	 && read_one_ptr (lm_addr + lmo->l_prev_offset,
+			  &l_prev, ptr_size) == 0
+	 && read_one_ptr (lm_addr + lmo->l_next_offset,
+			  &l_next, ptr_size) == 0)
+    {
+      unsigned char libname[PATH_MAX];
+
+      if (lm_prev != l_prev)
+	{
+	  warning ("Corrupted shared library list: 0x%s != 0x%s",
+		   paddress (lm_prev), paddress (l_prev));
+	  break;
+	}
+
+      /* Ignore the first entry even if it has valid name as the first entry
+	 corresponds to the main executable.  The first entry should not be
+	 skipped if the dynamic loader was loaded late by a static executable
+	 (see solib-svr4.c parameter ignore_first).  But in such case the main
+	 executable does not have PT_DYNAMIC present and this function already
+	 exited above due to failed get_r_debug.  */
+      if (ignore_first && lm_prev == 0)
+	string_appendf (document, " main-lm=\"0x%s\"", paddress (lm_addr));
+      else
+	{
+	  /* Not checking for error because reading may stop before
+	     we've got PATH_MAX worth of characters.  */
+	  libname[0] = '\0';
+	  linux_read_memory (l_name, libname, sizeof (libname) - 1);
+	  libname[sizeof (libname) - 1] = '\0';
+	  if (libname[0] != '\0')
+	    {
+	      if (!header_done)
+		{
+		  /* Terminate `<library-list-svr4'.  */
+		  document += '>';
+		  header_done = 1;
+		}
+
+	      string_appendf (document, "<library name=\"");
+	      xml_escape_text_append (&document, (char *) libname);
+	      string_appendf (document, "\" lm=\"0x%s\" l_addr=\"0x%s\" "
+			      "l_ld=\"0x%s\"/>",
+			      paddress (lm_addr), paddress (l_addr),
+			      paddress (l_ld));
+	    }
+	}
+
+      lm_prev = lm_addr;
+      lm_addr = l_next;
+    }
+}
+
 /* Construct qXfer:libraries-svr4:read reply.  */
 
 int
@@ -6462,33 +6557,8 @@ linux_process_target::qxfer_libraries_svr4 (const char *annex,
   struct process_info_private *const priv = current_process ()->priv;
   char filename[PATH_MAX];
   int pid, is_elf64;
-
-  static const struct link_map_offsets lmo_32bit_offsets =
-    {
-      0,     /* r_version offset. */
-      4,     /* r_debug.r_map offset.  */
-      0,     /* l_addr offset in link_map.  */
-      4,     /* l_name offset in link_map.  */
-      8,     /* l_ld offset in link_map.  */
-      12,    /* l_next offset in link_map.  */
-      16     /* l_prev offset in link_map.  */
-    };
-
-  static const struct link_map_offsets lmo_64bit_offsets =
-    {
-      0,     /* r_version offset. */
-      8,     /* r_debug.r_map offset.  */
-      0,     /* l_addr offset in link_map.  */
-      8,     /* l_name offset in link_map.  */
-      16,    /* l_ld offset in link_map.  */
-      24,    /* l_next offset in link_map.  */
-      32     /* l_prev offset in link_map.  */
-    };
-  const struct link_map_offsets *lmo;
   unsigned int machine;
-  int ptr_size;
   CORE_ADDR lm_addr = 0, lm_prev = 0;
-  CORE_ADDR l_name, l_addr, l_ld, l_next, l_prev;
   int header_done = 0;
 
   if (writebuf != NULL)
@@ -6499,8 +6569,18 @@ linux_process_target::qxfer_libraries_svr4 (const char *annex,
   pid = lwpid_of (current_thread);
   xsnprintf (filename, sizeof filename, "/proc/%d/exe", pid);
   is_elf64 = elf_64_file_p (filename, &machine);
-  lmo = is_elf64 ? &lmo_64bit_offsets : &lmo_32bit_offsets;
-  ptr_size = is_elf64 ? 8 : 4;
+  const link_map_offsets *lmo;
+  int ptr_size;
+  if (is_elf64)
+    {
+      lmo = &lmo_64bit_offsets;
+      ptr_size = 8;
+    }
+  else
+    {
+      lmo = &lmo_32bit_offsets;
+      ptr_size = 4;
+    }
 
   while (annex[0] != '\0')
     {
@@ -6529,95 +6609,74 @@ linux_process_target::qxfer_libraries_svr4 (const char *annex,
       annex = decode_address_to_semicolon (addrp, sep + 1);
     }
 
-  if (lm_addr == 0)
+  std::string document = "<library-list-svr4 version=\"1.0\"";
+
+  /* When the starting LM_ADDR is passed in the annex, only traverse that
+     namespace.
+
+     Otherwise, start with R_DEBUG and traverse all namespaces we find.  */
+  if (lm_addr != 0)
+    read_link_map (document, lm_addr, lm_prev, ptr_size, lmo, false,
+		   header_done);
+  else
     {
-      int r_version = 0;
+      if (lm_prev != 0)
+	warning ("ignoring prev=0x%s without start", paddress (lm_prev));
 
-      if (priv->r_debug == 0)
-	priv->r_debug = get_r_debug (pid, is_elf64);
+      CORE_ADDR r_debug = priv->r_debug;
+      if (r_debug == 0)
+	r_debug = priv->r_debug = get_r_debug (pid, is_elf64);
 
       /* We failed to find DT_DEBUG.  Such situation will not change
 	 for this inferior - do not retry it.  Report it to GDB as
 	 E01, see for the reasons at the GDB solib-svr4.c side.  */
-      if (priv->r_debug == (CORE_ADDR) -1)
+      if (r_debug == (CORE_ADDR) -1)
 	return -1;
 
-      if (priv->r_debug != 0)
+      bool ignore_first = true;
+      while (r_debug != 0)
 	{
-	  if (linux_read_memory (priv->r_debug + lmo->r_version_offset,
+	  int r_version = 0;
+	  if (linux_read_memory (r_debug + lmo->r_version_offset,
 				 (unsigned char *) &r_version,
-				 sizeof (r_version)) != 0
-	      || r_version < 1)
+				 sizeof (r_version)) != 0)
+	    {
+	      warning ("unable to read r_version from 0x%s",
+		       paddress (r_debug + lmo->r_version_offset));
+	      break;
+	    }
+
+	  if (r_version < 1)
 	    {
 	      warning ("unexpected r_debug version %d", r_version);
+	      break;
 	    }
-	  else if (read_one_ptr (priv->r_debug + lmo->r_map_offset,
-				 &lm_addr, ptr_size) != 0)
+
+	  if (read_one_ptr (r_debug + lmo->r_map_offset, &lm_addr,
+			    ptr_size) != 0)
 	    {
-	      warning ("unable to read r_map from 0x%lx",
-		       (long) priv->r_debug + lmo->r_map_offset);
+	      warning ("unable to read r_map from 0x%s",
+		       paddress (r_debug + lmo->r_map_offset));
+	      break;
 	    }
-	}
-    }
 
-  std::string document = "<library-list-svr4 version=\"1.0\"";
+	  read_link_map (document, lm_addr, 0, ptr_size, lmo,
+			 ignore_first, header_done);
 
-  while (lm_addr
-	 && read_one_ptr (lm_addr + lmo->l_name_offset,
-			  &l_name, ptr_size) == 0
-	 && read_one_ptr (lm_addr + lmo->l_addr_offset,
-			  &l_addr, ptr_size) == 0
-	 && read_one_ptr (lm_addr + lmo->l_ld_offset,
-			  &l_ld, ptr_size) == 0
-	 && read_one_ptr (lm_addr + lmo->l_prev_offset,
-			  &l_prev, ptr_size) == 0
-	 && read_one_ptr (lm_addr + lmo->l_next_offset,
-			  &l_next, ptr_size) == 0)
-    {
-      unsigned char libname[PATH_MAX];
+	  if (r_version < 2)
+	    break;
 
-      if (lm_prev != l_prev)
-	{
-	  warning ("Corrupted shared library list: 0x%lx != 0x%lx",
-		   (long) lm_prev, (long) l_prev);
-	  break;
-	}
+	  /* Only applies to the default namespace.  */
+	  ignore_first = false;
 
-      /* Ignore the first entry even if it has valid name as the first entry
-	 corresponds to the main executable.  The first entry should not be
-	 skipped if the dynamic loader was loaded late by a static executable
-	 (see solib-svr4.c parameter ignore_first).  But in such case the main
-	 executable does not have PT_DYNAMIC present and this function already
-	 exited above due to failed get_r_debug.  */
-      if (lm_prev == 0)
-	string_appendf (document, " main-lm=\"0x%lx\"", (unsigned long) lm_addr);
-      else
-	{
-	  /* Not checking for error because reading may stop before
-	     we've got PATH_MAX worth of characters.  */
-	  libname[0] = '\0';
-	  linux_read_memory (l_name, libname, sizeof (libname) - 1);
-	  libname[sizeof (libname) - 1] = '\0';
-	  if (libname[0] != '\0')
+	  if (read_one_ptr (r_debug + lmo->r_next_offset, &r_debug,
+			    ptr_size) != 0)
 	    {
-	      if (!header_done)
-		{
-		  /* Terminate `<library-list-svr4'.  */
-		  document += '>';
-		  header_done = 1;
-		}
-
-	      string_appendf (document, "<library name=\"");
-	      xml_escape_text_append (&document, (char *) libname);
-	      string_appendf (document, "\" lm=\"0x%lx\" "
-			      "l_addr=\"0x%lx\" l_ld=\"0x%lx\"/>",
-			      (unsigned long) lm_addr, (unsigned long) l_addr,
-			      (unsigned long) l_ld);
+	      warning ("unable to read r_next from 0x%s",
+		       paddress (r_debug + lmo->r_next_offset));
+	      break;
 	    }
 	}
-
-      lm_prev = lm_addr;
-      lm_addr = l_next;
     }
 
   if (!header_done)
-- 
2.35.3

Intel Deutschland GmbH
Registered Address: Am Campeon 10, 85579 Neubiberg, Germany
Tel: +49 89 99 8853-0, www.intel.de <http://www.intel.de>
Managing Directors: Christin Eisenschmid, Sharon Heck, Tiffany Doon Silva  
Chairperson of the Supervisory Board: Nicole Lau
Registered Office: Munich
Commercial Register: Amtsgericht Muenchen HRB 186928


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

* [PATCH v5 04/15] gdbserver: move main_lm handling into caller
  2022-06-02 13:24 [PATCH v5 00/15] basic linker namespace support Markus Metzger
                   ` (2 preceding siblings ...)
  2022-06-02 13:25 ` [PATCH v5 03/15] gdb, gdbserver: support dlmopen() Markus Metzger
@ 2022-06-02 13:25 ` Markus Metzger
  2022-06-19  4:22   ` Kevin Buettner
  2022-06-02 13:25 ` [PATCH v5 05/15] gdb, gdbserver: extend RSP to support namespaces Markus Metzger
                   ` (11 subsequent siblings)
  15 siblings, 1 reply; 52+ messages in thread
From: Markus Metzger @ 2022-06-02 13:25 UTC (permalink / raw)
  To: gdb-patches

When listing SVR4 shared libraries, special care has to be taken about the
first library in the default namespace as that refers to the main
executable.  The load map address of this main executable is provided in
an attribute of the library-list-svr4 element.

Move that code from where we enumerate libraries inside a single namespace
to where we generate the rest of the library-list-svr4 element.  This
allows us to complete the library-list-svr4 element inside one function.

There should be no functional change.
---
 gdbserver/linux-low.cc | 96 +++++++++++++++++++++---------------------
 1 file changed, 48 insertions(+), 48 deletions(-)

diff --git a/gdbserver/linux-low.cc b/gdbserver/linux-low.cc
index d765139e816..4b4d38b75bc 100644
--- a/gdbserver/linux-low.cc
+++ b/gdbserver/linux-low.cc
@@ -6482,8 +6482,7 @@ static const link_map_offsets lmo_64bit_offsets =
 
 static void
 read_link_map (std::string &document, CORE_ADDR lm_addr, CORE_ADDR lm_prev,
-	       int ptr_size, const link_map_offsets *lmo, bool ignore_first,
-	       int &header_done)
+	       int ptr_size, const link_map_offsets *lmo)
 {
   CORE_ADDR l_name, l_addr, l_ld, l_next, l_prev;
 
@@ -6508,37 +6507,19 @@ read_link_map (std::string &document, CORE_ADDR lm_addr, CORE_ADDR lm_prev,
 	  break;
 	}
 
-      /* Ignore the first entry even if it has valid name as the first entry
-	 corresponds to the main executable.  The first entry should not be
-	 skipped if the dynamic loader was loaded late by a static executable
-	 (see solib-svr4.c parameter ignore_first).  But in such case the main
-	 executable does not have PT_DYNAMIC present and this function already
-	 exited above due to failed get_r_debug.  */
-      if (ignore_first && lm_prev == 0)
-	string_appendf (document, " main-lm=\"0x%s\"", paddress (lm_addr));
-      else
+      /* Not checking for error because reading may stop before we've got
+	 PATH_MAX worth of characters.  */
+      libname[0] = '\0';
+      linux_read_memory (l_name, libname, sizeof (libname) - 1);
+      libname[sizeof (libname) - 1] = '\0';
+      if (libname[0] != '\0')
 	{
-	  /* Not checking for error because reading may stop before
-	     we've got PATH_MAX worth of characters.  */
-	  libname[0] = '\0';
-	  linux_read_memory (l_name, libname, sizeof (libname) - 1);
-	  libname[sizeof (libname) - 1] = '\0';
-	  if (libname[0] != '\0')
-	    {
-	      if (!header_done)
-		{
-		  /* Terminate `<library-list-svr4'.  */
-		  document += '>';
-		  header_done = 1;
-		}
-
-	      string_appendf (document, "<library name=\"");
-	      xml_escape_text_append (&document, (char *) libname);
-	      string_appendf (document, "\" lm=\"0x%s\" l_addr=\"0x%s\" "
-			      "l_ld=\"0x%s\"/>",
-			      paddress (lm_addr), paddress (l_addr),
-			      paddress (l_ld));
-	    }
+	  string_appendf (document, "<library name=\"");
+	  xml_escape_text_append (&document, (char *) libname);
+	  string_appendf (document, "\" lm=\"0x%s\" l_addr=\"0x%s\" "
+			  "l_ld=\"0x%s\"/>",
+			  paddress (lm_addr), paddress (l_addr),
+			  paddress (l_ld));
 	}
 
       lm_prev = lm_addr;
@@ -6559,7 +6540,6 @@ linux_process_target::qxfer_libraries_svr4 (const char *annex,
   int pid, is_elf64;
   unsigned int machine;
   CORE_ADDR lm_addr = 0, lm_prev = 0;
-  int header_done = 0;
 
   if (writebuf != NULL)
     return -2;
@@ -6616,8 +6596,10 @@ linux_process_target::qxfer_libraries_svr4 (const char *annex,
 
      Otherwise, start with R_DEBUG and traverse all namespaces we find.  */
   if (lm_addr != 0)
-    read_link_map (document, lm_addr, lm_prev, ptr_size, lmo, false,
-		   header_done);
+    {
+      document += ">";
+      read_link_map (document, lm_addr, lm_prev, ptr_size, lmo);
+    }
   else
     {
       if (lm_prev != 0)
@@ -6633,7 +6615,10 @@ linux_process_target::qxfer_libraries_svr4 (const char *annex,
       if (r_debug == (CORE_ADDR) -1)
 	return -1;
 
-      bool ignore_first = true;
+      /* Terminate the header if we end up with an empty list.  */
+      if (r_debug == 0)
+	document += ">";
+
       while (r_debug != 0)
 	{
 	  int r_version = 0;
@@ -6660,15 +6645,36 @@ linux_process_target::qxfer_libraries_svr4 (const char *annex,
 	      break;
 	    }
 
-	  read_link_map (document, lm_addr, 0, ptr_size, lmo,
-			 ignore_first, header_done);
+	  /* We read the entire namespace.  */
+	  lm_prev = 0;
+
+	  /* The first entry corresponds to the main executable unless the
+	     dynamic loader was loaded late by a static executable.  But
+	     in such case the main executable does not have PT_DYNAMIC
+	     present and we would not have gotten here.  */
+	  if (r_debug == priv->r_debug)
+	    {
+	      if (lm_addr != 0)
+		string_appendf (document, " main-lm=\"0x%s\">",
+				paddress (lm_addr));
+	      else
+		document += ">";
+
+	      lm_prev = lm_addr;
+	      if (read_one_ptr (lm_addr + lmo->l_next_offset,
+				&lm_addr, ptr_size) != 0)
+		{
+		  warning ("unable to read l_next from 0x%s",
+			   paddress (lm_addr + lmo->l_next_offset));
+		  break;
+		}
+	    }
+
+	  read_link_map (document, lm_addr, lm_prev, ptr_size, lmo);
 
 	  if (r_version < 2)
 	    break;
 
-	  /* Only applies to the default namespace.  */
-	  ignore_first = false;
-
 	  if (read_one_ptr (r_debug + lmo->r_next_offset, &r_debug,
 			    ptr_size) != 0)
 	    {
@@ -6679,13 +6685,7 @@ linux_process_target::qxfer_libraries_svr4 (const char *annex,
 	}
     }
 
-  if (!header_done)
-    {
-      /* Empty list; terminate `<library-list-svr4'.  */
-      document += "/>";
-    }
-  else
-    document += "</library-list-svr4>";
+  document += "</library-list-svr4>";
 
   int document_len = document.length ();
   if (offset < document_len)
-- 
2.35.3

Intel Deutschland GmbH
Registered Address: Am Campeon 10, 85579 Neubiberg, Germany
Tel: +49 89 99 8853-0, www.intel.de <http://www.intel.de>
Managing Directors: Christin Eisenschmid, Sharon Heck, Tiffany Doon Silva  
Chairperson of the Supervisory Board: Nicole Lau
Registered Office: Munich
Commercial Register: Amtsgericht Muenchen HRB 186928


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

* [PATCH v5 05/15] gdb, gdbserver: extend RSP to support namespaces
  2022-06-02 13:24 [PATCH v5 00/15] basic linker namespace support Markus Metzger
                   ` (3 preceding siblings ...)
  2022-06-02 13:25 ` [PATCH v5 04/15] gdbserver: move main_lm handling into caller Markus Metzger
@ 2022-06-02 13:25 ` Markus Metzger
  2022-06-02 16:09   ` Eli Zaretskii
  2022-06-19  4:32   ` Kevin Buettner
  2022-06-02 13:25 ` [PATCH v5 06/15] gdb, compile: unlink objfile stored in module Markus Metzger
                   ` (10 subsequent siblings)
  15 siblings, 2 replies; 52+ messages in thread
From: Markus Metzger @ 2022-06-02 13:25 UTC (permalink / raw)
  To: gdb-patches

Introduce a new qXfer:libraries-svr4:read annex key/value pair

    lmid=<namespace identifier>

to be used together with start and prev to provide the namespace of start
and prev to gdbserver.

Unknown key/value pairs are ignored by gdbserver so no new supports check
is needed.

Introduce a new library-list-svr4 library attribute

    lmid

to provide the namespace of a library entry to GDB.

This implementation uses the address of a namespace's r_debug object as
namespace identifier.

This should have incremented the minor version but since unknown XML
attributes are ignored, anyway, and since changing the version results in
a warning from GDB, the version is left at 1.0.
---
 gdb/doc/gdb.texinfo                | 16 +++++++++++--
 gdb/features/library-list-svr4.dtd |  4 ++++
 gdb/solib-svr4.c                   | 38 +++++++++++++++++++++++++++---
 gdbserver/linux-low.cc             | 26 +++++++++++++-------
 4 files changed, 70 insertions(+), 14 deletions(-)

diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 5f09f3a1433..e2f430feb7e 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -43334,6 +43334,12 @@ specified by the @samp{start} argument.  If unset or zero then
 the remote stub will expect that no @samp{struct link_map}
 exists prior to the starting point.
 
+@item lmid=@var{lmid}
+A hexadecimal number specifying a namespace identifier.  This is
+currently only used together with @samp{start} to provide the
+namespace identifier back to @value{GDBN} in the response.
+@value{GDBN} will only provide values that were previously reported to
+it.  If unset, the response will include @samp{lmid="0x0"}.
 @end table
 
 Arguments that are not understood by the remote stub will be silently
@@ -45872,6 +45878,11 @@ memory address.  It is a displacement of absolute memory address against
 address the file was prelinked to during the library load.
 @item
 @code{l_ld}, which is memory address of the @code{PT_DYNAMIC} segment
+@item
+@code{lmid}, which is an identifier for a linker namespace, such as
+the memory address of the @code{r_debug} object that contains this
+namespace's load map or the namespace identifier returned by
+@code{dlinfo (3)}.
 @end itemize
 
 Additionally the single @code{main-lm} attribute specifies address of
@@ -45887,9 +45898,9 @@ looks like this:
 @smallexample
 <library-list-svr4 version="1.0" main-lm="0xe4f8f8">
   <library name="/lib/ld-linux.so.2" lm="0xe4f51c" l_addr="0xe2d000"
-           l_ld="0xe4eefc"/>
+           l_ld="0xe4eefc" lmid="0xfffe0"/>
   <library name="/lib/libc.so.6" lm="0xe4fbe8" l_addr="0x154000"
-           l_ld="0x152350"/>
+           l_ld="0x152350" lmid="0xfffe0"/>
 </library-list-svr>
 @end smallexample
 
@@ -45905,6 +45916,7 @@ The format of an SVR4 library list is described by this DTD:
 <!ATTLIST library            lm      CDATA   #REQUIRED>
 <!ATTLIST library            l_addr  CDATA   #REQUIRED>
 <!ATTLIST library            l_ld    CDATA   #REQUIRED>
+<!ATTLIST library            lmid    CDATA   #IMPLIED>
 @end smallexample
 
 @node Memory Map Format
diff --git a/gdb/features/library-list-svr4.dtd b/gdb/features/library-list-svr4.dtd
index 7d62354c34c..e869ff1349e 100644
--- a/gdb/features/library-list-svr4.dtd
+++ b/gdb/features/library-list-svr4.dtd
@@ -14,3 +14,7 @@
 <!ATTLIST library            lm      CDATA   #REQUIRED>
 <!ATTLIST library            l_addr  CDATA   #REQUIRED>
 <!ATTLIST library            l_ld    CDATA   #REQUIRED>
+<!-- added lmid attribute to what should have become version 1.1 but
+     since this generates a warning in GDB and since unknown attributes
+     are ignored, anyway, leaving the version at 1.0. -->
+<!ATTLIST library            lmid    CDATA   #IMPLIED>
diff --git a/gdb/solib-svr4.c b/gdb/solib-svr4.c
index 1f2abcf16ef..ca396acf24f 100644
--- a/gdb/solib-svr4.c
+++ b/gdb/solib-svr4.c
@@ -1068,8 +1068,37 @@ library_list_start_library (struct gdb_xml_parser *parser,
   new_elem->so_name[sizeof (new_elem->so_name) - 1] = 0;
   strcpy (new_elem->so_original_name, new_elem->so_name);
 
-  *list->tailp = new_elem;
-  list->tailp = &new_elem->next;
+  /* Older versions did not supply lmid.  Put the element into the flat
+     list of the special namespace zero in that case.  */
+  gdb_xml_value *at_lmid = xml_find_attribute (attributes, "lmid");
+  if (at_lmid == nullptr)
+    {
+      *list->tailp = new_elem;
+      list->tailp = &new_elem->next;
+    }
+  else
+    {
+      ULONGEST lmid = *(ULONGEST *) at_lmid->value.get ();
+
+      /* Ensure that the element is actually initialized.  */
+      if (list->solib_lists.find (lmid) == list->solib_lists.end ())
+	list->solib_lists[lmid] = nullptr;
+
+      so_list **psolist = &list->solib_lists[lmid];
+      so_list **pnext = psolist;
+
+      /* Walk to the end of the list if we have one.  */
+      so_list *solist = *psolist;
+      if (solist != nullptr)
+	{
+	  for (; solist->next != nullptr; solist = solist->next)
+	    /* Nothing.  */;
+
+	  pnext = &solist->next;
+	}
+
+      *pnext = new_elem;
+    }
 }
 
 /* Handle the start of a <library-list-svr4> element.  */
@@ -1109,6 +1138,7 @@ static const struct gdb_xml_attribute svr4_library_attributes[] =
   { "lm", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
   { "l_addr", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
   { "l_ld", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
+  { "lmid", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
   { NULL, GDB_XML_AF_NONE, NULL, NULL }
 };
 
@@ -1866,7 +1896,9 @@ solist_update_incremental (svr4_info *info, CORE_ADDR debug_base,
       struct svr4_library_list library_list;
       char annex[64];
 
-      xsnprintf (annex, sizeof (annex), "start=%s;prev=%s",
+      /* Unknown key=value pairs are ignored by the gdbstub.  */
+      xsnprintf (annex, sizeof (annex), "lmid=%s;start=%s;prev=%s",
+		 phex_nz (debug_base, sizeof (debug_base)),
 		 phex_nz (lm, sizeof (lm)),
 		 phex_nz (prev_lm, sizeof (prev_lm)));
       if (!svr4_current_sos_via_xfer_libraries (&library_list, annex))
diff --git a/gdbserver/linux-low.cc b/gdbserver/linux-low.cc
index 4b4d38b75bc..f54551f2eca 100644
--- a/gdbserver/linux-low.cc
+++ b/gdbserver/linux-low.cc
@@ -6481,8 +6481,8 @@ static const link_map_offsets lmo_64bit_offsets =
 /* Get the loaded shared libraries from one namespace.  */
 
 static void
-read_link_map (std::string &document, CORE_ADDR lm_addr, CORE_ADDR lm_prev,
-	       int ptr_size, const link_map_offsets *lmo)
+read_link_map (std::string &document, CORE_ADDR lmid, CORE_ADDR lm_addr,
+	       CORE_ADDR lm_prev, int ptr_size, const link_map_offsets *lmo)
 {
   CORE_ADDR l_name, l_addr, l_ld, l_next, l_prev;
 
@@ -6517,9 +6517,9 @@ read_link_map (std::string &document, CORE_ADDR lm_addr, CORE_ADDR lm_prev,
 	  string_appendf (document, "<library name=\"");
 	  xml_escape_text_append (&document, (char *) libname);
 	  string_appendf (document, "\" lm=\"0x%s\" l_addr=\"0x%s\" "
-			  "l_ld=\"0x%s\"/>",
+			  "l_ld=\"0x%s\" lmid=\"0x%s\"/>",
 			  paddress (lm_addr), paddress (l_addr),
-			  paddress (l_ld));
+			  paddress (l_ld), paddress (lmid));
 	}
 
       lm_prev = lm_addr;
@@ -6539,7 +6539,7 @@ linux_process_target::qxfer_libraries_svr4 (const char *annex,
   char filename[PATH_MAX];
   int pid, is_elf64;
   unsigned int machine;
-  CORE_ADDR lm_addr = 0, lm_prev = 0;
+  CORE_ADDR lmid = 0, lm_addr = 0, lm_prev = 0;
 
   if (writebuf != NULL)
     return -2;
@@ -6573,7 +6573,9 @@ linux_process_target::qxfer_libraries_svr4 (const char *annex,
 	break;
 
       name_len = sep - annex;
-      if (name_len == 5 && startswith (annex, "start"))
+      if (name_len == 4 && startswith (annex, "lmid"))
+	addrp = &lmid;
+      else if (name_len == 5 && startswith (annex, "start"))
 	addrp = &lm_addr;
       else if (name_len == 4 && startswith (annex, "prev"))
 	addrp = &lm_prev;
@@ -6592,19 +6594,25 @@ linux_process_target::qxfer_libraries_svr4 (const char *annex,
   std::string document = "<library-list-svr4 version=\"1.0\"";
 
   /* When the starting LM_ADDR is passed in the annex, only traverse that
-     namespace.
+     namespace, which is assumed to be identified by LMID.
 
      Otherwise, start with R_DEBUG and traverse all namespaces we find.  */
   if (lm_addr != 0)
     {
       document += ">";
-      read_link_map (document, lm_addr, lm_prev, ptr_size, lmo);
+      read_link_map (document, lmid, lm_addr, lm_prev, ptr_size, lmo);
     }
   else
     {
       if (lm_prev != 0)
 	warning ("ignoring prev=0x%s without start", paddress (lm_prev));
 
+      /* We could interpret LMID as 'provide only the libraries for this
+	 namespace' but GDB is currently only providing lmid, start, and
+	 prev, or nothing.  */
+      if (lmid != 0)
+	warning ("ignoring lmid=0x%s without start", paddress (lmid));
+
       CORE_ADDR r_debug = priv->r_debug;
       if (r_debug == 0)
 	r_debug = priv->r_debug = get_r_debug (pid, is_elf64);
@@ -6670,7 +6678,7 @@ linux_process_target::qxfer_libraries_svr4 (const char *annex,
 		}
 	    }
 
-	  read_link_map (document, lm_addr, lm_prev, ptr_size, lmo);
+	  read_link_map (document, r_debug, lm_addr, lm_prev, ptr_size, lmo);
 
 	  if (r_version < 2)
 	    break;
-- 
2.35.3

Intel Deutschland GmbH
Registered Address: Am Campeon 10, 85579 Neubiberg, Germany
Tel: +49 89 99 8853-0, www.intel.de <http://www.intel.de>
Managing Directors: Christin Eisenschmid, Sharon Heck, Tiffany Doon Silva  
Chairperson of the Supervisory Board: Nicole Lau
Registered Office: Munich
Commercial Register: Amtsgericht Muenchen HRB 186928


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

* [PATCH v5 06/15] gdb, compile: unlink objfile stored in module
  2022-06-02 13:24 [PATCH v5 00/15] basic linker namespace support Markus Metzger
                   ` (4 preceding siblings ...)
  2022-06-02 13:25 ` [PATCH v5 05/15] gdb, gdbserver: extend RSP to support namespaces Markus Metzger
@ 2022-06-02 13:25 ` Markus Metzger
  2022-06-23 17:20   ` Kevin Buettner
  2022-06-02 13:25 ` [PATCH v5 07/15] gdb, python: use gdbarch_iterate_over_objfiles_in_search_order Markus Metzger
                   ` (9 subsequent siblings)
  15 siblings, 1 reply; 52+ messages in thread
From: Markus Metzger @ 2022-06-02 13:25 UTC (permalink / raw)
  To: gdb-patches

When cleaning up after a compile command, we iterate over all objfiles and
unlink the first objfile with the same name as the one we compiled.

Since we already store a pointer to that objfile in the module and use it
to get the name we're comparing against, there's no reason to iterate, at
all.  We can simply use that objfile.

This further avoids potential issues when an objfile with the same name is
loaded into a different linker namespace.
---
 gdb/compile/compile-object-run.c | 21 +++++++++------------
 1 file changed, 9 insertions(+), 12 deletions(-)

diff --git a/gdb/compile/compile-object-run.c b/gdb/compile/compile-object-run.c
index 331ae35c5e9..b9de626f4f0 100644
--- a/gdb/compile/compile-object-run.c
+++ b/gdb/compile/compile-object-run.c
@@ -79,21 +79,18 @@ do_module_cleanup (void *arg, int registers_valid)
 	}
     }
 
+  objfile *objfile = data->module->objfile;
+  gdb_assert (objfile != nullptr);
+
   /* We have to make a copy of the name so that we can unlink the
      underlying file -- removing the objfile will cause the name to be
      freed, so we can't simply keep a reference to it.  */
-  std::string objfile_name_s = objfile_name (data->module->objfile);
-  for (objfile *objfile : current_program_space->objfiles ())
-    if ((objfile->flags & OBJF_USERLOADED) == 0
-	&& objfile_name_s == objfile_name (objfile))
-      {
-	objfile->unlink ();
-
-	/* It may be a bit too pervasive in this dummy_frame dtor callback.  */
-	clear_symtab_users (0);
-
-	break;
-      }
+  std::string objfile_name_s = objfile_name (objfile);
+
+  objfile->unlink ();
+
+  /* It may be a bit too pervasive in this dummy_frame dtor callback.  */
+  clear_symtab_users (0);
 
   /* Delete the .c file.  */
   unlink (data->module->source_file.c_str ());
-- 
2.35.3

Intel Deutschland GmbH
Registered Address: Am Campeon 10, 85579 Neubiberg, Germany
Tel: +49 89 99 8853-0, www.intel.de <http://www.intel.de>
Managing Directors: Christin Eisenschmid, Sharon Heck, Tiffany Doon Silva  
Chairperson of the Supervisory Board: Nicole Lau
Registered Office: Munich
Commercial Register: Amtsgericht Muenchen HRB 186928


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

* [PATCH v5 07/15] gdb, python: use gdbarch_iterate_over_objfiles_in_search_order
  2022-06-02 13:24 [PATCH v5 00/15] basic linker namespace support Markus Metzger
                   ` (5 preceding siblings ...)
  2022-06-02 13:25 ` [PATCH v5 06/15] gdb, compile: unlink objfile stored in module Markus Metzger
@ 2022-06-02 13:25 ` Markus Metzger
  2022-06-24 17:18   ` Kevin Buettner
  2022-06-02 13:25 ` [PATCH v5 08/15] gdb, ada: collect standard exceptions in all objfiles Markus Metzger
                   ` (8 subsequent siblings)
  15 siblings, 1 reply; 52+ messages in thread
From: Markus Metzger @ 2022-06-02 13:25 UTC (permalink / raw)
  To: gdb-patches

The implementation of gdb.lookup_objfile() iterates over all objfiles and
compares their name or build id to the user-provided search string.

This will cause problems when supporting linker namespaces as the first
objfile in any namespace will be found.  Instead, use
gdbarch_iterate_over_objfiles_in_search_order to only consider the
namespace of gdb.current_objfile() for the search, which defaults to the
initial namespace when gdb.current_objfile() is None.
---
 gdb/python/py-objfile.c | 116 +++++++++++++++++++---------------------
 gdb/python/python.c     |   7 +--
 gdb/python/python.h     |   6 +++
 3 files changed, 64 insertions(+), 65 deletions(-)

diff --git a/gdb/python/py-objfile.c b/gdb/python/py-objfile.c
index 3e3270e7cd3..b278cec99d8 100644
--- a/gdb/python/py-objfile.c
+++ b/gdb/python/py-objfile.c
@@ -24,6 +24,7 @@
 #include "language.h"
 #include "build-id.h"
 #include "symtab.h"
+#include "python.h"
 
 struct objfile_object
 {
@@ -559,57 +560,6 @@ objfpy_build_id_matches (const struct bfd_build_id *build_id,
   return 1;
 }
 
-/* Subroutine of gdbpy_lookup_objfile to simplify it.
-   Look up an objfile by its file name.  */
-
-static struct objfile *
-objfpy_lookup_objfile_by_name (const char *name)
-{
-  for (objfile *objfile : current_program_space->objfiles ())
-    {
-      const char *filename;
-
-      if ((objfile->flags & OBJF_NOT_FILENAME) != 0)
-	continue;
-      /* Don't return separate debug files.  */
-      if (objfile->separate_debug_objfile_backlink != NULL)
-	continue;
-
-      filename = objfile_filename (objfile);
-      if (filename != NULL && compare_filenames_for_search (filename, name))
-	return objfile;
-      if (compare_filenames_for_search (objfile->original_name, name))
-	return objfile;
-    }
-
-  return NULL;
-}
-
-/* Subroutine of gdbpy_lookup_objfile to simplify it.
-   Look up an objfile by its build id.  */
-
-static struct objfile *
-objfpy_lookup_objfile_by_build_id (const char *build_id)
-{
-  for (objfile *objfile : current_program_space->objfiles ())
-    {
-      const struct bfd_build_id *obfd_build_id;
-
-      if (objfile->obfd == NULL)
-	continue;
-      /* Don't return separate debug files.  */
-      if (objfile->separate_debug_objfile_backlink != NULL)
-	continue;
-      obfd_build_id = build_id_bfd_get (objfile->obfd);
-      if (obfd_build_id == NULL)
-	continue;
-      if (objfpy_build_id_matches (obfd_build_id, build_id))
-	return objfile;
-    }
-
-  return NULL;
-}
-
 /* Implementation of gdb.lookup_objfile.  */
 
 PyObject *
@@ -619,7 +569,6 @@ gdbpy_lookup_objfile (PyObject *self, PyObject *args, PyObject *kw)
   const char *name;
   PyObject *by_build_id_obj = NULL;
   int by_build_id;
-  struct objfile *objfile;
 
   if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "s|O!", keywords,
 					&name, &PyBool_Type, &by_build_id_obj))
@@ -635,17 +584,64 @@ gdbpy_lookup_objfile (PyObject *self, PyObject *args, PyObject *kw)
       by_build_id = cmp;
     }
 
-  if (by_build_id)
+  if (by_build_id && !objfpy_build_id_ok (name))
     {
-      if (!objfpy_build_id_ok (name))
-	{
-	  PyErr_SetString (PyExc_TypeError, _("Not a valid build id."));
-	  return NULL;
-	}
-      objfile = objfpy_lookup_objfile_by_build_id (name);
+      PyErr_SetString (PyExc_TypeError, _("Not a valid build id."));
+      return NULL;
     }
+
+  struct objfile *objfile = nullptr;
+  if (by_build_id)
+    gdbarch_iterate_over_objfiles_in_search_order
+      (target_gdbarch (),
+       [&objfile, name] (struct objfile *obj)
+	 {
+	   /* Don't return separate debug files.  */
+	   if (obj->separate_debug_objfile_backlink != nullptr)
+	     return 0;
+
+	   bfd *obfd = obj->obfd;
+	   if (obfd == nullptr)
+	     return 0;
+
+	   const bfd_build_id *obfd_build_id = build_id_bfd_get (obfd);
+	   if (obfd_build_id == nullptr)
+	     return 0;
+
+	   if (!objfpy_build_id_matches (obfd_build_id, name))
+	     return 0;
+
+	   objfile = obj;
+	   return 1;
+	 }, gdbpy_current_objfile);
   else
-    objfile = objfpy_lookup_objfile_by_name (name);
+    gdbarch_iterate_over_objfiles_in_search_order
+      (target_gdbarch (),
+       [&objfile, name] (struct objfile *obj)
+	 {
+	   /* Don't return separate debug files.  */
+	   if (obj->separate_debug_objfile_backlink != nullptr)
+	     return 0;
+
+	   if ((obj->flags & OBJF_NOT_FILENAME) != 0)
+	     return 0;
+
+	   const char *filename = objfile_filename (obj);
+	   if (filename != NULL
+	       && compare_filenames_for_search (filename, name))
+	     {
+	       objfile = obj;
+	       return 1;
+	     }
+
+	   if (compare_filenames_for_search (obj->original_name, name))
+	     {
+	       objfile = obj;
+	       return 1;
+	     }
+
+	   return 0;
+	 }, gdbpy_current_objfile);
 
   if (objfile != NULL)
     return objfile_to_objfile_object (objfile).release ();
diff --git a/gdb/python/python.c b/gdb/python/python.c
index 9bef2252e88..ba6fdc455b7 100644
--- a/gdb/python/python.c
+++ b/gdb/python/python.c
@@ -1581,11 +1581,8 @@ gdbpy_current_language (PyObject *unused1, PyObject *unused2)
 
 \f
 
-/* The "current" objfile.  This is set when gdb detects that a new
-   objfile has been loaded.  It is only set for the duration of a call to
-   gdbpy_source_objfile_script and gdbpy_execute_objfile_script; it is NULL
-   at other times.  */
-static struct objfile *gdbpy_current_objfile;
+/* See python.h.  */
+struct objfile *gdbpy_current_objfile;
 
 /* Set the current objfile to OBJFILE and then read FILE named FILENAME
    as Python code.  This does not throw any errors.  If an exception
diff --git a/gdb/python/python.h b/gdb/python/python.h
index 4b150c36a9e..2be83ba2da6 100644
--- a/gdb/python/python.h
+++ b/gdb/python/python.h
@@ -28,4 +28,10 @@ extern const struct extension_language_defn extension_language_python;
 /* Command element for the 'python' command.  */
 extern cmd_list_element *python_cmd_element;
 
+/* The "current" objfile.  This is set when gdb detects that a new
+   objfile has been loaded.  It is only set for the duration of a call to
+   gdbpy_source_objfile_script and gdbpy_execute_objfile_script; it is NULL
+   at other times.  */
+extern struct objfile *gdbpy_current_objfile;
+
 #endif /* PYTHON_PYTHON_H */
-- 
2.35.3

Intel Deutschland GmbH
Registered Address: Am Campeon 10, 85579 Neubiberg, Germany
Tel: +49 89 99 8853-0, www.intel.de <http://www.intel.de>
Managing Directors: Christin Eisenschmid, Sharon Heck, Tiffany Doon Silva  
Chairperson of the Supervisory Board: Nicole Lau
Registered Office: Munich
Commercial Register: Amtsgericht Muenchen HRB 186928


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

* [PATCH v5 08/15] gdb, ada: collect standard exceptions in all objfiles
  2022-06-02 13:24 [PATCH v5 00/15] basic linker namespace support Markus Metzger
                   ` (6 preceding siblings ...)
  2022-06-02 13:25 ` [PATCH v5 07/15] gdb, python: use gdbarch_iterate_over_objfiles_in_search_order Markus Metzger
@ 2022-06-02 13:25 ` Markus Metzger
  2022-06-24 17:26   ` Kevin Buettner
  2022-07-18  5:35   ` Metzger, Markus T
  2022-06-02 13:25 ` [PATCH v5 09/15] gdb, ada: update ada_lookup_simple_minsym Markus Metzger
                   ` (7 subsequent siblings)
  15 siblings, 2 replies; 52+ messages in thread
From: Markus Metzger @ 2022-06-02 13:25 UTC (permalink / raw)
  To: gdb-patches

When searching for standard exceptions for Ada, we lookup the minimal
symbol of each exception.  With linker namespaces there can be multiple
instances in different namespaces.  Collect them all.
---
 gdb/ada-lang.c | 30 +++++++++++++++++++++++-------
 1 file changed, 23 insertions(+), 7 deletions(-)

diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c
index 6ab01fd27d4..2b251693b72 100644
--- a/gdb/ada-lang.c
+++ b/gdb/ada-lang.c
@@ -13016,15 +13016,29 @@ ada_add_standard_exceptions (compiled_regex *preg,
     {
       if (preg == NULL || preg->exec (name, 0, NULL, 0) == 0)
 	{
-	  struct bound_minimal_symbol msymbol
-	    = ada_lookup_simple_minsym (name);
+	  symbol_name_match_type match_type = name_match_type_from_name (name);
+	  lookup_name_info lookup_name (name, match_type);
 
-	  if (msymbol.minsym != NULL)
-	    {
-	      struct ada_exc_info info
-		= {name, msymbol.value_address ()};
+	  symbol_name_matcher_ftype *match_name
+	    = ada_get_symbol_name_matcher (lookup_name);
 
-	      exceptions->push_back (info);
+	  /* Iterate over all objfiles irrespective of scope or linker
+	     namespaces so we get all exceptions anywhere in the
+	     progspace.  */
+	  for (objfile *objfile : current_program_space->objfiles ())
+	    {
+	      for (minimal_symbol *msymbol : objfile->msymbols ())
+		{
+		  if (match_name (msymbol->linkage_name (), lookup_name,
+				  nullptr)
+		      && msymbol->type () != mst_solib_trampoline)
+		    {
+		      ada_exc_info info
+			= {name, msymbol->value_address (objfile)};
+
+		      exceptions->push_back (info);
+		    }
+		}
 	    }
 	}
     }
@@ -13122,6 +13136,8 @@ ada_add_global_exceptions (compiled_regex *preg,
 			   SEARCH_GLOBAL_BLOCK | SEARCH_STATIC_BLOCK,
 			   VARIABLES_DOMAIN);
 
+  /* Iterate over all objfiles irrespective of scope or linker namespaces
+     so we get all exceptions anywhere in the progspace.  */
   for (objfile *objfile : current_program_space->objfiles ())
     {
       for (compunit_symtab *s : objfile->compunits ())
-- 
2.35.3

Intel Deutschland GmbH
Registered Address: Am Campeon 10, 85579 Neubiberg, Germany
Tel: +49 89 99 8853-0, www.intel.de <http://www.intel.de>
Managing Directors: Christin Eisenschmid, Sharon Heck, Tiffany Doon Silva  
Chairperson of the Supervisory Board: Nicole Lau
Registered Office: Munich
Commercial Register: Amtsgericht Muenchen HRB 186928


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

* [PATCH v5 09/15] gdb, ada: update ada_lookup_simple_minsym
  2022-06-02 13:24 [PATCH v5 00/15] basic linker namespace support Markus Metzger
                   ` (7 preceding siblings ...)
  2022-06-02 13:25 ` [PATCH v5 08/15] gdb, ada: collect standard exceptions in all objfiles Markus Metzger
@ 2022-06-02 13:25 ` Markus Metzger
  2022-06-24 23:42   ` Kevin Buettner
  2022-07-18 17:02   ` Tom Tromey
  2022-06-02 13:25 ` [PATCH v5 10/15] gdb, ada: update ada_add_all_symbols Markus Metzger
                   ` (6 subsequent siblings)
  15 siblings, 2 replies; 52+ messages in thread
From: Markus Metzger @ 2022-06-02 13:25 UTC (permalink / raw)
  To: gdb-patches

Iterate over objfile in search order using the objfile of the context
block as current_objfile so the iteration can stay inside the block's
linker namespace.
---
 gdb/ada-exp.y  |  9 ++++++++-
 gdb/ada-lang.c | 32 ++++++++++++++++++--------------
 gdb/ada-lang.h |  3 ++-
 3 files changed, 28 insertions(+), 16 deletions(-)

diff --git a/gdb/ada-exp.y b/gdb/ada-exp.y
index 8660205809a..85569b841eb 100644
--- a/gdb/ada-exp.y
+++ b/gdb/ada-exp.y
@@ -1700,8 +1700,15 @@ write_var_or_type (struct parser_state *par_state,
 	    }
 	  else if (syms.empty ())
 	    {
+	      if (block == nullptr)
+		block = get_selected_block (nullptr);
+
+	      struct objfile *objfile = nullptr;
+	      if (block != nullptr)
+		objfile = block_objfile (block);
+
 	      struct bound_minimal_symbol msym
-		= ada_lookup_simple_minsym (decoded_name.c_str ());
+		= ada_lookup_simple_minsym (decoded_name.c_str (), objfile);
 	      if (msym.minsym != NULL)
 		{
 		  par_state->push_new<ada_var_msym_value_operation> (msym);
diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c
index 2b251693b72..20ea4c8f6aa 100644
--- a/gdb/ada-lang.c
+++ b/gdb/ada-lang.c
@@ -4887,7 +4887,7 @@ add_defn_to_vec (std::vector<struct block_symbol> &result,
    global symbols are searched.  */
 
 struct bound_minimal_symbol
-ada_lookup_simple_minsym (const char *name)
+ada_lookup_simple_minsym (const char *name, struct objfile *objfile)
 {
   struct bound_minimal_symbol result;
 
@@ -4897,19 +4897,23 @@ ada_lookup_simple_minsym (const char *name)
   symbol_name_matcher_ftype *match_name
     = ada_get_symbol_name_matcher (lookup_name);
 
-  for (objfile *objfile : current_program_space->objfiles ())
-    {
-      for (minimal_symbol *msymbol : objfile->msymbols ())
-	{
-	  if (match_name (msymbol->linkage_name (), lookup_name, NULL)
-	      && msymbol->type () != mst_solib_trampoline)
-	    {
-	      result.minsym = msymbol;
-	      result.objfile = objfile;
-	      break;
-	    }
-	}
-    }
+  gdbarch_iterate_over_objfiles_in_search_order
+    (objfile != NULL ? objfile->arch () : target_gdbarch (),
+     [&result, lookup_name, match_name] (struct objfile *obj)
+       {
+	 for (minimal_symbol *msymbol : obj->msymbols ())
+	   {
+	     if (match_name (msymbol->linkage_name (), lookup_name, nullptr)
+		 && msymbol->type () != mst_solib_trampoline)
+	       {
+		 result.minsym = msymbol;
+		 result.objfile = obj;
+		 return 1;
+	       }
+	   }
+
+	 return 0;
+       }, objfile);
 
   return result;
 }
diff --git a/gdb/ada-lang.h b/gdb/ada-lang.h
index 0dcdb56c198..df5df48d6c9 100644
--- a/gdb/ada-lang.h
+++ b/gdb/ada-lang.h
@@ -234,7 +234,8 @@ extern void ada_lookup_encoded_symbol
   (const char *name, const struct block *block, domain_enum domain,
    struct block_symbol *symbol_info);
 
-extern struct bound_minimal_symbol ada_lookup_simple_minsym (const char *);
+extern struct bound_minimal_symbol ada_lookup_simple_minsym (const char *,
+							     objfile *);
 
 extern int ada_scan_number (const char *, int, LONGEST *, int *);
 
-- 
2.35.3

Intel Deutschland GmbH
Registered Address: Am Campeon 10, 85579 Neubiberg, Germany
Tel: +49 89 99 8853-0, www.intel.de <http://www.intel.de>
Managing Directors: Christin Eisenschmid, Sharon Heck, Tiffany Doon Silva  
Chairperson of the Supervisory Board: Nicole Lau
Registered Office: Munich
Commercial Register: Amtsgericht Muenchen HRB 186928


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

* [PATCH v5 10/15] gdb, ada: update ada_add_all_symbols
  2022-06-02 13:24 [PATCH v5 00/15] basic linker namespace support Markus Metzger
                   ` (8 preceding siblings ...)
  2022-06-02 13:25 ` [PATCH v5 09/15] gdb, ada: update ada_lookup_simple_minsym Markus Metzger
@ 2022-06-02 13:25 ` Markus Metzger
  2022-06-24 23:53   ` Kevin Buettner
                     ` (2 more replies)
  2022-06-02 13:25 ` [PATCH v5 11/15] gdb, cp: update add_symbol_overload_list_qualified Markus Metzger
                   ` (5 subsequent siblings)
  15 siblings, 3 replies; 52+ messages in thread
From: Markus Metzger @ 2022-06-02 13:25 UTC (permalink / raw)
  To: gdb-patches

Iterate over objfile in search order using the objfile of the context
block as current_objfile so the iteration can stay inside the block's
linker namespace.
---
 gdb/ada-lang.c | 66 +++++++++++++++++++++++++++++++++-----------------
 1 file changed, 44 insertions(+), 22 deletions(-)

diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c
index 20ea4c8f6aa..110c246181e 100644
--- a/gdb/ada-lang.c
+++ b/gdb/ada-lang.c
@@ -5582,37 +5582,52 @@ map_matching_symbols (struct objfile *objfile,
 
 static void
 add_nonlocal_symbols (std::vector<struct block_symbol> &result,
+		      const struct block *block,
 		      const lookup_name_info &lookup_name,
 		      domain_enum domain, int global)
 {
-  struct match_data data (&result);
+  struct objfile *objfile = nullptr;
+  if (block != nullptr)
+    objfile = block_objfile (block);
 
   bool is_wild_match = lookup_name.ada ().wild_match_p ();
 
-  for (objfile *objfile : current_program_space->objfiles ())
-    {
-      map_matching_symbols (objfile, lookup_name, is_wild_match, domain,
-			    global, data);
+  match_data data (&result);
 
-      for (compunit_symtab *cu : objfile->compunits ())
-	{
-	  const struct block *global_block
-	    = cu->blockvector ()->global_block ();
+  gdbarch_iterate_over_objfiles_in_search_order
+    (objfile != nullptr ? objfile->arch () : target_gdbarch (),
+     [&data, lookup_name, domain, global, is_wild_match] (struct objfile *obj)
+       {
+	 map_matching_symbols (obj, lookup_name, is_wild_match, domain,
+			       global, data);
 
-	  if (ada_add_block_renamings (result, global_block, lookup_name,
-				       domain))
-	    data.found_sym = true;
-	}
-    }
+	 for (compunit_symtab *cu : obj->compunits ())
+	   {
+	     const struct block *global_block
+	       = cu->blockvector ()->global_block ();
 
-  if (result.empty () && global && !is_wild_match)
+	     if (ada_add_block_renamings (*data.resultp, global_block,
+					  lookup_name, domain))
+	       data.found_sym = true;
+	   }
+
+	 return 0;
+       }, objfile);
+
+  if (data.resultp->empty () && global && !is_wild_match)
     {
       const char *name = ada_lookup_name (lookup_name);
       std::string bracket_name = std::string ("<_ada_") + name + '>';
       lookup_name_info name1 (bracket_name, symbol_name_match_type::FULL);
 
-      for (objfile *objfile : current_program_space->objfiles ())
-	map_matching_symbols (objfile, name1, false, domain, global, data);
+      gdbarch_iterate_over_objfiles_in_search_order
+	(objfile != nullptr ? objfile->arch () : target_gdbarch (),
+	 [&data, name1, domain, global] (struct objfile *obj)
+	   {
+	     map_matching_symbols (obj, name1, false, domain, global, data);
+
+	     return 0;
+	   }, objfile);
     }
 }
 
@@ -5642,6 +5657,7 @@ ada_add_all_symbols (std::vector<struct block_symbol> &result,
 		     int *made_global_lookup_p)
 {
   struct symbol *sym;
+  const struct block *orig_block = block;
 
   if (made_global_lookup_p)
     *made_global_lookup_p = 0;
@@ -5688,15 +5704,21 @@ ada_add_all_symbols (std::vector<struct block_symbol> &result,
   if (made_global_lookup_p)
     *made_global_lookup_p = 1;
 
-  /* Search symbols from all global blocks.  */
+  /* Search symbols from all global blocks.
+
+     Pass the original block to restrict the search to that block's
+     namespace.  */
  
-  add_nonlocal_symbols (result, lookup_name, domain, 1);
+  add_nonlocal_symbols (result, orig_block, lookup_name, domain, 1);
+
+  /* Now add symbols from all per-file blocks if we've gotten no hits (not
+     strictly correct, but perhaps better than an error).
 
-  /* Now add symbols from all per-file blocks if we've gotten no hits
-     (not strictly correct, but perhaps better than an error).  */
+     Pass the original block to restrict the search to that block's
+     namespace.  */
 
   if (result.empty ())
-    add_nonlocal_symbols (result, lookup_name, domain, 0);
+    add_nonlocal_symbols (result, orig_block, lookup_name, domain, 0);
 }
 
 /* Find symbols in DOMAIN matching LOOKUP_NAME, in BLOCK and, if FULL_SEARCH
-- 
2.35.3

Intel Deutschland GmbH
Registered Address: Am Campeon 10, 85579 Neubiberg, Germany
Tel: +49 89 99 8853-0, www.intel.de <http://www.intel.de>
Managing Directors: Christin Eisenschmid, Sharon Heck, Tiffany Doon Silva  
Chairperson of the Supervisory Board: Nicole Lau
Registered Office: Munich
Commercial Register: Amtsgericht Muenchen HRB 186928


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

* [PATCH v5 11/15] gdb, cp: update add_symbol_overload_list_qualified
  2022-06-02 13:24 [PATCH v5 00/15] basic linker namespace support Markus Metzger
                   ` (9 preceding siblings ...)
  2022-06-02 13:25 ` [PATCH v5 10/15] gdb, ada: update ada_add_all_symbols Markus Metzger
@ 2022-06-02 13:25 ` Markus Metzger
  2022-06-24 23:59   ` Kevin Buettner
  2022-06-02 13:25 ` [PATCH v5 12/15] gdb, hppa: remove unused hppa_lookup_stub_minimal_symbol Markus Metzger
                   ` (4 subsequent siblings)
  15 siblings, 1 reply; 52+ messages in thread
From: Markus Metzger @ 2022-06-02 13:25 UTC (permalink / raw)
  To: gdb-patches

Iterate over objfiles in search order using the objfile of the selected
block as current_objfile so the iteration can stay inside the block's
linker namespace.
---
 gdb/cp-support.c | 48 ++++++++++++++++++++++++------------------------
 1 file changed, 24 insertions(+), 24 deletions(-)

diff --git a/gdb/cp-support.c b/gdb/cp-support.c
index 807c944a97c..d76ec433772 100644
--- a/gdb/cp-support.c
+++ b/gdb/cp-support.c
@@ -1460,30 +1460,30 @@ add_symbol_overload_list_qualified (const char *func_name,
   /* Go through the symtabs and check the externs and statics for
      symbols which match.  */
 
-  for (objfile *objfile : current_program_space->objfiles ())
-    {
-      for (compunit_symtab *cust : objfile->compunits ())
-	{
-	  QUIT;
-	  const block *b = cust->blockvector ()->global_block ();
-	  add_symbol_overload_list_block (func_name, b, overload_list);
-	}
-    }
-
-  for (objfile *objfile : current_program_space->objfiles ())
-    {
-      for (compunit_symtab *cust : objfile->compunits ())
-	{
-	  QUIT;
-	  const block *b = cust->blockvector ()->static_block ();
-
-	  /* Don't do this block twice.  */
-	  if (b == surrounding_static_block)
-	    continue;
-
-	  add_symbol_overload_list_block (func_name, b, overload_list);
-	}
-    }
+  const block *block = get_selected_block (0);
+  struct objfile *current_objfile = block ? block_objfile (block) : nullptr;
+
+  gdbarch_iterate_over_objfiles_in_search_order
+    (current_objfile ? current_objfile->arch () : target_gdbarch (),
+     [func_name, surrounding_static_block, &overload_list]
+     (struct objfile *obj)
+       {
+	 for (compunit_symtab *cust : obj->compunits ())
+	   {
+	     QUIT;
+	     const struct block *b = cust->blockvector ()->global_block ();
+	     add_symbol_overload_list_block (func_name, b, overload_list);
+
+	     b = cust->blockvector ()->static_block ();
+	     /* Don't do this block twice.  */
+	     if (b == surrounding_static_block)
+	       continue;
+
+	     add_symbol_overload_list_block (func_name, b, overload_list);
+	   }
+
+	 return 0;
+       }, current_objfile);
 }
 
 /* Lookup the rtti type for a class name.  */
-- 
2.35.3

Intel Deutschland GmbH
Registered Address: Am Campeon 10, 85579 Neubiberg, Germany
Tel: +49 89 99 8853-0, www.intel.de <http://www.intel.de>
Managing Directors: Christin Eisenschmid, Sharon Heck, Tiffany Doon Silva  
Chairperson of the Supervisory Board: Nicole Lau
Registered Office: Munich
Commercial Register: Amtsgericht Muenchen HRB 186928


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

* [PATCH v5 12/15] gdb, hppa: remove unused hppa_lookup_stub_minimal_symbol
  2022-06-02 13:24 [PATCH v5 00/15] basic linker namespace support Markus Metzger
                   ` (10 preceding siblings ...)
  2022-06-02 13:25 ` [PATCH v5 11/15] gdb, cp: update add_symbol_overload_list_qualified Markus Metzger
@ 2022-06-02 13:25 ` Markus Metzger
  2022-06-25  0:01   ` Kevin Buettner
  2022-06-02 13:25 ` [PATCH v5 13/15] gdb, symtab: inline find_quick_global_symbol_language Markus Metzger
                   ` (3 subsequent siblings)
  15 siblings, 1 reply; 52+ messages in thread
From: Markus Metzger @ 2022-06-02 13:25 UTC (permalink / raw)
  To: gdb-patches

I stumbled over this while reviewing all objfiles traversals with regards
to impact of linker namespaces.

Recursive grep only finds two occurrences of hppa_lookup_stub_minimal_symbol:
  - the declaration in hppa-tdep.h.
  - the definition in hppa-tdep.c.

There appear to be no calls to this function.  Remove it.
---
 gdb/hppa-tdep.c | 31 -------------------------------
 gdb/hppa-tdep.h |  4 ----
 2 files changed, 35 deletions(-)

diff --git a/gdb/hppa-tdep.c b/gdb/hppa-tdep.c
index f9ececbb04f..9352b62caf4 100644
--- a/gdb/hppa-tdep.c
+++ b/gdb/hppa-tdep.c
@@ -2511,37 +2511,6 @@ hppa_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
   return pc & ~0x3;
 }
 
-/* Return the minimal symbol whose name is NAME and stub type is STUB_TYPE.
-   Return NULL if no such symbol was found.  */
-
-struct bound_minimal_symbol
-hppa_lookup_stub_minimal_symbol (const char *name,
-				 enum unwind_stub_types stub_type)
-{
-  struct bound_minimal_symbol result;
-
-  for (objfile *objfile : current_program_space->objfiles ())
-    {
-      for (minimal_symbol *msym : objfile->msymbols ())
-	{
-	  if (strcmp (msym->linkage_name (), name) == 0)
-	    {
-	      struct unwind_table_entry *u;
-
-	      u = find_unwind_entry (msym->value_longest ());
-	      if (u != NULL && u->stub_unwind.stub_type == stub_type)
-		{
-		  result.objfile = objfile;
-		  result.minsym = msym;
-		  return result;
-		}
-	    }
-	}
-    }
-
-  return result;
-}
-
 static void
 unwind_command (const char *exp, int from_tty)
 {
diff --git a/gdb/hppa-tdep.h b/gdb/hppa-tdep.h
index f1e24a272c4..821d1bb58c6 100644
--- a/gdb/hppa-tdep.h
+++ b/gdb/hppa-tdep.h
@@ -210,10 +210,6 @@ extern void hppa_write_pc (struct regcache *regcache, CORE_ADDR pc);
 extern CORE_ADDR hppa_unwind_pc (struct gdbarch *gdbarch,
 				 struct frame_info *next_frame);
 
-extern struct bound_minimal_symbol
-  hppa_lookup_stub_minimal_symbol (const char *name,
-				   enum unwind_stub_types stub_type);
-
 extern int hppa_in_solib_call_trampoline (struct gdbarch *gdbarch,
 					  CORE_ADDR pc);
 extern CORE_ADDR hppa_skip_trampoline_code (struct frame_info *, CORE_ADDR pc);
-- 
2.35.3

Intel Deutschland GmbH
Registered Address: Am Campeon 10, 85579 Neubiberg, Germany
Tel: +49 89 99 8853-0, www.intel.de <http://www.intel.de>
Managing Directors: Christin Eisenschmid, Sharon Heck, Tiffany Doon Silva  
Chairperson of the Supervisory Board: Nicole Lau
Registered Office: Munich
Commercial Register: Amtsgericht Muenchen HRB 186928


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

* [PATCH v5 13/15] gdb, symtab: inline find_quick_global_symbol_language
  2022-06-02 13:24 [PATCH v5 00/15] basic linker namespace support Markus Metzger
                   ` (11 preceding siblings ...)
  2022-06-02 13:25 ` [PATCH v5 12/15] gdb, hppa: remove unused hppa_lookup_stub_minimal_symbol Markus Metzger
@ 2022-06-02 13:25 ` Markus Metzger
  2022-06-25  0:16   ` Kevin Buettner
  2022-06-02 13:25 ` [PATCH v5 14/15] gdb: update gnu ifunc resolve Markus Metzger
                   ` (2 subsequent siblings)
  15 siblings, 1 reply; 52+ messages in thread
From: Markus Metzger @ 2022-06-02 13:25 UTC (permalink / raw)
  To: gdb-patches

There is only one use of find_quick_global_symbol_language that calls it
for the special symbol "main".

Inline the function as it is probably not correct in the general case
where we may have multiple instances of global symbols with the same name
but different languages in different libraries in different linker
namespaces.

Further, change the objfiles iteration into a call to
gdbarch_iterate_over_objfiles_in_search_order, which would only search the
initial linker namespace, where we expect "main" to be located.
---
 gdb/symtab.c | 43 +++++++++++++++++++------------------------
 1 file changed, 19 insertions(+), 24 deletions(-)

diff --git a/gdb/symtab.c b/gdb/symtab.c
index 8564986f66d..11dac0f4432 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -2610,23 +2610,6 @@ lookup_symbol_in_objfile (struct objfile *objfile, enum block_enum block_index,
   return result;
 }
 
-/* Find the language for partial symbol with NAME.  */
-
-static enum language
-find_quick_global_symbol_language (const char *name, const domain_enum domain)
-{
-  for (objfile *objfile : current_program_space->objfiles ())
-    {
-      bool symbol_found_p;
-      enum language lang
-	= objfile->lookup_global_symbol_language (name, domain, &symbol_found_p);
-      if (symbol_found_p)
-	return lang;
-    }
-
-  return language_unknown;
-}
-
 /* This function contains the common code of lookup_{global,static}_symbol.
    OBJFILE is only used if BLOCK_INDEX is GLOBAL_SCOPE, in which case it is
    the objfile to start the lookup in.  */
@@ -6367,13 +6350,25 @@ find_main_name (void)
      Fallback to "main".  */
 
   /* Try to find language for main in psymtabs.  */
-  enum language lang
-    = find_quick_global_symbol_language ("main", VAR_DOMAIN);
-  if (lang != language_unknown)
-    {
-      set_main_name ("main", lang);
-      return;
-    }
+  bool symbol_found_p = false;
+  gdbarch_iterate_over_objfiles_in_search_order
+    (target_gdbarch (),
+     [&symbol_found_p] (objfile *obj)
+       {
+	 language lang
+	   = obj->lookup_global_symbol_language ("main", VAR_DOMAIN,
+						 &symbol_found_p);
+	 if (symbol_found_p)
+	   {
+	     set_main_name ("main", lang);
+	     return 1;
+	   }
+
+	 return 0;
+       }, nullptr);
+
+  if (symbol_found_p)
+    return;
 
   set_main_name ("main", language_unknown);
 }
-- 
2.35.3

Intel Deutschland GmbH
Registered Address: Am Campeon 10, 85579 Neubiberg, Germany
Tel: +49 89 99 8853-0, www.intel.de <http://www.intel.de>
Managing Directors: Christin Eisenschmid, Sharon Heck, Tiffany Doon Silva  
Chairperson of the Supervisory Board: Nicole Lau
Registered Office: Munich
Commercial Register: Amtsgericht Muenchen HRB 186928


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

* [PATCH v5 14/15] gdb: update gnu ifunc resolve
  2022-06-02 13:24 [PATCH v5 00/15] basic linker namespace support Markus Metzger
                   ` (12 preceding siblings ...)
  2022-06-02 13:25 ` [PATCH v5 13/15] gdb, symtab: inline find_quick_global_symbol_language Markus Metzger
@ 2022-06-02 13:25 ` Markus Metzger
  2022-06-25  0:34   ` Kevin Buettner
  2022-06-02 13:25 ` [PATCH v5 15/15] gdb, solib-svr4: support namespaces in DSO iteration Markus Metzger
  2022-07-15 10:30 ` [PATCH v5 00/15] basic linker namespace support Metzger, Markus T
  15 siblings, 1 reply; 52+ messages in thread
From: Markus Metzger @ 2022-06-02 13:25 UTC (permalink / raw)
  To: gdb-patches

Update elf_gnu_ifunc_resolve_by_cache() and elf_gnu_ifunc_resolve_by_got()
to use gdbarch_iterate_over_objfiles_in_search_order() in order to
restrict the objfile traversal to the initial namespace.

In order to extend this to other namespaces, we'd need to provide context,
e.g. via an objfile inside that namespace.
---
 gdb/elfread.c | 153 ++++++++++++++++++++++++++++----------------------
 1 file changed, 87 insertions(+), 66 deletions(-)

diff --git a/gdb/elfread.c b/gdb/elfread.c
index 32cb27c8967..c097d272a49 100644
--- a/gdb/elfread.c
+++ b/gdb/elfread.c
@@ -769,32 +769,42 @@ elf_gnu_ifunc_record_cache (const char *name, CORE_ADDR addr)
 static int
 elf_gnu_ifunc_resolve_by_cache (const char *name, CORE_ADDR *addr_p)
 {
-  for (objfile *objfile : current_program_space->objfiles ())
-    {
-      htab_t htab;
-      struct elf_gnu_ifunc_cache *entry_p;
-      void **slot;
-
-      htab = elf_objfile_gnu_ifunc_cache_data.get (objfile);
-      if (htab == NULL)
-	continue;
-
-      entry_p = ((struct elf_gnu_ifunc_cache *)
-		 alloca (sizeof (*entry_p) + strlen (name)));
-      strcpy (entry_p->name, name);
-
-      slot = htab_find_slot (htab, entry_p, NO_INSERT);
-      if (slot == NULL)
-	continue;
-      entry_p = (struct elf_gnu_ifunc_cache *) *slot;
-      gdb_assert (entry_p != NULL);
-
-      if (addr_p)
-	*addr_p = entry_p->addr;
-      return 1;
-    }
-
-  return 0;
+  int found = 0;
+
+  /* FIXME: we only search the initial namespace.
+
+     To search other namespaces, we would need to provide context, e.g. in
+     form of an objfile in that namespace.  */
+  gdbarch_iterate_over_objfiles_in_search_order
+    (target_gdbarch (),
+     [name, &addr_p, &found] (struct objfile *objfile)
+       {
+	 htab_t htab;
+	 elf_gnu_ifunc_cache *entry_p;
+	 void **slot;
+
+	 htab = elf_objfile_gnu_ifunc_cache_data.get (objfile);
+	 if (htab == NULL)
+	   return 0;
+
+	 entry_p = ((elf_gnu_ifunc_cache *)
+		    alloca (sizeof (*entry_p) + strlen (name)));
+	 strcpy (entry_p->name, name);
+
+	 slot = htab_find_slot (htab, entry_p, NO_INSERT);
+	 if (slot == NULL)
+	   return 0;
+	 entry_p = (elf_gnu_ifunc_cache *) *slot;
+	 gdb_assert (entry_p != NULL);
+
+	 if (addr_p)
+	   *addr_p = entry_p->addr;
+
+	 found = 1;
+	 return 1;
+       }, nullptr);
+
+  return found;
 }
 
 /* Try to find the target resolved function entry address of a STT_GNU_IFUNC
@@ -810,50 +820,61 @@ elf_gnu_ifunc_resolve_by_got (const char *name, CORE_ADDR *addr_p)
 {
   char *name_got_plt;
   const size_t got_suffix_len = strlen (SYMBOL_GOT_PLT_SUFFIX);
+  int found = 0;
 
   name_got_plt = (char *) alloca (strlen (name) + got_suffix_len + 1);
   sprintf (name_got_plt, "%s" SYMBOL_GOT_PLT_SUFFIX, name);
 
-  for (objfile *objfile : current_program_space->objfiles ())
-    {
-      bfd *obfd = objfile->obfd;
-      struct gdbarch *gdbarch = objfile->arch ();
-      struct type *ptr_type = builtin_type (gdbarch)->builtin_data_ptr;
-      size_t ptr_size = TYPE_LENGTH (ptr_type);
-      CORE_ADDR pointer_address, addr;
-      asection *plt;
-      gdb_byte *buf = (gdb_byte *) alloca (ptr_size);
-      struct bound_minimal_symbol msym;
-
-      msym = lookup_minimal_symbol (name_got_plt, NULL, objfile);
-      if (msym.minsym == NULL)
-	continue;
-      if (msym.minsym->type () != mst_slot_got_plt)
-	continue;
-      pointer_address = msym.value_address ();
-
-      plt = bfd_get_section_by_name (obfd, ".plt");
-      if (plt == NULL)
-	continue;
-
-      if (msym.minsym->size () != ptr_size)
-	continue;
-      if (target_read_memory (pointer_address, buf, ptr_size) != 0)
-	continue;
-      addr = extract_typed_address (buf, ptr_type);
-      addr = gdbarch_convert_from_func_ptr_addr
-	(gdbarch, addr, current_inferior ()->top_target ());
-      addr = gdbarch_addr_bits_remove (gdbarch, addr);
-
-      if (elf_gnu_ifunc_record_cache (name, addr))
-	{
-	  if (addr_p != NULL)
-	    *addr_p = addr;
-	  return 1;
-	}
-    }
-
-  return 0;
+  /* FIXME: we only search the initial namespace.
+
+     To search other namespaces, we would need to provide context, e.g. in
+     form of an objfile in that namespace.  */
+  gdbarch_iterate_over_objfiles_in_search_order
+    (target_gdbarch (),
+     [name, name_got_plt, &addr_p, &found] (struct objfile *objfile)
+       {
+	 bfd *obfd = objfile->obfd;
+	 struct gdbarch *gdbarch = objfile->arch ();
+	 type *ptr_type = builtin_type (gdbarch)->builtin_data_ptr;
+	 size_t ptr_size = TYPE_LENGTH (ptr_type);
+	 CORE_ADDR pointer_address, addr;
+	 asection *plt;
+	 gdb_byte *buf = (gdb_byte *) alloca (ptr_size);
+	 bound_minimal_symbol msym;
+
+	 msym = lookup_minimal_symbol (name_got_plt, NULL, objfile);
+	 if (msym.minsym == NULL)
+	   return 0;
+	 if (msym.minsym->type () != mst_slot_got_plt)
+	   return 0;
+	 pointer_address = msym.value_address ();
+
+	 plt = bfd_get_section_by_name (obfd, ".plt");
+	 if (plt == NULL)
+	   return 0;
+
+	 if (msym.minsym->size () != ptr_size)
+	   return 0;
+	 if (target_read_memory (pointer_address, buf, ptr_size) != 0)
+	   return 0;
+	 addr = extract_typed_address (buf, ptr_type);
+	 addr = gdbarch_convert_from_func_ptr_addr
+	   (gdbarch, addr, current_inferior ()->top_target ());
+	 addr = gdbarch_addr_bits_remove (gdbarch, addr);
+
+	 if (elf_gnu_ifunc_record_cache (name, addr))
+	   {
+	     if (addr_p != NULL)
+	       *addr_p = addr;
+
+	     found = 1;
+	     return 1;
+	   }
+
+	 return 0;
+       }, nullptr);
+
+  return found;
 }
 
 /* Try to find the target resolved function entry address of a STT_GNU_IFUNC
-- 
2.35.3

Intel Deutschland GmbH
Registered Address: Am Campeon 10, 85579 Neubiberg, Germany
Tel: +49 89 99 8853-0, www.intel.de <http://www.intel.de>
Managing Directors: Christin Eisenschmid, Sharon Heck, Tiffany Doon Silva  
Chairperson of the Supervisory Board: Nicole Lau
Registered Office: Munich
Commercial Register: Amtsgericht Muenchen HRB 186928


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

* [PATCH v5 15/15] gdb, solib-svr4: support namespaces in DSO iteration
  2022-06-02 13:24 [PATCH v5 00/15] basic linker namespace support Markus Metzger
                   ` (13 preceding siblings ...)
  2022-06-02 13:25 ` [PATCH v5 14/15] gdb: update gnu ifunc resolve Markus Metzger
@ 2022-06-02 13:25 ` Markus Metzger
  2022-06-25  0:42   ` Kevin Buettner
  2022-07-15 10:30 ` [PATCH v5 00/15] basic linker namespace support Metzger, Markus T
  15 siblings, 1 reply; 52+ messages in thread
From: Markus Metzger @ 2022-06-02 13:25 UTC (permalink / raw)
  To: gdb-patches

When looking up names, GDB needs to stay within one linker namespace to
find the correct instance in case the same name is provided in more than
one namespace.

Modify svr4_iterate_over_objfiles_in_search_order() to stay within the
namespace of the current_objfile argument.  If no current_objfile is
provided (i.e. it is nullptr), iterate over objfiles in the initial
namespace.

For objfiles that do not have a corresponding so_list to provide the
namespace, assume that the objfile was loaded into the initial namespace.
This would cover the main executable objfile (which is indeed loaded into
the initial namespace) as well as manually added symbol files.

Expected fails:

  - gdb.base/non-lazy-array-index.exp: the expression parser may lookup
    global symbols, which may result in xfers to read auxv for determining
    the debug base as part of svr4_iterate_over_objfiles_in_search_order().

  - gdb.server/non-lazy-array-index.exp: symbol lookup may access the
    target to read AUXV in order to determine the debug base for SVR4
    linker namespaces.

Known issues:

  - get_symbol_address() and get_msymbol_address() search objfiles for a
    'better' match.  This was introduced by

        4b610737f02 Handle copy relocations

    to handle copy relocations but it now causes a wrong address to be
    read after symbol lookup actually cound the correct symbol.  This can
    be seen, for example, with gdb.base/dlmopen.exp when compiled with
    clang.

  - gnu ifuncs are only looked up in the initial namespace.

  - lookup_minimal_symbol() and lookup_minimal_symbol_text() directly
    iterate over objfiles and are not aware of linker namespaces.
---
 gdb/solib-svr4.c                              | 78 ++++++++++++++++++-
 gdb/testsuite/gdb.base/dlmopen-lib-dep.c      | 21 +++++
 gdb/testsuite/gdb.base/dlmopen-lib.c          |  5 +-
 gdb/testsuite/gdb.base/dlmopen.exp            | 40 ++++++++--
 .../gdb.base/non-lazy-array-index.exp         | 18 ++++-
 .../gdb.server/bkpt-other-inferior.exp        | 13 +++-
 6 files changed, 159 insertions(+), 16 deletions(-)
 create mode 100644 gdb/testsuite/gdb.base/dlmopen-lib-dep.c

diff --git a/gdb/solib-svr4.c b/gdb/solib-svr4.c
index ca396acf24f..8d23905235e 100644
--- a/gdb/solib-svr4.c
+++ b/gdb/solib-svr4.c
@@ -3316,9 +3316,60 @@ svr4_lp64_fetch_link_map_offsets (void)
 
 struct target_so_ops svr4_so_ops;
 
+/* Return the DSO matching OBJFILE or nullptr if none can be found.  */
+
+static so_list *
+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 (so_list *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.
+
+   Current callers treat zero as initial namespace so they are doing the
+   right thing for the main executable.  */
+
+static CORE_ADDR
+find_debug_base_for_solib (so_list *solib)
+{
+  if (solib == nullptr)
+    return 0;
+
+  svr4_info *info = get_svr4_info (current_program_space);
+  gdb_assert (info != nullptr);
+  for (const std::pair<CORE_ADDR, so_list *> tuple
+	 : info->solib_lists)
+    {
+      CORE_ADDR debug_base = tuple.first;
+      so_list *solist = tuple.second;
+
+      for (; solist != nullptr; solist = solist->next)
+	if (svr4_same (solib, solist))
+	  return debug_base;
+    }
+
+  return 0;
+}
+
 /* Search order for ELF DSOs linked with -Bsymbolic.  Those DSOs have a
-   different rule for symbol lookup.  The lookup begins here in the DSO, not in
-   the main executable.  */
+   different rule for symbol lookup.  The lookup begins here in the DSO,
+   not in the main executable.  When starting from CURRENT_OBJFILE, we
+   stay in the same namespace as that file.  Otherwise, we only consider
+   the initial namespace.  */
 
 static void
 svr4_iterate_over_objfiles_in_search_order
@@ -3347,10 +3398,33 @@ svr4_iterate_over_objfiles_in_search_order
 	}
     }
 
+  /* The linker namespace to iterate identified by the address of its
+     r_debug object, defaulting to the initial namespace.  */
+  CORE_ADDR initial = elf_locate_base ();
+  so_list *curr_solib = find_solib_for_objfile (current_objfile);
+  CORE_ADDR debug_base = find_debug_base_for_solib (curr_solib);
+  if (debug_base == 0)
+    debug_base = initial;
+
   for (objfile *objfile : current_program_space->objfiles ())
     {
       if (checked_current_objfile && objfile == current_objfile)
 	continue;
+
+      /* Try to determine the namespace into which objfile was loaded.
+
+	 If we fail, e.g. for manually added symbol files or for the main
+	 executable, we assume that they were added to the initial
+	 namespace.  */
+      so_list *solib = find_solib_for_objfile (objfile);
+      CORE_ADDR solib_base = find_debug_base_for_solib (solib);
+      if (solib_base == 0)
+	solib_base = initial;
+
+      /* Ignore objfiles that were added to a different namespace.  */
+      if (solib_base != debug_base)
+	continue;
+
       if (cb (objfile))
 	return;
     }
diff --git a/gdb/testsuite/gdb.base/dlmopen-lib-dep.c b/gdb/testsuite/gdb.base/dlmopen-lib-dep.c
new file mode 100644
index 00000000000..c996d76dcb6
--- /dev/null
+++ b/gdb/testsuite/gdb.base/dlmopen-lib-dep.c
@@ -0,0 +1,21 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2021-2022 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+__attribute__((visibility ("default")))
+int gdb_dlmopen_glob = 1;
diff --git a/gdb/testsuite/gdb.base/dlmopen-lib.c b/gdb/testsuite/gdb.base/dlmopen-lib.c
index 616bf97b4f5..4645bfde2a6 100644
--- a/gdb/testsuite/gdb.base/dlmopen-lib.c
+++ b/gdb/testsuite/gdb.base/dlmopen-lib.c
@@ -17,9 +17,12 @@
 
 */
 
+extern int gdb_dlmopen_glob;
+
 __attribute__((visibility ("default")))
 int
 inc (int n)
 {
-  return n + 1;  /* bp.inc.  */
+  int amount = gdb_dlmopen_glob;
+  return n + amount;  /* bp.inc.  */
 }
diff --git a/gdb/testsuite/gdb.base/dlmopen.exp b/gdb/testsuite/gdb.base/dlmopen.exp
index 8e86d5d5ccc..a80db75f9ac 100644
--- a/gdb/testsuite/gdb.base/dlmopen.exp
+++ b/gdb/testsuite/gdb.base/dlmopen.exp
@@ -32,13 +32,22 @@ set basename_lib dlmopen-lib
 set srcfile_lib $srcdir/$subdir/$basename_lib.c
 set binfile_lib1 [standard_output_file $basename_lib.1.so]
 set binfile_lib2 [standard_output_file $basename_lib.2.so]
+set srcfile_lib_dep $srcdir/$subdir/$basename_lib-dep.c
+set binfile_lib_dep [standard_output_file $basename_lib-dep.so]
 
-if { [gdb_compile_shlib $srcfile_lib $binfile_lib1 {debug}] != "" } {
+if { [gdb_compile_shlib $srcfile_lib_dep $binfile_lib_dep {debug}] != "" } {
     untested "failed to prepare shlib"
     return -1
 }
 
-if { [gdb_compile_shlib $srcfile_lib $binfile_lib2 {debug}] != "" } {
+if { [gdb_compile_shlib $srcfile_lib $binfile_lib1 \
+	  [list debug shlib_load libs=$binfile_lib_dep]] != "" } {
+    untested "failed to prepare shlib"
+    return -1
+}
+
+if { [gdb_compile_shlib $srcfile_lib $binfile_lib2 \
+	  [list debug shlib_load libs=$binfile_lib_dep]] != "" } {
     untested "failed to prepare shlib"
     return -1
 }
@@ -46,7 +55,7 @@ if { [gdb_compile_shlib $srcfile_lib $binfile_lib2 {debug}] != "" } {
 if { [prepare_for_testing "failed to prepare" $testfile $srcfile \
 	  [list additional_flags=-DDSO1_NAME=\"$binfile_lib1\" \
 	       additional_flags=-DDSO2_NAME=\"$binfile_lib2\" \
-	       libs=-ldl debug]] } {
+	       shlib_load debug]] } {
     return -1
 }
 
@@ -73,7 +82,7 @@ proc check_dso_count { dso num } {
 }
 
 # The DSO part of the test.  We run it once per DSO call.
-proc test_dlmopen_one { ndso1 ndso2 } {
+proc test_dlmopen_one { ndso1 ndso2 exp_glob } {
     global srcfile_lib srcfile_lib basename_lib bp_inc
 
     # Try to reach the breakpoint in the dynamically loaded library.
@@ -87,16 +96,31 @@ proc test_dlmopen_one { ndso1 ndso2 } {
     # This might help debugging.
     gdb_test "info breakpoints" ".*"
     gdb_test "print \$pc" ".*"
+
+    # We expect different instances of GDB_DLMOPEN_GLOB per DSO.
+    gdb_test "print amount" "= $exp_glob"
+    gdb_test "print gdb_dlmopen_glob" "= $exp_glob"
+
+    # Modify that DSO's instance, which should leave the others intact.
+    gdb_test "print &gdb_dlmopen_glob" "= .*"
+    gdb_test "print gdb_dlmopen_glob = -1" "= -1"
 }
 
 # The actual test.  We run it twice.
 proc test_dlmopen {} {
     global srcfile basename_lib bp_main
 
-    with_test_prefix "dlmopen 1" { test_dlmopen_one 3 1 }
-    with_test_prefix "dlmopen 2" { test_dlmopen_one 2 1 }
-    with_test_prefix "dlmopen 3" { test_dlmopen_one 1 1 }
-    with_test_prefix "dlmopen 4" { test_dlmopen_one 0 1 }
+    # Note that when loading dlmopen-lib.1.so and dlmopen-lib.2.so into
+    # the same namespace, dlmopen-lib-dep.so is loaded only once, so in
+    # this case, the changes to gdb_dlmopen_glob inside test_dlmopen_one
+    # will actually be visible.
+    #
+    # Hence, we supply the expected value of this variable as argument to
+    # test_dlmopen_one.
+    with_test_prefix "dlmopen 1" { test_dlmopen_one 3 1 1 }
+    with_test_prefix "dlmopen 2" { test_dlmopen_one 2 1 1 }
+    with_test_prefix "dlmopen 3" { test_dlmopen_one 1 1 1 }
+    with_test_prefix "dlmopen 4" { test_dlmopen_one 0 1 -1 }
 
     with_test_prefix "main" {
 	# Try to reach the breakpoint in the dynamically loaded library.
diff --git a/gdb/testsuite/gdb.base/non-lazy-array-index.exp b/gdb/testsuite/gdb.base/non-lazy-array-index.exp
index 6b596eb042a..66686cfdd63 100644
--- a/gdb/testsuite/gdb.base/non-lazy-array-index.exp
+++ b/gdb/testsuite/gdb.base/non-lazy-array-index.exp
@@ -40,6 +40,7 @@ gdb_test_no_output "set debug target 1"
 # To check this we 'set debug target 1' (above), and then look for any
 # xfer_partial calls; there shouldn't be any.
 set saw_memory_access false
+set saw_auxv_parse false
 gdb_test_multiple "p \$.array\[1\]" "" {
     -re "^p \\\$\\.array\\\[1\\\]\r\n" {
 	exp_continue
@@ -48,6 +49,10 @@ gdb_test_multiple "p \$.array\[1\]" "" {
 	set saw_memory_access true
 	exp_continue
     }
+    -re "^->\[^\r\n\]+auxv_parse\[^\r\n\]+\r\n" {
+	set saw_auxv_parse true
+	exp_continue
+    }
     -re "^->\[^\r\n\]+\r\n" {
 	exp_continue
     }
@@ -58,7 +63,18 @@ gdb_test_multiple "p \$.array\[1\]" "" {
 	exp_continue
     }
     -re "^\\\$${decimal} = 2\r\n$gdb_prompt " {
-	gdb_assert { ! $saw_memory_access }
+	if { $saw_memory_access } {
+	    if { $saw_auxv_parse } {
+		# The expression parser may look up global symbols, which
+		# may require reading AUXV in order to determine the debug
+		# base for SVR4 linker namespaces.
+		xfail "$gdb_test_name"
+	    } else {
+		fail "$gdb_test_name"
+	    }
+	} else {
+	    pass "$gdb_test_name"
+	}
     }
 }
 
diff --git a/gdb/testsuite/gdb.server/bkpt-other-inferior.exp b/gdb/testsuite/gdb.server/bkpt-other-inferior.exp
index d01b911d1ed..452c7c93db3 100644
--- a/gdb/testsuite/gdb.server/bkpt-other-inferior.exp
+++ b/gdb/testsuite/gdb.server/bkpt-other-inferior.exp
@@ -78,13 +78,18 @@ foreach inf_sel {1 2} {
 
 	gdb_test_no_output "set debug remote 1"
 
-	set test "set breakpoint"
-	gdb_test_multiple "break -q main" $test {
+	gdb_test_multiple "break -q main" "set breakpoint" {
+	    -re "Sending packet: \\\$qXfer:auxv:read.*$gdb_prompt $" {
+		# Symbol lookup may access the target to read AUXV in
+		# order to determine the debug base for SVR4 linker
+		# namespaces.
+		xfail "$gdb_test_name"
+	    }
 	    -re "Sending packet.*$gdb_prompt $" {
-		fail $test
+		fail "$gdb_test_name"
 	    }
 	    -re "^break -q main\r\nBreakpoint .* at .*$gdb_prompt $" {
-		pass $test
+		pass "$gdb_test_name"
 	    }
 	}
 
-- 
2.35.3

Intel Deutschland GmbH
Registered Address: Am Campeon 10, 85579 Neubiberg, Germany
Tel: +49 89 99 8853-0, www.intel.de <http://www.intel.de>
Managing Directors: Christin Eisenschmid, Sharon Heck, Tiffany Doon Silva  
Chairperson of the Supervisory Board: Nicole Lau
Registered Office: Munich
Commercial Register: Amtsgericht Muenchen HRB 186928


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

* Re: [PATCH v5 05/15] gdb, gdbserver: extend RSP to support namespaces
  2022-06-02 13:25 ` [PATCH v5 05/15] gdb, gdbserver: extend RSP to support namespaces Markus Metzger
@ 2022-06-02 16:09   ` Eli Zaretskii
  2022-06-19  4:32   ` Kevin Buettner
  1 sibling, 0 replies; 52+ messages in thread
From: Eli Zaretskii @ 2022-06-02 16:09 UTC (permalink / raw)
  To: Markus Metzger; +Cc: gdb-patches

> Date: Thu,  2 Jun 2022 15:25:04 +0200
> From: Markus Metzger via Gdb-patches <gdb-patches@sourceware.org>
> 
> Introduce a new qXfer:libraries-svr4:read annex key/value pair
> 
>     lmid=<namespace identifier>
> 
> to be used together with start and prev to provide the namespace of start
> and prev to gdbserver.
> 
> Unknown key/value pairs are ignored by gdbserver so no new supports check
> is needed.
> 
> Introduce a new library-list-svr4 library attribute
> 
>     lmid
> 
> to provide the namespace of a library entry to GDB.
> 
> This implementation uses the address of a namespace's r_debug object as
> namespace identifier.
> 
> This should have incremented the minor version but since unknown XML
> attributes are ignored, anyway, and since changing the version results in
> a warning from GDB, the version is left at 1.0.
> ---
>  gdb/doc/gdb.texinfo                | 16 +++++++++++--
>  gdb/features/library-list-svr4.dtd |  4 ++++
>  gdb/solib-svr4.c                   | 38 +++++++++++++++++++++++++++---
>  gdbserver/linux-low.cc             | 26 +++++++++++++-------
>  4 files changed, 70 insertions(+), 14 deletions(-)

The gdb.texinfo part is OK.

Thanks.

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

* Re: [PATCH v5 02/15] gdb, solib-svr4: remove locate_base()
  2022-06-02 13:25 ` [PATCH v5 02/15] gdb, solib-svr4: remove locate_base() Markus Metzger
@ 2022-06-02 23:04   ` Kevin Buettner
  0 siblings, 0 replies; 52+ messages in thread
From: Kevin Buettner @ 2022-06-02 23:04 UTC (permalink / raw)
  To: Markus Metzger via Gdb-patches

On Thu,  2 Jun 2022 15:25:01 +0200
Markus Metzger via Gdb-patches <gdb-patches@sourceware.org> wrote:

> Whenever we call locate_base(), we clear info->debug_base directly before
> the call.  Thus, we never cache the base location as locate_base() had
> intended.
> 
> Move the svr4_have_link_map_offsets() check into elf_locate_base(), inline
> locate_base() at all call sites, and remove it.

Okay.

Kevin


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

* Re: [PATCH v5 01/15] gdb, testsuite: extend gdb_test_multiple checks
  2022-06-02 13:25 ` [PATCH v5 01/15] gdb, testsuite: extend gdb_test_multiple checks Markus Metzger
@ 2022-06-13  1:28   ` Kevin Buettner
  0 siblings, 0 replies; 52+ messages in thread
From: Kevin Buettner @ 2022-06-13  1:28 UTC (permalink / raw)
  To: Markus Metzger via Gdb-patches

Hi Markus,

On Thu,  2 Jun 2022 15:25:00 +0200
Markus Metzger via Gdb-patches <gdb-patches@sourceware.org> wrote:

> Check for
> 
>     warning: Corrupted shared library list
> 

Do you know the circumstances which produce this message?

Earlier this year, I was seeing it quite often, but now, at least
while running the test suite, I'm unable to reproduce it.  I'm
wondering if this was due to some bug in GDB which has since been
fixed?

Kevin


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

* Re: [PATCH v5 03/15] gdb, gdbserver: support dlmopen()
  2022-06-02 13:25 ` [PATCH v5 03/15] gdb, gdbserver: support dlmopen() Markus Metzger
@ 2022-06-19  4:02   ` Kevin Buettner
  2022-06-27 12:55     ` Metzger, Markus T
  0 siblings, 1 reply; 52+ messages in thread
From: Kevin Buettner @ 2022-06-19  4:02 UTC (permalink / raw)
  To: Markus Metzger via Gdb-patches; +Cc: Markus Metzger, Lu, Hongjiu

Hi Markus,

This patch looks pretty good.  Just a couple of comments/questions...

On Thu,  2 Jun 2022 15:25:02 +0200
Markus Metzger via Gdb-patches <gdb-patches@sourceware.org> wrote:

> diff --git a/gdb/solib-svr4.c b/gdb/solib-svr4.c
> index 6222f79a7a0..1f2abcf16ef 100644
[...]
> @@ -1258,49 +1338,110 @@ svr4_current_sos_direct (struct svr4_info *info)
>        if (library_list.main_lm)
>  	info->main_lm_addr = library_list.main_lm;
>  
> -      return library_list.head ? library_list.head : svr4_default_sos (info);
> +      /* Remove an empty special zero namespace so we know that when there
> +	 is one, it is actually used, and we have a flat list without
> +	 namespace information.  */
> +      if ((library_list.solib_lists.find (0)
> +	   != library_list.solib_lists.end ())
> +	  && (library_list.solib_lists[0] == nullptr))
> +	library_list.solib_lists.erase (0);
> +
> +      std::swap (info->solib_lists, library_list.solib_lists);
> +      return;
>      }
[...]
> @@ -1697,17 +1872,34 @@ solist_update_incremental (struct svr4_info *info, CORE_ADDR lm)
>        if (!svr4_current_sos_via_xfer_libraries (&library_list, annex))
>  	return 0;
>  
> -      tail->next = library_list.head;
> +      /* We expect gdbserver to provide updates for the namespace that
> +	 contains LM, which whould be this namespace...  */
> +      so_list *sos = nullptr;
> +      if (library_list.solib_lists.find (debug_base)
> +	  != library_list.solib_lists.end ())
> +	std::swap (sos, library_list.solib_lists[debug_base]);
> +      if (sos == nullptr)
> +	{
> +	  /* ...or for the special zero namespace for earlier versions...  */
> +	  if (library_list.solib_lists.find (0)
> +	      != library_list.solib_lists.end ())
> +	    std::swap (sos, library_list.solib_lists[0]);
[...]

I was puzzled for a while by the uses of std:swap() in the above
snippets of code.  I checked the rest of the GDB sources and found
that (at least in GDB) this is not a common idiom.  I'd appreciate
it if you could add a few lines of explanation for at least one
of them.

> diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp
> index 6aef39e5e02..98715fdc87e 100644
> --- a/gdb/testsuite/lib/gdb.exp
> +++ b/gdb/testsuite/lib/gdb.exp
> @@ -2451,6 +2451,102 @@ proc skip_shlib_tests {} {
>      return 1
>  }
>  
> +# Return 1 if we should skip dlmopen tests, 0 if we should not.
> +
> +proc skip_dlmopen_tests {} {
> +    global srcdir subdir gdb_prompt inferior_exited_re
> +
> +    # We need shared library support.
> +    if { [skip_shlib_tests] } {
> +	return 1
> +    }
> +
> +    set me "skip_dlmopen_tests"
> +    set lib {
> +	int foo (void) {
> +	    return 42;
> +	}
> +    }
> +    set src {
> +	#define _GNU_SOURCE
> +	#include <dlfcn.h>
> +	#include <link.h>
> +	#include <stdio.h>
> +	#include <errno.h>
> +
> +	int  main (void) {
> +	    struct r_debug *r_debug;
> +	    ElfW(Dyn) *dyn;
> +	    void *handle;
> +
> +	    /* The version is kept at 1 until we create a new namespace.  */
> +	    handle = dlmopen (LM_ID_NEWLM, DSO_NAME, RTLD_LAZY | RTLD_LOCAL);
> +	    if (!handle) {
> +		printf ("dlmopen failed: %s.\n", dlerror ());
> +		return 1;
> +	    }
> +
> +	    r_debug = 0;
> +	    /* Taken from /usr/include/link.h.  */
> +	    for (dyn = _DYNAMIC; dyn->d_tag != DT_NULL; ++dyn)
> +	        if (dyn->d_tag == DT_DEBUG)
> +	            r_debug = (struct r_debug *) dyn->d_un.d_ptr;
> +
> +	    if (!r_debug) {
> +	        printf ("r_debug not found.\n");
> +		return 1;
> +	    }
> +	    if (r_debug->r_version < 2) {
> +	        printf ("dlmopen debug not supported.\n");
> +		return 1;
> +	    }
> +	    printf ("dlmopen debug supported.\n");
> +	    return 0;
> +	}
> +    }
> +
> +    set libsrc [standard_temp_file "libfoo.c"]
> +    set libout [standard_temp_file "libfoo.so"]
> +    gdb_produce_source $libsrc $lib
> +
> +    if { [gdb_compile_shlib $libsrc $libout {debug}] != "" } {
> +	verbose -log "failed to build library"
> +	return 1
> +    }
> +    if { ![gdb_simple_compile $me $src executable \
> +	       [list shlib_load debug \
> +		    additional_flags=-DDSO_NAME=\"$libout\"]] } {
> +	verbose -log "failed to build executable"
> +        return 1
> +    }
> +
> +    gdb_exit
> +    gdb_start
> +    gdb_reinitialize_dir $srcdir/$subdir
> +    gdb_load $obj
> +
> +    if { [gdb_run_cmd] != 0 } {
> +	verbose -log "failed to start skip test"
> +	return 1
> +    }
> +    gdb_expect {
> +        -re "$inferior_exited_re normally.*${gdb_prompt} $" {
> +            set skip_dlmopen_tests 0
> +        }
> +        -re "$inferior_exited_re with code.*${gdb_prompt} $" {
> +            set skip_dlmopen_tests 1
> +        }
> +        default {
> +	    warning "\n$me: default case taken"
> +            set skip_dlmopen_tests 1
> +        }
> +    }
> +    gdb_exit
> +
> +    verbose "$me:  returning $skip_dlmopen_tests" 2
> +    return $skip_dlmopen_tests
> +}
> +
>  # Return 1 if we should skip tui related tests.

I'm wondering if this can be a gdb_caching_proc?  At the moment, there's
probably not much point since I think it's only used by the new test.
But if we end up with more tests which use it, it might be worthwhile.

Kevin


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

* Re: [PATCH v5 04/15] gdbserver: move main_lm handling into caller
  2022-06-02 13:25 ` [PATCH v5 04/15] gdbserver: move main_lm handling into caller Markus Metzger
@ 2022-06-19  4:22   ` Kevin Buettner
  0 siblings, 0 replies; 52+ messages in thread
From: Kevin Buettner @ 2022-06-19  4:22 UTC (permalink / raw)
  To: Markus Metzger via Gdb-patches

On Thu,  2 Jun 2022 15:25:03 +0200
Markus Metzger via Gdb-patches <gdb-patches@sourceware.org> wrote:

> When listing SVR4 shared libraries, special care has to be taken about the
> first library in the default namespace as that refers to the main
> executable.  The load map address of this main executable is provided in
> an attribute of the library-list-svr4 element.
> 
> Move that code from where we enumerate libraries inside a single namespace
> to where we generate the rest of the library-list-svr4 element.  This
> allows us to complete the library-list-svr4 element inside one function.
> 
> There should be no functional change.
> ---
>  gdbserver/linux-low.cc | 96 +++++++++++++++++++++---------------------
>  1 file changed, 48 insertions(+), 48 deletions(-)

LGTM.

Kevin


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

* Re: [PATCH v5 05/15] gdb, gdbserver: extend RSP to support namespaces
  2022-06-02 13:25 ` [PATCH v5 05/15] gdb, gdbserver: extend RSP to support namespaces Markus Metzger
  2022-06-02 16:09   ` Eli Zaretskii
@ 2022-06-19  4:32   ` Kevin Buettner
  1 sibling, 0 replies; 52+ messages in thread
From: Kevin Buettner @ 2022-06-19  4:32 UTC (permalink / raw)
  To: Markus Metzger via Gdb-patches

On Thu,  2 Jun 2022 15:25:04 +0200
Markus Metzger via Gdb-patches <gdb-patches@sourceware.org> wrote:

> Introduce a new qXfer:libraries-svr4:read annex key/value pair
> 
>     lmid=<namespace identifier>
> 
> to be used together with start and prev to provide the namespace of start
> and prev to gdbserver.
> 
> Unknown key/value pairs are ignored by gdbserver so no new supports check
> is needed.
> 
> Introduce a new library-list-svr4 library attribute
> 
>     lmid
> 
> to provide the namespace of a library entry to GDB.
> 
> This implementation uses the address of a namespace's r_debug object as
> namespace identifier.
> 
> This should have incremented the minor version but since unknown XML
> attributes are ignored, anyway, and since changing the version results in
> a warning from GDB, the version is left at 1.0.
> ---
>  gdb/doc/gdb.texinfo                | 16 +++++++++++--
>  gdb/features/library-list-svr4.dtd |  4 ++++
>  gdb/solib-svr4.c                   | 38 +++++++++++++++++++++++++++---
>  gdbserver/linux-low.cc             | 26 +++++++++++++-------
>  4 files changed, 70 insertions(+), 14 deletions(-)

Okay for everything but the doc changes.  (But Eli approved those, so it's
all okay.)

Kevin


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

* Re: [PATCH v5 06/15] gdb, compile: unlink objfile stored in module
  2022-06-02 13:25 ` [PATCH v5 06/15] gdb, compile: unlink objfile stored in module Markus Metzger
@ 2022-06-23 17:20   ` Kevin Buettner
  0 siblings, 0 replies; 52+ messages in thread
From: Kevin Buettner @ 2022-06-23 17:20 UTC (permalink / raw)
  To: Markus Metzger via Gdb-patches

On Thu,  2 Jun 2022 15:25:05 +0200
Markus Metzger via Gdb-patches <gdb-patches@sourceware.org> wrote:

> When cleaning up after a compile command, we iterate over all objfiles and
> unlink the first objfile with the same name as the one we compiled.
> 
> Since we already store a pointer to that objfile in the module and use it
> to get the name we're comparing against, there's no reason to iterate, at
> all.  We can simply use that objfile.
> 
> This further avoids potential issues when an objfile with the same name is
> loaded into a different linker namespace.
> ---
>  gdb/compile/compile-object-run.c | 21 +++++++++------------
>  1 file changed, 9 insertions(+), 12 deletions(-)

LGTM.

Kevin


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

* Re: [PATCH v5 07/15] gdb, python: use gdbarch_iterate_over_objfiles_in_search_order
  2022-06-02 13:25 ` [PATCH v5 07/15] gdb, python: use gdbarch_iterate_over_objfiles_in_search_order Markus Metzger
@ 2022-06-24 17:18   ` Kevin Buettner
  0 siblings, 0 replies; 52+ messages in thread
From: Kevin Buettner @ 2022-06-24 17:18 UTC (permalink / raw)
  To: Markus Metzger via Gdb-patches

On Thu,  2 Jun 2022 15:25:06 +0200
Markus Metzger via Gdb-patches <gdb-patches@sourceware.org> wrote:

> The implementation of gdb.lookup_objfile() iterates over all objfiles and
> compares their name or build id to the user-provided search string.
> 
> This will cause problems when supporting linker namespaces as the first
> objfile in any namespace will be found.  Instead, use
> gdbarch_iterate_over_objfiles_in_search_order to only consider the
> namespace of gdb.current_objfile() for the search, which defaults to the
> initial namespace when gdb.current_objfile() is None.
> ---
>  gdb/python/py-objfile.c | 116 +++++++++++++++++++---------------------
>  gdb/python/python.c     |   7 +--
>  gdb/python/python.h     |   6 +++
>  3 files changed, 64 insertions(+), 65 deletions(-)

Okay.

Kevin


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

* Re: [PATCH v5 08/15] gdb, ada: collect standard exceptions in all objfiles
  2022-06-02 13:25 ` [PATCH v5 08/15] gdb, ada: collect standard exceptions in all objfiles Markus Metzger
@ 2022-06-24 17:26   ` Kevin Buettner
  2022-07-18 16:49     ` Tom Tromey
  2022-07-18  5:35   ` Metzger, Markus T
  1 sibling, 1 reply; 52+ messages in thread
From: Kevin Buettner @ 2022-06-24 17:26 UTC (permalink / raw)
  To: Markus Metzger via Gdb-patches

On Thu,  2 Jun 2022 15:25:07 +0200
Markus Metzger via Gdb-patches <gdb-patches@sourceware.org> wrote:

> When searching for standard exceptions for Ada, we lookup the minimal
> symbol of each exception.  With linker namespaces there can be multiple
> instances in different namespaces.  Collect them all.
> ---
>  gdb/ada-lang.c | 30 +++++++++++++++++++++++-------
>  1 file changed, 23 insertions(+), 7 deletions(-)

I'm not an Ada expert, but this seems reasonable.

Kevin


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

* Re: [PATCH v5 09/15] gdb, ada: update ada_lookup_simple_minsym
  2022-06-02 13:25 ` [PATCH v5 09/15] gdb, ada: update ada_lookup_simple_minsym Markus Metzger
@ 2022-06-24 23:42   ` Kevin Buettner
  2022-07-18 17:02   ` Tom Tromey
  1 sibling, 0 replies; 52+ messages in thread
From: Kevin Buettner @ 2022-06-24 23:42 UTC (permalink / raw)
  To: Markus Metzger via Gdb-patches

On Thu,  2 Jun 2022 15:25:08 +0200
Markus Metzger via Gdb-patches <gdb-patches@sourceware.org> wrote:

> Iterate over objfile in search order using the objfile of the context
> block as current_objfile so the iteration can stay inside the block's
> linker namespace.
> ---
>  gdb/ada-exp.y  |  9 ++++++++-
>  gdb/ada-lang.c | 32 ++++++++++++++++++--------------
>  gdb/ada-lang.h |  3 ++-
>  3 files changed, 28 insertions(+), 16 deletions(-)

LGTM.

Kevin


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

* Re: [PATCH v5 10/15] gdb, ada: update ada_add_all_symbols
  2022-06-02 13:25 ` [PATCH v5 10/15] gdb, ada: update ada_add_all_symbols Markus Metzger
@ 2022-06-24 23:53   ` Kevin Buettner
  2022-07-18  5:36   ` Metzger, Markus T
  2022-07-18 16:56   ` Tom Tromey
  2 siblings, 0 replies; 52+ messages in thread
From: Kevin Buettner @ 2022-06-24 23:53 UTC (permalink / raw)
  To: Markus Metzger via Gdb-patches

On Thu,  2 Jun 2022 15:25:09 +0200
Markus Metzger via Gdb-patches <gdb-patches@sourceware.org> wrote:

> Iterate over objfile in search order using the objfile of the context
> block as current_objfile so the iteration can stay inside the block's
> linker namespace.
> ---
>  gdb/ada-lang.c | 66 +++++++++++++++++++++++++++++++++-----------------
>  1 file changed, 44 insertions(+), 22 deletions(-)

This (also) looks reasonable to me. However, as stated in another
review, I'm not an expert in this area; someone who is might want
to give it a look...

Kevin


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

* Re: [PATCH v5 11/15] gdb, cp: update add_symbol_overload_list_qualified
  2022-06-02 13:25 ` [PATCH v5 11/15] gdb, cp: update add_symbol_overload_list_qualified Markus Metzger
@ 2022-06-24 23:59   ` Kevin Buettner
  0 siblings, 0 replies; 52+ messages in thread
From: Kevin Buettner @ 2022-06-24 23:59 UTC (permalink / raw)
  To: Markus Metzger via Gdb-patches

On Thu,  2 Jun 2022 15:25:10 +0200
Markus Metzger via Gdb-patches <gdb-patches@sourceware.org> wrote:

> Iterate over objfiles in search order using the objfile of the selected
> block as current_objfile so the iteration can stay inside the block's
> linker namespace.
> ---
>  gdb/cp-support.c | 48 ++++++++++++++++++++++++------------------------
>  1 file changed, 24 insertions(+), 24 deletions(-)

LGTM.

Kevin


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

* Re: [PATCH v5 12/15] gdb, hppa: remove unused hppa_lookup_stub_minimal_symbol
  2022-06-02 13:25 ` [PATCH v5 12/15] gdb, hppa: remove unused hppa_lookup_stub_minimal_symbol Markus Metzger
@ 2022-06-25  0:01   ` Kevin Buettner
  0 siblings, 0 replies; 52+ messages in thread
From: Kevin Buettner @ 2022-06-25  0:01 UTC (permalink / raw)
  To: Markus Metzger via Gdb-patches

On Thu,  2 Jun 2022 15:25:11 +0200
Markus Metzger via Gdb-patches <gdb-patches@sourceware.org> wrote:

> I stumbled over this while reviewing all objfiles traversals with regards
> to impact of linker namespaces.
> 
> Recursive grep only finds two occurrences of hppa_lookup_stub_minimal_symbol:
>   - the declaration in hppa-tdep.h.
>   - the definition in hppa-tdep.c.
> 
> There appear to be no calls to this function.  Remove it.
> ---
>  gdb/hppa-tdep.c | 31 -------------------------------
>  gdb/hppa-tdep.h |  4 ----
>  2 files changed, 35 deletions(-)

Okay.

Kevin


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

* Re: [PATCH v5 13/15] gdb, symtab: inline find_quick_global_symbol_language
  2022-06-02 13:25 ` [PATCH v5 13/15] gdb, symtab: inline find_quick_global_symbol_language Markus Metzger
@ 2022-06-25  0:16   ` Kevin Buettner
  0 siblings, 0 replies; 52+ messages in thread
From: Kevin Buettner @ 2022-06-25  0:16 UTC (permalink / raw)
  To: Markus Metzger via Gdb-patches

On Thu,  2 Jun 2022 15:25:12 +0200
Markus Metzger via Gdb-patches <gdb-patches@sourceware.org> wrote:

> There is only one use of find_quick_global_symbol_language that calls it
> for the special symbol "main".
> 
> Inline the function as it is probably not correct in the general case
> where we may have multiple instances of global symbols with the same name
> but different languages in different libraries in different linker
> namespaces.
> 
> Further, change the objfiles iteration into a call to
> gdbarch_iterate_over_objfiles_in_search_order, which would only search the
> initial linker namespace, where we expect "main" to be located.

Okay.

Kevin


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

* Re: [PATCH v5 14/15] gdb: update gnu ifunc resolve
  2022-06-02 13:25 ` [PATCH v5 14/15] gdb: update gnu ifunc resolve Markus Metzger
@ 2022-06-25  0:34   ` Kevin Buettner
  0 siblings, 0 replies; 52+ messages in thread
From: Kevin Buettner @ 2022-06-25  0:34 UTC (permalink / raw)
  To: Markus Metzger via Gdb-patches

On Thu,  2 Jun 2022 15:25:13 +0200
Markus Metzger via Gdb-patches <gdb-patches@sourceware.org> wrote:

> Update elf_gnu_ifunc_resolve_by_cache() and elf_gnu_ifunc_resolve_by_got()
> to use gdbarch_iterate_over_objfiles_in_search_order() in order to
> restrict the objfile traversal to the initial namespace.
> 
> In order to extend this to other namespaces, we'd need to provide context,
> e.g. via an objfile inside that namespace.
> ---
>  gdb/elfread.c | 153 ++++++++++++++++++++++++++++----------------------
>  1 file changed, 87 insertions(+), 66 deletions(-)
> 

Okay.

(Though I do wish that 'found' could be declared as bool instead of int.)

Kevin


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

* Re: [PATCH v5 15/15] gdb, solib-svr4: support namespaces in DSO iteration
  2022-06-02 13:25 ` [PATCH v5 15/15] gdb, solib-svr4: support namespaces in DSO iteration Markus Metzger
@ 2022-06-25  0:42   ` Kevin Buettner
  0 siblings, 0 replies; 52+ messages in thread
From: Kevin Buettner @ 2022-06-25  0:42 UTC (permalink / raw)
  To: Markus Metzger via Gdb-patches

On Thu,  2 Jun 2022 15:25:14 +0200
Markus Metzger via Gdb-patches <gdb-patches@sourceware.org> wrote:

> When looking up names, GDB needs to stay within one linker namespace to
> find the correct instance in case the same name is provided in more than
> one namespace.
> 
> Modify svr4_iterate_over_objfiles_in_search_order() to stay within the
> namespace of the current_objfile argument.  If no current_objfile is
> provided (i.e. it is nullptr), iterate over objfiles in the initial
> namespace.
> 
> For objfiles that do not have a corresponding so_list to provide the
> namespace, assume that the objfile was loaded into the initial namespace.
> This would cover the main executable objfile (which is indeed loaded into
> the initial namespace) as well as manually added symbol files.
> 
> Expected fails:
> 
>   - gdb.base/non-lazy-array-index.exp: the expression parser may lookup
>     global symbols, which may result in xfers to read auxv for determining
>     the debug base as part of svr4_iterate_over_objfiles_in_search_order().
> 
>   - gdb.server/non-lazy-array-index.exp: symbol lookup may access the
>     target to read AUXV in order to determine the debug base for SVR4
>     linker namespaces.
> 
> Known issues:
> 
>   - get_symbol_address() and get_msymbol_address() search objfiles for a
>     'better' match.  This was introduced by
> 
>         4b610737f02 Handle copy relocations
> 
>     to handle copy relocations but it now causes a wrong address to be
>     read after symbol lookup actually cound the correct symbol.  This can
>     be seen, for example, with gdb.base/dlmopen.exp when compiled with
>     clang.
> 
>   - gnu ifuncs are only looked up in the initial namespace.
> 
>   - lookup_minimal_symbol() and lookup_minimal_symbol_text() directly
>     iterate over objfiles and are not aware of linker namespaces.
> ---
>  gdb/solib-svr4.c                              | 78 ++++++++++++++++++-
>  gdb/testsuite/gdb.base/dlmopen-lib-dep.c      | 21 +++++
>  gdb/testsuite/gdb.base/dlmopen-lib.c          |  5 +-
>  gdb/testsuite/gdb.base/dlmopen.exp            | 40 ++++++++--
>  .../gdb.base/non-lazy-array-index.exp         | 18 ++++-
>  .../gdb.server/bkpt-other-inferior.exp        | 13 +++-
>  6 files changed, 159 insertions(+), 16 deletions(-)
>  create mode 100644 gdb/testsuite/gdb.base/dlmopen-lib-dep.c

Okay.

Kevin


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

* RE: [PATCH v5 03/15] gdb, gdbserver: support dlmopen()
  2022-06-19  4:02   ` Kevin Buettner
@ 2022-06-27 12:55     ` Metzger, Markus T
  2022-06-30 22:35       ` Kevin Buettner
  0 siblings, 1 reply; 52+ messages in thread
From: Metzger, Markus T @ 2022-06-27 12:55 UTC (permalink / raw)
  To: Kevin Buettner; +Cc: Lu, Lu, Hongjiu, Markus Metzger via Gdb-patches

Thanks for your review, Kevin,


>> diff --git a/gdb/solib-svr4.c b/gdb/solib-svr4.c
>> index 6222f79a7a0..1f2abcf16ef 100644
>[...]
>> @@ -1697,17 +1872,34 @@ solist_update_incremental (struct svr4_info *info,
>CORE_ADDR lm)
>>        if (!svr4_current_sos_via_xfer_libraries (&library_list, annex))
>>  	return 0;
>>
>> -      tail->next = library_list.head;
>> +      /* We expect gdbserver to provide updates for the namespace that
>> +	 contains LM, which whould be this namespace...  */
>> +      so_list *sos = nullptr;
>> +      if (library_list.solib_lists.find (debug_base)
>> +	  != library_list.solib_lists.end ())
>> +	std::swap (sos, library_list.solib_lists[debug_base]);
>> +      if (sos == nullptr)
>> +	{
>> +	  /* ...or for the special zero namespace for earlier versions...  */
>> +	  if (library_list.solib_lists.find (0)
>> +	      != library_list.solib_lists.end ())
>> +	    std::swap (sos, library_list.solib_lists[0]);
>[...]
>
>I was puzzled for a while by the uses of std:swap() in the above
>snippets of code.  I checked the rest of the GDB sources and found
>that (at least in GDB) this is not a common idiom.  I'd appreciate
>it if you could add a few lines of explanation for at least one
>of them.

Do those comments help?

diff --git a/gdb/solib-svr4.c b/gdb/solib-svr4.c
index 1f2abcf16ef..b231888b001 100644
--- a/gdb/solib-svr4.c
+++ b/gdb/solib-svr4.c
@@ -1346,6 +1346,10 @@ svr4_current_sos_direct (struct svr4_info *info)
          && (library_list.solib_lists[0] == nullptr))
        library_list.solib_lists.erase (0);
 
+      /* Replace the (empty) solib_lists in INFO with the one generated
+        from the target.  We don't want to copy it on assignment and then
+        delete the original afterwards, so let's just swap the
+        internals.  */
       std::swap (info->solib_lists, library_list.solib_lists);
       return;
     }
@@ -1872,7 +1876,11 @@ solist_update_incremental (svr4_info *info, CORE_ADDR debug_base,
       if (!svr4_current_sos_via_xfer_libraries (&library_list, annex))
        return 0;
 
-      /* We expect gdbserver to provide updates for the namespace that
+      /* Get the so list from the target.  We replace the list in the
+         target response so we can easily check that the response only
+         covers one namespace.
+
+        We expect gdbserver to provide updates for the namespace that
         contains LM, which whould be this namespace...  */
       so_list *sos = nullptr;
       if (library_list.solib_lists.find (debug_base)


>> diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp
>> index 6aef39e5e02..98715fdc87e 100644
>> --- a/gdb/testsuite/lib/gdb.exp
>> +++ b/gdb/testsuite/lib/gdb.exp
>> @@ -2451,6 +2451,102 @@ proc skip_shlib_tests {} {
>>      return 1
>>  }
>>
>> +# Return 1 if we should skip dlmopen tests, 0 if we should not.
>> +
>> +proc skip_dlmopen_tests {} {
>> +    global srcdir subdir gdb_prompt inferior_exited_re
>> +
[...]
>> +    verbose "$me:  returning $skip_dlmopen_tests" 2
>> +    return $skip_dlmopen_tests
>> +}
>> +
>>  # Return 1 if we should skip tui related tests.
>
>I'm wondering if this can be a gdb_caching_proc?  At the moment, there's
>probably not much point since I think it's only used by the new test.
>But if we end up with more tests which use it, it might be worthwhile.

Makes sense.

thanks,
markus.
Intel Deutschland GmbH
Registered Address: Am Campeon 10, 85579 Neubiberg, Germany
Tel: +49 89 99 8853-0, www.intel.de <http://www.intel.de>
Managing Directors: Christin Eisenschmid, Sharon Heck, Tiffany Doon Silva  
Chairperson of the Supervisory Board: Nicole Lau
Registered Office: Munich
Commercial Register: Amtsgericht Muenchen HRB 186928


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

* Re: [PATCH v5 03/15] gdb, gdbserver: support dlmopen()
  2022-06-27 12:55     ` Metzger, Markus T
@ 2022-06-30 22:35       ` Kevin Buettner
  0 siblings, 0 replies; 52+ messages in thread
From: Kevin Buettner @ 2022-06-30 22:35 UTC (permalink / raw)
  To: Metzger, Markus T; +Cc: gdb-patches, Lu, Lu, Hongjiu

On Mon, 27 Jun 2022 12:55:57 +0000
"Metzger, Markus T" <markus.t.metzger@intel.com> wrote:

> Thanks for your review, Kevin,
[...]
> >I was puzzled for a while by the uses of std:swap() in the above
> >snippets of code.  I checked the rest of the GDB sources and found
> >that (at least in GDB) this is not a common idiom.  I'd appreciate
> >it if you could add a few lines of explanation for at least one
> >of them.  
> 
> Do those comments help?

Yes!  Thanks for adding them.

Kevin

> 
> diff --git a/gdb/solib-svr4.c b/gdb/solib-svr4.c
> index 1f2abcf16ef..b231888b001 100644
> --- a/gdb/solib-svr4.c
> +++ b/gdb/solib-svr4.c
> @@ -1346,6 +1346,10 @@ svr4_current_sos_direct (struct svr4_info *info)
>           && (library_list.solib_lists[0] == nullptr))
>         library_list.solib_lists.erase (0);
>  
> +      /* Replace the (empty) solib_lists in INFO with the one generated
> +        from the target.  We don't want to copy it on assignment and then
> +        delete the original afterwards, so let's just swap the
> +        internals.  */
>        std::swap (info->solib_lists, library_list.solib_lists);
>        return;
>      }
> @@ -1872,7 +1876,11 @@ solist_update_incremental (svr4_info *info, CORE_ADDR debug_base,
>        if (!svr4_current_sos_via_xfer_libraries (&library_list, annex))
>         return 0;
>  
> -      /* We expect gdbserver to provide updates for the namespace that
> +      /* Get the so list from the target.  We replace the list in the
> +         target response so we can easily check that the response only
> +         covers one namespace.
> +
> +        We expect gdbserver to provide updates for the namespace that
>          contains LM, which whould be this namespace...  */
>        so_list *sos = nullptr;
>        if (library_list.solib_lists.find (debug_base)


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

* RE: [PATCH v5 00/15] basic linker namespace support
  2022-06-02 13:24 [PATCH v5 00/15] basic linker namespace support Markus Metzger
                   ` (14 preceding siblings ...)
  2022-06-02 13:25 ` [PATCH v5 15/15] gdb, solib-svr4: support namespaces in DSO iteration Markus Metzger
@ 2022-07-15 10:30 ` Metzger, Markus T
  2022-07-16  0:04   ` Kevin Buettner
  15 siblings, 1 reply; 52+ messages in thread
From: Metzger, Markus T @ 2022-07-15 10:30 UTC (permalink / raw)
  To: gdb-patches

Hello,

Reviews have slowed down.  Here's the current status:

OK'ed by Kevin:
>  gdb, solib-svr4: remove locate_base()
>  gdb, gdbserver: support dlmopen()
>  gdbserver: move main_lm handling into caller
>  gdb, gdbserver: extend RSP to support namespaces
>  gdb, compile: unlink objfile stored in module
>  gdb, ada: update ada_lookup_simple_minsym
>  gdb, hppa: remove unused hppa_lookup_stub_minimal_symbol
>  gdb, symtab: inline find_quick_global_symbol_language
>  gdb, solib-svr4: support namespaces in DSO iteration

Reviewed by Kevin but asking for another reviewer:
>  gdb, ada: update ada_add_all_symbols

Not reviewed:
>  gdb, testsuite: extend gdb_test_multiple checks
>  gdb, python: use gdbarch_iterate_over_objfiles_in_search_order
>  gdb, ada: collect standard exceptions in all objfiles
>  gdb, cp: update add_symbol_overload_list_qualified
>  gdb: update gnu ifunc resolve

Another question is what to do about those known issues:

>  - get_symbol_address() and get_msymbol_address() search objfiles for a
>    'better' match.  This was introduced by
>
>        4b610737f02 Handle copy relocations
>
>    to handle copy relocations but it now causes a wrong address to be
>    read after symbol lookup actually found the correct symbol.  This can
>    be seen, for example, with gdb.base/dlmopen.exp when compiled with
>    clang.
>
>  - gnu ifuncs are only looked up in the initial namespace.
>
>  - lookup_minimal_symbol() and lookup_minimal_symbol_text() directly
>    iterate over objfiles and are not aware of linker namespaces.

Can they be accepted and addressed one-by-one?  Or would they all need
to be addressed before the series can be merged?  I had to adjust two expected
outputs but otherwise, tests pass on x86-64.  We know that namespace
support is incomplete, though.

For get_symbol_address() and get_msymbol_address() I believe we need
to remove the objfiles iteration and trust that the symbol is the right one
and just return its value.  That means we need to find another way to
handle copy relocations.  I was hoping that someone could help with that.

regards,
markus.
Intel Deutschland GmbH
Registered Address: Am Campeon 10, 85579 Neubiberg, Germany
Tel: +49 89 99 8853-0, www.intel.de <http://www.intel.de>
Managing Directors: Christin Eisenschmid, Sharon Heck, Tiffany Doon Silva  
Chairperson of the Supervisory Board: Nicole Lau
Registered Office: Munich
Commercial Register: Amtsgericht Muenchen HRB 186928


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

* Re: [PATCH v5 00/15] basic linker namespace support
  2022-07-15 10:30 ` [PATCH v5 00/15] basic linker namespace support Metzger, Markus T
@ 2022-07-16  0:04   ` Kevin Buettner
  2022-07-18  5:33     ` Metzger, Markus T
  0 siblings, 1 reply; 52+ messages in thread
From: Kevin Buettner @ 2022-07-16  0:04 UTC (permalink / raw)
  To: Metzger, Markus T; +Cc: gdb-patches

Hi Markus,

On Fri, 15 Jul 2022 10:30:42 +0000
"Metzger, Markus T" <markus.t.metzger@intel.com> wrote:

> OK'ed by Kevin:
> >  gdb, solib-svr4: remove locate_base()
> >  gdb, gdbserver: support dlmopen()
> >  gdbserver: move main_lm handling into caller
> >  gdb, gdbserver: extend RSP to support namespaces
> >  gdb, compile: unlink objfile stored in module
> >  gdb, ada: update ada_lookup_simple_minsym
> >  gdb, hppa: remove unused hppa_lookup_stub_minimal_symbol
> >  gdb, symtab: inline find_quick_global_symbol_language
> >  gdb, solib-svr4: support namespaces in DSO iteration  

Yep.

> Reviewed by Kevin but asking for another reviewer:
> >  gdb, ada: update ada_add_all_symbols  

To be clear, I think this patch is okay, but someone who knows about
this area may want to take a look.  If no one steps up, I think it
should go in.

> 
> Not reviewed:
> >  gdb, testsuite: extend gdb_test_multiple checks

I asked a question about this one.  Basically, I'd like to understand
the circumstances which led you to making these changes.

> >  gdb, python: use gdbarch_iterate_over_objfiles_in_search_order

I okayed this one.

> >  gdb, ada: collect standard exceptions in all objfiles

That one looked reasonable to me, but an Ada expert may want to
take a look.

> >  gdb, cp: update add_symbol_overload_list_qualified

I said, "LGTM", which is basically an "okay".

> >  gdb: update gnu ifunc resolve  

I okayed this one.

> 
> Another question is what to do about those known issues:
> 
> >  - get_symbol_address() and get_msymbol_address() search objfiles for a
> >    'better' match.  This was introduced by
> >
> >        4b610737f02 Handle copy relocations
> >
> >    to handle copy relocations but it now causes a wrong address to be
> >    read after symbol lookup actually found the correct symbol.  This can
> >    be seen, for example, with gdb.base/dlmopen.exp when compiled with
> >    clang.
> >
> >  - gnu ifuncs are only looked up in the initial namespace.
> >
> >  - lookup_minimal_symbol() and lookup_minimal_symbol_text() directly
> >    iterate over objfiles and are not aware of linker namespaces.  
> 
> Can they be accepted and addressed one-by-one?  Or would they all need
> to be addressed before the series can be merged?  I had to adjust two expected
> outputs but otherwise, tests pass on x86-64.  We know that namespace
> support is incomplete, though.
> 
> For get_symbol_address() and get_msymbol_address() I believe we need
> to remove the objfiles iteration and trust that the symbol is the right one
> and just return its value.  That means we need to find another way to
> handle copy relocations.  I was hoping that someone could help with that.

I'd like to see this work go in.  So long as it doesn't break existing
(non-linker namespace) use cases, I'm okay with fixing the other
problems later on.

Kevin


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

* RE: [PATCH v5 00/15] basic linker namespace support
  2022-07-16  0:04   ` Kevin Buettner
@ 2022-07-18  5:33     ` Metzger, Markus T
  2022-10-05 11:16       ` Metzger, Markus T
  0 siblings, 1 reply; 52+ messages in thread
From: Metzger, Markus T @ 2022-07-18  5:33 UTC (permalink / raw)
  To: Kevin Buettner; +Cc: gdb-patches

Thanks, Kevin,

>> Not reviewed:
>> >  gdb, testsuite: extend gdb_test_multiple checks
>
>I asked a question about this one.  Basically, I'd like to understand
>the circumstances which led you to making these changes.

Sorry, I missed your email.  I ran into

    Invalid cast.
    warning: Probes-based dynamic linker interface failed.
    Reverting to original interface.

and

    warning: Corrupted shared library list

during development.
See https://sourceware.org/pipermail/gdb-patches/2022-February/186135.html.

The other I believe I added for completeness but I see that this warning has been
removed, meanwhile.  Let me drop it from my patch.

>
>> >  gdb, python: use gdbarch_iterate_over_objfiles_in_search_order
>
>I okayed this one.
>
>> >  gdb, ada: collect standard exceptions in all objfiles
>
>That one looked reasonable to me, but an Ada expert may want to
>take a look.
>
>> >  gdb, cp: update add_symbol_overload_list_qualified
>
>I said, "LGTM", which is basically an "okay".
>
>> >  gdb: update gnu ifunc resolve
>
>I okayed this one.

Sorry, I must have missed your replies on those.  I haven't checked the
archive and relied on my email inbox.

>I'd like to see this work go in.  So long as it doesn't break existing
>(non-linker namespace) use cases, I'm okay with fixing the other
>problems later on.

As far as I could test (x86-64 on Fedora 35) it does not break anything.
I'll ask Joel about the Ada patches.

regards,
markus.
Intel Deutschland GmbH
Registered Address: Am Campeon 10, 85579 Neubiberg, Germany
Tel: +49 89 99 8853-0, www.intel.de <http://www.intel.de>
Managing Directors: Christin Eisenschmid, Sharon Heck, Tiffany Doon Silva  
Chairperson of the Supervisory Board: Nicole Lau
Registered Office: Munich
Commercial Register: Amtsgericht Muenchen HRB 186928


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

* RE: [PATCH v5 08/15] gdb, ada: collect standard exceptions in all objfiles
  2022-06-02 13:25 ` [PATCH v5 08/15] gdb, ada: collect standard exceptions in all objfiles Markus Metzger
  2022-06-24 17:26   ` Kevin Buettner
@ 2022-07-18  5:35   ` Metzger, Markus T
  2022-09-14  8:19     ` Metzger, Markus T
  1 sibling, 1 reply; 52+ messages in thread
From: Metzger, Markus T @ 2022-07-18  5:35 UTC (permalink / raw)
  To: brobecker; +Cc: gdb-patches, Kevin Buettner

Hello Joel,

Would you be able to review this Ada-related patch?

thanks,
markus.

>-----Original Message-----
>From: Metzger, Markus T <markus.t.metzger@intel.com>
>Sent: Donnerstag, 2. Juni 2022 15:25
>To: gdb-patches@sourceware.org
>Subject: [PATCH v5 08/15] gdb, ada: collect standard exceptions in all objfiles
>
>When searching for standard exceptions for Ada, we lookup the minimal
>symbol of each exception.  With linker namespaces there can be multiple
>instances in different namespaces.  Collect them all.
>---
> gdb/ada-lang.c | 30 +++++++++++++++++++++++-------
> 1 file changed, 23 insertions(+), 7 deletions(-)
>
>diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c
>index 6ab01fd27d4..2b251693b72 100644
>--- a/gdb/ada-lang.c
>+++ b/gdb/ada-lang.c
>@@ -13016,15 +13016,29 @@ ada_add_standard_exceptions (compiled_regex
>*preg,
>     {
>       if (preg == NULL || preg->exec (name, 0, NULL, 0) == 0)
> 	{
>-	  struct bound_minimal_symbol msymbol
>-	    = ada_lookup_simple_minsym (name);
>+	  symbol_name_match_type match_type = name_match_type_from_name
>(name);
>+	  lookup_name_info lookup_name (name, match_type);
>
>-	  if (msymbol.minsym != NULL)
>-	    {
>-	      struct ada_exc_info info
>-		= {name, msymbol.value_address ()};
>+	  symbol_name_matcher_ftype *match_name
>+	    = ada_get_symbol_name_matcher (lookup_name);
>
>-	      exceptions->push_back (info);
>+	  /* Iterate over all objfiles irrespective of scope or linker
>+	     namespaces so we get all exceptions anywhere in the
>+	     progspace.  */
>+	  for (objfile *objfile : current_program_space->objfiles ())
>+	    {
>+	      for (minimal_symbol *msymbol : objfile->msymbols ())
>+		{
>+		  if (match_name (msymbol->linkage_name (), lookup_name,
>+				  nullptr)
>+		      && msymbol->type () != mst_solib_trampoline)
>+		    {
>+		      ada_exc_info info
>+			= {name, msymbol->value_address (objfile)};
>+
>+		      exceptions->push_back (info);
>+		    }
>+		}
> 	    }
> 	}
>     }
>@@ -13122,6 +13136,8 @@ ada_add_global_exceptions (compiled_regex *preg,
> 			   SEARCH_GLOBAL_BLOCK | SEARCH_STATIC_BLOCK,
> 			   VARIABLES_DOMAIN);
>
>+  /* Iterate over all objfiles irrespective of scope or linker namespaces
>+     so we get all exceptions anywhere in the progspace.  */
>   for (objfile *objfile : current_program_space->objfiles ())
>     {
>       for (compunit_symtab *s : objfile->compunits ())
>--
>2.35.3

Intel Deutschland GmbH
Registered Address: Am Campeon 10, 85579 Neubiberg, Germany
Tel: +49 89 99 8853-0, www.intel.de <http://www.intel.de>
Managing Directors: Christin Eisenschmid, Sharon Heck, Tiffany Doon Silva  
Chairperson of the Supervisory Board: Nicole Lau
Registered Office: Munich
Commercial Register: Amtsgericht Muenchen HRB 186928


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

* RE: [PATCH v5 10/15] gdb, ada: update ada_add_all_symbols
  2022-06-02 13:25 ` [PATCH v5 10/15] gdb, ada: update ada_add_all_symbols Markus Metzger
  2022-06-24 23:53   ` Kevin Buettner
@ 2022-07-18  5:36   ` Metzger, Markus T
  2022-07-18 16:56   ` Tom Tromey
  2 siblings, 0 replies; 52+ messages in thread
From: Metzger, Markus T @ 2022-07-18  5:36 UTC (permalink / raw)
  To: brobecker; +Cc: gdb-patches, Kevin Buettner

Hello Joel,

Would you be able to review this Ada-related patch?

thanks,
markus.

>-----Original Message-----
>From: Metzger, Markus T <markus.t.metzger@intel.com>
>Sent: Donnerstag, 2. Juni 2022 15:25
>To: gdb-patches@sourceware.org
>Subject: [PATCH v5 10/15] gdb, ada: update ada_add_all_symbols
>
>Iterate over objfile in search order using the objfile of the context
>block as current_objfile so the iteration can stay inside the block's
>linker namespace.
>---
> gdb/ada-lang.c | 66 +++++++++++++++++++++++++++++++++-----------------
> 1 file changed, 44 insertions(+), 22 deletions(-)
>
>diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c
>index 20ea4c8f6aa..110c246181e 100644
>--- a/gdb/ada-lang.c
>+++ b/gdb/ada-lang.c
>@@ -5582,37 +5582,52 @@ map_matching_symbols (struct objfile *objfile,
>
> static void
> add_nonlocal_symbols (std::vector<struct block_symbol> &result,
>+		      const struct block *block,
> 		      const lookup_name_info &lookup_name,
> 		      domain_enum domain, int global)
> {
>-  struct match_data data (&result);
>+  struct objfile *objfile = nullptr;
>+  if (block != nullptr)
>+    objfile = block_objfile (block);
>
>   bool is_wild_match = lookup_name.ada ().wild_match_p ();
>
>-  for (objfile *objfile : current_program_space->objfiles ())
>-    {
>-      map_matching_symbols (objfile, lookup_name, is_wild_match, domain,
>-			    global, data);
>+  match_data data (&result);
>
>-      for (compunit_symtab *cu : objfile->compunits ())
>-	{
>-	  const struct block *global_block
>-	    = cu->blockvector ()->global_block ();
>+  gdbarch_iterate_over_objfiles_in_search_order
>+    (objfile != nullptr ? objfile->arch () : target_gdbarch (),
>+     [&data, lookup_name, domain, global, is_wild_match] (struct objfile *obj)
>+       {
>+	 map_matching_symbols (obj, lookup_name, is_wild_match, domain,
>+			       global, data);
>
>-	  if (ada_add_block_renamings (result, global_block, lookup_name,
>-				       domain))
>-	    data.found_sym = true;
>-	}
>-    }
>+	 for (compunit_symtab *cu : obj->compunits ())
>+	   {
>+	     const struct block *global_block
>+	       = cu->blockvector ()->global_block ();
>
>-  if (result.empty () && global && !is_wild_match)
>+	     if (ada_add_block_renamings (*data.resultp, global_block,
>+					  lookup_name, domain))
>+	       data.found_sym = true;
>+	   }
>+
>+	 return 0;
>+       }, objfile);
>+
>+  if (data.resultp->empty () && global && !is_wild_match)
>     {
>       const char *name = ada_lookup_name (lookup_name);
>       std::string bracket_name = std::string ("<_ada_") + name + '>';
>       lookup_name_info name1 (bracket_name, symbol_name_match_type::FULL);
>
>-      for (objfile *objfile : current_program_space->objfiles ())
>-	map_matching_symbols (objfile, name1, false, domain, global, data);
>+      gdbarch_iterate_over_objfiles_in_search_order
>+	(objfile != nullptr ? objfile->arch () : target_gdbarch (),
>+	 [&data, name1, domain, global] (struct objfile *obj)
>+	   {
>+	     map_matching_symbols (obj, name1, false, domain, global, data);
>+
>+	     return 0;
>+	   }, objfile);
>     }
> }
>
>@@ -5642,6 +5657,7 @@ ada_add_all_symbols (std::vector<struct
>block_symbol> &result,
> 		     int *made_global_lookup_p)
> {
>   struct symbol *sym;
>+  const struct block *orig_block = block;
>
>   if (made_global_lookup_p)
>     *made_global_lookup_p = 0;
>@@ -5688,15 +5704,21 @@ ada_add_all_symbols (std::vector<struct
>block_symbol> &result,
>   if (made_global_lookup_p)
>     *made_global_lookup_p = 1;
>
>-  /* Search symbols from all global blocks.  */
>+  /* Search symbols from all global blocks.
>+
>+     Pass the original block to restrict the search to that block's
>+     namespace.  */
>
>-  add_nonlocal_symbols (result, lookup_name, domain, 1);
>+  add_nonlocal_symbols (result, orig_block, lookup_name, domain, 1);
>+
>+  /* Now add symbols from all per-file blocks if we've gotten no hits (not
>+     strictly correct, but perhaps better than an error).
>
>-  /* Now add symbols from all per-file blocks if we've gotten no hits
>-     (not strictly correct, but perhaps better than an error).  */
>+     Pass the original block to restrict the search to that block's
>+     namespace.  */
>
>   if (result.empty ())
>-    add_nonlocal_symbols (result, lookup_name, domain, 0);
>+    add_nonlocal_symbols (result, orig_block, lookup_name, domain, 0);
> }
>
> /* Find symbols in DOMAIN matching LOOKUP_NAME, in BLOCK and, if
>FULL_SEARCH
>--
>2.35.3

Intel Deutschland GmbH
Registered Address: Am Campeon 10, 85579 Neubiberg, Germany
Tel: +49 89 99 8853-0, www.intel.de <http://www.intel.de>
Managing Directors: Christin Eisenschmid, Sharon Heck, Tiffany Doon Silva  
Chairperson of the Supervisory Board: Nicole Lau
Registered Office: Munich
Commercial Register: Amtsgericht Muenchen HRB 186928


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

* Re: [PATCH v5 08/15] gdb, ada: collect standard exceptions in all objfiles
  2022-06-24 17:26   ` Kevin Buettner
@ 2022-07-18 16:49     ` Tom Tromey
  0 siblings, 0 replies; 52+ messages in thread
From: Tom Tromey @ 2022-07-18 16:49 UTC (permalink / raw)
  To: Kevin Buettner via Gdb-patches

>> When searching for standard exceptions for Ada, we lookup the minimal
>> symbol of each exception.  With linker namespaces there can be multiple
>> instances in different namespaces.  Collect them all.
>> ---
>> gdb/ada-lang.c | 30 +++++++++++++++++++++++-------
>> 1 file changed, 23 insertions(+), 7 deletions(-)

Kevin> I'm not an Ada expert, but this seems reasonable.

This seems fine to me as well.

Tom

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

* Re: [PATCH v5 10/15] gdb, ada: update ada_add_all_symbols
  2022-06-02 13:25 ` [PATCH v5 10/15] gdb, ada: update ada_add_all_symbols Markus Metzger
  2022-06-24 23:53   ` Kevin Buettner
  2022-07-18  5:36   ` Metzger, Markus T
@ 2022-07-18 16:56   ` Tom Tromey
  2022-07-19  7:13     ` Metzger, Markus T
  2 siblings, 1 reply; 52+ messages in thread
From: Tom Tromey @ 2022-07-18 16:56 UTC (permalink / raw)
  To: Markus Metzger via Gdb-patches

>>>>> "Markus" == Markus Metzger via Gdb-patches <gdb-patches@sourceware.org> writes:

Markus> Iterate over objfile in search order using the objfile of the context
Markus> block as current_objfile so the iteration can stay inside the block's
Markus> linker namespace.

I think this function is used by linespec, meaning it's called when
setting a breakpoint.  So in this case, limiting the results to the
current namespace seems possibly incorrect to me.

Was there a particular reason for this limitation?

I tend to doubt that Ada users are using dlmopen.  So maybe either way
is ok.  However, erring on the side of too many results seems possibly
better, just in case someone does start using this combination of
features.

Tom

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

* Re: [PATCH v5 09/15] gdb, ada: update ada_lookup_simple_minsym
  2022-06-02 13:25 ` [PATCH v5 09/15] gdb, ada: update ada_lookup_simple_minsym Markus Metzger
  2022-06-24 23:42   ` Kevin Buettner
@ 2022-07-18 17:02   ` Tom Tromey
  2022-07-19  7:14     ` Metzger, Markus T
  1 sibling, 1 reply; 52+ messages in thread
From: Tom Tromey @ 2022-07-18 17:02 UTC (permalink / raw)
  To: Markus Metzger via Gdb-patches

>>>>> "Markus" == Markus Metzger via Gdb-patches <gdb-patches@sourceware.org> writes:

Markus> Iterate over objfile in search order using the objfile of the context
Markus> block as current_objfile so the iteration can stay inside the block's
Markus> linker namespace.

Markus> diff --git a/gdb/ada-exp.y b/gdb/ada-exp.y
Markus> index 8660205809a..85569b841eb 100644
Markus> --- a/gdb/ada-exp.y
Markus> +++ b/gdb/ada-exp.y
Markus> @@ -1700,8 +1700,15 @@ write_var_or_type (struct parser_state *par_state,
Markus>  	    }
Markus>  	  else if (syms.empty ())
Markus>  	    {
Markus> +	      if (block == nullptr)
Markus> +		block = get_selected_block (nullptr);

I don't think 'block' can be null here, since it's handled at the top of
the function:

  if (block == NULL)
    block = par_state->expression_context_block;

Tom

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

* RE: [PATCH v5 10/15] gdb, ada: update ada_add_all_symbols
  2022-07-18 16:56   ` Tom Tromey
@ 2022-07-19  7:13     ` Metzger, Markus T
  2022-07-19 12:23       ` Tom Tromey
  0 siblings, 1 reply; 52+ messages in thread
From: Metzger, Markus T @ 2022-07-19  7:13 UTC (permalink / raw)
  To: Tom Tromey; +Cc: Markus Metzger via Gdb-patches

Hello Tom,

>Markus> Iterate over objfile in search order using the objfile of the context
>Markus> block as current_objfile so the iteration can stay inside the block's
>Markus> linker namespace.
>
>I think this function is used by linespec, meaning it's called when
>setting a breakpoint.  So in this case, limiting the results to the
>current namespace seems possibly incorrect to me.
>
>Was there a particular reason for this limitation?

I was simply trying to preserve the existing behavior of not knowing about
linker namespaces.

Would you want me to drop the patch to keep the objfile traversal and
collect all symbols from all namespaces?

regards,
markus.

Intel Deutschland GmbH
Registered Address: Am Campeon 10, 85579 Neubiberg, Germany
Tel: +49 89 99 8853-0, www.intel.de <http://www.intel.de>
Managing Directors: Christin Eisenschmid, Sharon Heck, Tiffany Doon Silva  
Chairperson of the Supervisory Board: Nicole Lau
Registered Office: Munich
Commercial Register: Amtsgericht Muenchen HRB 186928


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

* RE: [PATCH v5 09/15] gdb, ada: update ada_lookup_simple_minsym
  2022-07-18 17:02   ` Tom Tromey
@ 2022-07-19  7:14     ` Metzger, Markus T
  2022-09-14  8:19       ` Metzger, Markus T
  0 siblings, 1 reply; 52+ messages in thread
From: Metzger, Markus T @ 2022-07-19  7:14 UTC (permalink / raw)
  To: Tom Tromey; +Cc: Markus Metzger via Gdb-patches

Hello Tom,

>Markus> diff --git a/gdb/ada-exp.y b/gdb/ada-exp.y
>Markus> index 8660205809a..85569b841eb 100644
>Markus> --- a/gdb/ada-exp.y
>Markus> +++ b/gdb/ada-exp.y
>Markus> @@ -1700,8 +1700,15 @@ write_var_or_type (struct parser_state
>*par_state,
>Markus>  	    }
>Markus>  	  else if (syms.empty ())
>Markus>  	    {
>Markus> +	      if (block == nullptr)
>Markus> +		block = get_selected_block (nullptr);
>
>I don't think 'block' can be null here, since it's handled at the top of
>the function:
>
>  if (block == NULL)
>    block = par_state->expression_context_block;

It can be null.  When I removed the check gdb.ada/minsyms.exp ran
into an internal error.

The question is whether calling get_selected_block (nullptr), here,
is the right thing to do or whether we should just leave objfile null
in that case.

regards,
markus.
Intel Deutschland GmbH
Registered Address: Am Campeon 10, 85579 Neubiberg, Germany
Tel: +49 89 99 8853-0, www.intel.de <http://www.intel.de>
Managing Directors: Christin Eisenschmid, Sharon Heck, Tiffany Doon Silva  
Chairperson of the Supervisory Board: Nicole Lau
Registered Office: Munich
Commercial Register: Amtsgericht Muenchen HRB 186928


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

* Re: [PATCH v5 10/15] gdb, ada: update ada_add_all_symbols
  2022-07-19  7:13     ` Metzger, Markus T
@ 2022-07-19 12:23       ` Tom Tromey
  2022-07-19 13:49         ` Metzger, Markus T
  0 siblings, 1 reply; 52+ messages in thread
From: Tom Tromey @ 2022-07-19 12:23 UTC (permalink / raw)
  To: Metzger, Markus T; +Cc: Tom Tromey, Markus Metzger via Gdb-patches

>> I think this function is used by linespec, meaning it's called when
>> setting a breakpoint.  So in this case, limiting the results to the
>> current namespace seems possibly incorrect to me.
>> 
>> Was there a particular reason for this limitation?

> I was simply trying to preserve the existing behavior of not knowing about
> linker namespaces.

I didn't really read through the rest of the series -- was this the rule
followed elsewhere?  I think it shouldn't be, because in gdb a linespec
should find all the matches.

> Would you want me to drop the patch to keep the objfile traversal and
> collect all symbols from all namespaces?

I think so.

Tom

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

* RE: [PATCH v5 10/15] gdb, ada: update ada_add_all_symbols
  2022-07-19 12:23       ` Tom Tromey
@ 2022-07-19 13:49         ` Metzger, Markus T
  0 siblings, 0 replies; 52+ messages in thread
From: Metzger, Markus T @ 2022-07-19 13:49 UTC (permalink / raw)
  To: Tom Tromey; +Cc: Markus Metzger via Gdb-patches

>> I was simply trying to preserve the existing behavior of not knowing about
>> linker namespaces.
>
>I didn't really read through the rest of the series -- was this the rule
>followed elsewhere?  I think it shouldn't be, because in gdb a linespec
>should find all the matches.

The patch series adds a C test that covers breakpoints on source line
getting set in all DSOs in all namespaces.

A handful of patches, including this one, tries to replace direct objfile traversals
with gdbarch_iterate_over_objfiles_in_search_order.


>> Would you want me to drop the patch to keep the objfile traversal and
>> collect all symbols from all namespaces?
>
>I think so.

Dropped.

regards,
markus.

Intel Deutschland GmbH
Registered Address: Am Campeon 10, 85579 Neubiberg, Germany
Tel: +49 89 99 8853-0, www.intel.de <http://www.intel.de>
Managing Directors: Christin Eisenschmid, Sharon Heck, Tiffany Doon Silva  
Chairperson of the Supervisory Board: Nicole Lau
Registered Office: Munich
Commercial Register: Amtsgericht Muenchen HRB 186928


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

* RE: [PATCH v5 08/15] gdb, ada: collect standard exceptions in all objfiles
  2022-07-18  5:35   ` Metzger, Markus T
@ 2022-09-14  8:19     ` Metzger, Markus T
  2022-09-14  8:37       ` Joel Brobecker
  0 siblings, 1 reply; 52+ messages in thread
From: Metzger, Markus T @ 2022-09-14  8:19 UTC (permalink / raw)
  To: Tom Tromey; +Cc: gdb-patches, Kevin Buettner, brobecker

Hello Tom,

would you be able to review this patch?

thanks,
markus.

>-----Original Message-----
>From: Metzger, Markus T <markus.t.metzger@intel.com>
>Sent: Montag, 18. Juli 2022 07:36
>To: brobecker@adacore.com
>Cc: gdb-patches@sourceware.org; Kevin Buettner <kevinb@redhat.com>
>Subject: RE: [PATCH v5 08/15] gdb, ada: collect standard exceptions in all objfiles
>
>Hello Joel,
>
>Would you be able to review this Ada-related patch?
>
>thanks,
>markus.
>
>>-----Original Message-----
>>From: Metzger, Markus T <markus.t.metzger@intel.com>
>>Sent: Donnerstag, 2. Juni 2022 15:25
>>To: gdb-patches@sourceware.org
>>Subject: [PATCH v5 08/15] gdb, ada: collect standard exceptions in all objfiles
>>
>>When searching for standard exceptions for Ada, we lookup the minimal
>>symbol of each exception.  With linker namespaces there can be multiple
>>instances in different namespaces.  Collect them all.
>>---
>> gdb/ada-lang.c | 30 +++++++++++++++++++++++-------
>> 1 file changed, 23 insertions(+), 7 deletions(-)
>>
>>diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c
>>index 6ab01fd27d4..2b251693b72 100644
>>--- a/gdb/ada-lang.c
>>+++ b/gdb/ada-lang.c
>>@@ -13016,15 +13016,29 @@ ada_add_standard_exceptions (compiled_regex
>>*preg,
>>     {
>>       if (preg == NULL || preg->exec (name, 0, NULL, 0) == 0)
>> 	{
>>-	  struct bound_minimal_symbol msymbol
>>-	    = ada_lookup_simple_minsym (name);
>>+	  symbol_name_match_type match_type = name_match_type_from_name
>>(name);
>>+	  lookup_name_info lookup_name (name, match_type);
>>
>>-	  if (msymbol.minsym != NULL)
>>-	    {
>>-	      struct ada_exc_info info
>>-		= {name, msymbol.value_address ()};
>>+	  symbol_name_matcher_ftype *match_name
>>+	    = ada_get_symbol_name_matcher (lookup_name);
>>
>>-	      exceptions->push_back (info);
>>+	  /* Iterate over all objfiles irrespective of scope or linker
>>+	     namespaces so we get all exceptions anywhere in the
>>+	     progspace.  */
>>+	  for (objfile *objfile : current_program_space->objfiles ())
>>+	    {
>>+	      for (minimal_symbol *msymbol : objfile->msymbols ())
>>+		{
>>+		  if (match_name (msymbol->linkage_name (), lookup_name,
>>+				  nullptr)
>>+		      && msymbol->type () != mst_solib_trampoline)
>>+		    {
>>+		      ada_exc_info info
>>+			= {name, msymbol->value_address (objfile)};
>>+
>>+		      exceptions->push_back (info);
>>+		    }
>>+		}
>> 	    }
>> 	}
>>     }
>>@@ -13122,6 +13136,8 @@ ada_add_global_exceptions (compiled_regex *preg,
>> 			   SEARCH_GLOBAL_BLOCK | SEARCH_STATIC_BLOCK,
>> 			   VARIABLES_DOMAIN);
>>
>>+  /* Iterate over all objfiles irrespective of scope or linker namespaces
>>+     so we get all exceptions anywhere in the progspace.  */
>>   for (objfile *objfile : current_program_space->objfiles ())
>>     {
>>       for (compunit_symtab *s : objfile->compunits ())
>>--
>>2.35.3

Intel Deutschland GmbH
Registered Address: Am Campeon 10, 85579 Neubiberg, Germany
Tel: +49 89 99 8853-0, www.intel.de <http://www.intel.de>
Managing Directors: Christin Eisenschmid, Sharon Heck, Tiffany Doon Silva  
Chairperson of the Supervisory Board: Nicole Lau
Registered Office: Munich
Commercial Register: Amtsgericht Muenchen HRB 186928


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

* RE: [PATCH v5 09/15] gdb, ada: update ada_lookup_simple_minsym
  2022-07-19  7:14     ` Metzger, Markus T
@ 2022-09-14  8:19       ` Metzger, Markus T
  2022-09-21 16:11         ` Tom Tromey
  0 siblings, 1 reply; 52+ messages in thread
From: Metzger, Markus T @ 2022-09-14  8:19 UTC (permalink / raw)
  To: Tom Tromey; +Cc: Markus Metzger via Gdb-patches, Kevin Buettner

ping.

>-----Original Message-----
>From: Metzger, Markus T <markus.t.metzger@intel.com>
>Sent: Dienstag, 19. Juli 2022 09:15
>To: Tom Tromey <tom@tromey.com>
>Cc: Markus Metzger via Gdb-patches <gdb-patches@sourceware.org>
>Subject: RE: [PATCH v5 09/15] gdb, ada: update ada_lookup_simple_minsym
>
>Hello Tom,
>
>>Markus> diff --git a/gdb/ada-exp.y b/gdb/ada-exp.y
>>Markus> index 8660205809a..85569b841eb 100644
>>Markus> --- a/gdb/ada-exp.y
>>Markus> +++ b/gdb/ada-exp.y
>>Markus> @@ -1700,8 +1700,15 @@ write_var_or_type (struct parser_state
>>*par_state,
>>Markus>  	    }
>>Markus>  	  else if (syms.empty ())
>>Markus>  	    {
>>Markus> +	      if (block == nullptr)
>>Markus> +		block = get_selected_block (nullptr);
>>
>>I don't think 'block' can be null here, since it's handled at the top of
>>the function:
>>
>>  if (block == NULL)
>>    block = par_state->expression_context_block;
>
>It can be null.  When I removed the check gdb.ada/minsyms.exp ran
>into an internal error.
>
>The question is whether calling get_selected_block (nullptr), here,
>is the right thing to do or whether we should just leave objfile null
>in that case.
>
>regards,
>markus.
Intel Deutschland GmbH
Registered Address: Am Campeon 10, 85579 Neubiberg, Germany
Tel: +49 89 99 8853-0, www.intel.de <http://www.intel.de>
Managing Directors: Christin Eisenschmid, Sharon Heck, Tiffany Doon Silva  
Chairperson of the Supervisory Board: Nicole Lau
Registered Office: Munich
Commercial Register: Amtsgericht Muenchen HRB 186928


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

* Re: [PATCH v5 08/15] gdb, ada: collect standard exceptions in all objfiles
  2022-09-14  8:19     ` Metzger, Markus T
@ 2022-09-14  8:37       ` Joel Brobecker
  2022-09-14  8:45         ` Metzger, Markus T
  0 siblings, 1 reply; 52+ messages in thread
From: Joel Brobecker @ 2022-09-14  8:37 UTC (permalink / raw)
  To: Metzger, Markus T; +Cc: Tom Tromey, gdb-patches, Kevin Buettner, brobecker

Hi Markus,

> would you be able to review this patch?

I think Tom already reviewed this patch (back in July), and he said
it looked fine to him. Here is the link to the email, in case I am
mistaken:

    https://sourceware.org/pipermail/gdb-patches/2022-July/190855.html

> >-----Original Message-----
> >From: Metzger, Markus T <markus.t.metzger@intel.com>
> >Sent: Montag, 18. Juli 2022 07:36
> >To: brobecker@adacore.com
> >Cc: gdb-patches@sourceware.org; Kevin Buettner <kevinb@redhat.com>
> >Subject: RE: [PATCH v5 08/15] gdb, ada: collect standard exceptions in all objfiles
> >
> >Hello Joel,
> >
> >Would you be able to review this Ada-related patch?
> >
> >thanks,
> >markus.
> >
> >>-----Original Message-----
> >>From: Metzger, Markus T <markus.t.metzger@intel.com>
> >>Sent: Donnerstag, 2. Juni 2022 15:25
> >>To: gdb-patches@sourceware.org
> >>Subject: [PATCH v5 08/15] gdb, ada: collect standard exceptions in all objfiles
> >>
> >>When searching for standard exceptions for Ada, we lookup the minimal
> >>symbol of each exception.  With linker namespaces there can be multiple
> >>instances in different namespaces.  Collect them all.
> >>---
> >> gdb/ada-lang.c | 30 +++++++++++++++++++++++-------
> >> 1 file changed, 23 insertions(+), 7 deletions(-)
> >>
> >>diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c
> >>index 6ab01fd27d4..2b251693b72 100644
> >>--- a/gdb/ada-lang.c
> >>+++ b/gdb/ada-lang.c
> >>@@ -13016,15 +13016,29 @@ ada_add_standard_exceptions (compiled_regex
> >>*preg,
> >>     {
> >>       if (preg == NULL || preg->exec (name, 0, NULL, 0) == 0)
> >> 	{
> >>-	  struct bound_minimal_symbol msymbol
> >>-	    = ada_lookup_simple_minsym (name);
> >>+	  symbol_name_match_type match_type = name_match_type_from_name
> >>(name);
> >>+	  lookup_name_info lookup_name (name, match_type);
> >>
> >>-	  if (msymbol.minsym != NULL)
> >>-	    {
> >>-	      struct ada_exc_info info
> >>-		= {name, msymbol.value_address ()};
> >>+	  symbol_name_matcher_ftype *match_name
> >>+	    = ada_get_symbol_name_matcher (lookup_name);
> >>
> >>-	      exceptions->push_back (info);
> >>+	  /* Iterate over all objfiles irrespective of scope or linker
> >>+	     namespaces so we get all exceptions anywhere in the
> >>+	     progspace.  */
> >>+	  for (objfile *objfile : current_program_space->objfiles ())
> >>+	    {
> >>+	      for (minimal_symbol *msymbol : objfile->msymbols ())
> >>+		{
> >>+		  if (match_name (msymbol->linkage_name (), lookup_name,
> >>+				  nullptr)
> >>+		      && msymbol->type () != mst_solib_trampoline)
> >>+		    {
> >>+		      ada_exc_info info
> >>+			= {name, msymbol->value_address (objfile)};
> >>+
> >>+		      exceptions->push_back (info);
> >>+		    }
> >>+		}
> >> 	    }
> >> 	}
> >>     }
> >>@@ -13122,6 +13136,8 @@ ada_add_global_exceptions (compiled_regex *preg,
> >> 			   SEARCH_GLOBAL_BLOCK | SEARCH_STATIC_BLOCK,
> >> 			   VARIABLES_DOMAIN);
> >>
> >>+  /* Iterate over all objfiles irrespective of scope or linker namespaces
> >>+     so we get all exceptions anywhere in the progspace.  */
> >>   for (objfile *objfile : current_program_space->objfiles ())
> >>     {
> >>       for (compunit_symtab *s : objfile->compunits ())
> >>--
> >>2.35.3
> 
> Intel Deutschland GmbH
> Registered Address: Am Campeon 10, 85579 Neubiberg, Germany
> Tel: +49 89 99 8853-0, www.intel.de <http://www.intel.de>
> Managing Directors: Christin Eisenschmid, Sharon Heck, Tiffany Doon Silva  
> Chairperson of the Supervisory Board: Nicole Lau
> Registered Office: Munich
> Commercial Register: Amtsgericht Muenchen HRB 186928
> 

-- 
Joel

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

* RE: [PATCH v5 08/15] gdb, ada: collect standard exceptions in all objfiles
  2022-09-14  8:37       ` Joel Brobecker
@ 2022-09-14  8:45         ` Metzger, Markus T
  0 siblings, 0 replies; 52+ messages in thread
From: Metzger, Markus T @ 2022-09-14  8:45 UTC (permalink / raw)
  To: Joel Brobecker; +Cc: Tom Tromey, gdb-patches, Kevin Buettner

Thanks, Joel,

I'm not getting some emails, it seems.  Or they get filtered away.  Let me check.

regards,
markus.

>-----Original Message-----
>From: Joel Brobecker <brobecker@adacore.com>
>Sent: Mittwoch, 14. September 2022 10:38
>To: Metzger, Markus T <markus.t.metzger@intel.com>
>Cc: Tom Tromey <tromey@adacore.com>; gdb-patches@sourceware.org; Kevin
>Buettner <kevinb@redhat.com>; brobecker@adacore.com
>Subject: Re: [PATCH v5 08/15] gdb, ada: collect standard exceptions in all objfiles
>
>Hi Markus,
>
>> would you be able to review this patch?
>
>I think Tom already reviewed this patch (back in July), and he said
>it looked fine to him. Here is the link to the email, in case I am
>mistaken:
>
>    https://sourceware.org/pipermail/gdb-patches/2022-July/190855.html
>
>> >-----Original Message-----
>> >From: Metzger, Markus T <markus.t.metzger@intel.com>
>> >Sent: Montag, 18. Juli 2022 07:36
>> >To: brobecker@adacore.com
>> >Cc: gdb-patches@sourceware.org; Kevin Buettner <kevinb@redhat.com>
>> >Subject: RE: [PATCH v5 08/15] gdb, ada: collect standard exceptions in all objfiles
>> >
>> >Hello Joel,
>> >
>> >Would you be able to review this Ada-related patch?
>> >
>> >thanks,
>> >markus.
>> >
>> >>-----Original Message-----
>> >>From: Metzger, Markus T <markus.t.metzger@intel.com>
>> >>Sent: Donnerstag, 2. Juni 2022 15:25
>> >>To: gdb-patches@sourceware.org
>> >>Subject: [PATCH v5 08/15] gdb, ada: collect standard exceptions in all objfiles
>> >>
>> >>When searching for standard exceptions for Ada, we lookup the minimal
>> >>symbol of each exception.  With linker namespaces there can be multiple
>> >>instances in different namespaces.  Collect them all.
>> >>---
>> >> gdb/ada-lang.c | 30 +++++++++++++++++++++++-------
>> >> 1 file changed, 23 insertions(+), 7 deletions(-)
>> >>
>> >>diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c
>> >>index 6ab01fd27d4..2b251693b72 100644
>> >>--- a/gdb/ada-lang.c
>> >>+++ b/gdb/ada-lang.c
>> >>@@ -13016,15 +13016,29 @@ ada_add_standard_exceptions (compiled_regex
>> >>*preg,
>> >>     {
>> >>       if (preg == NULL || preg->exec (name, 0, NULL, 0) == 0)
>> >> 	{
>> >>-	  struct bound_minimal_symbol msymbol
>> >>-	    = ada_lookup_simple_minsym (name);
>> >>+	  symbol_name_match_type match_type = name_match_type_from_name
>> >>(name);
>> >>+	  lookup_name_info lookup_name (name, match_type);
>> >>
>> >>-	  if (msymbol.minsym != NULL)
>> >>-	    {
>> >>-	      struct ada_exc_info info
>> >>-		= {name, msymbol.value_address ()};
>> >>+	  symbol_name_matcher_ftype *match_name
>> >>+	    = ada_get_symbol_name_matcher (lookup_name);
>> >>
>> >>-	      exceptions->push_back (info);
>> >>+	  /* Iterate over all objfiles irrespective of scope or linker
>> >>+	     namespaces so we get all exceptions anywhere in the
>> >>+	     progspace.  */
>> >>+	  for (objfile *objfile : current_program_space->objfiles ())
>> >>+	    {
>> >>+	      for (minimal_symbol *msymbol : objfile->msymbols ())
>> >>+		{
>> >>+		  if (match_name (msymbol->linkage_name (), lookup_name,
>> >>+				  nullptr)
>> >>+		      && msymbol->type () != mst_solib_trampoline)
>> >>+		    {
>> >>+		      ada_exc_info info
>> >>+			= {name, msymbol->value_address (objfile)};
>> >>+
>> >>+		      exceptions->push_back (info);
>> >>+		    }
>> >>+		}
>> >> 	    }
>> >> 	}
>> >>     }
>> >>@@ -13122,6 +13136,8 @@ ada_add_global_exceptions (compiled_regex
>*preg,
>> >> 			   SEARCH_GLOBAL_BLOCK | SEARCH_STATIC_BLOCK,
>> >> 			   VARIABLES_DOMAIN);
>> >>
>> >>+  /* Iterate over all objfiles irrespective of scope or linker namespaces
>> >>+     so we get all exceptions anywhere in the progspace.  */
>> >>   for (objfile *objfile : current_program_space->objfiles ())
>> >>     {
>> >>       for (compunit_symtab *s : objfile->compunits ())
>> >>--
>> >>2.35.3
>>
>> Intel Deutschland GmbH
>> Registered Address: Am Campeon 10, 85579 Neubiberg, Germany
>> Tel: +49 89 99 8853-0, www.intel.de <http://www.intel.de>
>> Managing Directors: Christin Eisenschmid, Sharon Heck, Tiffany Doon Silva
>> Chairperson of the Supervisory Board: Nicole Lau
>> Registered Office: Munich
>> Commercial Register: Amtsgericht Muenchen HRB 186928
>>
>
>--
>Joel
Intel Deutschland GmbH
Registered Address: Am Campeon 10, 85579 Neubiberg, Germany
Tel: +49 89 99 8853-0, www.intel.de <http://www.intel.de>
Managing Directors: Christin Eisenschmid, Sharon Heck, Tiffany Doon Silva  
Chairperson of the Supervisory Board: Nicole Lau
Registered Office: Munich
Commercial Register: Amtsgericht Muenchen HRB 186928


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

* Re: [PATCH v5 09/15] gdb, ada: update ada_lookup_simple_minsym
  2022-09-14  8:19       ` Metzger, Markus T
@ 2022-09-21 16:11         ` Tom Tromey
  0 siblings, 0 replies; 52+ messages in thread
From: Tom Tromey @ 2022-09-21 16:11 UTC (permalink / raw)
  To: Metzger, Markus T via Gdb-patches; +Cc: Tom Tromey, Metzger, Markus T

>>>>> "Metzger," == Metzger, Markus T via Gdb-patches <gdb-patches@sourceware.org> writes:

> ping.

Sorry about the delay.  I think the patch is ok.  Thanks for your
response.

Tom

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

* RE: [PATCH v5 00/15] basic linker namespace support
  2022-07-18  5:33     ` Metzger, Markus T
@ 2022-10-05 11:16       ` Metzger, Markus T
  0 siblings, 0 replies; 52+ messages in thread
From: Metzger, Markus T @ 2022-10-05 11:16 UTC (permalink / raw)
  To: Kevin Buettner; +Cc: gdb-patches

Hello Kevin,

>>I'd like to see this work go in.  So long as it doesn't break existing
>>(non-linker namespace) use cases, I'm okay with fixing the other
>>problems later on.
>
>As far as I could test (x86-64 on Fedora 35) it does not break anything.
>I'll ask Joel about the Ada patches.

Tom Tromey reviewed the remaining two Ada patches.

Looks like we're OK to merge this.  I will rebase it again and run tests
once more in the next days.

regards,
markus.
Intel Deutschland GmbH
Registered Address: Am Campeon 10, 85579 Neubiberg, Germany
Tel: +49 89 99 8853-0, www.intel.de <http://www.intel.de>
Managing Directors: Christin Eisenschmid, Sharon Heck, Tiffany Doon Silva  
Chairperson of the Supervisory Board: Nicole Lau
Registered Office: Munich
Commercial Register: Amtsgericht Muenchen HRB 186928


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

end of thread, other threads:[~2022-10-05 11:16 UTC | newest]

Thread overview: 52+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-06-02 13:24 [PATCH v5 00/15] basic linker namespace support Markus Metzger
2022-06-02 13:25 ` [PATCH v5 01/15] gdb, testsuite: extend gdb_test_multiple checks Markus Metzger
2022-06-13  1:28   ` Kevin Buettner
2022-06-02 13:25 ` [PATCH v5 02/15] gdb, solib-svr4: remove locate_base() Markus Metzger
2022-06-02 23:04   ` Kevin Buettner
2022-06-02 13:25 ` [PATCH v5 03/15] gdb, gdbserver: support dlmopen() Markus Metzger
2022-06-19  4:02   ` Kevin Buettner
2022-06-27 12:55     ` Metzger, Markus T
2022-06-30 22:35       ` Kevin Buettner
2022-06-02 13:25 ` [PATCH v5 04/15] gdbserver: move main_lm handling into caller Markus Metzger
2022-06-19  4:22   ` Kevin Buettner
2022-06-02 13:25 ` [PATCH v5 05/15] gdb, gdbserver: extend RSP to support namespaces Markus Metzger
2022-06-02 16:09   ` Eli Zaretskii
2022-06-19  4:32   ` Kevin Buettner
2022-06-02 13:25 ` [PATCH v5 06/15] gdb, compile: unlink objfile stored in module Markus Metzger
2022-06-23 17:20   ` Kevin Buettner
2022-06-02 13:25 ` [PATCH v5 07/15] gdb, python: use gdbarch_iterate_over_objfiles_in_search_order Markus Metzger
2022-06-24 17:18   ` Kevin Buettner
2022-06-02 13:25 ` [PATCH v5 08/15] gdb, ada: collect standard exceptions in all objfiles Markus Metzger
2022-06-24 17:26   ` Kevin Buettner
2022-07-18 16:49     ` Tom Tromey
2022-07-18  5:35   ` Metzger, Markus T
2022-09-14  8:19     ` Metzger, Markus T
2022-09-14  8:37       ` Joel Brobecker
2022-09-14  8:45         ` Metzger, Markus T
2022-06-02 13:25 ` [PATCH v5 09/15] gdb, ada: update ada_lookup_simple_minsym Markus Metzger
2022-06-24 23:42   ` Kevin Buettner
2022-07-18 17:02   ` Tom Tromey
2022-07-19  7:14     ` Metzger, Markus T
2022-09-14  8:19       ` Metzger, Markus T
2022-09-21 16:11         ` Tom Tromey
2022-06-02 13:25 ` [PATCH v5 10/15] gdb, ada: update ada_add_all_symbols Markus Metzger
2022-06-24 23:53   ` Kevin Buettner
2022-07-18  5:36   ` Metzger, Markus T
2022-07-18 16:56   ` Tom Tromey
2022-07-19  7:13     ` Metzger, Markus T
2022-07-19 12:23       ` Tom Tromey
2022-07-19 13:49         ` Metzger, Markus T
2022-06-02 13:25 ` [PATCH v5 11/15] gdb, cp: update add_symbol_overload_list_qualified Markus Metzger
2022-06-24 23:59   ` Kevin Buettner
2022-06-02 13:25 ` [PATCH v5 12/15] gdb, hppa: remove unused hppa_lookup_stub_minimal_symbol Markus Metzger
2022-06-25  0:01   ` Kevin Buettner
2022-06-02 13:25 ` [PATCH v5 13/15] gdb, symtab: inline find_quick_global_symbol_language Markus Metzger
2022-06-25  0:16   ` Kevin Buettner
2022-06-02 13:25 ` [PATCH v5 14/15] gdb: update gnu ifunc resolve Markus Metzger
2022-06-25  0:34   ` Kevin Buettner
2022-06-02 13:25 ` [PATCH v5 15/15] gdb, solib-svr4: support namespaces in DSO iteration Markus Metzger
2022-06-25  0:42   ` Kevin Buettner
2022-07-15 10:30 ` [PATCH v5 00/15] basic linker namespace support Metzger, Markus T
2022-07-16  0:04   ` Kevin Buettner
2022-07-18  5:33     ` Metzger, Markus T
2022-10-05 11:16       ` Metzger, Markus T

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).