/* Target-dependent code for GNU/Linux x86-64.
- Copyright (C) 2001-2019 Free Software Foundation, Inc.
+ Copyright (C) 2001-2020 Free Software Foundation, Inc.
Contributed by Jiri Smid, SuSE Labs.
This file is part of GDB.
#include "defs.h"
#include "arch-utils.h"
+#include "displaced-stepping.h"
#include "frame.h"
+#include "gdbarch.h"
#include "gdbcore.h"
#include "regcache.h"
#include "osabi.h"
#include "i386-linux-tdep.h"
#include "linux-tdep.h"
#include "gdbsupport/x86-xstate.h"
+#include "inferior.h"
#include "amd64-tdep.h"
#include "solib-svr4.h"
#include "glibc-tdep.h"
#include "arch/amd64.h"
#include "target-descriptions.h"
+#include "observable.h"
/* The syscall's XML filename for i386. */
#define XML_SYSCALL_FILENAME_AMD64 "syscalls/amd64-linux.xml"
}
}
+struct amd64_linux_per_inferior
+{
+ amd64_linux_per_inferior (gdb::array_view<CORE_ADDR> disp_step_buffer_addrs)
+ : disp_step_buf_mgr (disp_step_buffer_addrs)
+ {}
+
+ multiple_displaced_buffer_manager disp_step_buf_mgr;
+};
+
+static const inferior_key<amd64_linux_per_inferior>
+ amd64_linux_per_inferior_data;
+
+/* Get the per-inferior AMD64/Linux data for INF. */
+
+static amd64_linux_per_inferior *
+get_amd64_linux_per_inferior (inferior *inf, gdbarch *arch)
+{
+ amd64_linux_per_inferior *per_inf = amd64_linux_per_inferior_data.get (inf);
+
+ if (per_inf == nullptr)
+ {
+ std::vector<CORE_ADDR> buffers;
+#if 0
+ /* Alternative implementation that maps some pages in the inferior,
+ allowing to have many buffers. */
+ CORE_ADDR displaced_step_mmap = gdbarch_infcall_mmap (arch, 16384, GDB_MMAP_PROT_READ | GDB_MMAP_PROT_EXEC);
+ gdb_assert (displaced_step_mmap != 0);
+
+ for (int i = 0; i < 1024; i++)
+ buffers.push_back (displaced_step_mmap + 16 * i);
+
+#else
+ /* Figure out where the displaced step buffers are. */
+ CORE_ADDR addr = linux_displaced_step_location (arch);
+ buffers.push_back (addr);
+ buffers.push_back (addr + gdbarch_max_insn_length (arch));
+#endif
+ per_inf = amd64_linux_per_inferior_data.emplace (inf, buffers);
+ }
+
+ CORE_ADDR addr = per_inf->disp_step_buf_mgr.first_buf_addr ();
+ CORE_ADDR cur_addr = linux_displaced_step_location (arch);
+ gdb_assert (addr == cur_addr);
+
+ return per_inf;
+}
+
+/* Implementation of the gdbarch_displaced_step_prepare method. */
+
+static displaced_step_prepare_status
+amd64_linux_displaced_step_prepare (gdbarch *arch, thread_info *thread)
+{
+ amd64_linux_per_inferior *per_inferior
+ = get_amd64_linux_per_inferior (thread->inf, arch);
+
+
+ return per_inferior->disp_step_buf_mgr.prepare (thread);
+}
+
+/* Implementation of the gdbarch_displaced_step_finish method. */
+
+static displaced_step_finish_status
+amd64_linux_displaced_step_finish (gdbarch *arch, thread_info *thread,
+ gdb_signal sig)
+{
+ amd64_linux_per_inferior *per_inferior
+ = get_amd64_linux_per_inferior (thread->inf, arch);
+
+ return per_inferior->disp_step_buf_mgr.finish (arch, thread, sig);
+}
+
static void
amd64_linux_init_abi_common(struct gdbarch_info info, struct gdbarch *gdbarch)
{
set_gdbarch_displaced_step_copy_insn (gdbarch,
amd64_displaced_step_copy_insn);
set_gdbarch_displaced_step_fixup (gdbarch, amd64_displaced_step_fixup);
- set_gdbarch_displaced_step_location (gdbarch,
- linux_displaced_step_location);
+ set_gdbarch_displaced_step_prepare (gdbarch, amd64_linux_displaced_step_prepare);
+ set_gdbarch_displaced_step_finish (gdbarch, amd64_linux_displaced_step_finish);
set_gdbarch_process_record (gdbarch, i386_process_record);
set_gdbarch_process_record_signal (gdbarch, amd64_linux_record_signal);
(gdbarch, svr4_ilp32_fetch_link_map_offsets);
}
+static void
+amd64_linux_inferior_appeared (inferior *inf)
+{
+ amd64_linux_per_inferior_data.clear (inf);
+}
+
+static void
+amd64_linux_inferior_execd (inferior *inf)
+{
+ amd64_linux_per_inferior_data.clear (inf);
+}
+
+void _initialize_amd64_linux_tdep ();
void
-_initialize_amd64_linux_tdep (void)
+_initialize_amd64_linux_tdep ()
{
gdbarch_register_osabi (bfd_arch_i386, bfd_mach_x86_64,
GDB_OSABI_LINUX, amd64_linux_init_abi);
gdbarch_register_osabi (bfd_arch_i386, bfd_mach_x64_32,
GDB_OSABI_LINUX, amd64_x32_linux_init_abi);
+
+ gdb::observers::inferior_appeared.attach (amd64_linux_inferior_appeared);
+ gdb::observers::inferior_execd.attach (amd64_linux_inferior_execd);
}