aboutsummaryrefslogtreecommitdiff
path: root/gdb/mips-linux-tdep.c
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/mips-linux-tdep.c')
-rw-r--r--gdb/mips-linux-tdep.c78
1 files changed, 47 insertions, 31 deletions
diff --git a/gdb/mips-linux-tdep.c b/gdb/mips-linux-tdep.c
index b076d24..e4fa243 100644
--- a/gdb/mips-linux-tdep.c
+++ b/gdb/mips-linux-tdep.c
@@ -1,6 +1,6 @@
/* Target-dependent code for GNU/Linux on MIPS processors.
- Copyright (C) 2001-2024 Free Software Foundation, Inc.
+ Copyright (C) 2001-2025 Free Software Foundation, Inc.
This file is part of GDB.
@@ -30,13 +30,13 @@
#include "gdbtypes.h"
#include "objfiles.h"
#include "solib.h"
-#include "solist.h"
#include "symtab.h"
#include "target-descriptions.h"
#include "regset.h"
#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"
@@ -46,8 +46,6 @@
#include "features/mips64-linux.c"
#include "features/mips64-dsp-linux.c"
-static solib_ops mips_svr4_so_ops;
-
/* This enum represents the signals' numbers on the MIPS
architecture. It just contains the signal definitions which are
different from the generic implementation.
@@ -667,24 +665,57 @@ mips_linux_in_dynsym_stub (CORE_ADDR pc)
return 1;
}
-/* Return non-zero 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 int
-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))
- return 1;
+ if (Base::in_dynsym_resolve_code (pc))
+ return true;
/* Likewise for the stubs. They live in the .MIPS.stubs section these
days, so we check if the PC is within, than fall back to a pattern
match. */
if (mips_linux_in_dynsym_stub (pc))
- return 1;
+ return true;
- return 0;
+ 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,
@@ -1538,8 +1569,7 @@ mips_linux_init_abi (struct gdbarch_info info,
case MIPS_ABI_O32:
set_gdbarch_get_longjmp_target (gdbarch,
mips_linux_get_longjmp_target);
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, linux_ilp32_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, make_mips_linux_ilp32_svr4_solib_ops);
tramp_frame_prepend_unwinder (gdbarch, &micromips_linux_o32_sigframe);
tramp_frame_prepend_unwinder (gdbarch,
&micromips_linux_o32_rt_sigframe);
@@ -1550,8 +1580,7 @@ mips_linux_init_abi (struct gdbarch_info info,
case MIPS_ABI_N32:
set_gdbarch_get_longjmp_target (gdbarch,
mips_linux_get_longjmp_target);
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, linux_ilp32_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, make_mips_linux_ilp32_svr4_solib_ops);
set_gdbarch_long_double_bit (gdbarch, 128);
set_gdbarch_long_double_format (gdbarch, floatformats_ieee_quad);
tramp_frame_prepend_unwinder (gdbarch,
@@ -1562,8 +1591,7 @@ mips_linux_init_abi (struct gdbarch_info info,
case MIPS_ABI_N64:
set_gdbarch_get_longjmp_target (gdbarch,
mips64_linux_get_longjmp_target);
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, linux_lp64_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, make_mips_linux_lp64_svr4_solib_ops);
set_gdbarch_long_double_bit (gdbarch, 128);
set_gdbarch_long_double_format (gdbarch, floatformats_ieee_quad);
tramp_frame_prepend_unwinder (gdbarch,
@@ -1583,16 +1611,6 @@ mips_linux_init_abi (struct gdbarch_info info,
set_gdbarch_fetch_tls_load_module_address (gdbarch,
svr4_fetch_objfile_link_map);
- /* Initialize this lazily, to avoid an initialization order
- dependency on solib-svr4.c's _initialize routine. */
- if (mips_svr4_so_ops.in_dynsym_resolve_code == NULL)
- {
- mips_svr4_so_ops = svr4_so_ops;
- mips_svr4_so_ops.in_dynsym_resolve_code
- = mips_linux_in_dynsym_resolve_code;
- }
- set_gdbarch_so_ops (gdbarch, &mips_svr4_so_ops);
-
set_gdbarch_write_pc (gdbarch, mips_linux_write_pc);
set_gdbarch_core_read_description (gdbarch,
@@ -1629,9 +1647,7 @@ mips_linux_init_abi (struct gdbarch_info info,
}
}
-void _initialize_mips_linux_tdep ();
-void
-_initialize_mips_linux_tdep ()
+INIT_GDB_FILE (mips_linux_tdep)
{
const struct bfd_arch_info *arch_info;