gdb: use two displaced step buffers on amd64-linux
authorSimon Marchi <simon.marchi@efficios.com>
Mon, 16 Mar 2020 21:36:09 +0000 (17:36 -0400)
committerSimon Marchi <simon.marchi@efficios.com>
Wed, 10 Jun 2020 21:26:05 +0000 (17:26 -0400)
At least as observed with gcc 9, there is enough space at _start to have
two displaced stepping buffers of 16 bytes.

An alternative way is to call mmap in the inferior to allocate one or
more executable pages.  However, this is more intrusive.

gdb/amd64-linux-tdep.c
gdb/displaced-stepping.h
gdb/infrun.c
gdb/observable.c
gdb/observable.h

index 58532fdf26a17d5c7a144c1b2187d68b2e43d02c..94ed694c1db5a5e847e6fc4d00da24bc6ed835c7 100644 (file)
@@ -44,6 +44,7 @@
 #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"
@@ -1818,12 +1819,29 @@ get_amd64_linux_per_inferior (inferior *inf, gdbarch *arch)
 
   if (per_inf == nullptr)
     {
-      /* Figure out where the displaced step buffer is.  */
-      CORE_ADDR disp_step_buffer_addr = linux_displaced_step_location (arch);
-
-      per_inf = amd64_linux_per_inferior_data.emplace (inf, disp_step_buffer_addr);
+      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;
 }
 
@@ -1835,6 +1853,7 @@ 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);
 }
 
@@ -2328,6 +2347,18 @@ amd64_x32_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
     (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)
 {
@@ -2335,4 +2366,7 @@ _initialize_amd64_linux_tdep (void)
                          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);
 }
index 7bb02b3bbfc736e1a0984e80ec97bba859fe9ea2..e637c3892505c2e341be78a6bdf1e81b680dca94 100644 (file)
@@ -142,6 +142,11 @@ struct multiple_displaced_buffer_manager
   displaced_step_finish_status finish (gdbarch *arch, thread_info *thread,
                                       gdb_signal sig);
 
+  CORE_ADDR first_buf_addr () const
+    {
+      return m_buffers[0].m_buffer_addr;
+    }
+
 private:
   std::vector<displaced_step_buffer_state> m_buffers;
 };
index 80a0c0ad619010a1c9bcaed7cccabe02981d0dbd..89a250a9599b1eede5707f071aed893de4a53dd7 100644 (file)
@@ -1236,6 +1236,8 @@ follow_exec (ptid_t ptid, const char *exec_file_target)
      to symbol_file_command...).  */
   insert_breakpoints ();
 
+  gdb::observers::inferior_execd.notify (inf);
+
   /* The next resume of this inferior should bring it to the shlib
      startup breakpoints.  (If the user had also set bp's on
      "main" from the old (parent) process, then they'll auto-
index da6f50384d017820866f8272ce2d5d96f491b245..5d712e49fadad42121692bf0774b98258486c153 100644 (file)
@@ -63,6 +63,7 @@ DEFINE_OBSERVABLE (inferior_added);
 DEFINE_OBSERVABLE (inferior_appeared);
 DEFINE_OBSERVABLE (inferior_exit);
 DEFINE_OBSERVABLE (inferior_removed);
+DEFINE_OBSERVABLE (inferior_execd);
 DEFINE_OBSERVABLE (memory_changed);
 DEFINE_OBSERVABLE (before_prompt);
 DEFINE_OBSERVABLE (gdb_datadir_changed);
index 18146470562f0cefe8305518d8b72bb9655d7505..a8ead2c0e1886eb5663d7c44b30d49c6df6cb7cf 100644 (file)
@@ -184,6 +184,9 @@ extern observable<struct inferior */* inf */> inferior_exit;
    This method is called immediately before freeing INF.  */
 extern observable<struct inferior */* inf */> inferior_removed;
 
+/* The inferior INF has exec'ed a new executable file.  */
+extern observable<struct inferior */* inf */> inferior_execd;
+
 /* Bytes from DATA to DATA + LEN have been written to the inferior
    at ADDR.  */
 extern observable<struct inferior */* inferior */, CORE_ADDR /* addr */,
This page took 0.028756 seconds and 4 git commands to generate.