diff options
Diffstat (limited to 'gdb/mips-linux-tdep.c')
-rw-r--r-- | gdb/mips-linux-tdep.c | 69 |
1 files changed, 43 insertions, 26 deletions
diff --git a/gdb/mips-linux-tdep.c b/gdb/mips-linux-tdep.c index bf3df36..e4fa243 100644 --- a/gdb/mips-linux-tdep.c +++ b/gdb/mips-linux-tdep.c @@ -36,6 +36,7 @@ #include "mips-linux-tdep.h" #include "glibc-tdep.h" #include "linux-tdep.h" +#include "solib-svr4-linux.h" #include "xml-syscall.h" #include "gdbsupport/gdb_signals.h" #include "inferior.h" @@ -45,8 +46,6 @@ #include "features/mips64-linux.c" #include "features/mips64-dsp-linux.c" -static solib_ops mips_svr4_so_ops; - /* This enum represents the signals' numbers on the MIPS architecture. It just contains the signal definitions which are different from the generic implementation. @@ -666,15 +665,22 @@ mips_linux_in_dynsym_stub (CORE_ADDR pc) return 1; } -/* Return true iff PC belongs to the dynamic linker resolution - code, a PLT entry, or a lazy binding stub. */ +/* Mix-in class to add Linux/MIPS-specific methods to a base solib_ops + class. */ -static bool -mips_linux_in_dynsym_resolve_code (CORE_ADDR pc) +template <typename Base> +struct mips_linux_svr4_solib_ops : public Base +{ + bool in_dynsym_resolve_code (CORE_ADDR pc) const override; +}; + +template <typename Base> +bool +mips_linux_svr4_solib_ops<Base>::in_dynsym_resolve_code (CORE_ADDR pc) const { /* Check whether PC is in the dynamic linker. This also checks whether it is in the .plt section, used by non-PIC executables. */ - if (svr4_in_dynsym_resolve_code (pc)) + if (Base::in_dynsym_resolve_code (pc)) return true; /* Likewise for the stubs. They live in the .MIPS.stubs section these @@ -686,6 +692,32 @@ mips_linux_in_dynsym_resolve_code (CORE_ADDR pc) return false; } +/* solib_ops for ILP32 Linux/MIPS systems. */ + +using mips_linux_ilp32_svr4_solib_ops + = mips_linux_svr4_solib_ops<linux_ilp32_svr4_solib_ops>; + +/* Return a new solib_ops for ILP32 Linux/MIPS systems. */ + +static solib_ops_up +make_mips_linux_ilp32_svr4_solib_ops () +{ + return std::make_unique<mips_linux_ilp32_svr4_solib_ops> (); +} + +/* solib_ops for LP64 Linux/MIPS systems. */ + +using mips_linux_lp64_svr4_solib_ops + = mips_linux_svr4_solib_ops<linux_lp64_svr4_solib_ops>; + +/* Return a new solib_ops for LP64 Linux/MIPS systems. */ + +static solib_ops_up +make_mips_linux_lp64_svr4_solib_ops () +{ + return std::make_unique<mips_linux_lp64_svr4_solib_ops> (); +} + /* See the comments for SKIP_SOLIB_RESOLVER at the top of infrun.c, and glibc_skip_solib_resolver in glibc-tdep.c. The normal glibc implementation of this triggers at "fixup" from the same objfile as @@ -1537,8 +1569,7 @@ mips_linux_init_abi (struct gdbarch_info info, case MIPS_ABI_O32: set_gdbarch_get_longjmp_target (gdbarch, mips_linux_get_longjmp_target); - set_solib_svr4_fetch_link_map_offsets - (gdbarch, linux_ilp32_fetch_link_map_offsets); + set_solib_svr4_ops (gdbarch, make_mips_linux_ilp32_svr4_solib_ops); tramp_frame_prepend_unwinder (gdbarch, µmips_linux_o32_sigframe); tramp_frame_prepend_unwinder (gdbarch, µmips_linux_o32_rt_sigframe); @@ -1549,8 +1580,7 @@ mips_linux_init_abi (struct gdbarch_info info, case MIPS_ABI_N32: set_gdbarch_get_longjmp_target (gdbarch, mips_linux_get_longjmp_target); - set_solib_svr4_fetch_link_map_offsets - (gdbarch, linux_ilp32_fetch_link_map_offsets); + set_solib_svr4_ops (gdbarch, make_mips_linux_ilp32_svr4_solib_ops); set_gdbarch_long_double_bit (gdbarch, 128); set_gdbarch_long_double_format (gdbarch, floatformats_ieee_quad); tramp_frame_prepend_unwinder (gdbarch, @@ -1561,8 +1591,7 @@ mips_linux_init_abi (struct gdbarch_info info, case MIPS_ABI_N64: set_gdbarch_get_longjmp_target (gdbarch, mips64_linux_get_longjmp_target); - set_solib_svr4_fetch_link_map_offsets - (gdbarch, linux_lp64_fetch_link_map_offsets); + set_solib_svr4_ops (gdbarch, make_mips_linux_lp64_svr4_solib_ops); set_gdbarch_long_double_bit (gdbarch, 128); set_gdbarch_long_double_format (gdbarch, floatformats_ieee_quad); tramp_frame_prepend_unwinder (gdbarch, @@ -1582,16 +1611,6 @@ mips_linux_init_abi (struct gdbarch_info info, set_gdbarch_fetch_tls_load_module_address (gdbarch, svr4_fetch_objfile_link_map); - /* Initialize this lazily, to avoid an initialization order - dependency on solib-svr4.c's _initialize routine. */ - if (mips_svr4_so_ops.in_dynsym_resolve_code == NULL) - { - mips_svr4_so_ops = svr4_so_ops; - mips_svr4_so_ops.in_dynsym_resolve_code - = mips_linux_in_dynsym_resolve_code; - } - set_gdbarch_so_ops (gdbarch, &mips_svr4_so_ops); - set_gdbarch_write_pc (gdbarch, mips_linux_write_pc); set_gdbarch_core_read_description (gdbarch, @@ -1628,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; |