]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
gdb/progspace: add solib_ops pointer in program_space
authorSimon Marchi <simon.marchi@polymtl.ca>
Thu, 26 Jun 2025 17:36:06 +0000 (13:36 -0400)
committerSimon Marchi <simon.marchi@polymtl.ca>
Thu, 26 Jun 2025 18:08:31 +0000 (14:08 -0400)
The subsequent C++ification patch in this series will allocate one
instance of solib_ops per program space.  That instance will be held in
struct program_space.  As a small step towards this, add an `solib_ops
*` field to `struct program_space`.  This field represents the solib_ops
currently used to manage the solibs in that program space.  Initialize
it with the result of `gdbarch_so_ops` in `post_create_inferior`, and
use it whenever we need to do some solib stuff, rather than using
`gdbarch_so_ops` directly.

The difficulty here is knowing when exactly to set and unset the solib
ops.  What I have here passes the testsuite on Linux, but with more
testing we will probably discover more spots where it's needed.

The C++ification patch will turn this field into a unique pointer.

With this patch, the message we get when running "info
linker-namespaces" becomes always the same, so update the test in
gdb.base/dlmopen-ns-ids.exp.

Change-Id: Ide8ddc57328895720fcd645d46dc34491f84c656
Approved-By: Pedro Alves <pedro@palves.net>
Reviewed-By: Guinevere Larsen <guinevere@redhat.com>
gdb/corelow.c
gdb/infcmd.c
gdb/inferior.h
gdb/infrun.c
gdb/progspace.h
gdb/solib.c
gdb/target.c
gdb/testsuite/gdb.base/dlmopen-ns-ids.exp
gdb/tracectf.c
gdb/tracefile-tfile.c

index a61a41baf01f3c7bac5d6a00ea272577d6d372e1..24b949b83e7917f7f243be14df6aeaad2ee08072 100644 (file)
@@ -1180,7 +1180,7 @@ core_target_open (const char *arg, int from_tty)
   if (current_program_space->exec_bfd () == nullptr)
     set_gdbarch_from_file (current_program_space->core_bfd ());
 
-  post_create_inferior (from_tty);
+  post_create_inferior (from_tty, true);
 
   /* Now go through the target stack looking for threads since there
      may be a thread_stratum target loaded on top of target core by
index 4beab86267e94fed23490e580d702a2e123bacc9..36a2c809088efe250bca877401eb359ee3f9d9c5 100644 (file)
@@ -224,14 +224,11 @@ strip_bg_char (const char *args, int *bg_char_p)
   return make_unique_xstrdup (args);
 }
 
-/* Common actions to take after creating any sort of inferior, by any
-   means (running, attaching, connecting, et cetera).  The target
-   should be stopped.  */
+/* See inferior.h.  */
 
 void
-post_create_inferior (int from_tty)
+post_create_inferior (int from_tty, bool set_pspace_solib_ops)
 {
-
   /* Be sure we own the terminal in case write operations are performed.  */ 
   target_terminal::ours_for_output ();
 
@@ -261,6 +258,10 @@ post_create_inferior (int from_tty)
        throw;
     }
 
+  if (set_pspace_solib_ops)
+    current_program_space->set_solib_ops
+      (*gdbarch_so_ops (current_inferior ()->arch ()));
+
   if (current_program_space->exec_bfd ())
     {
       const unsigned solib_add_generation
@@ -482,7 +483,7 @@ run_command_1 (const char *args, int from_tty, enum run_how run_how)
 
   /* Pass zero for FROM_TTY, because at this point the "run" command
      has done its thing; now we are setting up the running program.  */
-  post_create_inferior (0);
+  post_create_inferior (0, true);
 
   /* Queue a pending event so that the program stops immediately.  */
   if (run_how == RUN_STOP_AT_FIRST_INSN)
@@ -2506,7 +2507,7 @@ setup_inferior (int from_tty)
   /* Take any necessary post-attaching actions for this platform.  */
   target_post_attach (inferior_ptid.pid ());
 
-  post_create_inferior (from_tty);
+  post_create_inferior (from_tty, true);
 }
 
 /* What to do after the first program stops after attaching.  */
index 54f5229b420fad16f26a95132b471b644d2bcd33..fe94e289bdc741e4763461e2df44e4153b6f5e12 100644 (file)
@@ -213,7 +213,14 @@ extern ptid_t gdb_startup_inferior (pid_t pid, int num_traps);
 
 extern void setup_inferior (int from_tty);
 
-extern void post_create_inferior (int from_tty);
+/* Common actions to take after creating any sort of inferior, by any
+   means (running, attaching, connecting, et cetera).  The target
+   should be stopped.
+
+   If SET_PSPACE_SOLIB_OPS is true, initialize the program space's solib
+   provider using the current inferior's architecture.  */
+
+extern void post_create_inferior (int from_tty, bool set_pspace_solib_ops);
 
 extern void attach_command (const char *, int);
 
index a5d3fb0454d590c22fc568f46909796d435ce3f0..ea1a64153d94c544f58e9adcfccc9efc1ff44283 100644 (file)
@@ -472,6 +472,7 @@ holding the child stopped.  Try \"set %ps\" or \"%ps\".\n"),
 
   inferior *parent_inf = current_inferior ();
   inferior *child_inf = nullptr;
+  bool child_has_new_pspace = false;
 
   gdb_assert (parent_inf->thread_waiting_for_vfork_done == nullptr);
 
@@ -536,6 +537,7 @@ holding the child stopped.  Try \"set %ps\" or \"%ps\".\n"),
          else
            {
              child_inf->pspace = new program_space (new_address_space ());
+             child_has_new_pspace = true;
              child_inf->aspace = child_inf->pspace->aspace;
              child_inf->removable = true;
              clone_program_space (child_inf->pspace, parent_inf->pspace);
@@ -625,6 +627,7 @@ holding the child stopped.  Try \"set %ps\" or \"%ps\".\n"),
       else
        {
          child_inf->pspace = new program_space (new_address_space ());
+         child_has_new_pspace = true;
          child_inf->aspace = child_inf->pspace->aspace;
          child_inf->removable = true;
          child_inf->symfile_flags = SYMFILE_NO_READ;
@@ -723,7 +726,8 @@ holding the child stopped.  Try \"set %ps\" or \"%ps\".\n"),
        maybe_restore.emplace ();
 
       switch_to_thread (*child_inf->threads ().begin ());
-      post_create_inferior (0);
+
+      post_create_inferior (0, child_has_new_pspace);
     }
 
   return false;
@@ -1321,6 +1325,7 @@ follow_exec (ptid_t ptid, const char *exec_file_target)
      we don't want those to be satisfied by the libraries of the
      previous incarnation of this process.  */
   no_shared_libraries (current_program_space);
+  current_program_space->unset_solib_ops ();
 
   inferior *execing_inferior = current_inferior ();
   inferior *following_inferior;
@@ -1377,6 +1382,8 @@ follow_exec (ptid_t ptid, const char *exec_file_target)
      registers.  */
   target_find_description ();
 
+  current_program_space->set_solib_ops
+    (*gdbarch_so_ops (following_inferior->arch ()));
   gdb::observers::inferior_execd.notify (execing_inferior, following_inferior);
 
   breakpoint_re_set ();
@@ -3818,7 +3825,7 @@ start_remote (int from_tty)
   /* Now that the inferior has stopped, do any bookkeeping like
      loading shared libraries.  We want to do this before normal_stop,
      so that the displayed frame is up to date.  */
-  post_create_inferior (from_tty);
+  post_create_inferior (from_tty, true);
 
   normal_stop ();
 }
index 5e5d5edd9b4b97d8b1382ee97376f6acb34e3916..3d0d677cbe01f02b1cfd93b8907c239a03e04495 100644 (file)
@@ -231,6 +231,23 @@ struct program_space
      is outside all objfiles in this progspace.  */
   struct objfile *objfile_for_address (CORE_ADDR address);
 
+  /* Set this program space's solib provider.
+
+     The solib provider must be unset prior to calling this method.  */
+  void set_solib_ops (const struct solib_ops &ops)
+  {
+    gdb_assert (m_solib_ops == nullptr);
+    m_solib_ops = &ops;
+  };
+
+  /* Unset this program space's solib provider.  */
+  void unset_solib_ops ()
+  { m_solib_ops = nullptr; }
+
+  /* Get this program space's solib provider.  */
+  const struct solib_ops *solib_ops () const
+  { return m_solib_ops; }
+
   /* Return the list of all the solibs in this program space.  */
   owning_intrusive_list<solib> &solibs ()
   { return m_solib_list; }
@@ -355,6 +372,9 @@ private:
   /* All known objfiles are kept in a linked list.  */
   owning_intrusive_list<objfile> m_objfiles_list;
 
+  /* solib_ops implementation used to provide solibs in this program space.  */
+  const struct solib_ops *m_solib_ops = nullptr;
+
   /* List of shared objects mapped into this space.  Managed by
      solib.c.  */
   owning_intrusive_list<solib> m_solib_list;
index 22bd59b43be53e952924c6ebb446305b472bfcd6..fab3ae39c2d0b3eb6316fa0a3269ffed4fd95abe 100644 (file)
@@ -707,7 +707,10 @@ notify_solib_unloaded (program_space *pspace, const solib &so,
 void
 update_solib_list (int from_tty)
 {
-  const solib_ops *ops = gdbarch_so_ops (current_inferior ()->arch ());
+  const solib_ops *ops = current_program_space->solib_ops ();
+
+  if (ops == nullptr)
+    return;
 
   /* We can reach here due to changing solib-search-path or the
      sysroot, before having any inferior.  */
@@ -1021,16 +1024,21 @@ print_solib_list_table (std::vector<const solib *> solib_list,
   gdbarch *gdbarch = current_inferior ()->arch ();
   /* "0x", a little whitespace, and two hex digits per byte of pointers.  */
   int addr_width = 4 + (gdbarch_ptr_bit (gdbarch) / 4);
-  const solib_ops *ops = gdbarch_so_ops (gdbarch);
+  const solib_ops *ops = current_program_space->solib_ops ();
   struct ui_out *uiout = current_uiout;
   bool so_missing_debug_info = false;
 
+  if (ops == nullptr)
+    return;
+
   /* There are 3 conditions for this command to print solib namespaces,
      first PRINT_NAMESPACE has to be true, second the solib_ops has to
      support multiple namespaces, and third there must be more than one
      active namespace.  Fold all these into the PRINT_NAMESPACE condition.  */
-  print_namespace = print_namespace && ops->num_active_namespaces != nullptr
-                   && ops->num_active_namespaces () > 1;
+  print_namespace = (print_namespace
+                    && ops != nullptr
+                    && ops->num_active_namespaces != nullptr
+                    && ops->num_active_namespaces () > 1);
 
   int num_cols = 4;
   if (print_namespace)
@@ -1155,10 +1163,11 @@ info_sharedlibrary_command (const char *pattern, int from_tty)
 static void
 info_linker_namespace_command (const char *pattern, int from_tty)
 {
-  const solib_ops *ops = gdbarch_so_ops (current_inferior ()->arch ());
+  const solib_ops *ops = current_program_space->solib_ops ();
+
   /* This command only really makes sense for inferiors that support
      linker namespaces, so we can leave early.  */
-  if (ops->num_active_namespaces == nullptr)
+  if (ops == nullptr || ops->num_active_namespaces == nullptr)
     error (_("Current inferior does not support linker namespaces.  "
             "Use \"info sharedlibrary\" instead."));
 
@@ -1273,9 +1282,9 @@ solib_name_from_address (struct program_space *pspace, CORE_ADDR address)
 bool
 solib_keep_data_in_core (CORE_ADDR vaddr, unsigned long size)
 {
-  const solib_ops *ops = gdbarch_so_ops (current_inferior ()->arch ());
+  const solib_ops *ops = current_program_space->solib_ops ();
 
-  if (ops->keep_data_in_core)
+  if (ops != nullptr && ops->keep_data_in_core != nullptr)
     return ops->keep_data_in_core (vaddr, size) != 0;
   else
     return false;
@@ -1286,8 +1295,6 @@ solib_keep_data_in_core (CORE_ADDR vaddr, unsigned long size)
 void
 clear_solib (program_space *pspace)
 {
-  const solib_ops *ops = gdbarch_so_ops (current_inferior ()->arch ());
-
   for (solib &so : pspace->solibs ())
     {
       bool still_in_use
@@ -1299,7 +1306,9 @@ clear_solib (program_space *pspace)
 
   pspace->solibs ().clear ();
 
-  if (ops->clear_solib != nullptr)
+  const solib_ops *ops = pspace->solib_ops ();
+
+  if (ops != nullptr && ops->clear_solib != nullptr)
     ops->clear_solib (pspace);
 }
 
@@ -1311,9 +1320,9 @@ clear_solib (program_space *pspace)
 void
 solib_create_inferior_hook (int from_tty)
 {
-  const solib_ops *ops = gdbarch_so_ops (current_inferior ()->arch ());
+  const solib_ops *ops = current_program_space->solib_ops ();
 
-  if (ops->solib_create_inferior_hook != nullptr)
+  if (ops != nullptr && ops->solib_create_inferior_hook != nullptr)
     ops->solib_create_inferior_hook (from_tty);
 }
 
@@ -1322,10 +1331,10 @@ solib_create_inferior_hook (int from_tty)
 bool
 in_solib_dynsym_resolve_code (CORE_ADDR pc)
 {
-  const auto in_dynsym_resolve_code
-    = gdbarch_so_ops (current_inferior ()->arch ())->in_dynsym_resolve_code;
+  const solib_ops *ops = current_program_space->solib_ops ();
 
-  return in_dynsym_resolve_code && in_dynsym_resolve_code (pc);
+  return (ops != nullptr && ops->in_dynsym_resolve_code != nullptr
+         && ops->in_dynsym_resolve_code (pc));
 }
 
 /* Implements the "sharedlibrary" command.  */
@@ -1367,9 +1376,9 @@ no_shared_libraries_command (const char *ignored, int from_tty)
 void
 update_solib_breakpoints (void)
 {
-  const solib_ops *ops = gdbarch_so_ops (current_inferior ()->arch ());
+  const solib_ops *ops = current_program_space->solib_ops ();
 
-  if (ops->update_breakpoints != NULL)
+  if (ops != nullptr && ops->update_breakpoints != nullptr)
     ops->update_breakpoints ();
 }
 
@@ -1378,9 +1387,9 @@ update_solib_breakpoints (void)
 void
 handle_solib_event (void)
 {
-  const solib_ops *ops = gdbarch_so_ops (current_inferior ()->arch ());
+  const solib_ops *ops = current_program_space->solib_ops ();
 
-  if (ops->handle_event != NULL)
+  if (ops != nullptr && ops->handle_event != nullptr)
     ops->handle_event ();
 
   current_inferior ()->pspace->clear_solib_cache ();
@@ -1464,8 +1473,6 @@ reload_shared_libraries (const char *ignored, int from_tty,
 {
   reload_shared_libraries_1 (from_tty);
 
-  const solib_ops *ops = gdbarch_so_ops (current_inferior ()->arch ());
-
   /* Creating inferior hooks here has two purposes.  First, if we reload 
      shared libraries then the address of solib breakpoint we've computed
      previously might be no longer valid.  For example, if we forgot to set
@@ -1477,9 +1484,11 @@ reload_shared_libraries (const char *ignored, int from_tty,
      about ld.so.  */
   if (target_has_execution ())
     {
+      const solib_ops *ops = current_program_space->solib_ops ();
+
       /* Reset or free private data structures not associated with
         solib entries.  */
-      if (ops->clear_solib != nullptr)
+      if (ops != nullptr && ops->clear_solib != nullptr)
        ops->clear_solib (current_program_space);
 
       /* Remove any previous solib event breakpoint.  This is usually
index 7e35cb3a958f5cc5d93e3fc0ce3297b87795d0d7..f7c43f69a288728750b5dc85626742bca013e694 100644 (file)
@@ -2464,6 +2464,7 @@ target_pre_inferior ()
   if (!gdbarch_has_global_solist (current_inferior ()->arch ()))
     {
       no_shared_libraries (current_program_space);
+      current_program_space->unset_solib_ops ();
 
       invalidate_target_mem_regions ();
 
index e95732a5bbbef2eebb4b3799b1b64f619328f5b4..4d3e8eba2ab13bdd8fe74f5c1cdcff3ce72b191d 100644 (file)
@@ -171,7 +171,8 @@ proc test_info_linker_namespaces {} {
 
     # Check that "info linker-namespaces" while the inferior is not running
     # doesn't crash.
-    gdb_test "info linker-namespaces" "" \
+    gdb_test "info linker-namespaces" \
+       "Current inferior does not support linker namespaces\\.  Use \"info sharedlibrary\" instead\\." \
        "info linker-namespaces before running"
 
     if { ![runto_main] } {
index fcb0708d787cd5e6fdd1ba444563dd82a14d5ea7..0f80d08e6d6c636a832df59d1bb872bc785a9166 100644 (file)
@@ -1174,7 +1174,7 @@ ctf_target_open (const char *args, int from_tty)
   merge_uploaded_trace_state_variables (&uploaded_tsvs);
   merge_uploaded_tracepoints (&uploaded_tps);
 
-  post_create_inferior (from_tty);
+  post_create_inferior (from_tty, true);
 }
 
 /* This is the implementation of target_ops method to_close.  Destroy
index 3fce218e967609b62bfa304982be8b7d2ef79431..a45001cf318fdb2ff9c1c71fa118148248755ee8 100644 (file)
@@ -567,7 +567,7 @@ tfile_target_open (const char *arg, int from_tty)
 
   merge_uploaded_tracepoints (&uploaded_tps);
 
-  post_create_inferior (from_tty);
+  post_create_inferior (from_tty, true);
 }
 
 /* Interpret the given line from the definitions part of the trace