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 \
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 \
/* 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);
#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"
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,
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"
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,
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;
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;
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
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");
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,
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)
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);
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)
#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"
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);
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)
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)
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);
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)
/* GDB header files. */
#include "linux-tdep.h"
+#include "solib-svr4-linux.h"
#include "objfiles.h"
#include "opcode/arc.h"
#include "osabi.h"
/* 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)
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;
#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"
}
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);
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)
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;
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
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)
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*)
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
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*-*-*)
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
# 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"
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
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-*-*)
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
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
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
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
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-*-*)
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 \
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"
;;
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"
;;
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)
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
# 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)
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"
;;
# 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"
;;
#include "osabi.h"
#include "linux-tdep.h"
+#include "solib-svr4-linux.h"
#include "solib-svr4.h"
#include "symtab.h"
#include "gdbarch.h"
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)
#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"
/* 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,
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,
#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"
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);
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 */
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;
/* 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. */
"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));
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
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
#include "displaced-stepping.h"
#include "gdbsupport/gdb-checked-static-cast.h"
#include "registry.h"
+#include "solib.h"
struct floatformat;
struct ui_file;
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,
)
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);
#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. */
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);
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
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);
/* 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);
#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"
/* 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);
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;
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)
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
#include "solib-svr4.h"
#include "symtab.h"
#include "linux-tdep.h"
+#include "solib-svr4-linux.h"
#include "regset.h"
#include <ctype.h>
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,
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 ())
{
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 ();
&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;
-}
#include "bfd.h"
#include "displaced-stepping.h"
+#include "solib.h"
struct inferior;
struct regcache;
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 */
#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"
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);
#include "m32r-tdep.h"
#include "linux-tdep.h"
+#include "solib-svr4-linux.h"
#include "gdbarch.h"
\f
/* 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
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)
#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. */
/* 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);
#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,
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,
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;
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;
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)
#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"
#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.
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
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
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, µmips_linux_o32_sigframe);
tramp_frame_prepend_unwinder (gdbarch,
µmips_linux_o32_rt_sigframe);
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,
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,
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,
|| 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;
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;
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)
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)
#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>... */
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);
#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"
{
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);
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");
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");
}
#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"
#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"
/* 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. */
/* 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);
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);
}
/* 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);
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);
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);
#ifndef GDB_PROGSPACE_H
#define GDB_PROGSPACE_H
+#include "solib.h"
#include "target.h"
#include "gdb_bfd.h"
#include "registry.h"
/* 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 ()
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. */
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);
#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"
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);
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);
}
#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"
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);
}
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);
}
#include "glibc-tdep.h"
#include "sh-tdep.h"
#include "linux-tdep.h"
+#include "solib-svr4-linux.h"
#include "gdbarch.h"
#define REGSx16(base) \
/* 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,
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)
#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
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;
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";
}
}
-/* 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);
}
/* 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);
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).
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, '(');
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;
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,
#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 */
#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). */
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;
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> ();
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 ())
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);
/* 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 ());
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;
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,
-};
#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 */
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
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;
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. */
/* 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);
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 ();
}
}
-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);
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 ());
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. */
#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 */
#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 };
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;
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;
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)
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 ();
}
}
-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;
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 ());
/* 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,
-};
--- /dev/null
+/* 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 */
#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"
/* 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. */
/* 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;
}
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;
/* 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;
}
}
-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 *
{
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
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
{
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. */
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
(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 () });
}
--- /dev/null
+/* 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;
+}
--- /dev/null
+/* 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 */
#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
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
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 ());
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);
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 ());
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;
/* 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);
}
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;
/* 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;
/* 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);
/* 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);
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;
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);
/* 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 ();
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);
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
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
/* 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 ());
/* 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;
/* 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 {};
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;
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;
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;
/* 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);
}
}
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);
}
}
/* 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;
/* 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;
/* 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
{
/* 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)
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);
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
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. */
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;
}
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."));
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;
/* 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);
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 ();
}
/* 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);
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++)
{
}
}
- 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);
/* 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;
}
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));
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;
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)
{
= 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;
}
}
{
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;
}
}
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;
}
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;
}
}
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;
}
}
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 ();
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;
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);
}
}
}
-\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
/* 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;
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;
}
}
-/* 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);
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);
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,
#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. */
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. */
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. */
{ 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)
{
}
#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;
/* 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);
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 ());
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,
-};
#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 */
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
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;
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
{
/* 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
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;
/* 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."));
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
{
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. */
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);
}
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. */
{
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. */
{
const solib_ops *ops = current_program_space->solib_ops ();
- if (ops != nullptr && ops->update_breakpoints != nullptr)
+ if (ops != nullptr)
ops->update_breakpoints ();
}
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 ();
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 ());
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
}
}
-/* 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. */
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;
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.
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
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);
/* 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. */
#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"
/* 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. */
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)
/* 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. */
/* 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)
#include "tramp-frame.h"
#include "xml-syscall.h"
#include "linux-tdep.h"
+#include "solib-svr4-linux.h"
/* ADI specific si_code */
#ifndef SEGV_ACCADI
/* 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. */
/* 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)
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. */
/* 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. */
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;
#include "osabi.h"
#include "linux-tdep.h"
+#include "solib-svr4-linux.h"
#include "glibc-tdep.h"
#include "solib-svr4.h"
#include "symtab.h"
/* 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,
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)
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;
}
}
-static solib_ops windows_so_ops;
-
/* Common parts for gdbarch initialization for the Windows and Cygwin OS
ABIs. */
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);
}
#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"
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);
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);