]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
gdb/solib: C++ify solib_ops
authorSimon Marchi <simon.marchi@polymtl.ca>
Thu, 26 Jun 2025 17:36:58 +0000 (13:36 -0400)
committerSimon Marchi <simon.marchi@polymtl.ca>
Thu, 26 Jun 2025 18:08:31 +0000 (14:08 -0400)
Convert solib_ops into an abstract base class (with abstract methods,
some of them with default implementations) and convert all the existing
solib_ops instances to solib_ops derived classes / implementations.

Prior to this patch, solib_ops is a structure holding function pointers,
of which there are only a handful of global instances (in the
`solib-*.c` files).  When passing an `solib_ops *` around, it's a
pointer to one of these instances.  After this patch, there are no more
global solib_ops instances.  Instances are created as needed and stored
in struct program_space.  These instances could eventually be made to
contain the program space-specific data, which is currently kept in
per-program space registries (I have some pending patches for that).

Prior to this patch, `gdbarch_so_ops` is a gdbarch method that returns a
pointer to the appropriate solib_ops implementation for the gdbarch.
This is replaced with the `gdbarch_make_solib_ops` method, which returns
a new instance of the appropriate solib_ops implementation for this
gdbarch.  This requires introducing some factory functions for the
various solib_ops implementation, to be used as `gdbarch_make_solib_ops`
callbacks.  For instance:

    solib_ops_up
    make_linux_ilp32_svr4_solib_ops ()
    {
      return std::make_unique<linux_ilp32_svr4_solib_ops> ();
    }

The previous code is full of cases of tdep files copying some base
solib_ops implementation, and overriding one or more function pointer
(see ppc_linux_init_abi, for instance).  I tried to convert all of this
is a class hierarchy.  I like that it's now possible to get a good
static view of all the existing solib_ops variants.  The hierarchy looks
like this:

    solib_ops
    ├── aix_solib_ops
    ├── darwin_solib_ops
    ├── dsbt_solib_ops
    ├── frv_solib_ops
    ├── rocm_solib_ops
    ├── svr4_solib_ops
    │   ├── ilp32_svr4_solib_ops
    │   ├── lp64_svr4_solib_ops
    │   ├── linux_ilp32_svr4_solib_ops
    │   │   ├── mips_linux_ilp32_svr4_solib_ops
    │   │   └── ppc_linux_ilp32_svr4_solib_ops
    │   ├── linux_lp64_svr4_solib_ops
    │   │   └── mips_linux_lp64_svr4_solib_ops
    │   ├── mips_nbsd_ilp32_svr4_solib_ops
    │   ├── mips_nbsd_lp64_svr4_solib_ops
    │   ├── mips_fbsd_ilp32_svr4_solib_ops
    │   └── mips_fbsd_lp64_svr4_solib_ops
    └── target_solib_ops
        └── windows_solib_ops

The solib-svr4 code has per-arch specialization to provide a
link_map_offsets, containing the offsets of the interesting fields in
`struct link_map` on that particular architecture.  Prior to this patch,
arches would set a callback returning the appropriate link_map_offsets
by calling `set_solib_svr4_fetch_link_map_offsets`, which also happened
to set the gdbarch's so_ops to `&svr_so_ops`.  I converted this to an
abstract virtual method of `struct svr4_solib_ops`, meaning that all
classes deriving from svr4_solib_ops must provide a method returning the
appropriate link_map_offsets for the architecture.  I renamed
`set_solib_svr4_fetch_link_map_offsets` to `set_solib_svr4_ops`.  This
function is still necessary because it also calls
set_gdbarch_iterate_over_objfiles_in_search_order, but if it was not for
that, we could get rid of it.

There is an instance of CRTP in mips-linux-tdep.c, because both
mips_linux_ilp32_svr4_solib_ops and mips_linux_lp64_svr4_solib_ops need
to derive from different SVR4 base classes (linux_ilp32_svr4_solib_ops
and linux_lp64_svr4_solib_ops), but they both want to override the
in_dynsym_resolve_code method with the same implementation.

The solib_ops::supports_namespaces method is new: the support for
namespaces was previously predicated by the presence or absence of a
find_solib_ns method.  It now needs to be explicit.

There is a new progspace::release_solib_ops method, which is only needed
for rocm_solib_ops.  For the moment, rocm_solib_ops replaces and wraps
the existing svr4_solib_ops instance, in order to combine the results of
the two.  The plan is to have a subsequent patch to allow program spaces to have
multiple solib_ops, removing the need for release_solib_ops.

Speaking of rocm_solib_ops: it previously overrode only a few methods by
copying svr4_solib_ops and overwriting some function pointers.  Now, it
needs to implement all the methods that svr4_solib_ops implements, in
order to forward the call.  Otherwise, the default solib_ops method
would be called, hiding the svr4_solib_ops implementation.  Again, this
can be removed once we have support for multiple solib_ops in a
program_space.

There is also a small change in how rocm_solib_ops is activated.  Prior
to this patch, it's done at the end of rocm_update_solib_list.  Since it
overrides the function pointer in the static svr4_solib_ops, and then
overwrites the host gdbarch, so_ops field, it's something that happens
only once.  After the patch though, we need to set rocm_solib_ops in all
the program spaces that appear.  We do this in
rocm_solib_target_inferior_created and in the new
rocm_solib_target_inferior_execd.  After this, I will explore doing a
change where rocm_solib_ops is only set when we detect the ROCm runtime
is loaded.

Change-Id: I5896b5bcbf8bdb024d67980380feba1ffefaa4c9
Approved-By: Pedro Alves <pedro@palves.net>
97 files changed:
gdb/Makefile.in
gdb/aarch64-fbsd-tdep.c
gdb/aarch64-linux-tdep.c
gdb/alpha-linux-tdep.c
gdb/alpha-netbsd-tdep.c
gdb/alpha-obsd-tdep.c
gdb/amd-dbgapi-target.c
gdb/amd-dbgapi-target.h
gdb/amd64-darwin-tdep.c
gdb/amd64-fbsd-tdep.c
gdb/amd64-gnu-tdep.c
gdb/amd64-linux-tdep.c
gdb/amd64-netbsd-tdep.c
gdb/amd64-obsd-tdep.c
gdb/amd64-sol2-tdep.c
gdb/arc-linux-tdep.c
gdb/arm-fbsd-tdep.c
gdb/arm-linux-tdep.c
gdb/arm-netbsd-tdep.c
gdb/arm-obsd-tdep.c
gdb/configure.tgt
gdb/cris-linux-tdep.c
gdb/csky-linux-tdep.c
gdb/dicos-tdep.c
gdb/frv-tdep.c
gdb/frv-tdep.h
gdb/gdbarch-gen.c
gdb/gdbarch-gen.h
gdb/gdbarch.h
gdb/gdbarch_components.py
gdb/hppa-bsd-tdep.c
gdb/hppa-linux-tdep.c
gdb/i386-darwin-tdep.c
gdb/i386-fbsd-tdep.c
gdb/i386-gnu-tdep.c
gdb/i386-linux-tdep.c
gdb/i386-netbsd-tdep.c
gdb/i386-obsd-tdep.c
gdb/i386-sol2-tdep.c
gdb/ia64-linux-tdep.c
gdb/infcmd.c
gdb/infrun.c
gdb/linux-tdep.c
gdb/linux-tdep.h
gdb/loongarch-linux-tdep.c
gdb/m32r-linux-tdep.c
gdb/m68k-bsd-tdep.c
gdb/m68k-linux-tdep.c
gdb/microblaze-linux-tdep.c
gdb/mips-fbsd-tdep.c
gdb/mips-linux-tdep.c
gdb/mips-netbsd-tdep.c
gdb/mips64-obsd-tdep.c
gdb/mn10300-linux-tdep.c
gdb/or1k-linux-tdep.c
gdb/ppc-fbsd-tdep.c
gdb/ppc-linux-tdep.c
gdb/ppc-netbsd-tdep.c
gdb/ppc-obsd-tdep.c
gdb/progspace.h
gdb/riscv-fbsd-tdep.c
gdb/riscv-linux-tdep.c
gdb/rs6000-aix-tdep.c
gdb/s390-linux-tdep.c
gdb/sh-linux-tdep.c
gdb/sh-netbsd-tdep.c
gdb/solib-aix.c
gdb/solib-aix.h
gdb/solib-darwin.c
gdb/solib-darwin.h
gdb/solib-dsbt.c
gdb/solib-dsbt.h
gdb/solib-frv.c
gdb/solib-frv.h [new file with mode: 0644]
gdb/solib-rocm.c
gdb/solib-svr4-linux.c [new file with mode: 0644]
gdb/solib-svr4-linux.h [new file with mode: 0644]
gdb/solib-svr4.c
gdb/solib-svr4.h
gdb/solib-target.c
gdb/solib-target.h
gdb/solib.c
gdb/solib.h
gdb/sparc-linux-tdep.c
gdb/sparc-netbsd-tdep.c
gdb/sparc-sol2-tdep.c
gdb/sparc64-fbsd-tdep.c
gdb/sparc64-linux-tdep.c
gdb/sparc64-netbsd-tdep.c
gdb/sparc64-obsd-tdep.c
gdb/sparc64-sol2-tdep.c
gdb/tic6x-linux-tdep.c
gdb/tilegx-linux-tdep.c
gdb/vax-netbsd-tdep.c
gdb/windows-tdep.c
gdb/xtensa-linux-tdep.c
gdb/xtensa-tdep.c

index 998203ce1e2068465460989d70c807c257abca93..fc0c56564c232523b5974a128da6bf58c6bb3160 100644 (file)
@@ -891,6 +891,7 @@ ALL_TARGET_OBS = \
        solib-dsbt.o \
        solib-frv.o \
        solib-svr4.o \
+       solib-svr4-linux.o \
        sparc-linux-tdep.o \
        sparc-netbsd-tdep.o \
        sparc-obsd-tdep.o \
@@ -1478,7 +1479,9 @@ HFILES_NO_SRCDIR = \
        solib.h \
        solib-aix.h \
        solib-darwin.h \
+       solib-frv.h \
        solib-svr4.h \
+       solib-svr4-linux.h \
        solib-target.h \
        source.h \
        source-cache.h \
index 3049fb0f901c00310246df35535aa5f9bb36bc38..db9b82fa694fbf983603391c33883988044686fb 100644 (file)
@@ -239,8 +239,7 @@ aarch64_fbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
   /* Generic FreeBSD support.  */
   fbsd_init_abi (info, gdbarch);
 
-  set_solib_svr4_fetch_link_map_offsets (gdbarch,
-                                        svr4_lp64_fetch_link_map_offsets);
+  set_solib_svr4_ops (gdbarch, make_svr4_lp64_solib_ops);
 
   tramp_frame_prepend_unwinder (gdbarch, &aarch64_fbsd_sigframe);
 
index ff4bf59d4e3e06bd630a960e4fd38c2ee3ca487b..dd35eaff9143a6d0fecf9dc44d3c27dd591ca0d1 100644 (file)
@@ -23,6 +23,7 @@
 #include "extract-store-integer.h"
 #include "gdbarch.h"
 #include "glibc-tdep.h"
+#include "solib-svr4-linux.h"
 #include "linux-tdep.h"
 #include "svr4-tls-tdep.h"
 #include "aarch64-tdep.h"
@@ -2768,9 +2769,7 @@ aarch64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
   tdep->lowest_pc = 0x8000;
 
   linux_init_abi (info, gdbarch, 1);
-
-  set_solib_svr4_fetch_link_map_offsets (gdbarch,
-                                        linux_lp64_fetch_link_map_offsets);
+  set_solib_svr4_ops (gdbarch, make_linux_lp64_svr4_solib_ops);
 
   /* Enable TLS support.  */
   set_gdbarch_fetch_tls_load_module_address (gdbarch,
index cd1f76990fa045c618b81c3caa67f8c4a8343e92..8b4b4f1fd496150250c662227b90ad0dce419245 100644 (file)
@@ -17,6 +17,7 @@
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include "frame.h"
+#include "solib-svr4-linux.h"
 #include "osabi.h"
 #include "solib-svr4.h"
 #include "symtab.h"
@@ -369,9 +370,7 @@ alpha_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
   tdep->jb_elt_size = 8;
 
   set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
-
-  set_solib_svr4_fetch_link_map_offsets
-    (gdbarch, linux_lp64_fetch_link_map_offsets);
+  set_solib_svr4_ops (gdbarch, make_linux_lp64_svr4_solib_ops);
 
   /* Enable TLS support.  */
   set_gdbarch_fetch_tls_load_module_address (gdbarch,
index 2921340dfe54e4f405652a72e91e3c10be8c3f47..0f5e3051cc20991dfd828bcc9c095232a4e4109f 100644 (file)
@@ -264,8 +264,7 @@ alphanbsd_init_abi (struct gdbarch_info info,
   set_gdbarch_software_single_step (gdbarch, alpha_software_single_step);
 
   /* NetBSD/alpha has SVR4-style shared libraries.  */
-  set_solib_svr4_fetch_link_map_offsets
-    (gdbarch, svr4_lp64_fetch_link_map_offsets);
+  set_solib_svr4_ops (gdbarch, make_svr4_lp64_solib_ops);
 
   tdep->dynamic_sigtramp_offset = alphanbsd_sigtramp_offset;
   tdep->pc_in_sigtramp = alphanbsd_pc_in_sigtramp;
index 2fc55fdb4604ca04a9701bfa3bf84a91905efa2a..63f90506af18c618a443127ac9d44561aa11adf2 100644 (file)
@@ -109,8 +109,7 @@ alphaobsd_init_abi(struct gdbarch_info info, struct gdbarch *gdbarch)
   set_gdbarch_software_single_step (gdbarch, alpha_software_single_step);
 
   /* OpenBSD/alpha has SVR4-style shared libraries.  */
-  set_solib_svr4_fetch_link_map_offsets
-    (gdbarch, svr4_lp64_fetch_link_map_offsets);
+  set_solib_svr4_ops (gdbarch, make_svr4_lp64_solib_ops);
   set_gdbarch_skip_solib_resolver (gdbarch, obsd_skip_solib_resolver);
 
   tdep->dynamic_sigtramp_offset = alphaobsd_sigtramp_offset;
index 0ccf53a9c58f0bde21a4b260e849beaf3566646c..a0210f4878fa2fa5396125555253ec6b5b1c7a70 100644 (file)
@@ -104,12 +104,26 @@ amd_dbgapi_lib_debug_module ()
 
 static gdb::observers::token amd_dbgapi_target_inferior_created_observer_token;
 
+/* See amd-dbgapi-target.h.  */
+
 const gdb::observers::token &
 get_amd_dbgapi_target_inferior_created_observer_token ()
 {
   return amd_dbgapi_target_inferior_created_observer_token;
 }
 
+/* inferior_execd observer token.  */
+
+static gdb::observers::token amd_dbgapi_target_inferior_execd_observer_token;
+
+/* See amd-dbgapi-target.h.  */
+
+const gdb::observers::token &
+get_amd_dbgapi_target_inferior_execd_observer_token ()
+{
+  return amd_dbgapi_target_inferior_execd_observer_token;
+}
+
 /* A type holding coordinates, etc. info for a given wave.  */
 
 struct wave_coordinates
@@ -2503,7 +2517,9 @@ INIT_GDB_FILE (amd_dbgapi_target)
   gdb::observers::inferior_created.attach
     (amd_dbgapi_target_inferior_created,
      amd_dbgapi_target_inferior_created_observer_token, "amd-dbgapi");
-  gdb::observers::inferior_execd.attach (amd_dbgapi_inferior_execd, "amd-dbgapi");
+  gdb::observers::inferior_execd.attach
+    (amd_dbgapi_inferior_execd, amd_dbgapi_target_inferior_execd_observer_token,
+     "amd-dbgapi");
   gdb::observers::inferior_forked.attach (amd_dbgapi_inferior_forked, "amd-dbgapi");
   gdb::observers::inferior_exit.attach (amd_dbgapi_inferior_exited, "amd-dbgapi");
   gdb::observers::inferior_pre_detach.attach (amd_dbgapi_inferior_pre_detach, "amd-dbgapi");
index dd37ba3b82d22f580b439bc4cef8e42c92bbbf06..fe3a50ba33b022022d278e3a9a3469a19773d54a 100644 (file)
@@ -54,6 +54,11 @@ using is_amd_dbgapi_handle
 const gdb::observers::token &
   get_amd_dbgapi_target_inferior_created_observer_token ();
 
+/* Get the token of amd-dbgapi's inferior_execd observer.  */
+
+const gdb::observers::token &
+  get_amd_dbgapi_target_inferior_execd_observer_token ();
+
 /* Comparison operators for amd-dbgapi handle types.  */
 
 template <typename T,
index 35da938d062a64d2edcc4cb663b8d6fec1edbe6f..c687b1f097a975ffc41c27fe4bc216f670a8bfe3 100644 (file)
@@ -113,7 +113,7 @@ x86_darwin_init_abi_64 (struct gdbarch_info info, struct gdbarch *gdbarch)
 
   tdep->jb_pc_offset = 56;
 
-  set_gdbarch_so_ops (gdbarch, &darwin_so_ops);
+  set_gdbarch_make_solib_ops (gdbarch, make_darwin_solib_ops);
 }
 
 INIT_GDB_FILE (amd64_darwin_tdep)
index 2991575b9b6f53506d4db2988c6c6e13a4ade05b..12f1e2293962e57402e5f7c24e2a42a7ccccf0f2 100644 (file)
@@ -328,8 +328,7 @@ amd64fbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
                                     amd64fbsd_core_read_description);
 
   /* FreeBSD uses SVR4-style shared libraries.  */
-  set_solib_svr4_fetch_link_map_offsets
-    (gdbarch, svr4_lp64_fetch_link_map_offsets);
+  set_solib_svr4_ops (gdbarch, make_svr4_lp64_solib_ops);
 
   set_gdbarch_fetch_tls_load_module_address (gdbarch,
                                             svr4_fetch_objfile_link_map);
index 7cb94d22060c1b70746a259fe3d5c204dad81461..2b7337ba280602a826ac09d18287564a12f91307 100644 (file)
@@ -218,8 +218,7 @@ amd64_gnu_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
   tdep->sc_num_regs = ARRAY_SIZE (amd64_gnu_sc_reg_offset);
 
   /* Hurd uses SVR4-style shared libraries.  */
-  set_solib_svr4_fetch_link_map_offsets
-    (gdbarch, svr4_lp64_fetch_link_map_offsets);
+  set_solib_svr4_ops (gdbarch, make_svr4_lp64_solib_ops);
 }
 
 INIT_GDB_FILE (amd64_gnu_tdep)
index 69fb668bfdc4f659d0725c46604b49654bf9648e..13e9c0e86eab1ac4f85f8304084ef74edd61b131 100644 (file)
@@ -33,6 +33,7 @@
 #include "amd64-linux-tdep.h"
 #include "i386-linux-tdep.h"
 #include "linux-tdep.h"
+#include "solib-svr4-linux.h"
 #include "svr4-tls-tdep.h"
 #include "gdbsupport/x86-xstate.h"
 #include "inferior.h"
@@ -2130,8 +2131,7 @@ amd64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
   tdep->i386_syscall_record = amd64_linux_syscall_record;
 
   /* GNU/Linux uses SVR4-style shared libraries.  */
-  set_solib_svr4_fetch_link_map_offsets
-    (gdbarch, linux_lp64_fetch_link_map_offsets);
+  set_solib_svr4_ops (gdbarch, make_linux_lp64_svr4_solib_ops);
 
   /* Register DTrace handlers.  */
   set_gdbarch_dtrace_parse_probe_argument (gdbarch, amd64_dtrace_parse_probe_argument);
@@ -2344,8 +2344,7 @@ amd64_x32_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
   tdep->i386_syscall_record = amd64_x32_linux_syscall_record;
 
   /* GNU/Linux uses SVR4-style shared libraries.  */
-  set_solib_svr4_fetch_link_map_offsets
-    (gdbarch, linux_ilp32_fetch_link_map_offsets);
+  set_solib_svr4_ops (gdbarch, make_linux_ilp32_svr4_solib_ops);
 }
 
 INIT_GDB_FILE (amd64_linux_tdep)
index a2938392d630b29befef3f55c11725e48689ce61..3dbbdd984ca7164b79ebbb4619c3ea5c3c5db4ca 100644 (file)
@@ -116,8 +116,7 @@ amd64nbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
   tdep->sc_num_regs = ARRAY_SIZE (amd64nbsd_r_reg_offset);
 
   /* NetBSD uses SVR4-style shared libraries.  */
-  set_solib_svr4_fetch_link_map_offsets
-    (gdbarch, svr4_lp64_fetch_link_map_offsets);
+  set_solib_svr4_ops (gdbarch, make_svr4_lp64_solib_ops);
 }
 
 INIT_GDB_FILE (amd64nbsd_tdep)
index b55afde451bb93bb2a042e994cc01ea850bea0d9..6b60e0aff6d54099c5768e21b9e0ed583984e5d4 100644 (file)
@@ -443,8 +443,7 @@ amd64obsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
   bsd_uthread_set_collect_uthread (gdbarch, amd64obsd_collect_uthread);
 
   /* OpenBSD uses SVR4-style shared libraries.  */
-  set_solib_svr4_fetch_link_map_offsets
-    (gdbarch, svr4_lp64_fetch_link_map_offsets);
+  set_solib_svr4_ops (gdbarch, make_svr4_lp64_solib_ops);
 
   /* Unwind kernel trap frames correctly.  */
   frame_unwind_prepend_unwinder (gdbarch, &amd64obsd_trapframe_unwind);
index 01409205752ca986929ee090b4c404c7cc0fcb0f..da551a1d21d67c4b606d749691aaf3fec69ee62f 100644 (file)
@@ -96,8 +96,7 @@ amd64_sol2_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
   tdep->sc_num_regs = tdep->gregset_num_regs;
 
   /* Solaris uses SVR4-style shared libraries.  */
-  set_solib_svr4_fetch_link_map_offsets
-    (gdbarch, svr4_lp64_fetch_link_map_offsets);
+  set_solib_svr4_ops (gdbarch, make_svr4_lp64_solib_ops);
 }
 
 INIT_GDB_FILE (amd64_sol2_tdep)
index ace40847f2ddeb80facf9c318f53a60ce2e3be5b..edbb3f87a5e9200759c79f1b2a5253e76d0fa8da 100644 (file)
@@ -19,6 +19,7 @@
 
 /* GDB header files.  */
 #include "linux-tdep.h"
+#include "solib-svr4-linux.h"
 #include "objfiles.h"
 #include "opcode/arc.h"
 #include "osabi.h"
@@ -736,8 +737,7 @@ arc_linux_init_osabi (struct gdbarch_info info, struct gdbarch *gdbarch)
 
   /* GNU/Linux uses SVR4-style shared libraries, with 32-bit ints, longs
      and pointers (ILP32).  */
-  set_solib_svr4_fetch_link_map_offsets (gdbarch,
-                                        linux_ilp32_fetch_link_map_offsets);
+  set_solib_svr4_ops (gdbarch, make_linux_ilp32_svr4_solib_ops);
 }
 
 INIT_GDB_FILE (arc_linux_tdep)
index b5d3b78096ba14d8a77818634f9745c4fe6be567..a37d8b76e1d82f8d7e8d3185808c0fd616866c9f 100644 (file)
@@ -300,8 +300,7 @@ arm_fbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
 
   tramp_frame_prepend_unwinder (gdbarch, &arm_fbsd_sigframe);
 
-  set_solib_svr4_fetch_link_map_offsets
-    (gdbarch, svr4_ilp32_fetch_link_map_offsets);
+  set_solib_svr4_ops (gdbarch, make_svr4_ilp32_solib_ops);
 
   tdep->jb_pc = 24;
   tdep->jb_elt_size = 4;
index ce9a24b86b29264a998caafcced71aeb8e3f3e21..08526d8e39ddb624e5291689279cdb26496d9209 100644 (file)
@@ -41,6 +41,7 @@
 #include "arm-tdep.h"
 #include "arm-linux-tdep.h"
 #include "linux-tdep.h"
+#include "solib-svr4-linux.h"
 #include "glibc-tdep.h"
 #include "arch-utils.h"
 #include "inferior.h"
@@ -1801,8 +1802,7 @@ arm_linux_init_abi (struct gdbarch_info info,
     }
   tdep->jb_elt_size = ARM_LINUX_JB_ELEMENT_SIZE;
 
-  set_solib_svr4_fetch_link_map_offsets
-    (gdbarch, linux_ilp32_fetch_link_map_offsets);
+  set_solib_svr4_ops (gdbarch, make_linux_ilp32_svr4_solib_ops);
 
   /* Single stepping.  */
   set_gdbarch_software_single_step (gdbarch, arm_linux_software_single_step);
index 570e26e5a7fbe2d4ea1d928d7265484e5372172f..82ba0c607a799a57a9b0eb0f993c838092e5a281 100644 (file)
@@ -156,8 +156,7 @@ arm_netbsd_elf_init_abi (struct gdbarch_info info,
     tdep->fp_model = ARM_FLOAT_SOFT_VFP;
 
   /* NetBSD ELF uses SVR4-style shared libraries.  */
-  set_solib_svr4_fetch_link_map_offsets
-    (gdbarch, svr4_ilp32_fetch_link_map_offsets);
+  set_solib_svr4_ops (gdbarch, make_svr4_ilp32_solib_ops);
 }
 
 INIT_GDB_FILE (arm_netbsd_tdep)
index b97b31610333168b37da6630e1493c646f83ae7e..00e4bfd0b5957637b6679af118629f9764b2ece7 100644 (file)
@@ -83,8 +83,7 @@ armobsd_init_abi (struct gdbarch_info info,
   tramp_frame_prepend_unwinder (gdbarch, &armobsd_sigframe);
 
   /* OpenBSD/arm uses SVR4-style shared libraries.  */
-  set_solib_svr4_fetch_link_map_offsets
-    (gdbarch, svr4_ilp32_fetch_link_map_offsets);
+  set_solib_svr4_ops (gdbarch, make_svr4_ilp32_solib_ops);
   set_gdbarch_skip_solib_resolver (gdbarch, obsd_skip_solib_resolver);
 
   tdep->jb_pc = 24;
index e9b306809dc153dbe1f83a15769b9d467e7c88ef..255c77e9f8c0d642fa1773b54ae7dfaaf25e6ef5 100644 (file)
@@ -150,14 +150,15 @@ aarch64*-*-linux*)
                        arch/aarch64-scalable-linux.o \
                        arch/arm.o arch/arm-linux.o arch/arm-get-next-pcs.o \
                        arm-tdep.o arm-linux-tdep.o \
-                       glibc-tdep.o linux-tdep.o solib-svr4.o svr4-tls-tdep.o \
+                       glibc-tdep.o linux-tdep.o solib-svr4.o \
+                       solib-svr4-linux.o svr4-tls-tdep.o \
                        symfile-mem.o linux-record.o"
        ;;
 
 alpha*-*-linux*)
        # Target: Little-endian Alpha running Linux
        gdb_target_obs="alpha-mdebug-tdep.o alpha-linux-tdep.o \
-                       linux-tdep.o solib-svr4.o"
+                       linux-tdep.o solib-svr4.o solib-svr4-linux.o"
        ;;
 alpha*-*-netbsd* | alpha*-*-knetbsd*-gnu)
        # Target: NetBSD/alpha
@@ -179,7 +180,7 @@ amdgcn*-*-*)
 am33_2.0*-*-linux*)
        # Target: Matsushita mn10300 (AM33) running Linux
        gdb_target_obs="mn10300-tdep.o mn10300-linux-tdep.o linux-tdep.o \
-                       solib-svr4.o"
+                       solib-svr4.o solib-svr4-linux.o"
        ;;
 
 arc*-*-elf32)
@@ -189,7 +190,8 @@ arc*-*-elf32)
 
 arc*-*-linux*)
        # Target: ARC machine running Linux
-       gdb_target_obs="arc-linux-tdep.o linux-tdep.o solib-svr4.o"
+       gdb_target_obs="arc-linux-tdep.o linux-tdep.o solib-svr4.o \
+                       solib-svr4-linux.o"
        ;;
 
 arm*-wince-pe | arm*-*-mingw32ce*)
@@ -199,7 +201,8 @@ arm*-wince-pe | arm*-*-mingw32ce*)
 arm*-*-linux*)
        # Target: ARM based machine running GNU/Linux
        gdb_target_obs="arch/arm-linux.o arm-linux-tdep.o glibc-tdep.o \
-                       solib-svr4.o symfile-mem.o linux-tdep.o linux-record.o"
+                       solib-svr4.o solib-svr4-linux.o symfile-mem.o \
+                       linux-tdep.o linux-record.o"
        ;;
 arm*-*-freebsd*)
        # Target: FreeBSD/arm
@@ -239,13 +242,14 @@ bpf-*-*)
 
 cris*)
        # Target: CRIS
-       gdb_target_obs="cris-tdep.o cris-linux-tdep.o linux-tdep.o solib-svr4.o"
+       gdb_target_obs="cris-tdep.o cris-linux-tdep.o linux-tdep.o \
+                       solib-svr4.o solib-svr4-linux.o"
        ;;
 
 csky*-*-linux*)
        # Target: CSKY running GNU/Linux
        gdb_target_obs="csky-tdep.o csky-linux-tdep.o glibc-tdep.o \
-                       linux-tdep.o solib-svr4.o"
+                       linux-tdep.o solib-svr4.o solib-svr4-linux.o"
        ;;
 
 csky*-*-*)
@@ -270,7 +274,8 @@ h8300-*-*)
 hppa*-*-linux*)
        # Target: HP PA-RISC running Linux
        gdb_target_obs="hppa-linux-tdep.o glibc-tdep.o \
-                       linux-tdep.o solib-svr4.o symfile-mem.o"
+                       linux-tdep.o solib-svr4.o solib-svr4-linux.o \
+                       symfile-mem.o"
        ;;
 hppa*-*-netbsd*)
        # Target: NetBSD/hppa
@@ -315,7 +320,7 @@ i[34567]86-*-linux*)
        # Target: Intel 386 running GNU/Linux
        gdb_target_obs="i386-linux-tdep.o \
                        glibc-tdep.o \
-                       solib-svr4.o symfile-mem.o \
+                       solib-svr4.o solib-svr4-linux.o symfile-mem.o \
                        linux-tdep.o linux-record.o \
                        arch/i386-linux-tdesc.o \
                        arch/x86-linux-tdesc-features.o"
@@ -345,7 +350,7 @@ i[34567]86-*-go32* | i[34567]86-*-msdosdjgpp*)
 ia64-*-linux*)
        # Target: Intel IA-64 running GNU/Linux
        gdb_target_obs="ia64-linux-tdep.o linux-tdep.o \
-                       solib-svr4.o symfile-mem.o"
+                       solib-svr4.o solib-svr4-linux.o symfile-mem.o"
        ;;
 ia64-*-*vms*)
        # Target: Intel IA-64 running OpenVMS
@@ -363,7 +368,8 @@ lm32-*-*)
 loongarch*-*-linux*)
        # Target: LoongArch running Linux
        gdb_target_obs="loongarch-linux-tdep.o glibc-tdep.o \
-                       linux-tdep.o solib-svr4.o linux-record.o"
+                       linux-tdep.o solib-svr4.o solib-svr4-linux.o \
+                       linux-record.o"
        ;;
 
 m32c-*-*)
@@ -374,8 +380,8 @@ m32c-*-*)
 m32r*-*-linux*)
        # Target: Renesas M32R running GNU/Linux
        gdb_target_obs="m32r-tdep.o m32r-linux-tdep.o \
-                       glibc-tdep.o solib-svr4.o symfile-mem.o \
-                       linux-tdep.o"
+                       glibc-tdep.o solib-svr4.o solib-svr4-linux.o \
+                       symfile-mem.o linux-tdep.o"
        ;;
 m32r*-*-*)
        # Target: Renesas m32r processor
@@ -395,7 +401,8 @@ fido-*-elf*)
 m68*-*-linux*)
        # Target: Motorola m68k with a.out and ELF
        gdb_target_obs="m68k-tdep.o m68k-linux-tdep.o solib-svr4.o \
-                       linux-tdep.o glibc-tdep.o symfile-mem.o"
+                       solib-svr4-linux.o linux-tdep.o glibc-tdep.o \
+                       symfile-mem.o"
        ;;
 m68*-*-netbsd* | m68*-*-knetbsd*-gnu)
        # Target: NetBSD/m68k
@@ -415,7 +422,7 @@ mep-*-*)
 microblaze*-linux-*|microblaze*-*-linux*)
        # Target: Xilinx MicroBlaze running Linux
        gdb_target_obs="microblaze-tdep.o microblaze-linux-tdep.o solib-svr4.o \
-                       symfile-mem.o linux-tdep.o"
+                       solib-svr4-linux.o symfile-mem.o linux-tdep.o"
        ;;
 microblaze*-*-*)
        # Target: Xilinx MicroBlaze running standalone
@@ -425,7 +432,8 @@ microblaze*-*-*)
 mips*-*-linux*)
        # Target: Linux/MIPS
        gdb_target_obs="mips-tdep.o mips-linux-tdep.o glibc-tdep.o \
-                       solib-svr4.o symfile-mem.o linux-tdep.o"
+                       solib-svr4.o solib-svr4-linux.o symfile-mem.o \
+                       linux-tdep.o"
        ;;
 mips*-*-netbsd* | mips*-*-knetbsd*-gnu)
        # Target: MIPS running NetBSD
@@ -469,7 +477,8 @@ nds32*-*-elf)
 or1k*-*-linux*)
        # Target: OpenCores OpenRISC 1000 32-bit running Linux
        gdb_target_obs="or1k-tdep.o or1k-linux-tdep.o solib-svr4.o \
-                       symfile-mem.o glibc-tdep.o linux-tdep.o"
+                       solib-svr4-linux.o symfile-mem.o glibc-tdep.o \
+                       linux-tdep.o"
        ;;
 
 or1k-*-* | or1knd-*-*)
@@ -503,7 +512,8 @@ powerpc-*-aix* | rs6000-*-* | powerpc64-*-aix*)
 powerpc*-*-linux*)
        # Target: PowerPC running Linux
        gdb_target_obs="rs6000-tdep.o ppc-linux-tdep.o ppc-sysv-tdep.o \
-                       ppc64-tdep.o solib-svr4.o svr4-tls-tdep.o \
+                       ppc64-tdep.o solib-svr4.o solib-svr4-linux.o \
+                       svr4-tls-tdep.o \
                        glibc-tdep.o symfile-mem.o linux-tdep.o \
                        ravenscar-thread.o ppc-ravenscar-thread.o \
                        linux-record.o \
@@ -524,6 +534,7 @@ powerpc*-*-*)
 s390*-*-linux*)
        # Target: S390 running Linux
        gdb_target_obs="s390-linux-tdep.o s390-tdep.o solib-svr4.o \
+                       solib-svr4-linux.o \
                        linux-tdep.o linux-record.o symfile-mem.o \
                        svr4-tls-tdep.o"
        ;;
@@ -536,7 +547,8 @@ riscv*-*-freebsd*)
 riscv*-*-linux*)
        # Target: Linux/RISC-V
        gdb_target_obs="riscv-linux-tdep.o riscv-canonicalize-syscall-gen.o \
-                       glibc-tdep.o linux-tdep.o solib-svr4.o symfile-mem.o \
+                       glibc-tdep.o linux-tdep.o solib-svr4.o solib-svr4-linux.o \
+                       symfile-mem.o \
                        linux-record.o svr4-tls-tdep.o"
        ;;
 
@@ -558,7 +570,7 @@ rx-*-*)
 sh*-*-linux*)
        # Target: GNU/Linux Super-H
        gdb_target_obs="sh-tdep.o sh-linux-tdep.o \
-                       solib-svr4.o symfile-mem.o \
+                       solib-svr4.o solib-svr4-linux.o symfile-mem.o \
                        glibc-tdep.o linux-tdep.o"
        ;;
 sh*-*-netbsd* | sh*-*-knetbsd*-gnu)
@@ -577,7 +589,8 @@ sh*)
 sparc-*-linux*)
        # Target: GNU/Linux SPARC
        gdb_target_obs="sparc-tdep.o \
-                       sparc-linux-tdep.o solib-svr4.o symfile-mem.o \
+                       sparc-linux-tdep.o solib-svr4.o solib-svr4-linux.o \
+                       symfile-mem.o \
                        linux-tdep.o \
                        ravenscar-thread.o sparc-ravenscar-thread.o"
        if test "x$have_64_bit_bfd" = "xyes"; then
@@ -590,7 +603,8 @@ sparc64-*-linux*)
        # Target: GNU/Linux UltraSPARC
        gdb_target_obs="sparc64-tdep.o \
                        sparc64-linux-tdep.o sparc-tdep.o \
-                       sparc-linux-tdep.o solib-svr4.o linux-tdep.o \
+                       sparc-linux-tdep.o solib-svr4.o solib-svr4-linux.o \
+                       linux-tdep.o \
                        ravenscar-thread.o sparc-ravenscar-thread.o"
        ;;
 sparc*-*-freebsd* | sparc*-*-kfreebsd*-gnu)
@@ -658,6 +672,7 @@ tic6x-*-*)
 tilegx-*-linux*)
        # Target: TILE-Gx
        gdb_target_obs="tilegx-tdep.o tilegx-linux-tdep.o solib-svr4.o \
+                       solib-svr4-linux.o \
                        symfile-mem.o glibc-tdep.o linux-tdep.o"
        ;;
 
@@ -708,7 +723,8 @@ x86_64-*-linux*)
        # Target: GNU/Linux x86-64
        gdb_target_obs="amd64-linux-tdep.o ${i386_tobjs}  \
                        i386-linux-tdep.o glibc-tdep.o svr4-tls-tdep.o \
-                       solib-svr4.o symfile-mem.o linux-tdep.o linux-record.o \
+                       solib-svr4.o solib-svr4-linux.o symfile-mem.o \
+                       linux-tdep.o linux-record.o \
                        arch/i386-linux-tdesc.o arch/amd64-linux-tdesc.o \
                        arch/x86-linux-tdesc-features.o"
        ;;
index 5f4135a582d149235f111f6ecc50406af0fb5be8..a39441eab015d6e5bd76487551c05411a509d648 100644 (file)
@@ -23,6 +23,7 @@
 
 #include "osabi.h"
 #include "linux-tdep.h"
+#include "solib-svr4-linux.h"
 #include "solib-svr4.h"
 #include "symtab.h"
 #include "gdbarch.h"
@@ -41,9 +42,7 @@ cris_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
     set_gdbarch_fetch_tls_load_module_address (gdbarch,
                                               svr4_fetch_objfile_link_map);
 
-  set_solib_svr4_fetch_link_map_offsets (gdbarch,
-                                        linux_ilp32_fetch_link_map_offsets);
-
+  set_solib_svr4_ops (gdbarch, make_linux_ilp32_svr4_solib_ops);
 }
 
 INIT_GDB_FILE (cris_linux_tdep)
index 374ed257964bbd1872de0df782cf4e46e6326d36..0651645d39c3ec3d09b57e07774e648b629f5f09 100644 (file)
@@ -22,6 +22,7 @@
 #include "osabi.h"
 #include "glibc-tdep.h"
 #include "linux-tdep.h"
+#include "solib-svr4-linux.h"
 #include "gdbarch.h"
 #include "solib-svr4.h"
 #include "regset.h"
@@ -407,8 +408,7 @@ csky_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
   /* Shared library handling.  */
   set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
   set_gdbarch_skip_solib_resolver (gdbarch, glibc_skip_solib_resolver);
-  set_solib_svr4_fetch_link_map_offsets (gdbarch,
-                                        linux_ilp32_fetch_link_map_offsets);
+  set_solib_svr4_ops (gdbarch, make_linux_ilp32_svr4_solib_ops);
 
   /* Enable TLS support.  */
   set_gdbarch_fetch_tls_load_module_address (gdbarch,
index 4dfac76654e87dff7645c2a8f2400b1fa334b4fe..d6bc9a567d973992d37519a5491e2afd920a16da 100644 (file)
@@ -27,7 +27,7 @@
 void
 dicos_init_abi (struct gdbarch *gdbarch)
 {
-  set_gdbarch_so_ops (gdbarch, &solib_target_so_ops);
+  set_gdbarch_make_solib_ops (gdbarch, make_target_solib_ops);
 
   /* Every process, although has its own address space, sees the same
      list of shared libraries.  There's no "main executable" in DICOS,
index 56456172b97813d930cdc6f94934107fd26592ff..b2d6e1a1eabf6ad4869c4c083113510fc35b3d5b 100644 (file)
@@ -25,6 +25,7 @@
 #include "frame.h"
 #include "frame-unwind.h"
 #include "frame-base.h"
+#include "solib-frv.h"
 #include "trad-frame.h"
 #include "dis-asm.h"
 #include "sim-regno.h"
@@ -1554,7 +1555,7 @@ frv_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
     set_gdbarch_convert_from_func_ptr_addr (gdbarch,
                                            frv_convert_from_func_ptr_addr);
 
-  set_gdbarch_so_ops (gdbarch, &frv_so_ops);
+  set_gdbarch_make_solib_ops (gdbarch, make_frv_solib_ops);
 
   /* Hook in ABI-specific overrides, if they have been registered.  */
   gdbarch_init_osabi (info, gdbarch);
index 07982b40db0f67546658ed8b3ec590e3883cfb8f..7b51b428e9c4cbf2f35e0f3df97db6a31ef1f7e3 100644 (file)
@@ -118,7 +118,4 @@ CORE_ADDR frv_fdpic_find_canonical_descriptor (CORE_ADDR entry_point);
    needed for TLS support.  */
 CORE_ADDR frv_fetch_objfile_link_map (struct objfile *objfile);
 
-struct solib_ops;
-extern const solib_ops frv_so_ops;
-
 #endif /* GDB_FRV_TDEP_H */
index 32d16598940b8a6cc7674d007fe5f00adb6ffc68..fc570d37a8dc1913ba9990881a059db05edbd9b2 100644 (file)
@@ -157,7 +157,7 @@ struct gdbarch
   gdbarch_single_step_through_delay_ftype *single_step_through_delay = nullptr;
   gdbarch_print_insn_ftype *print_insn = default_print_insn;
   gdbarch_skip_trampoline_code_ftype *skip_trampoline_code = generic_skip_trampoline_code;
-  const solib_ops * so_ops = &solib_target_so_ops;
+  gdbarch_make_solib_ops_ftype *make_solib_ops = make_target_solib_ops;
   gdbarch_skip_solib_resolver_ftype *skip_solib_resolver = generic_skip_solib_resolver;
   gdbarch_in_solib_return_trampoline_ftype *in_solib_return_trampoline = generic_in_solib_return_trampoline;
   gdbarch_in_indirect_branch_thunk_ftype *in_indirect_branch_thunk = default_in_indirect_branch_thunk;
@@ -425,7 +425,7 @@ verify_gdbarch (struct gdbarch *gdbarch)
   /* Skip verify of single_step_through_delay, has predicate.  */
   /* Skip verify of print_insn, invalid_p == 0.  */
   /* Skip verify of skip_trampoline_code, invalid_p == 0.  */
-  /* Skip verify of so_ops, invalid_p == 0.  */
+  /* Skip verify of make_solib_ops, invalid_p == 0.  */
   /* Skip verify of skip_solib_resolver, invalid_p == 0.  */
   /* Skip verify of in_solib_return_trampoline, invalid_p == 0.  */
   /* Skip verify of in_indirect_branch_thunk, invalid_p == 0.  */
@@ -966,8 +966,8 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file)
              "gdbarch_dump: skip_trampoline_code = <%s>\n",
              host_address_to_string (gdbarch->skip_trampoline_code));
   gdb_printf (file,
-             "gdbarch_dump: so_ops = %s\n",
-             host_address_to_string (gdbarch->so_ops));
+             "gdbarch_dump: make_solib_ops = <%s>\n",
+             host_address_to_string (gdbarch->make_solib_ops));
   gdb_printf (file,
              "gdbarch_dump: skip_solib_resolver = <%s>\n",
              host_address_to_string (gdbarch->skip_solib_resolver));
@@ -3469,21 +3469,21 @@ set_gdbarch_skip_trampoline_code (struct gdbarch *gdbarch,
   gdbarch->skip_trampoline_code = skip_trampoline_code;
 }
 
-const solib_ops *
-gdbarch_so_ops (struct gdbarch *gdbarch)
+solib_ops_up
+gdbarch_make_solib_ops (struct gdbarch *gdbarch)
 {
   gdb_assert (gdbarch != NULL);
-  /* Skip verify of so_ops, invalid_p == 0.  */
+  gdb_assert (gdbarch->make_solib_ops != NULL);
   if (gdbarch_debug >= 2)
-    gdb_printf (gdb_stdlog, "gdbarch_so_ops called\n");
-  return gdbarch->so_ops;
+    gdb_printf (gdb_stdlog, "gdbarch_make_solib_ops called\n");
+  return gdbarch->make_solib_ops ();
 }
 
 void
-set_gdbarch_so_ops (struct gdbarch *gdbarch,
-                   const solib_ops * so_ops)
+set_gdbarch_make_solib_ops (struct gdbarch *gdbarch,
+                           gdbarch_make_solib_ops_ftype make_solib_ops)
 {
-  gdbarch->so_ops = so_ops;
+  gdbarch->make_solib_ops = make_solib_ops;
 }
 
 CORE_ADDR
index 313a8f198fdbcf5cc94d534d647bf4a3f5f6b07f..281b97b7aa8ce00a350e18fc83d1b92e8da8c5b4 100644 (file)
@@ -818,10 +818,11 @@ typedef CORE_ADDR (gdbarch_skip_trampoline_code_ftype) (const frame_info_ptr &fr
 extern CORE_ADDR gdbarch_skip_trampoline_code (struct gdbarch *gdbarch, const frame_info_ptr &frame, CORE_ADDR pc);
 extern void set_gdbarch_skip_trampoline_code (struct gdbarch *gdbarch, gdbarch_skip_trampoline_code_ftype *skip_trampoline_code);
 
-/* Vtable of solib operations functions. */
+/* Return a newly-allocated solib_ops object capable of providing the solibs for this architecture. */
 
-extern const solib_ops * gdbarch_so_ops (struct gdbarch *gdbarch);
-extern void set_gdbarch_so_ops (struct gdbarch *gdbarch, const solib_ops * so_ops);
+typedef solib_ops_up (gdbarch_make_solib_ops_ftype) ();
+extern solib_ops_up gdbarch_make_solib_ops (struct gdbarch *gdbarch);
+extern void set_gdbarch_make_solib_ops (struct gdbarch *gdbarch, gdbarch_make_solib_ops_ftype *make_solib_ops);
 
 /* If in_solib_dynsym_resolve_code() returns true, and SKIP_SOLIB_RESOLVER
    evaluates non-zero, this is the address where the debugger will place
index 9feb2cc24e5bd6a125c2e267eab7a265f79903a5..6accbd2fd5eeeebf6000009c2ec6c47d3b56328e 100644 (file)
@@ -30,6 +30,7 @@
 #include "displaced-stepping.h"
 #include "gdbsupport/gdb-checked-static-cast.h"
 #include "registry.h"
+#include "solib.h"
 
 struct floatformat;
 struct ui_file;
index ec09d95508891855dd923a116e049b285a86797d..91c867e69bfb0e1b5023771840b24965e2720355 100644 (file)
@@ -1431,12 +1431,12 @@ Function(
     invalid=False,
 )
 
-Value(
-    comment="Vtable of solib operations functions.",
-    type="const solib_ops *",
-    name="so_ops",
-    predefault="&solib_target_so_ops",
-    printer="host_address_to_string (gdbarch->so_ops)",
+Function(
+    comment="Return a newly-allocated solib_ops object capable of providing the solibs for this architecture.",
+    type="solib_ops_up",
+    name="make_solib_ops",
+    params=[],
+    predefault="make_target_solib_ops",
     invalid=False,
 )
 
index db6c92f8aab5a99a7241dd4a0c62309c9129486a..715e79457a860c3870026e42ea793328218ef5c2 100644 (file)
@@ -128,8 +128,7 @@ hppabsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
   set_gdbarch_skip_trampoline_code (gdbarch, hppa_skip_trampoline_code);
 
   /* OpenBSD and NetBSD use SVR4-style shared libraries.  */
-  set_solib_svr4_fetch_link_map_offsets
-    (gdbarch, svr4_ilp32_fetch_link_map_offsets);
+  set_solib_svr4_ops (gdbarch, make_svr4_ilp32_solib_ops);
 
   /* Hook in the DWARF CFI frame unwinder.  */
   dwarf2_frame_set_init_reg (gdbarch, hppabsd_dwarf2_frame_init_reg);
index 01e2caf193e5807e37e0b3a4cbab10565f4623d4..2eb8d46565049c74fb8c995fe60cbb20d39238cc 100644 (file)
@@ -32,6 +32,7 @@
 #include "regcache.h"
 #include "hppa-tdep.h"
 #include "linux-tdep.h"
+#include "solib-svr4-linux.h"
 #include "elf/common.h"
 
 /* Map DWARF DBX register numbers to GDB register numbers.  */
@@ -499,8 +500,7 @@ hppa_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
   frame_unwind_append_unwinder (gdbarch, &hppa_linux_sigtramp_frame_unwind);
 
   /* GNU/Linux uses SVR4-style shared libraries.  */
-  set_solib_svr4_fetch_link_map_offsets
-    (gdbarch, linux_ilp32_fetch_link_map_offsets);
+  set_solib_svr4_ops (gdbarch, make_linux_ilp32_svr4_solib_ops);
 
   tdep->in_solib_call_trampoline = hppa_in_solib_call_trampoline;
   set_gdbarch_skip_trampoline_code (gdbarch, hppa_skip_trampoline_code);
index 184a6cf5a1356bac5d8e2917980cfb7185662f73..a91afa25d0148bda799ab038668e1273c7ac779b 100644 (file)
@@ -271,7 +271,7 @@ i386_darwin_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
      alignment.  */
   set_gdbarch_long_double_bit (gdbarch, 128);
 
-  set_gdbarch_so_ops (gdbarch, &darwin_so_ops);
+  set_gdbarch_make_solib_ops (gdbarch, make_darwin_solib_ops);
 }
 
 static enum gdb_osabi
index b992d79f63d349f42c4b1ed5688439d0548949a0..827d53ce5d0cea24f0340401012cb7a9e5f4990d 100644 (file)
@@ -402,8 +402,7 @@ i386fbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
                                     i386fbsd_core_read_description);
 
   /* FreeBSD uses SVR4-style shared libraries.  */
-  set_solib_svr4_fetch_link_map_offsets
-    (gdbarch, svr4_ilp32_fetch_link_map_offsets);
+  set_solib_svr4_ops (gdbarch, make_svr4_ilp32_solib_ops);
 
   set_gdbarch_fetch_tls_load_module_address (gdbarch,
                                             svr4_fetch_objfile_link_map);
index 58a71775ed9c3f223df5ed08d280a315ecf5cf1f..f944fa5339b78d504d71146ee4c46e2c3ee86cce 100644 (file)
@@ -180,8 +180,7 @@ i386gnu_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
 
   /* Hurd uses SVR4-style shared libraries.  */
   set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
-  set_solib_svr4_fetch_link_map_offsets
-    (gdbarch, svr4_ilp32_fetch_link_map_offsets);
+  set_solib_svr4_ops (gdbarch, make_svr4_ilp32_solib_ops);
 
   /* Hurd uses the dynamic linker included in the GNU C Library.  */
   set_gdbarch_skip_solib_resolver (gdbarch, glibc_skip_solib_resolver);
index 606672acb2aa91854ed667cb03ebfb575b74c0a4..efbde6a3ccfec496602541f992191729a62be1b7 100644 (file)
@@ -30,6 +30,7 @@
 #include "i386-tdep.h"
 #include "i386-linux-tdep.h"
 #include "linux-tdep.h"
+#include "solib-svr4-linux.h"
 #include "utils.h"
 #include "glibc-tdep.h"
 #include "solib-svr4.h"
@@ -1461,8 +1462,7 @@ i386_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
 
   /* GNU/Linux uses SVR4-style shared libraries.  */
   set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
-  set_solib_svr4_fetch_link_map_offsets
-    (gdbarch, linux_ilp32_fetch_link_map_offsets);
+  set_solib_svr4_ops (gdbarch, make_linux_ilp32_svr4_solib_ops);
 
   /* GNU/Linux uses the dynamic linker included in the GNU C Library.  */
   set_gdbarch_skip_solib_resolver (gdbarch, glibc_skip_solib_resolver);
index 6344d2b704f9a8fe4fe54737ae47e540e9819e71..a1124d03e4f3e97aee2365743d2f2f0f6a289440 100644 (file)
@@ -415,8 +415,7 @@ i386nbsdelf_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
   i386_elf_init_abi (info, gdbarch);
 
   /* NetBSD ELF uses SVR4-style shared libraries.  */
-  set_solib_svr4_fetch_link_map_offsets
-    (gdbarch, svr4_ilp32_fetch_link_map_offsets);
+  set_solib_svr4_ops (gdbarch, make_svr4_ilp32_solib_ops);
 
   /* NetBSD ELF uses -fpcc-struct-return by default.  */
   tdep->struct_return = pcc_struct_return;
index 4820160517939df36a5e21999aa744bd63da9885..1126597aa6bf5b473c1aa14bc7ee7eb46cf02456 100644 (file)
@@ -441,8 +441,7 @@ i386obsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
   frame_unwind_prepend_unwinder (gdbarch, &i386obsd_trapframe_unwind);
 
   /* OpenBSD ELF uses SVR4-style shared libraries.  */
-  set_solib_svr4_fetch_link_map_offsets
-    (gdbarch, svr4_ilp32_fetch_link_map_offsets);
+  set_solib_svr4_ops (gdbarch, make_svr4_ilp32_solib_ops);
 }
 
 INIT_GDB_FILE (i386obsd_tdep)
index b552d8433dabc43e86d2385e7be1066bf49bc9b5..4ff08d25dc0050e1f57ff585d54bcd5b59041b9b 100644 (file)
@@ -86,8 +86,7 @@ i386_sol2_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
   tdep->sc_num_regs = tdep->gregset_num_regs;
 
   /* Solaris has SVR4-style shared libraries.  */
-  set_solib_svr4_fetch_link_map_offsets
-    (gdbarch, svr4_ilp32_fetch_link_map_offsets);
+  set_solib_svr4_ops (gdbarch, make_svr4_ilp32_solib_ops);
 }
 \f
 
index d2fe10b9b1498c59a16e34aad3bdfa42abbc70da..6afffeea4e3bda9c39fd713e2bc9a890ead48d8a 100644 (file)
@@ -26,6 +26,7 @@
 #include "solib-svr4.h"
 #include "symtab.h"
 #include "linux-tdep.h"
+#include "solib-svr4-linux.h"
 #include "regset.h"
 
 #include <ctype.h>
@@ -235,8 +236,7 @@ ia64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
 
   set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
 
-  set_solib_svr4_fetch_link_map_offsets
-    (gdbarch, linux_lp64_fetch_link_map_offsets);
+  set_solib_svr4_ops (gdbarch, make_linux_lp64_svr4_solib_ops);
 
   /* Enable TLS support.  */
   set_gdbarch_fetch_tls_load_module_address (gdbarch,
index 36a2c809088efe250bca877401eb359ee3f9d9c5..8978c8a63038d1db39168cc47c49e738863e7f36 100644 (file)
@@ -260,7 +260,7 @@ post_create_inferior (int from_tty, bool set_pspace_solib_ops)
 
   if (set_pspace_solib_ops)
     current_program_space->set_solib_ops
-      (*gdbarch_so_ops (current_inferior ()->arch ()));
+      (gdbarch_make_solib_ops (current_inferior ()->arch ()));
 
   if (current_program_space->exec_bfd ())
     {
index ea1a64153d94c544f58e9adcfccc9efc1ff44283..05bf6ab77bf1144d143d9bc50329894be35ecb2c 100644 (file)
@@ -1383,7 +1383,7 @@ follow_exec (ptid_t ptid, const char *exec_file_target)
   target_find_description ();
 
   current_program_space->set_solib_ops
-    (*gdbarch_so_ops (following_inferior->arch ()));
+    (gdbarch_make_solib_ops (following_inferior->arch ()));
   gdb::observers::inferior_execd.notify (execing_inferior, following_inferior);
 
   breakpoint_re_set ();
index 1ffbf218c370258da90a5136de64d07a5bb59415..5c4bbf665637748ef279870f55f9057b5f0ac5f7 100644 (file)
@@ -3116,64 +3116,3 @@ more information about this file, refer to the manpage of proc(5) and core(5).")
                           &setlist, &showlist);
 
 }
-
-/* Fetch (and possibly build) an appropriate `link_map_offsets' for
-   ILP32/LP64 Linux systems which don't have the r_ldsomap field.  */
-
-link_map_offsets *
-linux_ilp32_fetch_link_map_offsets ()
-{
-  static link_map_offsets lmo;
-  static link_map_offsets *lmp = nullptr;
-
-  if (lmp == nullptr)
-    {
-      lmp = &lmo;
-
-      lmo.r_version_offset = 0;
-      lmo.r_version_size = 4;
-      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;
-      lmo.l_addr_offset = 0;
-      lmo.l_name_offset = 4;
-      lmo.l_ld_offset = 8;
-      lmo.l_next_offset = 12;
-      lmo.l_prev_offset = 16;
-    }
-
-  return lmp;
-}
-
-link_map_offsets *
-linux_lp64_fetch_link_map_offsets ()
-{
-  static link_map_offsets lmo;
-  static link_map_offsets *lmp = nullptr;
-
-  if (lmp == nullptr)
-    {
-      lmp = &lmo;
-
-      lmo.r_version_offset = 0;
-      lmo.r_version_size = 4;
-      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;
-      lmo.l_addr_offset = 0;
-      lmo.l_name_offset = 8;
-      lmo.l_ld_offset = 16;
-      lmo.l_next_offset = 24;
-      lmo.l_prev_offset = 32;
-    }
-
-  return lmp;
-}
index 7485fc132a6390102b4709bd743b61ab1ae74dd2..3d82ea5bbdf3011aad492ca716f37153aaa0741f 100644 (file)
@@ -22,6 +22,7 @@
 
 #include "bfd.h"
 #include "displaced-stepping.h"
+#include "solib.h"
 
 struct inferior;
 struct regcache;
@@ -112,9 +113,4 @@ extern CORE_ADDR linux_get_hwcap2 (const std::optional<gdb::byte_vector> &auxv,
 
 extern CORE_ADDR linux_get_hwcap2 ();
 
-/* Fetch (and possibly build) an appropriate `struct link_map_offsets'
-   for ILP32 and LP64 Linux systems.  */
-extern struct link_map_offsets *linux_ilp32_fetch_link_map_offsets ();
-extern struct link_map_offsets *linux_lp64_fetch_link_map_offsets ();
-
 #endif /* GDB_LINUX_TDEP_H */
index 4a1ac12e142e756de1ae37a088ae336eb99b764e..37663382c06550f8d5ed24790e9e4f3c0875765f 100644 (file)
@@ -25,6 +25,7 @@
 #include "inferior.h"
 #include "linux-record.h"
 #include "linux-tdep.h"
+#include "solib-svr4-linux.h"
 #include "loongarch-tdep.h"
 #include "record-full.h"
 #include "regset.h"
@@ -1145,10 +1146,9 @@ loongarch_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
 
   linux_init_abi (info, gdbarch, 0);
 
-  set_solib_svr4_fetch_link_map_offsets (gdbarch,
-                                        info.bfd_arch_info->bits_per_address == 32
-                                        ? linux_ilp32_fetch_link_map_offsets
-                                        : linux_lp64_fetch_link_map_offsets);
+  set_solib_svr4_ops (gdbarch, (info.bfd_arch_info->bits_per_address == 32
+                               ? make_linux_ilp32_svr4_solib_ops
+                               : make_linux_lp64_svr4_solib_ops));
 
   /* GNU/Linux uses SVR4-style shared libraries.  */
   set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
index 3c583ce7cef10920f22e13a8e2f7b63cb9b92fc8..03000cc99da00a974eba84d8d11d2af9474fad88 100644 (file)
@@ -36,6 +36,7 @@
 
 #include "m32r-tdep.h"
 #include "linux-tdep.h"
+#include "solib-svr4-linux.h"
 #include "gdbarch.h"
 
 \f
@@ -461,8 +462,7 @@ m32r_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
 
   /* GNU/Linux uses SVR4-style shared libraries.  */
   set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
-  set_solib_svr4_fetch_link_map_offsets
-    (gdbarch, linux_ilp32_fetch_link_map_offsets);
+  set_solib_svr4_ops (gdbarch, make_linux_ilp32_svr4_solib_ops);
 
   /* Core file support.  */
   set_gdbarch_iterate_over_regset_sections
index 05d77a4cf304797a3c2980ad3ecbbf48ec698656..37c1464b6cc510697dbef49e129a6f3a4c0124a6 100644 (file)
@@ -147,8 +147,7 @@ m68kbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
   tdep->struct_return = pcc_struct_return;
 
   /* NetBSD ELF uses SVR4-style shared libraries.  */
-  set_solib_svr4_fetch_link_map_offsets
-    (gdbarch, svr4_ilp32_fetch_link_map_offsets);
+  set_solib_svr4_ops (gdbarch, make_svr4_ilp32_solib_ops);
 }
 
 INIT_GDB_FILE (m68kbsd_tdep)
index 47f1f5f387fed536d4b554a4efa9e1f03c67f5bc..bd2a14a80da8cd84315d9ac714d3d44f7cf8c0f9 100644 (file)
@@ -35,6 +35,7 @@
 #include "observable.h"
 #include "elf/common.h"
 #include "linux-tdep.h"
+#include "solib-svr4-linux.h"
 #include "regset.h"
 \f
 /* Offsets (in target ints) into jmp_buf.  */
@@ -407,8 +408,7 @@ m68k_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
   /* Shared library handling.  */
 
   /* GNU/Linux uses SVR4-style shared libraries.  */
-  set_solib_svr4_fetch_link_map_offsets (gdbarch,
-                                        linux_ilp32_fetch_link_map_offsets);
+  set_solib_svr4_ops (gdbarch, make_linux_ilp32_svr4_solib_ops);
 
   /* GNU/Linux uses the dynamic linker included in the GNU C Library.  */
   set_gdbarch_skip_solib_resolver (gdbarch, glibc_skip_solib_resolver);
index 76cf939b542724ea06151126eb0afe049f74cd69..0fdda189ee9d6b5707d0ed7067e3f52727faf46b 100644 (file)
@@ -35,6 +35,7 @@
 #include "frame-unwind.h"
 #include "tramp-frame.h"
 #include "linux-tdep.h"
+#include "solib-svr4-linux.h"
 
 static int
 microblaze_linux_memory_remove_breakpoint (struct gdbarch *gdbarch, 
@@ -125,8 +126,7 @@ microblaze_linux_init_abi (struct gdbarch_info info,
                                        microblaze_linux_memory_remove_breakpoint);
 
   /* Shared library handling.  */
-  set_solib_svr4_fetch_link_map_offsets (gdbarch,
-                                        linux_ilp32_fetch_link_map_offsets);
+  set_solib_svr4_ops (gdbarch, make_linux_ilp32_svr4_solib_ops);
 
   /* Trampolines.  */
   tramp_frame_prepend_unwinder (gdbarch,
index 129f2d1279e10727a9aa9381f587788f29588570..c1b5f9c20bc5af95ab84136d200e9b21d5bcc49b 100644 (file)
@@ -476,12 +476,28 @@ mips_fbsd_skip_solib_resolver (struct gdbarch *gdbarch, CORE_ADDR pc)
   return fbsd_skip_solib_resolver (gdbarch, pc);
 }
 
-/* FreeBSD/mips uses a slightly different `struct link_map' than the
-   other FreeBSD platforms as it includes an additional `l_off'
-   member.  */
+/* solib_ops for ILP32 FreeBSD/MIPS systems.  */
 
-static struct link_map_offsets *
-mips_fbsd_ilp32_fetch_link_map_offsets (void)
+struct mips_fbsd_ilp32_solib_ops : public svr4_solib_ops
+{
+  /* FreeBSD/MIPS uses a slightly different `struct link_map' than the
+     other FreeBSD platforms as it includes an additional `l_off' member.  */
+
+  link_map_offsets *fetch_link_map_offsets () const override;
+};
+
+/* Return a new solib_ops for ILP32 FreeBSD/MIPS systems.  */
+
+static solib_ops_up
+make_mips_fbsd_ilp32_solib_ops ()
+{
+  return std::make_unique<mips_fbsd_ilp32_solib_ops> ();
+}
+
+/* See mips_fbsd_ilp32_solib_ops.  */
+
+link_map_offsets *
+mips_fbsd_ilp32_solib_ops::fetch_link_map_offsets () const
 {
   static struct link_map_offsets lmo;
   static struct link_map_offsets *lmp = NULL;
@@ -508,8 +524,28 @@ mips_fbsd_ilp32_fetch_link_map_offsets (void)
   return lmp;
 }
 
-static struct link_map_offsets *
-mips_fbsd_lp64_fetch_link_map_offsets (void)
+/* solib_ops for LP64 FreeBSD/MIPS systems.  */
+
+struct mips_fbsd_lp64_solib_ops : public svr4_solib_ops
+{
+  /* FreeBSD/MIPS uses a slightly different `struct link_map' than the
+     other FreeBSD platforms as it includes an additional `l_off' member.  */
+
+  link_map_offsets *fetch_link_map_offsets () const override;
+};
+
+/* Return a new solib_ops for LP64 FreeBSD/MIPS systems.  */
+
+static solib_ops_up
+make_mips_fbsd_lp64_solib_ops ()
+{
+  return std::make_unique<mips_fbsd_lp64_solib_ops> ();
+}
+
+/* See mips_fbsd_lp64_solib_ops.  */
+
+link_map_offsets *
+mips_fbsd_lp64_solib_ops::fetch_link_map_offsets () const
 {
   static struct link_map_offsets lmo;
   static struct link_map_offsets *lmp = NULL;
@@ -565,10 +601,9 @@ mips_fbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
   set_gdbarch_skip_solib_resolver (gdbarch, mips_fbsd_skip_solib_resolver);
 
   /* FreeBSD/mips has SVR4-style shared libraries.  */
-  set_solib_svr4_fetch_link_map_offsets
-    (gdbarch, (gdbarch_ptr_bit (gdbarch) == 32 ?
-              mips_fbsd_ilp32_fetch_link_map_offsets :
-              mips_fbsd_lp64_fetch_link_map_offsets));
+  set_solib_svr4_ops (gdbarch, (gdbarch_ptr_bit (gdbarch) == 32
+                               ? make_mips_fbsd_ilp32_solib_ops
+                               : make_mips_fbsd_lp64_solib_ops));
 }
 
 INIT_GDB_FILE (mips_fbsd_tdep)
index 755586cddd4f30694c6bc353f658fbdc7263224e..e4fa2438a9fc1909623751977c443553356b28c2 100644 (file)
@@ -36,6 +36,7 @@
 #include "mips-linux-tdep.h"
 #include "glibc-tdep.h"
 #include "linux-tdep.h"
+#include "solib-svr4-linux.h"
 #include "xml-syscall.h"
 #include "gdbsupport/gdb_signals.h"
 #include "inferior.h"
@@ -45,8 +46,6 @@
 #include "features/mips64-linux.c"
 #include "features/mips64-dsp-linux.c"
 
-static solib_ops mips_svr4_so_ops;
-
 /* This enum represents the signals' numbers on the MIPS
    architecture.  It just contains the signal definitions which are
    different from the generic implementation.
@@ -666,15 +665,22 @@ mips_linux_in_dynsym_stub (CORE_ADDR pc)
   return 1;
 }
 
-/* Return true iff PC belongs to the dynamic linker resolution
-   code, a PLT entry, or a lazy binding stub.  */
+/* Mix-in class to add Linux/MIPS-specific methods to a base solib_ops
+   class.  */
 
-static bool
-mips_linux_in_dynsym_resolve_code (CORE_ADDR pc)
+template <typename Base>
+struct mips_linux_svr4_solib_ops : public Base
+{
+  bool in_dynsym_resolve_code (CORE_ADDR pc) const override;
+};
+
+template <typename Base>
+bool
+mips_linux_svr4_solib_ops<Base>::in_dynsym_resolve_code (CORE_ADDR pc) const
 {
   /* Check whether PC is in the dynamic linker.  This also checks
      whether it is in the .plt section, used by non-PIC executables.  */
-  if (svr4_in_dynsym_resolve_code (pc))
+  if (Base::in_dynsym_resolve_code (pc))
     return true;
 
   /* Likewise for the stubs.  They live in the .MIPS.stubs section these
@@ -686,6 +692,32 @@ mips_linux_in_dynsym_resolve_code (CORE_ADDR pc)
   return false;
 }
 
+/* solib_ops for ILP32 Linux/MIPS systems.  */
+
+using mips_linux_ilp32_svr4_solib_ops
+  = mips_linux_svr4_solib_ops<linux_ilp32_svr4_solib_ops>;
+
+/* Return a new solib_ops for ILP32 Linux/MIPS systems.  */
+
+static solib_ops_up
+make_mips_linux_ilp32_svr4_solib_ops ()
+{
+  return std::make_unique<mips_linux_ilp32_svr4_solib_ops> ();
+}
+
+/* solib_ops for LP64 Linux/MIPS systems.  */
+
+using mips_linux_lp64_svr4_solib_ops
+  = mips_linux_svr4_solib_ops<linux_lp64_svr4_solib_ops>;
+
+/* Return a new solib_ops for LP64 Linux/MIPS systems.  */
+
+static solib_ops_up
+make_mips_linux_lp64_svr4_solib_ops ()
+{
+  return std::make_unique<mips_linux_lp64_svr4_solib_ops> ();
+}
+
 /* See the comments for SKIP_SOLIB_RESOLVER at the top of infrun.c,
    and glibc_skip_solib_resolver in glibc-tdep.c.  The normal glibc
    implementation of this triggers at "fixup" from the same objfile as
@@ -1537,8 +1569,7 @@ mips_linux_init_abi (struct gdbarch_info info,
       case MIPS_ABI_O32:
        set_gdbarch_get_longjmp_target (gdbarch,
                                        mips_linux_get_longjmp_target);
-       set_solib_svr4_fetch_link_map_offsets
-         (gdbarch, linux_ilp32_fetch_link_map_offsets);
+       set_solib_svr4_ops (gdbarch, make_mips_linux_ilp32_svr4_solib_ops);
        tramp_frame_prepend_unwinder (gdbarch, &micromips_linux_o32_sigframe);
        tramp_frame_prepend_unwinder (gdbarch,
                                      &micromips_linux_o32_rt_sigframe);
@@ -1549,8 +1580,7 @@ mips_linux_init_abi (struct gdbarch_info info,
       case MIPS_ABI_N32:
        set_gdbarch_get_longjmp_target (gdbarch,
                                        mips_linux_get_longjmp_target);
-       set_solib_svr4_fetch_link_map_offsets
-         (gdbarch, linux_ilp32_fetch_link_map_offsets);
+       set_solib_svr4_ops (gdbarch, make_mips_linux_ilp32_svr4_solib_ops);
        set_gdbarch_long_double_bit (gdbarch, 128);
        set_gdbarch_long_double_format (gdbarch, floatformats_ieee_quad);
        tramp_frame_prepend_unwinder (gdbarch,
@@ -1561,8 +1591,7 @@ mips_linux_init_abi (struct gdbarch_info info,
       case MIPS_ABI_N64:
        set_gdbarch_get_longjmp_target (gdbarch,
                                        mips64_linux_get_longjmp_target);
-       set_solib_svr4_fetch_link_map_offsets
-         (gdbarch, linux_lp64_fetch_link_map_offsets);
+       set_solib_svr4_ops (gdbarch, make_mips_linux_lp64_svr4_solib_ops);
        set_gdbarch_long_double_bit (gdbarch, 128);
        set_gdbarch_long_double_format (gdbarch, floatformats_ieee_quad);
        tramp_frame_prepend_unwinder (gdbarch,
@@ -1582,16 +1611,6 @@ mips_linux_init_abi (struct gdbarch_info info,
   set_gdbarch_fetch_tls_load_module_address (gdbarch,
                                             svr4_fetch_objfile_link_map);
 
-  /* Initialize this lazily, to avoid an initialization order
-     dependency on solib-svr4.c's _initialize routine.  */
-  if (mips_svr4_so_ops.in_dynsym_resolve_code == NULL)
-    {
-      mips_svr4_so_ops = svr4_so_ops;
-      mips_svr4_so_ops.in_dynsym_resolve_code
-       = mips_linux_in_dynsym_resolve_code;
-    }
-  set_gdbarch_so_ops (gdbarch, &mips_svr4_so_ops);
-
   set_gdbarch_write_pc (gdbarch, mips_linux_write_pc);
 
   set_gdbarch_core_read_description (gdbarch,
index 4814cd15d0370e2f3907c546b4f70242921270ef..42eb515bc212b85bd9dd1f115c9caf17d3088e7d 100644 (file)
@@ -288,13 +288,27 @@ mipsnbsd_cannot_store_register (struct gdbarch *gdbarch, int regno)
          || regno == mips_regnum (gdbarch)->fp_implementation_revision);
 }
 
-/* Shared library support.  */
+/* solib_ops for ILP32 NetBSD/MIPS systems.  */
 
-/* NetBSD/mips uses a slightly different `struct link_map' than the
-   other NetBSD platforms.  */
+struct mips_nbsd_ilp32_svr4_solib_ops : public svr4_solib_ops
+{
+  /* NetBSD/MIPS uses a slightly different `struct link_map' than the
+     other NetBSD platforms.  */
+  link_map_offsets *fetch_link_map_offsets () const override;
+};
+
+/* Return a new solib_ops for ILP32 NetBSD/MIPS systems.  */
+
+static solib_ops_up
+make_mips_nbsd_ilp32_svr4_solib_ops ()
+{
+  return std::make_unique<mips_nbsd_ilp32_svr4_solib_ops> ();
+}
 
-static struct link_map_offsets *
-mipsnbsd_ilp32_fetch_link_map_offsets (void)
+/* See mips_nbsd_ilp32_svr4_solib_ops.  */
+
+link_map_offsets *
+mips_nbsd_ilp32_svr4_solib_ops::fetch_link_map_offsets () const
 {
   static struct link_map_offsets lmo;
   static struct link_map_offsets *lmp = NULL;
@@ -322,8 +336,27 @@ mipsnbsd_ilp32_fetch_link_map_offsets (void)
   return lmp;
 }
 
-static struct link_map_offsets *
-mipsnbsd_lp64_fetch_link_map_offsets (void)
+/* solib_ops for LP64 NetBSD/MIPS systems.  */
+
+struct mips_nbsd_lp64_svr4_solib_ops : public svr4_solib_ops
+{
+  /* NetBSD/MIPS uses a slightly different `struct link_map' than the
+     other NetBSD platforms.  */
+  link_map_offsets *fetch_link_map_offsets () const override;
+};
+
+/* Return a new solib_ops for LP64 NetBSD/MIPS systems.  */
+
+static solib_ops_up
+make_mips_nbsd_lp64_svr4_solib_ops ()
+{
+  return std::make_unique<mips_nbsd_lp64_svr4_solib_ops> ();
+}
+
+/* See mips_nbsd_lp64_svr4_solib_ops.  */
+
+link_map_offsets *
+mips_nbsd_lp64_svr4_solib_ops::fetch_link_map_offsets () const
 {
   static struct link_map_offsets lmo;
   static struct link_map_offsets *lmp = NULL;
@@ -369,10 +402,9 @@ mipsnbsd_init_abi (struct gdbarch_info info,
   set_gdbarch_software_single_step (gdbarch, mips_software_single_step);
 
   /* NetBSD/mips has SVR4-style shared libraries.  */
-  set_solib_svr4_fetch_link_map_offsets
-    (gdbarch, (gdbarch_ptr_bit (gdbarch) == 32 ?
-              mipsnbsd_ilp32_fetch_link_map_offsets :
-              mipsnbsd_lp64_fetch_link_map_offsets));
+  set_solib_svr4_ops (gdbarch, (gdbarch_ptr_bit (gdbarch) == 32
+                               ? make_mips_nbsd_ilp32_svr4_solib_ops
+                               : make_mips_nbsd_lp64_svr4_solib_ops));
 }
 
 INIT_GDB_FILE (mipsnbsd_tdep)
index aa1070f80a6f432cfa4ab1c29c7f8b970d0acd25..b9a6fe5812c265c90137b39e8d8ce57da7904f2c 100644 (file)
@@ -150,8 +150,7 @@ mips64obsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
   obsd_init_abi(info, gdbarch);
 
   /* OpenBSD/mips64 has SVR4-style shared libraries.  */
-  set_solib_svr4_fetch_link_map_offsets
-    (gdbarch, svr4_lp64_fetch_link_map_offsets);
+  set_solib_svr4_ops (gdbarch, make_svr4_lp64_solib_ops);
 }
 
 INIT_GDB_FILE (mips64obsd_tdep)
index 7bac6920499ebf41930f700e391137505a52d651..6c312411d0149125c0715332fd8176c51166bdc9 100644 (file)
@@ -29,6 +29,7 @@
 #include "trad-frame.h"
 #include "tramp-frame.h"
 #include "linux-tdep.h"
+#include "solib-svr4-linux.h"
 #include "gdbarch.h"
 
 /* Transliterated from <asm-mn10300/elf.h>...  */
@@ -707,8 +708,7 @@ am33_linux_init_osabi (struct gdbarch_info info, struct gdbarch *gdbarch)
 
   set_gdbarch_iterate_over_regset_sections
     (gdbarch, am33_iterate_over_regset_sections);
-  set_solib_svr4_fetch_link_map_offsets
-    (gdbarch, linux_ilp32_fetch_link_map_offsets);
+  set_solib_svr4_ops (gdbarch, make_linux_ilp32_svr4_solib_ops);
 
   tramp_frame_prepend_unwinder (gdbarch, &am33_linux_sigframe);
   tramp_frame_prepend_unwinder (gdbarch, &am33_linux_rt_sigframe);
index acab3025e2af661ec9ba380b76e819fe0b66ccf1..afefefe9c0e99fa6a1f44118352f36c22479d5d3 100644 (file)
@@ -20,6 +20,7 @@
 #include "osabi.h"
 #include "glibc-tdep.h"
 #include "linux-tdep.h"
+#include "solib-svr4-linux.h"
 #include "solib-svr4.h"
 #include "regset.h"
 #include "tramp-frame.h"
@@ -144,8 +145,7 @@ or1k_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
 {
   linux_init_abi (info, gdbarch, 0);
 
-  set_solib_svr4_fetch_link_map_offsets (gdbarch,
-                                        linux_ilp32_fetch_link_map_offsets);
+  set_solib_svr4_ops (gdbarch, make_linux_ilp32_svr4_solib_ops);
 
   /* GNU/Linux uses SVR4-style shared libraries.  */
   set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
index ccc6db6ef8f67f9d96dd4549ded2a4c1295207ba..a6665097333fd24b348dcb7d9236a12f94602352 100644 (file)
@@ -332,8 +332,7 @@ ppcfbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
       set_gdbarch_return_value (gdbarch, ppcfbsd_return_value);
 
       set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
-      set_solib_svr4_fetch_link_map_offsets (gdbarch,
-                                            svr4_ilp32_fetch_link_map_offsets);
+      set_solib_svr4_ops (gdbarch, make_svr4_ilp32_solib_ops);
 
       frame_unwind_append_unwinder (gdbarch, &ppcfbsd_sigtramp_frame_unwind);
       set_gdbarch_gcore_bfd_target (gdbarch, "elf32-powerpc");
@@ -347,8 +346,7 @@ ppcfbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
                                            ppc64_elf_make_msymbol_special);
 
       set_gdbarch_skip_trampoline_code (gdbarch, ppc64_skip_trampoline_code);
-      set_solib_svr4_fetch_link_map_offsets (gdbarch,
-                                            svr4_lp64_fetch_link_map_offsets);
+      set_solib_svr4_ops (gdbarch, make_svr4_lp64_solib_ops);
       set_gdbarch_gcore_bfd_target (gdbarch, "elf64-powerpc");
     }
 
index 2c280bda7fbb80d776df0cb9f3664cd680b4b664..5067b89cbe0ffb446681493c93eb333315b8a000 100644 (file)
@@ -48,6 +48,7 @@
 #include "arch-utils.h"
 #include "xml-syscall.h"
 #include "linux-tdep.h"
+#include "solib-svr4-linux.h"
 #include "svr4-tls-tdep.h"
 #include "linux-record.h"
 #include "record-full.h"
@@ -86,8 +87,6 @@
 #include "features/rs6000/powerpc-e500l.c"
 #include "dwarf2/frame.h"
 
-/* Shared library operations for PowerPC-Linux.  */
-static solib_ops powerpc_so_ops;
 
 /* The syscall's XML filename for PPC and PPC64.  */
 #define XML_SYSCALL_FILENAME_PPC "syscalls/ppc-linux.xml"
@@ -306,16 +305,33 @@ static const struct ppc_insn_pattern powerpc32_plt_stub_so_2[] =
 /* The max number of insns we check using ppc_insns_match_pattern.  */
 #define POWERPC32_PLT_CHECK_LEN (ARRAY_SIZE (powerpc32_plt_stub) - 1)
 
-/* Check if PC is in PLT stub.  For non-secure PLT, stub is in .plt
-   section.  For secure PLT, stub is in .text and we need to check
-   instruction patterns.  */
+/* solib_ops for ILP32 PowerPC/Linux systems.  */
 
-static bool
-powerpc_linux_in_dynsym_resolve_code (CORE_ADDR pc)
+struct ppc_linux_ilp32_svr4_solib_ops : public linux_ilp32_svr4_solib_ops
+{
+  /* Check if PC is in PLT stub.  For non-secure PLT, stub is in .plt
+     section.  For secure PLT, stub is in .text and we need to check
+     instruction patterns.  */
+
+  bool in_dynsym_resolve_code (CORE_ADDR pc) const override;
+};
+
+/* Return a new solib_ops for ILP32 PowerPC/Linux systems.  */
+
+static solib_ops_up
+make_ppc_linux_ilp32_svr4_solib_ops ()
+{
+  return std::make_unique<ppc_linux_ilp32_svr4_solib_ops> ();
+}
+
+/* See ppc_linux_ilp32_svr4_solib_ops.  */
+
+bool
+ppc_linux_ilp32_svr4_solib_ops::in_dynsym_resolve_code (CORE_ADDR pc) const
 {
   /* Check whether PC is in the dynamic linker.  This also checks
      whether it is in the .plt section, used by non-PIC executables.  */
-  if (svr4_in_dynsym_resolve_code (pc))
+  if (linux_ilp32_svr4_solib_ops::in_dynsym_resolve_code (pc))
     return true;
 
   /* Check if we are in the resolver.  */
@@ -2265,8 +2281,6 @@ ppc_linux_init_abi (struct gdbarch_info info,
 
       /* Shared library handling.  */
       set_gdbarch_skip_trampoline_code (gdbarch, ppc_skip_trampoline_code);
-      set_solib_svr4_fetch_link_map_offsets
-       (gdbarch, linux_ilp32_fetch_link_map_offsets);
 
       /* Setting the correct XML syscall filename.  */
       set_xml_syscall_file_name (gdbarch, XML_SYSCALL_FILENAME_PPC);
@@ -2283,14 +2297,7 @@ ppc_linux_init_abi (struct gdbarch_info info,
       else
        set_gdbarch_gcore_bfd_target (gdbarch, "elf32-powerpc");
 
-      if (powerpc_so_ops.in_dynsym_resolve_code == NULL)
-       {
-         powerpc_so_ops = svr4_so_ops;
-         /* Override dynamic resolve function.  */
-         powerpc_so_ops.in_dynsym_resolve_code =
-           powerpc_linux_in_dynsym_resolve_code;
-       }
-      set_gdbarch_so_ops (gdbarch, &powerpc_so_ops);
+      set_solib_svr4_ops (gdbarch, make_ppc_linux_ilp32_svr4_solib_ops);
 
       set_gdbarch_skip_solib_resolver (gdbarch, glibc_skip_solib_resolver);
     }
@@ -2317,8 +2324,7 @@ ppc_linux_init_abi (struct gdbarch_info info,
 
       /* Shared library handling.  */
       set_gdbarch_skip_trampoline_code (gdbarch, ppc64_skip_trampoline_code);
-      set_solib_svr4_fetch_link_map_offsets
-       (gdbarch, linux_lp64_fetch_link_map_offsets);
+      set_solib_svr4_ops (gdbarch, make_linux_lp64_svr4_solib_ops);
 
       /* Setting the correct XML syscall filename.  */
       set_xml_syscall_file_name (gdbarch, XML_SYSCALL_FILENAME_PPC64);
index d586887e79da03245a83c22e1336ad5487b883f9..99135923417c9ce41c3f1ec85ac8985674aebee1 100644 (file)
@@ -179,8 +179,7 @@ ppcnbsd_init_abi (struct gdbarch_info info,
   set_gdbarch_return_value (gdbarch, ppcnbsd_return_value);
 
   /* NetBSD uses SVR4-style shared libraries.  */
-  set_solib_svr4_fetch_link_map_offsets
-    (gdbarch, svr4_ilp32_fetch_link_map_offsets);
+  set_solib_svr4_ops (gdbarch, make_svr4_ilp32_solib_ops);
 
   set_gdbarch_iterate_over_regset_sections
     (gdbarch, ppcnbsd_iterate_over_regset_sections);
index f14505e359f043e92b52f85da0c1e41dcd0765dc..18f4d79b69d2b05409d137bc7d2220f2bad32a18 100644 (file)
@@ -254,8 +254,7 @@ ppcobsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
   set_gdbarch_return_value (gdbarch, ppc_sysv_abi_broken_return_value);
 
   /* OpenBSD uses SVR4-style shared libraries.  */
-  set_solib_svr4_fetch_link_map_offsets
-    (gdbarch, svr4_ilp32_fetch_link_map_offsets);
+  set_solib_svr4_ops (gdbarch, make_svr4_ilp32_solib_ops);
 
   set_gdbarch_iterate_over_regset_sections
     (gdbarch, ppcobsd_iterate_over_regset_sections);
index 3d0d677cbe01f02b1cfd93b8907c239a03e04495..a761e62b8cc4ad50102f3b0cab0cae6f8968ad33 100644 (file)
@@ -21,6 +21,7 @@
 #ifndef GDB_PROGSPACE_H
 #define GDB_PROGSPACE_H
 
+#include "solib.h"
 #include "target.h"
 #include "gdb_bfd.h"
 #include "registry.h"
@@ -234,19 +235,23 @@ struct program_space
   /* 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)
+  void set_solib_ops (solib_ops_up ops)
   {
     gdb_assert (m_solib_ops == nullptr);
-    m_solib_ops = &ops;
+    m_solib_ops = std::move (ops);
   };
 
-  /* Unset this program space's solib provider.  */
+  /* Unset and free this program space's solib provider.  */
   void unset_solib_ops ()
   { m_solib_ops = nullptr; }
 
+  /* Unset and return this program space's solib provider.  */
+  solib_ops_up release_solib_ops ()
+  { return std::move (m_solib_ops); }
+
   /* Get this program space's solib provider.  */
   const struct solib_ops *solib_ops () const
-  { return m_solib_ops; }
+  { return m_solib_ops.get (); }
 
   /* Return the list of all the solibs in this program space.  */
   owning_intrusive_list<solib> &solibs ()
@@ -373,7 +378,7 @@ private:
   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;
+  solib_ops_up m_solib_ops;
 
   /* List of shared objects mapped into this space.  Managed by
      solib.c.  */
index dadfeb989880f85aa5dca0d41663ed8e29d742a6..7bdc6e75ccb237038a296ed87991d23e3d4157ba 100644 (file)
@@ -191,10 +191,9 @@ riscv_fbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
 
   set_gdbarch_software_single_step (gdbarch, riscv_software_single_step);
 
-  set_solib_svr4_fetch_link_map_offsets (gdbarch,
-                                        (riscv_isa_xlen (gdbarch) == 4
-                                         ? svr4_ilp32_fetch_link_map_offsets
-                                         : svr4_lp64_fetch_link_map_offsets));
+  set_solib_svr4_ops (gdbarch, (riscv_isa_xlen (gdbarch) == 4
+                               ? make_svr4_ilp32_solib_ops
+                               : make_svr4_lp64_solib_ops));
 
   tramp_frame_prepend_unwinder (gdbarch, &riscv_fbsd_sigframe);
 
index ccac665ecac59f0061070e7a8e3c83cc7ce4f208..e5d77e7f208069b9e9562cbcce14f88b7954f2d2 100644 (file)
@@ -20,6 +20,7 @@
 #include "osabi.h"
 #include "glibc-tdep.h"
 #include "linux-tdep.h"
+#include "solib-svr4-linux.h"
 #include "svr4-tls-tdep.h"
 #include "solib-svr4.h"
 #include "regset.h"
@@ -512,10 +513,9 @@ riscv_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
 
   set_gdbarch_software_single_step (gdbarch, riscv_software_single_step);
 
-  set_solib_svr4_fetch_link_map_offsets (gdbarch,
-                                        (riscv_isa_xlen (gdbarch) == 4
-                                         ? linux_ilp32_fetch_link_map_offsets
-                                         : linux_lp64_fetch_link_map_offsets));
+  set_solib_svr4_ops (gdbarch, (riscv_isa_xlen (gdbarch) == 4
+                               ? make_linux_ilp32_svr4_solib_ops
+                               : make_linux_lp64_svr4_solib_ops));
 
   /* GNU/Linux uses SVR4-style shared libraries.  */
   set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
index 3e0062f0d0afa78f64532b1cbc30613671ce9e1a..853a66e65054a4ac004ca879dabc3b33ed25c31b 100644 (file)
@@ -1411,7 +1411,7 @@ rs6000_aix_init_osabi (struct gdbarch_info info, struct gdbarch *gdbarch)
   set_gdbarch_wchar_signed (gdbarch, 0);
   set_gdbarch_auto_wide_charset (gdbarch, rs6000_aix_auto_wide_charset);
 
-  set_gdbarch_so_ops (gdbarch, &solib_aix_so_ops);
+  set_gdbarch_make_solib_ops (gdbarch, make_aix_solib_ops);
   frame_unwind_append_unwinder (gdbarch, &aix_sighandle_frame_unwind);
 }
 
index 22b70914c4899cfa721c584f88aa794a6d82219b..66e571d47dd3be5148c8da7c432132e65009ccf5 100644 (file)
@@ -29,6 +29,7 @@
 #include "gdbcore.h"
 #include "linux-record.h"
 #include "linux-tdep.h"
+#include "solib-svr4-linux.h"
 #include "svr4-tls-tdep.h"
 #include "objfiles.h"
 #include "osabi.h"
@@ -1214,8 +1215,7 @@ s390_linux_init_abi_31 (struct gdbarch_info info, struct gdbarch *gdbarch)
 
   s390_linux_init_abi_any (info, gdbarch);
 
-  set_solib_svr4_fetch_link_map_offsets (gdbarch,
-                                        linux_ilp32_fetch_link_map_offsets);
+  set_solib_svr4_ops (gdbarch, make_linux_ilp32_svr4_solib_ops);
   set_xml_syscall_file_name (gdbarch, XML_SYSCALL_FILENAME_S390);
 }
 
@@ -1230,8 +1230,7 @@ s390_linux_init_abi_64 (struct gdbarch_info info, struct gdbarch *gdbarch)
 
   s390_linux_init_abi_any (info, gdbarch);
 
-  set_solib_svr4_fetch_link_map_offsets (gdbarch,
-                                        linux_lp64_fetch_link_map_offsets);
+  set_solib_svr4_ops (gdbarch, make_linux_lp64_svr4_solib_ops);
   set_xml_syscall_file_name (gdbarch, XML_SYSCALL_FILENAME_S390X);
 }
 
index 9113963501b6f1315bd50ceb12d50dc404e3156d..25781922e5fd4c2c937ee3b7ab16c6482abdc135 100644 (file)
@@ -28,6 +28,7 @@
 #include "glibc-tdep.h"
 #include "sh-tdep.h"
 #include "linux-tdep.h"
+#include "solib-svr4-linux.h"
 #include "gdbarch.h"
 
 #define REGSx16(base) \
@@ -187,8 +188,7 @@ sh_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
 
   /* GNU/Linux uses SVR4-style shared libraries.  */
   set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
-  set_solib_svr4_fetch_link_map_offsets
-    (gdbarch, linux_ilp32_fetch_link_map_offsets);
+  set_solib_svr4_ops (gdbarch, make_linux_ilp32_svr4_solib_ops);
   set_gdbarch_skip_solib_resolver (gdbarch, glibc_skip_solib_resolver);
 
   set_gdbarch_fetch_tls_load_module_address (gdbarch,
index 3c1ae09ee7098ce16e926ce3994abe1f8600bda3..4b0181bcdecd07bb03cb8cfbf0928079bb571a9c 100644 (file)
@@ -68,8 +68,7 @@ shnbsd_init_abi (struct gdbarch_info info,
   tdep->core_gregmap = (struct sh_corefile_regmap *)regmap;
   tdep->sizeof_gregset = 84;
 
-  set_solib_svr4_fetch_link_map_offsets
-    (gdbarch, svr4_ilp32_fetch_link_map_offsets);
+  set_solib_svr4_ops (gdbarch, make_svr4_ilp32_solib_ops);
 }
 
 INIT_GDB_FILE (shnbsd_tdep)
index b10e41164bdfa9338122a405a45888f6d0a44c0c..b246df82561e17d5d028aa81730b9bf8aed85a52 100644 (file)
 #include "xcoffread.h"
 #include "observable.h"
 
+/* solib_ops for AIX systems.  */
+
+struct aix_solib_ops : public solib_ops
+{
+  void relocate_section_addresses (solib &so, target_section *) const override;
+  void create_inferior_hook (int from_tty) const override;
+  owning_intrusive_list<solib> current_sos () const override;
+  gdb_bfd_ref_ptr bfd_open (const char *pathname) const override;
+};
+
+/* See solib-aix.h.  */
+
+solib_ops_up
+make_aix_solib_ops ()
+{
+  return std::make_unique<aix_solib_ops> ();
+}
+
 /* Our private data in struct solib.  */
 
 struct lm_info_aix final : public lm_info
@@ -306,10 +324,9 @@ solib_aix_bss_data_overlap (bfd *abfd)
   return 0;
 }
 
-/* Implement the "relocate_section_addresses" solib_ops method.  */
-
-static void
-solib_aix_relocate_section_addresses (solib &so, target_section *sec)
+void
+aix_solib_ops::relocate_section_addresses (solib &so,
+                                          target_section *sec) const
 {
   struct bfd_section *bfd_sect = sec->the_bfd_section;
   bfd *abfd = bfd_sect->owner;
@@ -410,10 +427,8 @@ solib_aix_get_section_offsets (struct objfile *objfile,
   return offsets;
 }
 
-/* Implement the "solib_create_inferior_hook" solib_ops method.  */
-
-static void
-solib_aix_solib_create_inferior_hook (int from_tty)
+void
+aix_solib_ops::create_inferior_hook (int from_tty) const
 {
   const char *warning_msg = "unable to relocate main executable";
 
@@ -441,10 +456,8 @@ solib_aix_solib_create_inferior_hook (int from_tty)
     }
 }
 
-/* Implement the "current_sos" solib_ops method.  */
-
-static owning_intrusive_list<solib>
-solib_aix_current_sos ()
+owning_intrusive_list<solib>
+aix_solib_ops::current_sos () const
 {
   std::optional<std::vector<lm_info_aix>> &library_list
     = solib_aix_get_library_list (current_inferior (), NULL);
@@ -480,7 +493,7 @@ solib_aix_current_sos ()
        }
 
       /* Add it to the list.  */
-      auto &new_solib = sos.emplace_back (solib_aix_so_ops);
+      auto &new_solib = sos.emplace_back (*this);
       new_solib.original_name = so_name;
       new_solib.name = so_name;
       new_solib.lm_info = std::make_unique<lm_info_aix> (info);
@@ -489,10 +502,8 @@ solib_aix_current_sos ()
   return sos;
 }
 
-/* Implement the "bfd_open" solib_ops method.  */
-
-static gdb_bfd_ref_ptr
-solib_aix_bfd_open (const char *pathname)
+gdb_bfd_ref_ptr
+aix_solib_ops::bfd_open (const char *pathname) const
 {
   /* The pathname is actually a synthetic filename with the following
      form: "/path/to/sharedlib(member.o)" (double-quotes excluded).
@@ -506,7 +517,7 @@ solib_aix_bfd_open (const char *pathname)
   int found_file;
 
   if (pathname[path_len - 1] != ')')
-    return solib_bfd_open (pathname);
+    return solib_ops::bfd_open (pathname);
 
   /* Search for the associated parens.  */
   sep = strrchr (pathname, '(');
@@ -516,7 +527,7 @@ solib_aix_bfd_open (const char *pathname)
         to open pathname without decoding, possibly leading to
         a failure), rather than triggering an assert failure).  */
       warning (_("missing '(' in shared object pathname: %s"), pathname);
-      return solib_bfd_open (pathname);
+      return solib_ops::bfd_open (pathname);
     }
   filename_len = sep - pathname;
 
@@ -659,24 +670,6 @@ solib_aix_normal_stop_observer (struct bpstat *unused_1, int unused_2)
   data->library_list.reset ();
 }
 
-/* The solib_ops for AIX targets.  */
-const solib_ops solib_aix_so_ops =
-{
-  solib_aix_relocate_section_addresses,
-  nullptr,
-  nullptr,
-  solib_aix_solib_create_inferior_hook,
-  solib_aix_current_sos,
-  nullptr,
-  nullptr,
-  solib_aix_bfd_open,
-  nullptr,
-  nullptr,
-  nullptr,
-  nullptr,
-  default_find_solib_addr,
-};
-
 INIT_GDB_FILE (solib_aix)
 {
   gdb::observers::normal_stop.attach (solib_aix_normal_stop_observer,
index 7a1bc7b4b567b70981fd62421281d61f8dca31dc..628b7c8df474959c2418ef94905425e13d2f98f8 100644 (file)
 #ifndef GDB_SOLIB_AIX_H
 #define GDB_SOLIB_AIX_H
 
-struct solib_ops;
-extern const solib_ops solib_aix_so_ops;
+#include "solib.h"
 
 extern CORE_ADDR solib_aix_get_toc_value (CORE_ADDR pc);
 
+/* Return a new solib_ops for AIX systems.  */
+
+solib_ops_up make_aix_solib_ops ();
+
 #endif /* GDB_SOLIB_AIX_H */
index 88a2962f5dd5f3ac2667a02cb442313ff5c58a20..aac8ab2942edd703fe35169ad56a654bcf684f05 100644 (file)
 #include "mach-o.h"
 #include "mach-o/external.h"
 
+/* solib_ops for Darwin systems.  */
+
+struct darwin_solib_ops : public solib_ops
+{
+  void relocate_section_addresses (solib &so, target_section *) const override;
+  void clear_solib (program_space *pspace) const override;
+  void create_inferior_hook (int from_tty) const override;
+  owning_intrusive_list<solib> current_sos () const override;
+  gdb_bfd_ref_ptr bfd_open (const char *pathname) const override;
+};
+
+/* See solib-darwin.h.  */
+
+solib_ops_up
+make_darwin_solib_ops ()
+{
+  return std::make_unique<darwin_solib_ops> ();
+}
+
 struct gdb_dyld_image_info
 {
   /* Base address (which corresponds to the Mach-O header).  */
@@ -188,10 +207,8 @@ find_program_interpreter (void)
   return buf;
 }
 
-/* Build a list of currently loaded shared objects.  See solib-svr4.c.  */
-
-static owning_intrusive_list<solib>
-darwin_current_sos ()
+owning_intrusive_list<solib>
+darwin_solib_ops::current_sos () const
 {
   type *ptr_type
     = builtin_type (current_inferior ()->arch ())->builtin_data_ptr;
@@ -250,7 +267,7 @@ darwin_current_sos ()
        break;
 
       /* Create and fill the new struct solib element.  */
-      auto &newobj = sos.emplace_back (darwin_so_ops);
+      auto &newobj = sos.emplace_back (*this);
 
       auto li = std::make_unique<lm_info_darwin> ();
 
@@ -457,10 +474,8 @@ darwin_solib_read_all_image_info_addr (struct darwin_info *info)
   info->all_image_addr = extract_unsigned_integer (buf, len, BFD_ENDIAN_BIG);
 }
 
-/* Shared library startup support.  See documentation in solib-svr4.c.  */
-
-static void
-darwin_solib_create_inferior_hook (int from_tty)
+void
+darwin_solib_ops::create_inferior_hook (int from_tty) const
 {
   /* Everything below only makes sense if we have a running inferior.  */
   if (!target_has_execution ())
@@ -560,8 +575,8 @@ darwin_solib_create_inferior_hook (int from_tty)
     create_solib_event_breakpoint (current_inferior ()->arch (), notifier);
 }
 
-static void
-darwin_clear_solib (program_space *pspace)
+void
+darwin_solib_ops::clear_solib (program_space *pspace) const
 {
   darwin_info *info = get_darwin_info (pspace);
 
@@ -572,8 +587,9 @@ darwin_clear_solib (program_space *pspace)
 /* The section table is built from bfd sections using bfd VMAs.
    Relocate these VMAs according to solib info.  */
 
-static void
-darwin_relocate_section_addresses (solib &so, target_section *sec)
+void
+darwin_solib_ops::relocate_section_addresses (solib &so,
+                                             target_section *sec) const
 {
   auto *li = gdb::checked_static_cast<lm_info_darwin *> (so.lm_info.get ());
 
@@ -592,9 +608,9 @@ darwin_relocate_section_addresses (solib &so, target_section *sec)
   if (sec->addr < so.addr_low)
     so.addr_low = sec->addr;
 }
-\f
-static gdb_bfd_ref_ptr
-darwin_bfd_open (const char *pathname)
+
+gdb_bfd_ref_ptr
+darwin_solib_ops::bfd_open (const char *pathname) const
 {
   int found_file;
 
@@ -622,20 +638,3 @@ darwin_bfd_open (const char *pathname)
 
   return res;
 }
-
-const solib_ops darwin_so_ops =
-{
-  darwin_relocate_section_addresses,
-  nullptr,
-  darwin_clear_solib,
-  darwin_solib_create_inferior_hook,
-  darwin_current_sos,
-  nullptr,
-  nullptr,
-  darwin_bfd_open,
-  nullptr,
-  nullptr,
-  nullptr,
-  nullptr,
-  default_find_solib_addr,
-};
index b96e744669fb7efd742f1561493dcd78593c4bbc..f5bcdd124551d75a1faf538f041d6427e74c4003 100644 (file)
 #ifndef GDB_SOLIB_DARWIN_H
 #define GDB_SOLIB_DARWIN_H
 
-struct solib_ops;
+#include "solib.h"
 
-extern const solib_ops darwin_so_ops;
+/* Return a new solib_ops for Darwin systems.  */
+
+extern solib_ops_up make_darwin_solib_ops ();
 
 #endif /* GDB_SOLIB_DARWIN_H */
index 6cc0264b45c2fd757427b5054db7f43550a0b73c..f18d9a2e75e294fc82ada9fc71e0ec1ad16b73f3 100644 (file)
@@ -120,6 +120,25 @@ struct dbst_ext_link_map
   ext_ptr l_next, l_prev;      /* struct link_map *l_next, *l_prev; */
 };
 
+/* solib_ops for DSBT systems.  */
+
+struct dsbt_solib_ops : public solib_ops
+{
+  void relocate_section_addresses (solib &so, target_section *) const override;
+  void clear_solib (program_space *pspace) const override;
+  void create_inferior_hook (int from_tty) const override;
+  owning_intrusive_list<solib> current_sos () const override;
+  bool in_dynsym_resolve_code (CORE_ADDR pc) const override;
+};
+
+/* See solib-dsbt.h.  */
+
+solib_ops_up
+make_dsbt_solib_ops ()
+{
+  return std::make_unique<dsbt_solib_ops> ();
+}
+
 /* Link map info to include in an allocated solib entry */
 
 struct lm_info_dsbt final : public lm_info
@@ -502,8 +521,8 @@ lm_base (void)
    themselves.  The declaration of `struct solib' says which fields
    we provide values for.  */
 
-static owning_intrusive_list<solib>
-dsbt_current_sos (void)
+owning_intrusive_list<solib>
+dsbt_solib_ops::current_sos () const
 {
   bfd_endian byte_order = gdbarch_byte_order (current_inferior ()->arch ());
   CORE_ADDR lm_addr;
@@ -584,7 +603,7 @@ dsbt_current_sos (void)
              break;
            }
 
-         auto &sop = sos.emplace_back (dsbt_so_ops);
+         auto &sop = sos.emplace_back (*this);
          auto li = std::make_unique<lm_info_dsbt> ();
          li->map = loadmap;
          /* Fetch the name.  */
@@ -623,8 +642,8 @@ dsbt_current_sos (void)
 /* Return true if PC lies in the dynamic symbol resolution code of the
    run time loader.  */
 
-static bool
-dsbt_in_dynsym_resolve_code (CORE_ADDR pc)
+bool
+dsbt_solib_ops::in_dynsym_resolve_code (CORE_ADDR pc) const
 {
   dsbt_info *info = get_dsbt_info (current_program_space);
 
@@ -840,8 +859,8 @@ dsbt_relocate_main_executable (void)
    For the DSBT shared library, the main executable needs to be relocated.
    The shared library breakpoints also need to be enabled.  */
 
-static void
-dsbt_solib_create_inferior_hook (int from_tty)
+void
+dsbt_solib_ops::create_inferior_hook (int from_tty) const
 {
   /* Relocate main executable.  */
   dsbt_relocate_main_executable ();
@@ -854,8 +873,8 @@ dsbt_solib_create_inferior_hook (int from_tty)
     }
 }
 
-static void
-dsbt_clear_solib (program_space *pspace)
+void
+dsbt_solib_ops::clear_solib (program_space *pspace) const
 {
   dsbt_info *info = get_dsbt_info (pspace);
 
@@ -866,8 +885,9 @@ dsbt_clear_solib (program_space *pspace)
   info->main_executable_lm_info = NULL;
 }
 
-static void
-dsbt_relocate_section_addresses (solib &so, target_section *sec)
+void
+dsbt_solib_ops::relocate_section_addresses (solib &so,
+                                           target_section *sec) const
 {
   int seg;
   auto *li = gdb::checked_static_cast<lm_info_dsbt *> (so.lm_info.get ());
@@ -893,23 +913,6 @@ show_dsbt_debug (struct ui_file *file, int from_tty,
   gdb_printf (file, _("solib-dsbt debugging is %s.\n"), value);
 }
 
-const solib_ops dsbt_so_ops =
-{
-  dsbt_relocate_section_addresses,
-  nullptr,
-  dsbt_clear_solib,
-  dsbt_solib_create_inferior_hook,
-  dsbt_current_sos,
-  nullptr,
-  dsbt_in_dynsym_resolve_code,
-  solib_bfd_open,
-  nullptr,
-  nullptr,
-  nullptr,
-  nullptr,
-  default_find_solib_addr,
-};
-
 INIT_GDB_FILE (dsbt_solib)
 {
   /* Debug this file's internals.  */
index d5c52c69e432f3219881bb9789ea5dfd8ab32c0b..d44613c7b248208f4d7c2b18932e3d1d46d2baa5 100644 (file)
 #ifndef GDB_SOLIB_DSBT_H
 #define GDB_SOLIB_DSBT_H
 
-struct solib_ops;
+#include "solib.h"
 
-extern const solib_ops dsbt_so_ops;
+/* Return a new solib_ops for DSBT systems.  */
+
+solib_ops_up make_dsbt_solib_ops ();
 
 #endif /* GDB_SOLIB_DSBT_H */
index 12d3140b513cd845e4f10ac0e1de67dc53ed90d2..6165d0bfab7b9547c86fcebf631b97fef4a54f94 100644 (file)
 #include "elf/frv.h"
 #include "gdb_bfd.h"
 #include "inferior.h"
+#include "solib-frv.h"
+
+/* solib_ops for FR-V systems.  */
+
+struct frv_solib_ops : public solib_ops
+{
+  void relocate_section_addresses (solib &so, target_section *) const override;
+  void clear_solib (program_space *pspace) const override;
+  void create_inferior_hook (int from_tty) const override;
+  owning_intrusive_list<solib> current_sos () const override;
+  bool in_dynsym_resolve_code (CORE_ADDR pc) const override;
+};
+
+/* See solib-frv.h.  */
+
+solib_ops_up
+make_frv_solib_ops ()
+{
+  return std::make_unique<frv_solib_ops> ();
+}
 
 /* FR-V pointers are four bytes wide.  */
 enum { FRV_PTR_SIZE = 4 };
@@ -293,11 +313,8 @@ lm_base (void)
   return lm_base_cache;
 }
 
-
-/* Implement the "current_sos" solib_ops method.  */
-
-static owning_intrusive_list<solib>
-frv_current_sos ()
+owning_intrusive_list<solib>
+frv_solib_ops::current_sos () const
 {
   bfd_endian byte_order = gdbarch_byte_order (current_inferior ()->arch ());
   CORE_ADDR lm_addr, mgot;
@@ -367,7 +384,7 @@ frv_current_sos ()
              break;
            }
 
-         auto &sop = sos.emplace_back (frv_so_ops);
+         auto &sop = sos.emplace_back (*this);
          auto li = std::make_unique<lm_info_frv> ();
          li->map = loadmap;
          li->got_value = got_addr;
@@ -414,8 +431,8 @@ static CORE_ADDR interp_text_sect_high;
 static CORE_ADDR interp_plt_sect_low;
 static CORE_ADDR interp_plt_sect_high;
 
-static bool
-frv_in_dynsym_resolve_code (CORE_ADDR pc)
+bool
+frv_solib_ops::in_dynsym_resolve_code (CORE_ADDR pc) const
 {
   return ((pc >= interp_text_sect_low && pc < interp_text_sect_high)
          || (pc >= interp_plt_sect_low && pc < interp_plt_sect_high)
@@ -776,8 +793,8 @@ frv_relocate_main_executable (void)
    to be relocated.  The shared library breakpoints also need to be
    enabled.  */
 
-static void
-frv_solib_create_inferior_hook (int from_tty)
+void
+frv_solib_ops::create_inferior_hook (int from_tty) const
 {
   /* Relocate main executable.  */
   frv_relocate_main_executable ();
@@ -790,8 +807,8 @@ frv_solib_create_inferior_hook (int from_tty)
     }
 }
 
-static void
-frv_clear_solib (program_space *pspace)
+void
+frv_solib_ops::clear_solib (program_space *pspace) const
 {
   lm_base_cache = 0;
   enable_break2_done = 0;
@@ -801,8 +818,9 @@ frv_clear_solib (program_space *pspace)
   main_executable_lm_info = NULL;
 }
 
-static void
-frv_relocate_section_addresses (solib &so, target_section *sec)
+void
+frv_solib_ops::relocate_section_addresses (solib &so,
+                                          target_section *sec) const
 {
   int seg;
   auto *li = gdb::checked_static_cast<lm_info_frv *> (so.lm_info.get ());
@@ -1063,20 +1081,3 @@ frv_fetch_objfile_link_map (struct objfile *objfile)
   /* Not found!  */
   return 0;
 }
-
-const solib_ops frv_so_ops =
-{
-  frv_relocate_section_addresses,
-  nullptr,
-  frv_clear_solib,
-  frv_solib_create_inferior_hook,
-  frv_current_sos,
-  nullptr,
-  frv_in_dynsym_resolve_code,
-  solib_bfd_open,
-  nullptr,
-  nullptr,
-  nullptr,
-  nullptr,
-  default_find_solib_addr,
-};
diff --git a/gdb/solib-frv.h b/gdb/solib-frv.h
new file mode 100644 (file)
index 0000000..710a424
--- /dev/null
@@ -0,0 +1,28 @@
+/* Handle FR-V (FDPIC) shared libraries for GDB, the GNU Debugger.
+   Copyright (C) 2024 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   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/>.  */
+
+#ifndef GDB_SOLIB_FRV_H
+#define GDB_SOLIB_FRV_H
+
+#include "solib.h"
+
+/* Return a new solib_ops for FR-V systems.  */
+
+solib_ops_up make_frv_solib_ops ();
+
+#endif /* GDB_SOLIB_FRV_H */
index bda19ac4b82980349d383cbd8b9289e148e6d97e..2d26c3c1c6edabc4ca1f3002d6b2b9b3c8edff0d 100644 (file)
@@ -26,6 +26,7 @@
 #include "event-top.h"
 #include "gdbsupport/fileio.h"
 #include "inferior.h"
+#include "linux-tdep.h"
 #include "observable.h"
 #include "solib.h"
 #include "solib-svr4.h"
@@ -153,7 +154,69 @@ struct solib_info
 /* Per-inferior data key.  */
 static const registry<inferior>::key<solib_info> rocm_solib_data;
 
-static solib_ops rocm_solib_ops;
+/* solib_ops for ROCm systems.  */
+
+struct rocm_solib_ops : public solib_ops
+{
+  /* HOST_OPS is the host solib_ops that rocm_solib_ops hijacks / wraps,
+     in order to provide support for ROCm code objects.  */
+  explicit rocm_solib_ops (solib_ops_up host_ops)
+    : m_host_ops (std::move (host_ops))
+  {
+  }
+
+  /* The methods implemented by rocm_solib_ops.  */
+  owning_intrusive_list<solib> current_sos () const override;
+  void create_inferior_hook (int from_tty) const override;
+  gdb_bfd_ref_ptr bfd_open (const char *pathname) const override;
+  void relocate_section_addresses (solib &so, target_section *) const override;
+  void handle_event () const override;
+
+  /* Implement the following methods just to forward the calls to the host
+     solib_ops.  We currently need to implement all the methods that
+     svr4_solib_ops implements.  */
+  void clear_so (const solib &so) const override
+  { return m_host_ops->clear_so (so); }
+
+  void clear_solib (program_space *pspace) const override
+  { return m_host_ops->clear_solib (pspace); }
+
+  bool open_symbol_file_object (int from_tty) const override
+  { return m_host_ops->open_symbol_file_object (from_tty); }
+
+  bool in_dynsym_resolve_code (CORE_ADDR pc) const override
+  { return m_host_ops->in_dynsym_resolve_code (pc); }
+
+  bool same (const solib &gdb, const solib &inferior) const override
+  { return m_host_ops->same (gdb, inferior); }
+
+  bool keep_data_in_core (CORE_ADDR vaddr, unsigned long size) const override
+  { return m_host_ops->keep_data_in_core (vaddr, size); }
+
+  void update_breakpoints () const override
+  { return m_host_ops->update_breakpoints (); }
+
+  std::optional<CORE_ADDR> find_solib_addr (solib &so) const override
+  { return m_host_ops->find_solib_addr (so); }
+
+  bool supports_namespaces () const override
+  { return true; }
+
+  int find_solib_ns (const solib &so) const override
+  { return m_host_ops->find_solib_ns (so); }
+
+  int num_active_namespaces () const override
+  { return m_host_ops->num_active_namespaces (); }
+
+  std::vector<const solib *> get_solibs_in_ns (int nsid) const override
+  { return m_host_ops->get_solibs_in_ns (nsid); }
+
+private:
+  owning_intrusive_list<solib>
+  solibs_from_rocm_sos (const std::vector<rocm_so> &sos) const;
+
+  solib_ops_up m_host_ops;
+};
 
 /* Fetch the solib_info data for INF.  */
 
@@ -170,13 +233,13 @@ get_solib_info (inferior *inf)
 
 /* Relocate section addresses.  */
 
-static void
-rocm_solib_relocate_section_addresses (solib &so,
-                                      struct target_section *sec)
+void
+rocm_solib_ops::relocate_section_addresses (solib &so,
+                                           struct target_section *sec) const
 {
   if (!is_amdgpu_arch (gdbarch_from_bfd (so.abfd.get ())))
     {
-      svr4_so_ops.relocate_section_addresses (so, sec);
+      m_host_ops->relocate_section_addresses (so, sec);
       return;
     }
 
@@ -187,30 +250,30 @@ rocm_solib_relocate_section_addresses (solib &so,
 
 static void rocm_update_solib_list ();
 
-static void
-rocm_solib_handle_event ()
+void
+rocm_solib_ops::handle_event () const
 {
-  /* Since we sit on top of svr4_so_ops, we might get called following an event
-     concerning host libraries.  We must therefore forward the call.  If the
-     event was for a ROCm code object, it will be a no-op.  On the other hand,
+  /* Since we sit on top of a host solib_ops, we might get called following an
+     event concerning host libraries.  We must therefore forward the call.  If
+     the event was for a ROCm code object, it will be a no-op.  On the other hand
      if the event was for host libraries, rocm_update_solib_list will be
      essentially be a no-op (it will reload the same code object list as was
      previously loaded).  */
-  svr4_so_ops.handle_event ();
+  m_host_ops->handle_event ();
 
   rocm_update_solib_list ();
 }
 
 /* Create solib objects from rocm_so objects in SOS.  */
 
-static owning_intrusive_list<solib>
-solibs_from_rocm_sos (const std::vector<rocm_so> &sos)
+owning_intrusive_list<solib>
+rocm_solib_ops::solibs_from_rocm_sos (const std::vector<rocm_so> &sos) const
 {
   owning_intrusive_list<solib> dst;
 
   for (const rocm_so &so : sos)
     {
-      auto &newobj = dst.emplace_back (rocm_solib_ops);
+      auto &newobj = dst.emplace_back (*this);
 
       newobj.lm_info = std::make_unique<lm_info_svr4> (*so.lm_info);
       newobj.name = so.name;
@@ -223,11 +286,11 @@ solibs_from_rocm_sos (const std::vector<rocm_so> &sos)
 /* Build a list of `struct solib' objects describing the shared
    objects currently loaded in the inferior.  */
 
-static owning_intrusive_list<solib>
-rocm_solib_current_sos ()
+owning_intrusive_list<solib>
+rocm_solib_ops::current_sos () const
 {
   /* First, retrieve the host-side shared library list.  */
-  owning_intrusive_list<solib> sos = svr4_so_ops.current_sos ();
+  owning_intrusive_list<solib> sos = m_host_ops->current_sos ();
 
   /* Then, the device-side shared library list.  */
   std::vector<rocm_so> &dev_sos = get_solib_info (current_inferior ())->solib_list;
@@ -579,12 +642,12 @@ rocm_bfd_iovec_open (bfd *abfd, inferior *inferior)
     }
 }
 
-static gdb_bfd_ref_ptr
-rocm_solib_bfd_open (const char *pathname)
+gdb_bfd_ref_ptr
+rocm_solib_ops::bfd_open (const char *pathname) const
 {
   /* Handle regular files with SVR4 open.  */
   if (strstr (pathname, "://") == nullptr)
-    return svr4_so_ops.bfd_open (pathname);
+    return m_host_ops->bfd_open (pathname);
 
   auto open = [] (bfd *nbfd) -> gdb_bfd_iovec_base *
   {
@@ -668,12 +731,12 @@ rocm_solib_bfd_open (const char *pathname)
   return abfd;
 }
 
-static void
-rocm_solib_create_inferior_hook (int from_tty)
+void
+rocm_solib_ops::create_inferior_hook (int from_tty) const
 {
   get_solib_info (current_inferior ())->solib_list.clear ();
 
-  svr4_so_ops.solib_create_inferior_hook (from_tty);
+  m_host_ops->create_inferior_hook (from_tty);
 }
 
 static void
@@ -736,22 +799,6 @@ rocm_update_solib_list ()
 
       sos.emplace_back (uri_bytes, std::move (unique_name), std::move (li));
     }
-
-  if (rocm_solib_ops.current_sos == NULL)
-    {
-      /* Override what we need to.  */
-      rocm_solib_ops = svr4_so_ops;
-      rocm_solib_ops.current_sos = rocm_solib_current_sos;
-      rocm_solib_ops.solib_create_inferior_hook
-       = rocm_solib_create_inferior_hook;
-      rocm_solib_ops.bfd_open = rocm_solib_bfd_open;
-      rocm_solib_ops.relocate_section_addresses
-       = rocm_solib_relocate_section_addresses;
-      rocm_solib_ops.handle_event = rocm_solib_handle_event;
-
-      /* Engage the ROCm so_ops.  */
-      set_gdbarch_so_ops (current_inferior ()->arch (), &rocm_solib_ops);
-    }
 }
 
 static void
@@ -759,6 +806,10 @@ rocm_solib_target_inferior_created (inferior *inf)
 {
   get_solib_info (inf)->solib_list.clear ();
 
+  auto prev_ops = inf->pspace->release_solib_ops ();
+  auto rocm_ops = std::make_unique<rocm_solib_ops> (std::move (prev_ops));
+  inf->pspace->set_solib_ops (std::move (rocm_ops));
+
   rocm_update_solib_list ();
 
   /* Force GDB to reload the solibs.  */
@@ -766,6 +817,21 @@ rocm_solib_target_inferior_created (inferior *inf)
   solib_add (nullptr, 0, auto_solib_add);
 }
 
+static void
+rocm_solib_target_inferior_execd (inferior *exec_inf, inferior *follow_inf)
+{
+  /* Engage the ROCm so_ops, but only if dbgapi is attached to the inferior
+     (avoiding remote inferiors and core file debugging).  */
+  if (get_amd_dbgapi_process_id (follow_inf) == AMD_DBGAPI_PROCESS_NONE)
+    return;
+
+  auto prev_ops = follow_inf->pspace->release_solib_ops ();
+  auto rocm_ops = std::make_unique<rocm_solib_ops> (std::move (prev_ops));
+  follow_inf->pspace->set_solib_ops (std::move (rocm_ops));
+
+  get_solib_info (exec_inf)->solib_list.clear ();
+}
+
 INIT_GDB_FILE (rocm_solib)
 {
   /* The dependency on the amd-dbgapi exists because solib-rocm's
@@ -775,4 +841,8 @@ INIT_GDB_FILE (rocm_solib)
     (rocm_solib_target_inferior_created,
      "solib-rocm",
      { &get_amd_dbgapi_target_inferior_created_observer_token () });
+
+  gdb::observers::inferior_execd.attach
+    (rocm_solib_target_inferior_execd, "solib-rocm",
+     { &get_amd_dbgapi_target_inferior_execd_observer_token () });
 }
diff --git a/gdb/solib-svr4-linux.c b/gdb/solib-svr4-linux.c
new file mode 100644 (file)
index 0000000..fd86cf0
--- /dev/null
@@ -0,0 +1,98 @@
+/* Target-dependent code for GNU/Linux using SVR4-style libraries.
+
+   Copyright (C) 2025 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   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/>.  */
+
+#include "solib-svr4-linux.h"
+
+/* See solib-svr4-linux.h.  */
+
+solib_ops_up
+make_linux_ilp32_svr4_solib_ops ()
+{
+  return std::make_unique<linux_ilp32_svr4_solib_ops> ();
+}
+
+/* See solib-svr4-linux.h.  */
+
+link_map_offsets *
+linux_ilp32_svr4_solib_ops::fetch_link_map_offsets () const
+{
+  static link_map_offsets lmo;
+  static link_map_offsets *lmp = nullptr;
+
+  if (lmp == nullptr)
+    {
+      lmp = &lmo;
+
+      lmo.r_version_offset = 0;
+      lmo.r_version_size = 4;
+      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;
+      lmo.l_addr_offset = 0;
+      lmo.l_name_offset = 4;
+      lmo.l_ld_offset = 8;
+      lmo.l_next_offset = 12;
+      lmo.l_prev_offset = 16;
+    }
+
+  return lmp;
+}
+
+/* See solib-svr4-linux.h.  */
+
+solib_ops_up
+make_linux_lp64_svr4_solib_ops ()
+{
+  return std::make_unique<linux_lp64_svr4_solib_ops> ();
+}
+
+/* See linux-tdep.h.  */
+
+link_map_offsets *
+linux_lp64_svr4_solib_ops::fetch_link_map_offsets () const
+{
+  static link_map_offsets lmo;
+  static link_map_offsets *lmp = nullptr;
+
+  if (lmp == nullptr)
+    {
+      lmp = &lmo;
+
+      lmo.r_version_offset = 0;
+      lmo.r_version_size = 4;
+      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;
+      lmo.l_addr_offset = 0;
+      lmo.l_name_offset = 8;
+      lmo.l_ld_offset = 16;
+      lmo.l_next_offset = 24;
+      lmo.l_prev_offset = 32;
+    }
+
+  return lmp;
+}
diff --git a/gdb/solib-svr4-linux.h b/gdb/solib-svr4-linux.h
new file mode 100644 (file)
index 0000000..623013c
--- /dev/null
@@ -0,0 +1,47 @@
+/* Target-dependent code for GNU/Linux using SVR4-style libraries.
+
+   Copyright (C) 2025 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   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/>.  */
+
+#ifndef GDB_SOLIB_SVR4_LINUX_H
+#define GDB_SOLIB_SVR4_LINUX_H
+
+#include "solib-svr4.h"
+
+/* solib_ops for ILP32 Linux systems.  */
+
+struct linux_ilp32_svr4_solib_ops : public svr4_solib_ops
+{
+  link_map_offsets *fetch_link_map_offsets () const override;
+};
+
+/* solib_ops for LP64 Linux systems.  */
+
+struct linux_lp64_svr4_solib_ops : public svr4_solib_ops
+{
+  link_map_offsets *fetch_link_map_offsets () const override;
+};
+
+/* Return a new solib_ops for ILP32 Linux systems.  */
+
+extern solib_ops_up make_linux_ilp32_svr4_solib_ops ();
+
+/* Return a new solib_ops for LP64 Linux systems.  */
+
+extern solib_ops_up make_linux_lp64_svr4_solib_ops ();
+
+#endif /* GDB_SOLIB_SVR4_LINUX_H */
index b5945f5ac82ca54da34b862c185a6af524f19df2..9b4cabfd5f4b99a6e444bbfcb768819549d74488 100644 (file)
@@ -47,7 +47,6 @@
 
 #include <map>
 
-static struct link_map_offsets *svr4_fetch_link_map_offsets (void);
 static void svr4_relocate_main_executable (void);
 static void probes_table_remove_objfile_probes (struct objfile *objfile);
 static void svr4_iterate_over_objfiles_in_search_order
@@ -89,27 +88,6 @@ static const  char * const main_name_list[] =
   NULL
 };
 
-/* What to do when a probe stop occurs.  */
-
-enum probe_action
-{
-  /* Something went seriously wrong.  Stop using probes and
-     revert to using the older interface.  */
-  PROBES_INTERFACE_FAILED,
-
-  /* No action is required.  The shared object list is still
-     valid.  */
-  DO_NOTHING,
-
-  /* The shared object list should be reloaded entirely.  */
-  FULL_RELOAD,
-
-  /* Attempt to incrementally update the shared object list. If
-     the update fails or is not possible, fall back to reloading
-     the list in full.  */
-  UPDATE_OR_RELOAD,
-};
-
 /* A probe's name and its associated action.  */
 
 struct probe_info
@@ -184,8 +162,8 @@ svr4_same (const char *gdb_name, const char *inferior_name,
   return gdb_lm_info.l_addr_inferior == inferior_lm_info.l_addr_inferior;
 }
 
-static int
-svr4_same (const solib &gdb, const solib &inferior)
+bool
+svr4_solib_ops::same (const solib &gdb, const solib &inferior) const
 {
   auto *lmg
     = gdb::checked_static_cast<const lm_info_svr4 *> (gdb.lm_info.get ());
@@ -196,10 +174,10 @@ svr4_same (const solib &gdb, const solib &inferior)
                    inferior.original_name.c_str (), *lmg, *lmi);
 }
 
-static lm_info_svr4_up
-lm_info_read (CORE_ADDR lm_addr)
+lm_info_svr4_up
+svr4_solib_ops::read_lm_info (CORE_ADDR lm_addr) const
 {
-  struct link_map_offsets *lmo = svr4_fetch_link_map_offsets ();
+  link_map_offsets *lmo = this->fetch_link_map_offsets ();
   lm_info_svr4_up lm_info;
 
   gdb::byte_vector lm (lmo->link_map_size);
@@ -229,16 +207,16 @@ lm_info_read (CORE_ADDR lm_addr)
   return lm_info;
 }
 
-static int
-has_lm_dynamic_from_link_map (void)
+int
+svr4_solib_ops::has_lm_dynamic_from_link_map () const
 {
-  struct link_map_offsets *lmo = svr4_fetch_link_map_offsets ();
+  link_map_offsets *lmo = this->fetch_link_map_offsets ();
 
   return lmo->l_ld_offset >= 0;
 }
 
-static CORE_ADDR
-lm_addr_check (const solib &so, bfd *abfd)
+CORE_ADDR
+svr4_solib_ops::lm_addr_check (const solib &so, bfd *abfd) const
 {
   auto *li = gdb::checked_static_cast<lm_info_svr4 *> (so.lm_info.get ());
 
@@ -249,7 +227,7 @@ lm_addr_check (const solib &so, bfd *abfd)
 
       l_addr = li->l_addr_inferior;
 
-      if (! abfd || ! has_lm_dynamic_from_link_map ())
+      if (!abfd || !this->has_lm_dynamic_from_link_map ())
        goto set_addr;
 
       l_dynaddr = li->l_ld;
@@ -475,8 +453,8 @@ svr4_is_default_namespace (const svr4_info *info, CORE_ADDR debug_base)
 
 /* Free the probes table.  */
 
-static void
-free_probes_table (struct svr4_info *info)
+void
+svr4_solib_ops::free_probes_table (svr4_info *info) const
 {
   info->probes_table.reset (nullptr);
 }
@@ -820,10 +798,10 @@ elf_locate_base (void)
    checking r_version for a known version number, or r_state for
    RT_CONSISTENT.  */
 
-static CORE_ADDR
-solib_svr4_r_map (CORE_ADDR debug_base)
+CORE_ADDR
+svr4_solib_ops::read_r_map (CORE_ADDR debug_base) const
 {
-  struct link_map_offsets *lmo = svr4_fetch_link_map_offsets ();
+  link_map_offsets *lmo = this->fetch_link_map_offsets ();
   type *ptr_type
     = builtin_type (current_inferior ()->arch ())->builtin_data_ptr;
   CORE_ADDR addr = 0;
@@ -843,10 +821,10 @@ solib_svr4_r_map (CORE_ADDR debug_base)
 
 /* Find r_brk from the inferior's debug base.  */
 
-static CORE_ADDR
-solib_svr4_r_brk (struct svr4_info *info)
+CORE_ADDR
+svr4_solib_ops::find_r_brk (svr4_info *info) const
 {
-  struct link_map_offsets *lmo = svr4_fetch_link_map_offsets ();
+  link_map_offsets *lmo = this->fetch_link_map_offsets ();
   type *ptr_type
     = builtin_type (current_inferior ()->arch ())->builtin_data_ptr;
 
@@ -857,10 +835,10 @@ solib_svr4_r_brk (struct svr4_info *info)
 /* Find the link map for the dynamic linker (if it is not in the
    normal list of loaded shared objects).  */
 
-static CORE_ADDR
-solib_svr4_r_ldsomap (struct svr4_info *info)
+CORE_ADDR
+svr4_solib_ops::find_r_ldsomap (svr4_info *info) const
 {
-  struct link_map_offsets *lmo = svr4_fetch_link_map_offsets ();
+  link_map_offsets *lmo = this->fetch_link_map_offsets ();
   type *ptr_type
     = builtin_type (current_inferior ()->arch ())->builtin_data_ptr;
   enum bfd_endian byte_order = type_byte_order (ptr_type);
@@ -888,10 +866,10 @@ solib_svr4_r_ldsomap (struct svr4_info *info)
 
 /* Find the next namespace from the r_next field.  */
 
-static CORE_ADDR
-solib_svr4_r_next (CORE_ADDR debug_base)
+CORE_ADDR
+svr4_solib_ops::read_r_next (CORE_ADDR debug_base) const
 {
-  link_map_offsets *lmo = svr4_fetch_link_map_offsets ();
+  link_map_offsets *lmo = this->fetch_link_map_offsets ();
   type *ptr_type
     = builtin_type (current_inferior ()->arch ())->builtin_data_ptr;
   bfd_endian byte_order = type_byte_order (ptr_type);
@@ -923,8 +901,8 @@ solib_svr4_r_next (CORE_ADDR debug_base)
    memory areas containing the l_name string are saved in the core
    file.  */
 
-static int
-svr4_keep_data_in_core (CORE_ADDR vaddr, unsigned long size)
+bool
+svr4_solib_ops::keep_data_in_core (CORE_ADDR vaddr, unsigned long size) const
 {
   struct svr4_info *info;
   CORE_ADDR ldsomap;
@@ -934,13 +912,13 @@ svr4_keep_data_in_core (CORE_ADDR vaddr, unsigned long size)
 
   info->debug_base = elf_locate_base ();
   if (info->debug_base == 0)
-    return 0;
+    return false;
 
-  ldsomap = solib_svr4_r_ldsomap (info);
+  ldsomap = this->find_r_ldsomap (info);
   if (!ldsomap)
-    return 0;
+    return false;
 
-  std::unique_ptr<lm_info_svr4> li = lm_info_read (ldsomap);
+  std::unique_ptr<lm_info_svr4> li = this->read_lm_info (ldsomap);
   name_lm = li != NULL ? li->l_name : 0;
 
   return (name_lm >= vaddr && name_lm < vaddr + size);
@@ -948,11 +926,11 @@ svr4_keep_data_in_core (CORE_ADDR vaddr, unsigned long size)
 
 /* See solib.h.  */
 
-static int
-open_symbol_file_object (int from_tty)
+bool
+svr4_solib_ops::open_symbol_file_object (int from_tty) const
 {
   CORE_ADDR lm, l_name;
-  struct link_map_offsets *lmo = svr4_fetch_link_map_offsets ();
+  link_map_offsets *lmo = this->fetch_link_map_offsets ();
   type *ptr_type
     = builtin_type (current_inferior ()->arch ())->builtin_data_ptr;
   int l_name_size = ptr_type->length ();
@@ -965,17 +943,17 @@ open_symbol_file_object (int from_tty)
 
   if (current_program_space->symfile_object_file)
     if (!query (_("Attempt to reload symbols from process? ")))
-      return 0;
+      return false;
 
   /* Always locate the debug struct, in case it has moved.  */
   info->debug_base = elf_locate_base ();
   if (info->debug_base == 0)
-    return 0;  /* failed somehow...  */
+    return false;      /* failed somehow...  */
 
   /* First link map member should be the executable.  */
-  lm = solib_svr4_r_map (info->debug_base);
+  lm = this->read_r_map (info->debug_base);
   if (lm == 0)
-    return 0;  /* failed somehow...  */
+    return false;      /* failed somehow...  */
 
   /* Read address of name from target memory to GDB.  */
   read_memory (lm + lmo->l_name_offset, l_name_buf.data (), l_name_size);
@@ -984,7 +962,7 @@ open_symbol_file_object (int from_tty)
   l_name = extract_typed_address (l_name_buf.data (), ptr_type);
 
   if (l_name == 0)
-    return 0;          /* No filename.  */
+    return false;              /* No filename.  */
 
   /* Now fetch the filename from target memory.  */
   gdb::unique_xmalloc_ptr<char> filename
@@ -993,13 +971,13 @@ open_symbol_file_object (int from_tty)
   if (filename == nullptr)
     {
       warning (_("failed to read exec filename from attached file"));
-      return 0;
+      return false;
     }
 
   /* Have a pathname: read the symbol file.  */
   symbol_file_add_main (filename.get (), add_flags);
 
-  return 1;
+  return true;
 }
 
 /* Data exchange structure for the XML parser as returned by
@@ -1032,8 +1010,8 @@ svr4_free_objfile_observer (struct objfile *objfile)
 
 /* Implement solib_ops.clear_so.  */
 
-static void
-svr4_clear_so (const solib &so)
+void
+svr4_solib_ops::clear_so (const solib &so) const
 {
   auto *li = gdb::checked_static_cast<lm_info_svr4 *> (so.lm_info.get ());
 
@@ -1043,14 +1021,14 @@ svr4_clear_so (const solib &so)
 
 /* Create the solib objects equivalent to the svr4_sos in SOS.  */
 
-static owning_intrusive_list<solib>
-solib_from_svr4_sos (const std::vector<svr4_so> &sos)
+owning_intrusive_list<solib>
+svr4_solib_ops::solibs_from_svr4_sos (const std::vector<svr4_so> &sos) const
 {
   owning_intrusive_list<solib> dst;
 
   for (const svr4_so &so : sos)
     {
-      auto &newobj = dst.emplace_back (svr4_so_ops);
+      auto &newobj = dst.emplace_back (*this);
 
       newobj.name = so.name;
       newobj.original_name = so.name;
@@ -1237,8 +1215,8 @@ svr4_current_sos_via_xfer_libraries (struct svr4_library_list *list,
 /* If no shared library information is available from the dynamic
    linker, build a fallback list from other sources.  */
 
-static owning_intrusive_list<solib>
-svr4_default_sos (svr4_info *info)
+owning_intrusive_list<solib>
+svr4_solib_ops::default_sos (svr4_info *info) const
 {
   if (!info->debug_loader_offset_p)
     return {};
@@ -1250,7 +1228,7 @@ svr4_default_sos (svr4_info *info)
   li->l_addr_p = 1;
 
   owning_intrusive_list<solib> sos;
-  auto &newobj = sos.emplace_back (svr4_so_ops);
+  auto &newobj = sos.emplace_back (*this);
 
   newobj.lm_info = std::move (li);
   newobj.name = info->debug_loader_name;
@@ -1266,16 +1244,16 @@ svr4_default_sos (svr4_info *info)
    is returned the entries stored to LINK_PTR_PTR are still valid although they may
    represent only part of the inferior library list.  */
 
-static int
-svr4_read_so_list (svr4_info *info, CORE_ADDR lm, CORE_ADDR prev_lm,
-                  std::vector<svr4_so> &sos, int ignore_first)
+int
+svr4_solib_ops::read_so_list (svr4_info *info, CORE_ADDR lm, CORE_ADDR prev_lm,
+                             std::vector<svr4_so> &sos, int ignore_first) const
 {
   CORE_ADDR first_l_name = 0;
   CORE_ADDR next_lm;
 
   for (; lm != 0; prev_lm = lm, lm = next_lm)
     {
-      lm_info_svr4_up li = lm_info_read (lm);
+      lm_info_svr4_up li = this->read_lm_info (lm);
       if (li == NULL)
        return 0;
 
@@ -1331,8 +1309,8 @@ svr4_read_so_list (svr4_info *info, CORE_ADDR lm, CORE_ADDR prev_lm,
    stored by the probes interface.  Handle special cases relating
    to the first elements of the list in default namespace.  */
 
-static void
-svr4_current_sos_direct (struct svr4_info *info)
+void
+svr4_solib_ops::current_sos_direct (svr4_info *info) const
 {
   CORE_ADDR lm;
   bool ignore_first;
@@ -1398,15 +1376,15 @@ svr4_current_sos_direct (struct svr4_info *info)
   /* 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))
+       ignore_first = false, debug_base = this->read_r_next (debug_base))
     {
       /* Walk the inferior's link map list, and build our so_list list.  */
-      lm = solib_svr4_r_map (debug_base);
+      lm = this->read_r_map (debug_base);
       if (lm != 0)
        {
          svr4_maybe_add_namespace (info, debug_base);
-         svr4_read_so_list (info, lm, 0, info->solib_lists[debug_base],
-                            ignore_first);
+         this->read_so_list (info, lm, 0, info->solib_lists[debug_base],
+                             ignore_first);
        }
     }
 
@@ -1419,15 +1397,15 @@ svr4_current_sos_direct (struct svr4_info *info)
      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);
+  debug_base = this->find_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 ())
        {
          svr4_maybe_add_namespace (info, debug_base);
-         svr4_read_so_list (info, debug_base, 0, info->solib_lists[debug_base],
-                            0);
+         this->read_so_list (info, debug_base, 0,
+                             info->solib_lists[debug_base], 0);
        }
     }
 
@@ -1436,15 +1414,15 @@ svr4_current_sos_direct (struct svr4_info *info)
 
 /* Collect sos read and stored by the probes interface.  */
 
-static owning_intrusive_list<solib>
-svr4_collect_probes_sos (svr4_info *info)
+owning_intrusive_list<solib>
+svr4_solib_ops::collect_probes_sos (svr4_info *info) const
 {
   owning_intrusive_list<solib> res;
 
   for (const auto &tuple : info->solib_lists)
     {
       const std::vector<svr4_so> &sos = tuple.second;
-      res.splice (solib_from_svr4_sos (sos));
+      res.splice (this->solibs_from_svr4_sos (sos));
     }
 
   return res;
@@ -1453,26 +1431,26 @@ svr4_collect_probes_sos (svr4_info *info)
 /* Implement the main part of the "current_sos" solib_ops
    method.  */
 
-static owning_intrusive_list<solib>
-svr4_current_sos_1 (svr4_info *info)
+owning_intrusive_list<solib>
+svr4_solib_ops::current_sos_1 (svr4_info *info) const
 {
   owning_intrusive_list<solib> sos;
 
   /* 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);
+    sos = this->collect_probes_sos (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.empty ())
     {
-      svr4_current_sos_direct (info);
+      this->current_sos_direct (info);
 
-      sos = svr4_collect_probes_sos (info);
+      sos = this->collect_probes_sos (info);
       if (sos.empty ())
-       sos = svr4_default_sos (info);
+       sos = this->default_sos (info);
     }
 
   return sos;
@@ -1480,11 +1458,11 @@ svr4_current_sos_1 (svr4_info *info)
 
 /* Implement the "current_sos" solib_ops method.  */
 
-static owning_intrusive_list<solib>
-svr4_current_sos ()
+owning_intrusive_list<solib>
+svr4_solib_ops::current_sos () const
 {
   svr4_info *info = get_svr4_info (current_program_space);
-  owning_intrusive_list<solib> sos = svr4_current_sos_1 (info);
+  owning_intrusive_list<solib> sos = this->current_sos_1 (info);
   struct mem_range vsyscall_range;
 
   /* Filter out the vDSO module, if present.  Its symbol file would
@@ -1731,7 +1709,11 @@ tls_maybe_fill_slot (solib &so)
     {
       /* Cause svr4_current_sos() to be run if it hasn't been already.  */
       if (info->main_lm_addr == 0)
-       svr4_current_sos_direct (info);
+       {
+         auto &ops
+           = gdb::checked_static_cast<const svr4_solib_ops &> (so.ops ());
+         ops.current_sos_direct (info);
+       }
 
       /* Quit early when main_lm_addr is still 0.  */
       if (info->main_lm_addr == 0)
@@ -1802,7 +1784,7 @@ match_main (const char *soname)
    SVR4 run time loader.  */
 
 bool
-svr4_in_dynsym_resolve_code (CORE_ADDR pc)
+svr4_solib_ops::in_dynsym_resolve_code (CORE_ADDR pc) const
 {
   struct svr4_info *info = get_svr4_info (current_program_space);
 
@@ -2001,12 +1983,10 @@ solib_event_probe_action (struct probe_and_action *pa)
    shared objects from the inferior.  Handle special cases relating
    to the first elements of the list.  Returns nonzero on success.  */
 
-static int
-solist_update_full (struct svr4_info *info)
+void
+svr4_solib_ops::update_full (svr4_info *info) const
 {
-  svr4_current_sos_direct (info);
-
-  return 1;
+  this->current_sos_direct (info);
 }
 
 /* Update the shared object list starting from the link-map entry
@@ -2014,9 +1994,9 @@ solist_update_full (struct svr4_info *info)
    nonzero if the list was successfully updated, or zero to indicate
    failure.  */
 
-static int
-solist_update_incremental (svr4_info *info, CORE_ADDR debug_base,
-                          CORE_ADDR lm)
+int
+svr4_solib_ops::update_incremental (svr4_info *info, CORE_ADDR debug_base,
+                                   CORE_ADDR lm) const
 {
   /* Fall back to a full update if we are using a remote target
      that does not support incremental transfers.  */
@@ -2094,7 +2074,7 @@ solist_update_incremental (svr4_info *info, CORE_ADDR debug_base,
         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, solist, 0))
+      if (!this->read_so_list (info, lm, prev_lm, solist, 0))
        return 0;
     }
 
@@ -2105,8 +2085,8 @@ solist_update_incremental (svr4_info *info, CORE_ADDR debug_base,
    original interface.  We don't reset the breakpoints as the
    ones set up for the probes-based interface are adequate.  */
 
-static void
-disable_probes_interface (svr4_info *info)
+void
+svr4_solib_ops::disable_probes_interface (svr4_info *info) const
 {
   warning (_("Probes-based dynamic linker interface failed.\n"
             "Reverting to original interface."));
@@ -2121,8 +2101,8 @@ disable_probes_interface (svr4_info *info)
    probes-based linker interface.  Do nothing if using the
    standard interface.  */
 
-static void
-svr4_handle_solib_event (void)
+void
+svr4_solib_ops::handle_event () const
 {
   struct svr4_info *info = get_svr4_info (current_program_space);
   struct probe_and_action *pa;
@@ -2147,9 +2127,9 @@ svr4_handle_solib_event (void)
 
   /* If anything goes wrong we revert to the original linker
      interface.  */
-  auto cleanup = make_scope_exit ([info] ()
+  auto cleanup = make_scope_exit ([this, info] ()
     {
-      disable_probes_interface (info);
+      this->disable_probes_interface (info);
     });
 
   action = solib_event_probe_action (pa);
@@ -2251,15 +2231,12 @@ svr4_handle_solib_event (void)
 
   if (action == UPDATE_OR_RELOAD)
     {
-      if (!solist_update_incremental (info, debug_base, lm))
+      if (!this->update_incremental (info, debug_base, lm))
        action = FULL_RELOAD;
     }
 
   if (action == FULL_RELOAD)
-    {
-      if (!solist_update_full (info))
-       return;
-    }
+    this->update_full (info);
 
   cleanup.release ();
 }
@@ -2306,8 +2283,8 @@ svr4_update_solib_event_breakpoint (struct breakpoint *b)
 /* Enable or disable optional solib event breakpoints as appropriate.
    Called whenever stop_on_solib_events is changed.  */
 
-static void
-svr4_update_solib_event_breakpoints (void)
+void
+svr4_solib_ops::update_breakpoints () const
 {
   for (breakpoint &bp : all_breakpoints_safe ())
     svr4_update_solib_event_breakpoint (&bp);
@@ -2318,10 +2295,10 @@ svr4_update_solib_event_breakpoints (void)
    solib event breakpoint will be created and registered for each
    probe.  */
 
-static void
-svr4_create_probe_breakpoints (svr4_info *info, struct gdbarch *gdbarch,
-                              const std::vector<probe *> *probes,
-                              struct objfile *objfile)
+void
+svr4_solib_ops::create_probe_breakpoints (svr4_info *info, gdbarch *gdbarch,
+                                         const std::vector<probe *> *probes,
+                                         objfile *objfile) const
 {
   for (int i = 0; i < NUM_PROBES; i++)
     {
@@ -2339,17 +2316,17 @@ svr4_create_probe_breakpoints (svr4_info *info, struct gdbarch *gdbarch,
        }
     }
 
-  svr4_update_solib_event_breakpoints ();
+  this->update_breakpoints ();
 }
 
 /* Find all the glibc named probes.  Only if all of the probes are found, then
    create them and return true.  Otherwise return false.  If WITH_PREFIX is set
    then add "rtld" to the front of the probe names.  */
-static bool
-svr4_find_and_create_probe_breakpoints (svr4_info *info,
-                                       struct gdbarch *gdbarch,
-                                       struct obj_section *os,
-                                       bool with_prefix)
+bool
+svr4_solib_ops::find_and_create_probe_breakpoints (svr4_info *info,
+                                                  gdbarch *gdbarch,
+                                                  obj_section *os,
+                                                  bool with_prefix) const
 {
   SOLIB_SCOPED_DEBUG_START_END ("objfile=%s, with_prefix=%d",
                                os->objfile->original_name, with_prefix);
@@ -2427,7 +2404,7 @@ svr4_find_and_create_probe_breakpoints (svr4_info *info,
 
   /* All probes found.  Now create them.  */
   solib_debug_printf ("using probes interface");
-  svr4_create_probe_breakpoints (info, gdbarch, probes, os->objfile);
+  this->create_probe_breakpoints (info, gdbarch, probes, os->objfile);
   return true;
 }
 
@@ -2443,15 +2420,16 @@ svr4_find_and_create_probe_breakpoints (svr4_info *info,
    probes aren't found, a single breakpoint is set on the original
    marker function.  */
 
-static void
-svr4_create_solib_event_breakpoints (svr4_info *info, struct gdbarch *gdbarch,
-                                    CORE_ADDR address)
+void
+svr4_solib_ops::create_event_breakpoints (svr4_info *info, gdbarch *gdbarch,
+                                         CORE_ADDR address) const
 {
   struct obj_section *os = find_pc_section (address);
 
   if (os == nullptr
-      || (!svr4_find_and_create_probe_breakpoints (info, gdbarch, os, false)
-         && !svr4_find_and_create_probe_breakpoints (info, gdbarch, os, true)))
+      || (!this->find_and_create_probe_breakpoints (info, gdbarch, os, false)
+         && !this->find_and_create_probe_breakpoints (info, gdbarch, os,
+                                                      true)))
     {
       solib_debug_printf ("falling back to r_brk breakpoint: addr=%s",
                          paddress (gdbarch, address));
@@ -2491,8 +2469,8 @@ svr4_create_solib_event_breakpoints (svr4_info *info, struct gdbarch *gdbarch,
    depending upon whether or not the library is being mapped or unmapped,
    and then set to RT_CONSISTENT after the library is mapped/unmapped.  */
 
-static int
-enable_break (struct svr4_info *info, int from_tty)
+int
+svr4_solib_ops::enable_break (svr4_info *info, int from_tty) const
 {
   const char * const *bkpt_namep;
   asection *interp_sect;
@@ -2508,8 +2486,8 @@ 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->debug_base) != 0)
-    sym_addr = solib_svr4_r_brk (info);
+  if (info->debug_base && this->read_r_map (info->debug_base) != 0)
+    sym_addr = this->find_r_brk (info);
 
   if (sym_addr != 0)
     {
@@ -2568,8 +2546,8 @@ enable_break (struct svr4_info *info, int from_tty)
                = info->interp_plt_sect_low + bfd_section_size (interp_sect);
            }
 
-         svr4_create_solib_event_breakpoints
-           (info, current_inferior ()->arch (), sym_addr);
+         this->create_event_breakpoints (info, current_inferior ()->arch (),
+                                         sym_addr);
          return 1;
        }
     }
@@ -2621,7 +2599,7 @@ enable_break (struct svr4_info *info, int from_tty)
            {
              load_addr_found = 1;
              loader_found_in_list = 1;
-             load_addr = lm_addr_check (so, tmp_bfd.get ());
+             load_addr = this->lm_addr_check (so, tmp_bfd.get ());
              break;
            }
        }
@@ -2728,9 +2706,8 @@ enable_break (struct svr4_info *info, int from_tty)
 
       if (sym_addr != 0)
        {
-         svr4_create_solib_event_breakpoints (info,
-                                              current_inferior ()->arch (),
-                                              load_addr + sym_addr);
+         this->create_event_breakpoints (info, current_inferior ()->arch (),
+                                         load_addr + sym_addr);
          return 1;
        }
 
@@ -2757,9 +2734,8 @@ enable_break (struct svr4_info *info, int from_tty)
          sym_addr = gdbarch_convert_from_func_ptr_addr
            (current_inferior ()->arch (), sym_addr,
             current_inferior ()->top_target ());
-         svr4_create_solib_event_breakpoints (info,
-                                              current_inferior ()->arch (),
-                                              sym_addr);
+         this->create_event_breakpoints (info, current_inferior ()->arch (),
+                                         sym_addr);
          return 1;
        }
     }
@@ -2777,8 +2753,9 @@ enable_break (struct svr4_info *info, int from_tty)
              sym_addr = gdbarch_convert_from_func_ptr_addr
                (current_inferior ()->arch (), sym_addr,
                 current_inferior ()->top_target ());
-             svr4_create_solib_event_breakpoints
-               (info, current_inferior ()->arch (), sym_addr);
+             this->create_event_breakpoints (info,
+                                             current_inferior ()->arch (),
+                                             sym_addr);
              return 1;
            }
        }
@@ -3302,15 +3279,15 @@ svr4_relocate_main_executable (void)
    addresses, and saving sufficient information about them to allow
    their symbols to be read at a later time.  */
 
-static void
-svr4_solib_create_inferior_hook (int from_tty)
+void
+svr4_solib_ops::create_inferior_hook (int from_tty) const
 {
   struct svr4_info *info;
 
   info = get_svr4_info (current_program_space);
 
   /* Clear the probes-based interface's state.  */
-  free_probes_table (info);
+  this->free_probes_table (info);
   info->solib_lists.clear ();
   info->namespace_id.clear ();
   info->active_namespaces.clear ();
@@ -3323,12 +3300,12 @@ svr4_solib_create_inferior_hook (int from_tty)
   if (!target_has_execution ())
     return;
 
-  if (!enable_break (info, from_tty))
+  if (!this->enable_break (info, from_tty))
     return;
 }
 
-static void
-svr4_clear_solib (program_space *pspace)
+void
+svr4_solib_ops::clear_solib (program_space *pspace) const
 {
   svr4_info *info = get_svr4_info (pspace);
   info->debug_base = 0;
@@ -3391,15 +3368,15 @@ find_loadable_elf_internal_phdr (bfd *abfd, bfd_section *asect)
   return nullptr;
 }
 
-/* Implement solib_ops::relocate_section_addresses() for svr4 targets.  */
-
-static void
-svr4_relocate_section_addresses (solib &so, target_section *sec)
+void
+svr4_solib_ops::relocate_section_addresses (solib &so,
+                                           target_section *sec) const
 {
   bfd *abfd = sec->the_bfd_section->owner;
 
-  sec->addr = svr4_truncate_ptr (sec->addr + lm_addr_check (so, abfd));
-  sec->endaddr = svr4_truncate_ptr (sec->endaddr + lm_addr_check (so, abfd));
+  sec->addr = svr4_truncate_ptr (sec->addr + this->lm_addr_check (so, abfd));
+  sec->endaddr
+    = svr4_truncate_ptr (sec->endaddr + this->lm_addr_check (so, abfd));
 
   struct bfd_section *asect = sec->the_bfd_section;
   gdb_assert (asect != nullptr);
@@ -3469,56 +3446,23 @@ svr4_relocate_section_addresses (solib &so, target_section *sec)
        }
     }
 }
-\f
-
-/* Architecture-specific operations.  */
-
-struct solib_svr4_ops
-{
-  /* Return a description of the layout of `struct link_map'.  */
-  struct link_map_offsets *(*fetch_link_map_offsets)(void) = nullptr;
-};
-
-/* Per-architecture data key.  */
-static const registry<gdbarch>::key<struct solib_svr4_ops> solib_svr4_data;
 
-/* Return a default for the architecture-specific operations.  */
-
-static struct solib_svr4_ops *
-get_ops (struct gdbarch *gdbarch)
-{
-  struct solib_svr4_ops *ops = solib_svr4_data.get (gdbarch);
-  if (ops == nullptr)
-    ops = solib_svr4_data.emplace (gdbarch);
-  return ops;
-}
-
-/* Set the architecture-specific `struct link_map_offsets' fetcher for
-   GDBARCH to FLMO.  Also, install SVR4 solib_ops into GDBARCH.  */
+/* See solib-svr4.h.  */
 
 void
-set_solib_svr4_fetch_link_map_offsets (struct gdbarch *gdbarch,
-                                      struct link_map_offsets *(*flmo) (void))
+set_solib_svr4_ops (gdbarch *gdbarch, gdbarch_make_solib_ops_ftype make_solib_ops)
 {
-  struct solib_svr4_ops *ops = get_ops (gdbarch);
-
-  ops->fetch_link_map_offsets = flmo;
-
-  set_gdbarch_so_ops (gdbarch, &svr4_so_ops);
+  set_gdbarch_make_solib_ops (gdbarch, make_solib_ops);
   set_gdbarch_iterate_over_objfiles_in_search_order
     (gdbarch, svr4_iterate_over_objfiles_in_search_order);
 }
 
-/* Fetch a link_map_offsets structure using the architecture-specific
-   `struct link_map_offsets' fetcher.  */
+/* See solib-svr4.h.  */
 
-static struct link_map_offsets *
-svr4_fetch_link_map_offsets (void)
+solib_ops_up
+make_svr4_ilp32_solib_ops ()
 {
-  struct solib_svr4_ops *ops = get_ops (current_inferior ()->arch ());
-
-  gdb_assert (ops->fetch_link_map_offsets);
-  return ops->fetch_link_map_offsets ();
+  return std::make_unique<ilp32_svr4_solib_ops> ();
 }
 
 /* Most OS'es that have SVR4-style ELF dynamic libraries define a
@@ -3528,8 +3472,8 @@ svr4_fetch_link_map_offsets (void)
 /* Fetch (and possibly build) an appropriate `struct link_map_offsets'
    for an ILP32 SVR4 system.  */
 
-struct link_map_offsets *
-svr4_ilp32_fetch_link_map_offsets (void)
+link_map_offsets *
+ilp32_svr4_solib_ops::fetch_link_map_offsets () const
 {
   static struct link_map_offsets lmo;
   static struct link_map_offsets *lmp = NULL;
@@ -3557,11 +3501,26 @@ svr4_ilp32_fetch_link_map_offsets (void)
   return lmp;
 }
 
+/* solib_ops for LP64 SVR4 systems.  */
+
+struct lp64_svr4_solib_ops : public svr4_solib_ops
+{
+  link_map_offsets *fetch_link_map_offsets () const override;
+};
+
+/* See solib-svr4.h.  */
+
+solib_ops_up
+make_svr4_lp64_solib_ops ()
+{
+  return std::make_unique<lp64_svr4_solib_ops> ();
+}
+
 /* Fetch (and possibly build) an appropriate `struct link_map_offsets'
    for an LP64 SVR4 system.  */
 
-struct link_map_offsets *
-svr4_lp64_fetch_link_map_offsets (void)
+link_map_offsets *
+lp64_svr4_solib_ops::fetch_link_map_offsets () const
 {
   static struct link_map_offsets lmo;
   static struct link_map_offsets *lmp = NULL;
@@ -3708,19 +3667,15 @@ svr4_iterate_over_objfiles_in_search_order
     }
 }
 
-/* See solib_ops::find_solib_addr in solist.h.  */
-
-static std::optional<CORE_ADDR>
-svr4_find_solib_addr (solib &so)
+std::optional<CORE_ADDR>
+svr4_solib_ops::find_solib_addr (solib &so) const
 {
   auto *li = gdb::checked_static_cast<lm_info_svr4 *> (so.lm_info.get ());
   return li->l_addr_inferior;
 }
 
-/* See solib_ops::find_solib_ns in solist.h.  */
-
-static int
-svr4_find_solib_ns (const solib &so)
+int
+svr4_solib_ops::find_solib_ns (const solib &so) const
 {
   CORE_ADDR debug_base = find_debug_base_for_solib (&so);
   svr4_info *info = get_svr4_info (current_program_space);
@@ -3735,17 +3690,15 @@ svr4_find_solib_ns (const solib &so)
   error (_("No namespace found"));
 }
 
-/* see solib_ops::num_active_namespaces in solist.h.  */
-static int
-svr4_num_active_namespaces ()
+int
+svr4_solib_ops::num_active_namespaces () const
 {
   svr4_info *info = get_svr4_info (current_program_space);
   return info->active_namespaces.size ();
 }
 
-/* See solib_ops::get_solibs_in_ns in solist.h.  */
-static std::vector<const solib *>
-svr4_get_solibs_in_ns (int nsid)
+std::vector<const solib *>
+svr4_solib_ops::get_solibs_in_ns (int nsid) const
 {
   std::vector<const solib*> ns_solibs;
   svr4_info *info = get_svr4_info (current_program_space);
@@ -3791,26 +3744,6 @@ svr4_get_solibs_in_ns (int nsid)
   return ns_solibs;
 }
 
-const struct solib_ops svr4_so_ops =
-{
-  svr4_relocate_section_addresses,
-  svr4_clear_so,
-  svr4_clear_solib,
-  svr4_solib_create_inferior_hook,
-  svr4_current_sos,
-  open_symbol_file_object,
-  svr4_in_dynsym_resolve_code,
-  solib_bfd_open,
-  svr4_same,
-  svr4_keep_data_in_core,
-  svr4_update_solib_event_breakpoints,
-  svr4_handle_solib_event,
-  svr4_find_solib_addr,
-  svr4_find_solib_ns,
-  svr4_num_active_namespaces,
-  svr4_get_solibs_in_ns,
-};
-
 INIT_GDB_FILE (svr4_solib)
 {
   gdb::observers::free_objfile.attach (svr4_free_objfile_observer,
index 1ff9be78a43d993584c18cce7aa9733bf32be2ae..b331fa7a32b629673b883f9d25582926ca31f2c6 100644 (file)
 #ifndef GDB_SOLIB_SVR4_H
 #define GDB_SOLIB_SVR4_H
 
+#include "gdbarch.h"
 #include "solib.h"
 
 struct objfile;
-struct solib_ops;
-
-extern const solib_ops svr4_so_ops;
+struct link_map_offsets;
+struct probe_and_action;
+struct svr4_info;
+struct svr4_library_list;
+struct svr4_so;
 
 /* Link map info to include in an allocated solib entry.  */
 
@@ -50,6 +53,101 @@ struct lm_info_svr4 final : public lm_info
 
 using lm_info_svr4_up = std::unique_ptr<lm_info_svr4>;
 
+/* What to do when a probe stop occurs.  */
+
+enum probe_action
+{
+  /* Something went seriously wrong.  Stop using probes and
+     revert to using the older interface.  */
+  PROBES_INTERFACE_FAILED,
+
+  /* No action is required.  The shared object list is still
+     valid.  */
+  DO_NOTHING,
+
+  /* The shared object list should be reloaded entirely.  */
+  FULL_RELOAD,
+
+  /* Attempt to incrementally update the shared object list. If
+     the update fails or is not possible, fall back to reloading
+     the list in full.  */
+  UPDATE_OR_RELOAD,
+};
+
+/* solib_ops for SVR4 systems.  */
+
+struct svr4_solib_ops : public solib_ops
+{
+  void relocate_section_addresses (solib &so, target_section *) const override;
+  void clear_so (const solib &so) const override;
+  void clear_solib (program_space *pspace) const override;
+  void create_inferior_hook (int from_tty) const override;
+  owning_intrusive_list<solib> current_sos () const override;
+  bool open_symbol_file_object (int from_tty) const override;
+  bool in_dynsym_resolve_code (CORE_ADDR pc) const override;
+  bool same (const solib &gdb, const solib &inferior) const override;
+  bool keep_data_in_core (CORE_ADDR vaddr, unsigned long size) const override;
+  void update_breakpoints () const override;
+  void handle_event () const override;
+  std::optional<CORE_ADDR> find_solib_addr (solib &so) const override;
+  bool supports_namespaces () const override { return true; }
+  int find_solib_ns (const solib &so) const override;
+  int num_active_namespaces () const override;
+  std::vector<const solib *> get_solibs_in_ns (int nsid) const override;
+
+  /* Return the appropriate link map offsets table for the architecture.  */
+  virtual link_map_offsets *fetch_link_map_offsets () const = 0;
+
+  /* This needs to be public because it's accessed from an observer.  */
+  void current_sos_direct (svr4_info *info) const;
+
+private:
+  void create_probe_breakpoints (svr4_info *info, gdbarch *gdbarch,
+                                const std::vector<probe *> *probes,
+                                objfile *objfile) const;
+  bool find_and_create_probe_breakpoints (svr4_info *info, gdbarch *gdbarch,
+                                         obj_section *os,
+                                         bool with_prefix) const;
+  void create_event_breakpoints (svr4_info *info, gdbarch *gdbarch,
+                                CORE_ADDR address) const;
+  int enable_break (svr4_info *info, int from_tty) const;
+  bool is_default_namespace (CORE_ADDR debug_base) const;
+  void free_probes_table (svr4_info *info) const;
+  CORE_ADDR find_r_brk (svr4_info *info) const;
+  CORE_ADDR find_r_ldsomap (svr4_info *info) const;
+  owning_intrusive_list<solib> default_sos (svr4_info *info) const;
+  int read_so_list (svr4_info *info, CORE_ADDR lm, CORE_ADDR prev_lm,
+                   std::vector<svr4_so> &sos, int ignore_first) const;
+  lm_info_svr4_up read_lm_info (CORE_ADDR lm_addr) const;
+  int has_lm_dynamic_from_link_map () const;
+  CORE_ADDR lm_addr_check (const solib &so, bfd *abfd) const;
+  CORE_ADDR read_r_next (CORE_ADDR debug_base) const;
+  CORE_ADDR read_r_map (CORE_ADDR debug_base) const;
+  int parse_libraries (const char *document, svr4_library_list *list);
+  int current_sos_via_xfer_libraries (svr4_library_list *list,
+                                     const char *annex) const;
+  owning_intrusive_list<solib> collect_probes_sos (svr4_info *info) const;
+  owning_intrusive_list<solib> current_sos_1 (svr4_info *info) const;
+  owning_intrusive_list<solib> solibs_from_svr4_sos
+    (const std::vector<svr4_so> &sos) const;
+  void register_event_probe (objfile *objfile, probe *prob, CORE_ADDR address,
+                            enum probe_action action) const;
+  void disable_probes_interface (svr4_info *info) const;
+  probe_and_action *event_probe_at (CORE_ADDR address) const;
+  void update_full (svr4_info *info) const;
+  int update_incremental (svr4_info *info, CORE_ADDR debug_base,
+                         CORE_ADDR lm) const;
+  bool update_event_breakpoint (breakpoint *b) const;
+  CORE_ADDR find_debug_base (const solib *solib) const;
+};
+
+/* solib_ops for ILP32 SVR4 systems.  */
+
+struct ilp32_svr4_solib_ops : public svr4_solib_ops
+{
+  link_map_offsets *fetch_link_map_offsets () const override;
+};
+
 /* Critical offsets and sizes which describe struct r_debug and
    struct link_map on SVR4-like targets.  All offsets and sizes are
    in bytes unless otherwise specified.  */
@@ -91,26 +189,22 @@ struct link_map_offsets
     int l_name_offset;
   };
 
-/* set_solib_svr4_fetch_link_map_offsets() is intended to be called by
-   a <arch>_gdbarch_init() function.  It is used to establish an
-   architecture specific link_map_offsets fetcher for the architecture
-   being defined.  */
+/* Set the gdbarch methods for SVR4 systems.  */
 
-extern void set_solib_svr4_fetch_link_map_offsets
-  (struct gdbarch *gdbarch, struct link_map_offsets *(*func) (void));
+extern void set_solib_svr4_ops (gdbarch *gdbarch,
+                               gdbarch_make_solib_ops_ftype make_solib_ops);
 
 /* This function is called by thread_db.c.  Return the address of the
    link map for the given objfile.  */
 extern CORE_ADDR svr4_fetch_objfile_link_map (struct objfile *objfile);
 
-/* Fetch (and possibly build) an appropriate `struct link_map_offsets'
-   for ILP32 and LP64 SVR4 systems.  */
-extern struct link_map_offsets *svr4_ilp32_fetch_link_map_offsets (void);
-extern struct link_map_offsets *svr4_lp64_fetch_link_map_offsets (void);
+/* Return a new solib_ops for ILP32 SVR4 systems.  */
+
+extern solib_ops_up make_svr4_ilp32_solib_ops ();
+
+/* Return a new solib_ops for LP64 SVR4 systems.  */
 
-/* Return true if PC lies in the dynamic symbol resolution code of the
-   SVR4 run time loader.  */
-bool svr4_in_dynsym_resolve_code (CORE_ADDR pc);
+extern solib_ops_up make_svr4_lp64_solib_ops ();
 
 /* For the MUSL C library, given link map address LM_ADDR, return the
    corresponding TLS module id, or 0 if not found.  */
index 61b841928ff8a6070512a2e5de67bd83b67c8aa5..4f0c0ec3b68d5abdc40366537e93cfd8dd88950c 100644 (file)
@@ -209,6 +209,14 @@ static const struct gdb_xml_element library_list_elements[] = {
   { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
 };
 
+/* See solib-target.h.  */
+
+solib_ops_up
+make_target_solib_ops ()
+{
+  return std::make_unique<target_solib_ops> ();
+}
+
 static std::vector<lm_info_target_up>
 solib_target_parse_libraries (const char *library)
 {
@@ -226,8 +234,8 @@ solib_target_parse_libraries (const char *library)
 }
 #endif
 
-static owning_intrusive_list<solib>
-solib_target_current_sos (void)
+owning_intrusive_list<solib>
+target_solib_ops::current_sos () const
 {
   owning_intrusive_list<solib> sos;
 
@@ -245,7 +253,7 @@ solib_target_current_sos (void)
   /* Build a struct solib for each entry on the list.  */
   for (lm_info_target_up &info : library_list)
     {
-      auto &new_solib = sos.emplace_back (solib_target_so_ops);
+      auto &new_solib = sos.emplace_back (*this);
 
       /* We don't need a copy of the name in INFO anymore.  */
       new_solib.name = std::move (info->name);
@@ -256,8 +264,9 @@ solib_target_current_sos (void)
   return sos;
 }
 
-static void
-solib_target_relocate_section_addresses (solib &so, target_section *sec)
+void
+target_solib_ops::relocate_section_addresses (solib &so,
+                                             target_section *sec) const
 {
   CORE_ADDR offset;
   auto *li = gdb::checked_static_cast<lm_info_target *> (so.lm_info.get ());
@@ -376,28 +385,11 @@ Could not relocate shared library \"%s\": bad offsets"), so.name.c_str ());
   sec->endaddr += offset;
 }
 
-static bool
-solib_target_in_dynsym_resolve_code (CORE_ADDR pc)
+bool
+target_solib_ops::in_dynsym_resolve_code (CORE_ADDR pc) const
 {
   /* We don't have a range of addresses for the dynamic linker; there
      may not be one in the program's address space.  So only report
      PLT entries (which may be import stubs).  */
   return in_plt_section (pc);
 }
-
-const solib_ops solib_target_so_ops =
-{
-  solib_target_relocate_section_addresses,
-  nullptr,
-  nullptr,
-  nullptr,
-  solib_target_current_sos,
-  nullptr,
-  solib_target_in_dynsym_resolve_code,
-  solib_bfd_open,
-  nullptr,
-  nullptr,
-  nullptr,
-  nullptr,
-  default_find_solib_addr,
-};
index f8a22fd6f6ad570afaad7c03148fca7aa99a18db..89ae2bc9b9e155b9cc31b7410a814e2340ab867a 100644 (file)
 #ifndef GDB_SOLIB_TARGET_H
 #define GDB_SOLIB_TARGET_H
 
-struct solib_ops;
-extern const solib_ops solib_target_so_ops;
+#include "solib.h"
+
+/* solib_ops for systems fetching solibs from the target.  */
+
+struct target_solib_ops : solib_ops
+{
+  void relocate_section_addresses (solib &so, target_section *) const override;
+  owning_intrusive_list<solib> current_sos () const override;
+  bool in_dynsym_resolve_code (CORE_ADDR pc) const override;
+};
+
+/* Return a new solib_ops for systems fetching solibs from the target.  */
+
+solib_ops_up make_target_solib_ops ();
 
 #endif /* GDB_SOLIB_TARGET_H */
index fab3ae39c2d0b3eb6316fa0a3269ffed4fd95abe..e43b1a326f3fd41f72ecd5f0d7e3bebd89d1b419 100644 (file)
@@ -467,6 +467,12 @@ solib_bfd_open (const char *pathname)
   return abfd;
 }
 
+gdb_bfd_ref_ptr
+solib_ops::bfd_open (const char *pathname) const
+{
+  return solib_bfd_open (pathname);
+}
+
 /* Given a pointer to one of the shared objects in our list of mapped
    objects, use the recorded name to open a bfd descriptor for the
    object, build a section table, relocate all the section addresses
@@ -598,8 +604,7 @@ solib::clear ()
   this->name = this->original_name;
 
   /* Do the same for target-specific data.  */
-  if (this->ops ().clear_so != NULL)
-    this->ops ().clear_so (*this);
+  this->ops ().clear_so (*this);
 }
 
 lm_info::~lm_info () = default;
@@ -722,8 +727,7 @@ update_solib_list (int from_tty)
         have not opened a symbol file, we may be able to get its
         symbols now!  */
       if (inf->attach_flag
-         && current_program_space->symfile_object_file == nullptr
-         && ops->open_symbol_file_object != nullptr)
+         && current_program_space->symfile_object_file == nullptr)
        {
          try
            {
@@ -772,19 +776,8 @@ update_solib_list (int from_tty)
       /* Check to see whether the shared object *gdb also appears in
         the inferior's current list.  */
       for (; inferior_iter != inferior.end (); ++inferior_iter)
-       {
-         if (ops->same)
-           {
-             if (ops->same (*gdb_iter, *inferior_iter))
-               break;
-           }
-         else
-           {
-             if (!filename_cmp (gdb_iter->original_name.c_str (),
-                                inferior_iter->original_name.c_str ()))
-               break;
-           }
-       }
+       if (ops->same (*gdb_iter, *inferior_iter))
+         break;
 
       /* If the shared object appears on the inferior's list too, then
         it's still loaded, so we don't need to do anything.  Delete
@@ -1037,7 +1030,7 @@ print_solib_list_table (std::vector<const solib *> solib_list,
      active namespace.  Fold all these into the PRINT_NAMESPACE condition.  */
   print_namespace = (print_namespace
                     && ops != nullptr
-                    && ops->num_active_namespaces != nullptr
+                    && ops->supports_namespaces ()
                     && ops->num_active_namespaces () > 1);
 
   int num_cols = 4;
@@ -1167,7 +1160,7 @@ info_linker_namespace_command (const char *pattern, int from_tty)
 
   /* This command only really makes sense for inferiors that support
      linker namespaces, so we can leave early.  */
-  if (ops == nullptr || ops->num_active_namespaces == nullptr)
+  if (ops == nullptr || !ops->supports_namespaces ())
     error (_("Current inferior does not support linker namespaces.  "
             "Use \"info sharedlibrary\" instead."));
 
@@ -1277,6 +1270,13 @@ solib_name_from_address (struct program_space *pspace, CORE_ADDR address)
   return nullptr;
 }
 
+bool
+solib_ops::same (const solib &a, const solib &b) const
+{
+  return (filename_cmp (a.original_name.c_str (), b.original_name.c_str ())
+         == 0);
+}
+
 /* See solib.h.  */
 
 bool
@@ -1284,10 +1284,7 @@ solib_keep_data_in_core (CORE_ADDR vaddr, unsigned long size)
 {
   const solib_ops *ops = current_program_space->solib_ops ();
 
-  if (ops != nullptr && ops->keep_data_in_core != nullptr)
-    return ops->keep_data_in_core (vaddr, size) != 0;
-  else
-    return false;
+  return ops != nullptr && ops->keep_data_in_core (vaddr, size);
 }
 
 /* See solib.h.  */
@@ -1306,9 +1303,8 @@ clear_solib (program_space *pspace)
 
   pspace->solibs ().clear ();
 
-  const solib_ops *ops = pspace->solib_ops ();
-
-  if (ops != nullptr && ops->clear_solib != nullptr)
+  if (const solib_ops *ops = pspace->solib_ops ();
+      ops != nullptr)
     ops->clear_solib (pspace);
 }
 
@@ -1320,10 +1316,9 @@ clear_solib (program_space *pspace)
 void
 solib_create_inferior_hook (int from_tty)
 {
-  const solib_ops *ops = current_program_space->solib_ops ();
-
-  if (ops != nullptr && ops->solib_create_inferior_hook != nullptr)
-    ops->solib_create_inferior_hook (from_tty);
+  if (const solib_ops *ops = current_program_space->solib_ops ();
+      ops != nullptr)
+    ops->create_inferior_hook (from_tty);
 }
 
 /* See solib.h.  */
@@ -1333,8 +1328,7 @@ in_solib_dynsym_resolve_code (CORE_ADDR pc)
 {
   const solib_ops *ops = current_program_space->solib_ops ();
 
-  return (ops != nullptr && ops->in_dynsym_resolve_code != nullptr
-         && ops->in_dynsym_resolve_code (pc));
+  return ops != nullptr && ops->in_dynsym_resolve_code (pc);
 }
 
 /* Implements the "sharedlibrary" command.  */
@@ -1378,7 +1372,7 @@ update_solib_breakpoints (void)
 {
   const solib_ops *ops = current_program_space->solib_ops ();
 
-  if (ops != nullptr && ops->update_breakpoints != nullptr)
+  if (ops != nullptr)
     ops->update_breakpoints ();
 }
 
@@ -1387,9 +1381,8 @@ update_solib_breakpoints (void)
 void
 handle_solib_event (void)
 {
-  const solib_ops *ops = current_program_space->solib_ops ();
-
-  if (ops != nullptr && ops->handle_event != nullptr)
+  if (const solib_ops *ops = current_program_space->solib_ops ();
+      ops != nullptr)
     ops->handle_event ();
 
   current_inferior ()->pspace->clear_solib_cache ();
@@ -1422,7 +1415,8 @@ reload_shared_libraries_1 (int from_tty)
 
       gdb::unique_xmalloc_ptr<char> filename (
        tilde_expand (so.original_name.c_str ()));
-      gdb_bfd_ref_ptr abfd (solib_bfd_open (filename.get ()));
+
+      gdb_bfd_ref_ptr abfd = so.ops ().bfd_open (filename.get ());
       if (abfd != NULL)
        found_pathname = bfd_get_filename (abfd.get ());
 
@@ -1484,11 +1478,10 @@ 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 != nullptr && ops->clear_solib != nullptr)
+      if (const solib_ops *ops = current_program_space->solib_ops ();
+         ops != nullptr)
        ops->clear_solib (current_program_space);
 
       /* Remove any previous solib event breakpoint.  This is usually
@@ -1815,15 +1808,8 @@ remove_user_added_objfile (struct objfile *objfile)
     }
 }
 
-/* See solist.h.  */
-
-std::optional<CORE_ADDR>
-default_find_solib_addr (solib &so)
-{
-  return {};
-}
-
 /* Implementation of the linker_namespace convenience variable.
+
    This returns the GDB internal identifier of the linker namespace,
    for the selected frame, as an integer.  If the inferior doesn't support
    linker namespaces, this always returns 0.  */
@@ -1838,7 +1824,7 @@ linker_namespace_make_value (gdbarch *gdbarch, internalvar *var,
   for (const solib &so : current_program_space->solibs ())
     if (solib_contains_address_p (so, curr_pc))
       {
-       if (so.ops ().find_solib_ns != nullptr)
+       if (so.ops ().supports_namespaces ())
          nsid = so.ops ().find_solib_ns (so);
 
        break;
index 09d56c08b9533045860961e9b2d04597875541d5..b9465e103bdd89c83ba575d7551ce84e5e1c7a36 100644 (file)
@@ -133,22 +133,31 @@ using solib_up = std::unique_ptr<solib>;
 
 struct solib_ops
 {
+  virtual ~solib_ops () = default;
+
   /* Adjust the section binding addresses by the base address at
      which the object was actually mapped.  */
-  void (*relocate_section_addresses) (solib &so, target_section *);
+  virtual void relocate_section_addresses (solib &so, target_section *) const
+    = 0;
 
   /* Reset private data structures associated with SO.
      This is called when SO is about to be reloaded.
-     It is also called when SO is about to be freed.  */
-  void (*clear_so) (const solib &so);
+     It is also called when SO is about to be freed.
+
+     Defaults to no-op.  */
+  virtual void clear_so (const solib &so) const {}
 
   /* Free private data structures associated to PSPACE.  This method
      should not free resources associated to individual solib entries,
-     those are cleared by the clear_so method.  */
-  void (*clear_solib) (program_space *pspace);
+     those are cleared by the clear_so method.
+
+     Defaults to no-op.  */
+  virtual void clear_solib (program_space *pspace) const {}
 
-  /* Target dependent code to run after child process fork.  */
-  void (*solib_create_inferior_hook) (int from_tty);
+  /* Target dependent code to run after child process fork.
+
+     Defaults to no-op.  */
+  virtual void create_inferior_hook (int from_tty) const {};
 
   /* Construct a list of the currently loaded shared objects.  This
      list does not include an entry for the main executable file.
@@ -157,45 +166,51 @@ struct solib_ops
      inferior --- we don't examine any of the shared library files
      themselves.  The declaration of `struct solib' says which fields
      we provide values for.  */
-  owning_intrusive_list<solib> (*current_sos) ();
+  virtual owning_intrusive_list<solib> current_sos () const = 0;
 
   /* Find, open, and read the symbols for the main executable.  If
-     FROM_TTY is non-zero, allow messages to be printed.  */
-  int (*open_symbol_file_object) (int from_ttyp);
+     FROM_TTY is non-zero, allow messages to be printed.
+
+     Return true if this was done successfully.  Defaults to false.  */
+  virtual bool open_symbol_file_object (int from_tty) const { return false; }
 
   /* Determine if PC lies in the dynamic symbol resolution code of
-     the run time loader.  */
-  bool (*in_dynsym_resolve_code) (CORE_ADDR pc);
+     the run time loader.
+
+     Defaults to false.  */
+  virtual bool in_dynsym_resolve_code (CORE_ADDR pc) const
+  { return false; };
 
   /* Find and open shared library binary file.  */
-  gdb_bfd_ref_ptr (*bfd_open) (const char *pathname);
+  virtual gdb_bfd_ref_ptr bfd_open (const char *pathname) const;
+
+  /* Given two solib objects, GDB from the GDB thread list and INFERIOR from the
+     list returned by current_sos, return true if they represent the same library.
 
-  /* Given two solib objects, one from the GDB thread list
-     and another from the list returned by current_sos, return 1
-     if they represent the same library.
-     Falls back to using strcmp on ORIGINAL_NAME when set to nullptr.  */
-  int (*same) (const solib &gdb, const solib &inferior);
+     Defaults to comparing the solib original names using filename_cmp.  */
+  virtual bool same (const solib &gdb, const solib &inferior) const;
 
   /* Return whether a region of memory must be kept in a core file
      for shared libraries loaded before "gcore" is used to be
      handled correctly when the core file is loaded.  This only
      applies when the section would otherwise not be kept in the
-     core file (in particular, for readonly sections).  */
-  int (*keep_data_in_core) (CORE_ADDR vaddr,
-                           unsigned long size);
-
-  /* Enable or disable optional solib event breakpoints as
-     appropriate.  This should be called whenever
-     stop_on_solib_events is changed.  This pointer can be
-     NULL, in which case no enabling or disabling is necessary
-     for this target.  */
-  void (*update_breakpoints) (void);
-
-  /* Target-specific processing of solib events that will be
-     performed before solib_add is called.  This pointer can be
-     NULL, in which case no specific preprocessing is necessary
-     for this target.  */
-  void (*handle_event) (void);
+     core file (in particular, for readonly sections).
+
+     Defaults to false.  */
+  virtual bool keep_data_in_core (CORE_ADDR vaddr, unsigned long size) const
+  { return false; };
+
+  /* Enable or disable optional solib event breakpoints as appropriate.  This
+     should be called whenever stop_on_solib_events is changed.
+
+     Defaults to no-op.  */
+  virtual void update_breakpoints () const {};
+
+  /* Target-specific processing of solib events that will be performed before
+     solib_add is called.
+
+     Defaults to no-op.  */
+  virtual void handle_event () const {};
 
   /* Return an address within the inferior's address space which is known
      to be part of SO.  If there is no such address, or GDB doesn't know
@@ -210,28 +225,45 @@ struct solib_ops
      mapped file, and thus to a build-id.  GDB can then use this
      information to help locate the shared library objfile, if the objfile
      is not in the expected place (as defined by the shared libraries file
-     name).  */
-  std::optional<CORE_ADDR> (*find_solib_addr) (solib &so);
+     name).
+
+     The default implementation of returns an empty option, indicating GDB is
+     unable to find an address within the library SO.  */
+  virtual std::optional<CORE_ADDR> find_solib_addr (solib &so) const
+  { return {}; };
+
+  /* Return true if the linker or libc supports linkage namespaces.
+
+     Defaults to false.  */
+  virtual bool supports_namespaces () const { return false; }
 
-  /* Return which linker namespace contains the current so.
-     If the linker or libc does not support linkage namespaces at all
-     (which is basically all of them but solib-svr4), this function should
-     be set to nullptr, so that "info shared" won't add an unnecessary
-     column.
+  /* Return which linker namespace contains SO.
 
-     If the namespace can not be determined (such as when we're stepping
-     though the dynamic linker), this function should throw a
-     gdb_exception_error.  */
-  int (*find_solib_ns) (const solib &so);
+     The supports_namespaces method must return true for this to be
+     called.
 
-  /* Returns the number of active namespaces in the inferior.  */
-  int (*num_active_namespaces) ();
+     Throw an error if the namespace can not be determined (such as when we're
+     stepping though the dynamic linker).  */
+  virtual int find_solib_ns (const solib &so) const
+  { gdb_assert_not_reached ("namespaces not supported"); }
+
+  /* Returns the number of active namespaces in the inferior.
+
+     The supports_namespaces method must return true for this to be called.  */
+  virtual int num_active_namespaces () const
+  { gdb_assert_not_reached ("namespaces not supported"); }
 
   /* Returns all solibs for a given namespace.  If the namespace is not
-     active, returns an empty vector.  */
-  std::vector<const solib *> (*get_solibs_in_ns) (int ns);
+     active, returns an empty vector.
+
+     The supports_namespaces method must return true for this to be called.  */
+  virtual std::vector<const solib *> get_solibs_in_ns (int ns) const
+  { gdb_assert_not_reached ("namespaces not supported"); }
 };
 
+/* A unique pointer to an solib_ops.  */
+using solib_ops_up = std::unique_ptr<solib_ops>;
+
 /* Find main executable binary file.  */
 extern gdb::unique_xmalloc_ptr<char> exec_file_find (const char *in_pathname,
                                                     int *fd);
@@ -246,11 +278,6 @@ extern gdb_bfd_ref_ptr solib_bfd_fopen (const char *pathname, int fd);
 /* Find solib binary file and open it.  */
 extern gdb_bfd_ref_ptr solib_bfd_open (const char *in_pathname);
 
-/* A default implementation of the solib_ops::find_solib_addr callback.
-   This just returns an empty std::optional<CORE_ADDR> indicating GDB is
-   unable to find an address within the library SO.  */
-extern std::optional<CORE_ADDR> default_find_solib_addr (solib &so);
-
 /* Called when we free all symtabs of PSPACE, to free the shared library
    information as well.  */
 
index 26b13e7b62f76da8da2cf8a5c730e96c021b763a..6e23fdd7f9ee0190ad7d8a68cb853f3835915c9e 100644 (file)
@@ -33,6 +33,7 @@
 #include "tramp-frame.h"
 #include "xml-syscall.h"
 #include "linux-tdep.h"
+#include "solib-svr4-linux.h"
 
 /* The syscall's XML filename for sparc 32-bit.  */
 #define XML_SYSCALL_FILENAME_SPARC32 "syscalls/sparc-linux.xml"
@@ -436,8 +437,7 @@ sparc32_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
 
   /* GNU/Linux has SVR4-style shared libraries...  */
   set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
-  set_solib_svr4_fetch_link_map_offsets
-    (gdbarch, linux_ilp32_fetch_link_map_offsets);
+  set_solib_svr4_ops (gdbarch, make_linux_ilp32_svr4_solib_ops);
 
   /* ...which means that we need some special handling when doing
      prologue analysis.  */
index 4938eb561611ab5a63bdb604f546d1eedf4d3932..8e8a1ba8d3738d80d59b22ef5a7e714e1d8413d5 100644 (file)
@@ -313,8 +313,7 @@ sparc32nbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
 
   frame_unwind_append_unwinder (gdbarch, &sparc32nbsd_sigcontext_frame_unwind);
 
-  set_solib_svr4_fetch_link_map_offsets
-    (gdbarch, svr4_ilp32_fetch_link_map_offsets);
+  set_solib_svr4_ops (gdbarch, make_svr4_ilp32_solib_ops);
 }
 
 INIT_GDB_FILE (sparcnbsd_tdep)
index fbc351ce0d40b6c045ebad36902b6fcee577c544..337b9293dd952f047010235be553884a72a547a5 100644 (file)
@@ -207,8 +207,7 @@ sparc32_sol2_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
 
   /* Solaris has SVR4-style shared libraries...  */
   set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
-  set_solib_svr4_fetch_link_map_offsets
-    (gdbarch, svr4_ilp32_fetch_link_map_offsets);
+  set_solib_svr4_ops (gdbarch, make_svr4_ilp32_solib_ops);
 
   /* ...which means that we need some special handling when doing
      prologue analysis.  */
index 548f4780c514dc7007c61b2b2f9d98eff144fb66..ba04a711808967e46319b9644b2846879520ea2c 100644 (file)
@@ -238,8 +238,7 @@ sparc64fbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
 
   /* FreeBSD/sparc64 has SVR4-style shared libraries.  */
   set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
-  set_solib_svr4_fetch_link_map_offsets
-    (gdbarch, svr4_lp64_fetch_link_map_offsets);
+  set_solib_svr4_ops (gdbarch, make_svr4_lp64_solib_ops);
 }
 
 INIT_GDB_FILE (sparc64fbsd_tdep)
index 5d7386b11f4b7e12f40eaf39bc11a7a1fe057d54..373dfb69a262ccef41fdb7e981f2d9054cb25696 100644 (file)
@@ -32,6 +32,7 @@
 #include "tramp-frame.h"
 #include "xml-syscall.h"
 #include "linux-tdep.h"
+#include "solib-svr4-linux.h"
 
 /* ADI specific si_code */
 #ifndef SEGV_ACCADI
@@ -383,8 +384,7 @@ sparc64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
 
   /* GNU/Linux has SVR4-style shared libraries...  */
   set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
-  set_solib_svr4_fetch_link_map_offsets
-    (gdbarch, linux_lp64_fetch_link_map_offsets);
+  set_solib_svr4_ops (gdbarch, make_linux_lp64_svr4_solib_ops);
 
   /* ...which means that we need some special handling when doing
      prologue analysis.  */
index 8c9a5c9d720c6488c0f7df30bc8d3fe3033b5905..0227ec4c492dc0f39eb38df8bee54dcb43e669d3 100644 (file)
@@ -266,8 +266,7 @@ sparc64nbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
 
   /* NetBSD/sparc64 has SVR4-style shared libraries.  */
   set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
-  set_solib_svr4_fetch_link_map_offsets
-    (gdbarch, svr4_lp64_fetch_link_map_offsets);
+  set_solib_svr4_ops (gdbarch, make_svr4_lp64_solib_ops);
 }
 
 INIT_GDB_FILE (sparc64nbsd_tdep)
index e09156bd0b692268e2c52190761db4a441bc617c..83cc9c081ad56a044d502a2d0181277820c40746 100644 (file)
@@ -440,8 +440,7 @@ sparc64obsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
   obsd_init_abi (info, gdbarch);
 
   /* OpenBSD/sparc64 has SVR4-style shared libraries.  */
-  set_solib_svr4_fetch_link_map_offsets
-    (gdbarch, svr4_lp64_fetch_link_map_offsets);
+  set_solib_svr4_ops (gdbarch, make_svr4_lp64_solib_ops);
   set_gdbarch_skip_solib_resolver (gdbarch, obsd_skip_solib_resolver);
 
   /* OpenBSD provides a user-level threads implementation.  */
index 85f4f33aa68f4767bb005120ae384fab86119512..6d091f58d32408032c93afeb29d704671ffc359f 100644 (file)
@@ -214,8 +214,7 @@ sparc64_sol2_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
 
   /* Solaris has SVR4-style shared libraries...  */
   set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
-  set_solib_svr4_fetch_link_map_offsets
-    (gdbarch, svr4_lp64_fetch_link_map_offsets);
+  set_solib_svr4_ops (gdbarch, make_svr4_lp64_solib_ops);
 
   /* ...which means that we need some special handling when doing
      prologue analysis.  */
index a063b90ea4c27994e617e6b1999358c85e4aa590..5b3d402051d2147f4f61ef288b2401b9b75605d1 100644 (file)
@@ -169,7 +169,7 @@ tic6x_uclinux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
   linux_init_abi (info, gdbarch, 0);
 
   /* Shared library handling.  */
-  set_gdbarch_so_ops (gdbarch, &dsbt_so_ops);
+  set_gdbarch_make_solib_ops (gdbarch, make_dsbt_solib_ops);
 
   tdep->syscall_next_pc = tic6x_linux_syscall_next_pc;
 
index 54dc6a2ebcf2d6aa1d83b79578d7cda84e9f416f..f54e2807f5d88d23b2c9cb92c3fd3fb5ea8531c9 100644 (file)
@@ -19,6 +19,7 @@
 
 #include "osabi.h"
 #include "linux-tdep.h"
+#include "solib-svr4-linux.h"
 #include "glibc-tdep.h"
 #include "solib-svr4.h"
 #include "symtab.h"
@@ -119,11 +120,9 @@ tilegx_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
 
   /* GNU/Linux uses SVR4-style shared libraries.  */
   if (arch_size == 32)
-    set_solib_svr4_fetch_link_map_offsets (gdbarch,
-                                          linux_ilp32_fetch_link_map_offsets);
+    set_solib_svr4_ops (gdbarch, make_linux_ilp32_svr4_solib_ops);
   else
-    set_solib_svr4_fetch_link_map_offsets (gdbarch,
-                                          linux_lp64_fetch_link_map_offsets);
+    set_solib_svr4_ops (gdbarch, make_linux_lp64_svr4_solib_ops);
 
   /* Enable TLS support.  */
   set_gdbarch_fetch_tls_load_module_address (gdbarch,
index 6a3fd88d66d4866d7b5ad12dbed236b965014671..7781264544758c4a97bbd9efa06bb7584bbaaacb 100644 (file)
@@ -32,8 +32,7 @@ vaxnbsd_elf_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
   nbsd_init_abi (info, gdbarch);
 
   /* NetBSD ELF uses SVR4-style shared libraries.  */
-  set_solib_svr4_fetch_link_map_offsets
-    (gdbarch, svr4_ilp32_fetch_link_map_offsets);
+  set_solib_svr4_ops (gdbarch, make_svr4_ilp32_solib_ops);
 }
 
 INIT_GDB_FILE (vaxnbsd_tdep)
index 1d25c2be1ec1a8fe875822b2fb7ae669767b894e..05335d2958794175340bcd116163ef46822580cb 100644 (file)
@@ -862,10 +862,25 @@ windows_get_siginfo_type (struct gdbarch *gdbarch)
   return siginfo_type;
 }
 
+/* solib_ops for Windows systems.  */
+
+struct windows_solib_ops : target_solib_ops
+{
+  void create_inferior_hook (int from_tty) const override;
+};
+
+/* Return a new solib_ops for Windows systems.  */
+
+static solib_ops_up
+make_windows_solib_ops ()
+{
+  return std::make_unique<windows_solib_ops> ();
+}
+
 /* Implement the "solib_create_inferior_hook" solib_ops method.  */
 
-static void
-windows_solib_create_inferior_hook (int from_tty)
+void
+windows_solib_ops::create_inferior_hook (int from_tty) const
 {
   CORE_ADDR exec_base = 0;
 
@@ -910,8 +925,6 @@ windows_solib_create_inferior_hook (int from_tty)
     }
 }
 
-static solib_ops windows_so_ops;
-
 /* Common parts for gdbarch initialization for the Windows and Cygwin OS
    ABIs.  */
 
@@ -928,10 +941,7 @@ windows_init_abi_common (struct gdbarch_info info, struct gdbarch *gdbarch)
   set_gdbarch_iterate_over_objfiles_in_search_order
     (gdbarch, windows_iterate_over_objfiles_in_search_order);
 
-  windows_so_ops = solib_target_so_ops;
-  windows_so_ops.solib_create_inferior_hook
-    = windows_solib_create_inferior_hook;
-  set_gdbarch_so_ops (gdbarch, &windows_so_ops);
+  set_gdbarch_make_solib_ops (gdbarch, make_windows_solib_ops);
 
   set_gdbarch_get_siginfo_type (gdbarch, windows_get_siginfo_type);
 }
index 8a3534359e2c1c1565c3b0da766df7b11c67de0b..7792408ee2391f0e340d67d997f9cbfcb3138953 100644 (file)
@@ -20,6 +20,7 @@
 #include "xtensa-tdep.h"
 #include "osabi.h"
 #include "linux-tdep.h"
+#include "solib-svr4-linux.h"
 #include "solib-svr4.h"
 #include "symtab.h"
 #include "gdbarch.h"
@@ -111,8 +112,7 @@ xtensa_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
 
   linux_init_abi (info, gdbarch, 0);
 
-  set_solib_svr4_fetch_link_map_offsets
-    (gdbarch, linux_ilp32_fetch_link_map_offsets);
+  set_solib_svr4_ops (gdbarch, make_linux_ilp32_svr4_solib_ops);
 
   set_gdbarch_gdb_signal_from_target (gdbarch,
                                      xtensa_linux_gdb_signal_from_target);
index c0ae87d306bbceff0f211dea33c156d5e499eb21..8a2f129c7580dd198a6ea9fd8341329d47e559c3 100644 (file)
@@ -3238,8 +3238,7 @@ xtensa_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   set_gdbarch_iterate_over_regset_sections
     (gdbarch, xtensa_iterate_over_regset_sections);
 
-  set_solib_svr4_fetch_link_map_offsets
-    (gdbarch, svr4_ilp32_fetch_link_map_offsets);
+  set_solib_svr4_ops (gdbarch, make_svr4_ilp32_solib_ops);
 
   /* Hook in the ABI-specific overrides, if they have been registered.  */
   gdbarch_init_osabi (info, gdbarch);