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>
Thu, 4 Jun 2020 19:04:21 +0000 (15:04 -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 4cb33d5b5d2a55cfa51ae98951ae97088c74631e..ef19be275f3e16c4ec16fe52c1d47d5fdf10e081 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
 _initialize_amd64_linux_tdep ()
@@ -2336,4 +2367,7 @@ _initialize_amd64_linux_tdep ()
                          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 ec06e5703bea7f6ea5d295320bebbb17e8e8b5e5..284353004d99baa61a6592d2651b5c57544f9761 100644 (file)
@@ -1269,6 +1269,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 81aa392cc21fe8fad8d86f422e53fae24aa25c4a..8462b44c25d0b00d77b2f8bb89ac77b6b07b214d 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 070cf0f18e5197bad9c41e9fe7521dfb91fc9a0b..eafcfb29382c26e63819282d68f25e9732c7223a 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.029711 seconds and 4 git commands to generate.