gdb: add target_ops::supports_displaced_step
[deliverable/binutils-gdb.git] / gdb / i386-linux-nat.c
index 70d954fdc00bc03b1d7053bbe26d13aeaad398d3..b4224b27c3a2d26f4e3841b5768fbc4c0aed5f92 100644 (file)
@@ -1,6 +1,6 @@
 /* Native-dependent code for GNU/Linux i386.
 
-   Copyright (C) 1999-2016 Free Software Foundation, Inc.
+   Copyright (C) 1999-2020 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
 #include "i387-tdep.h"
 #include "i386-tdep.h"
 #include "i386-linux-tdep.h"
-#include "x86-xstate.h"
+#include "gdbsupport/x86-xstate.h"
 
-#include "linux-nat.h"
 #include "x86-linux-nat.h"
 #include "nat/linux-ptrace.h"
+#include "inf-ptrace.h"
+
+struct i386_linux_nat_target final : public x86_linux_nat_target
+{
+  /* Add our register access methods.  */
+  void fetch_registers (struct regcache *, int) override;
+  void store_registers (struct regcache *, int) override;
+
+  /* Override the default ptrace resume method.  */
+  void low_resume (ptid_t ptid, int step, enum gdb_signal sig) override;
+};
+
+static i386_linux_nat_target the_i386_linux_nat_target;
 
 /* The register sets used in GNU/Linux ELF core-dumps are identical to
    the register sets in `struct user' that is used for a.out
@@ -59,7 +71,7 @@
   (I386_ST0_REGNUM <= (regno) && (regno) < I386_SSE_NUM_REGS)
 
 #define GETXSTATEREGS_SUPPLIES(regno) \
-  (I386_ST0_REGNUM <= (regno) && (regno) < I386_AVX512_NUM_REGS)
+  (I386_ST0_REGNUM <= (regno) && (regno) < I386_PKEYS_NUM_REGS)
 
 /* Does the current host support the GETREGS request?  */
 int have_ptrace_getregs =
@@ -94,30 +106,27 @@ int have_ptrace_getfpxregs =
 static void
 fetch_register (struct regcache *regcache, int regno)
 {
-  int tid;
+  pid_t tid;
   int val;
 
   gdb_assert (!have_ptrace_getregs);
   if (i386_linux_gregset_reg_offset[regno] == -1)
     {
-      regcache_raw_supply (regcache, regno, NULL);
+      regcache->raw_supply (regno, NULL);
       return;
     }
 
-  /* GNU/Linux LWP ID's are process ID's.  */
-  tid = ptid_get_lwp (inferior_ptid);
-  if (tid == 0)
-    tid = ptid_get_pid (inferior_ptid); /* Not a threaded program.  */
+  tid = get_ptrace_pid (regcache->ptid ());
 
   errno = 0;
   val = ptrace (PTRACE_PEEKUSER, tid,
                i386_linux_gregset_reg_offset[regno], 0);
   if (errno != 0)
     error (_("Couldn't read register %s (#%d): %s."), 
-          gdbarch_register_name (get_regcache_arch (regcache), regno),
+          gdbarch_register_name (regcache->arch (), regno),
           regno, safe_strerror (errno));
 
-  regcache_raw_supply (regcache, regno, &val);
+  regcache->raw_supply (regno, &val);
 }
 
 /* Store one register.  */
@@ -125,25 +134,22 @@ fetch_register (struct regcache *regcache, int regno)
 static void
 store_register (const struct regcache *regcache, int regno)
 {
-  int tid;
+  pid_t tid;
   int val;
 
   gdb_assert (!have_ptrace_getregs);
   if (i386_linux_gregset_reg_offset[regno] == -1)
     return;
 
-  /* GNU/Linux LWP ID's are process ID's.  */
-  tid = ptid_get_lwp (inferior_ptid);
-  if (tid == 0)
-    tid = ptid_get_pid (inferior_ptid); /* Not a threaded program.  */
+  tid = get_ptrace_pid (regcache->ptid ());
 
   errno = 0;
-  regcache_raw_collect (regcache, regno, &val);
+  regcache->raw_collect (regno, &val);
   ptrace (PTRACE_POKEUSER, tid,
          i386_linux_gregset_reg_offset[regno], val);
   if (errno != 0)
     error (_("Couldn't write register %s (#%d): %s."),
-          gdbarch_register_name (get_regcache_arch (regcache), regno),
+          gdbarch_register_name (regcache->arch (), regno),
           regno, safe_strerror (errno));
 }
 \f
@@ -161,13 +167,13 @@ supply_gregset (struct regcache *regcache, const elf_gregset_t *gregsetp)
   int i;
 
   for (i = 0; i < I386_NUM_GREGS; i++)
-    regcache_raw_supply (regcache, i,
-                        regp + i386_linux_gregset_reg_offset[i]);
+    regcache->raw_supply (i, regp + i386_linux_gregset_reg_offset[i]);
 
   if (I386_LINUX_ORIG_EAX_REGNUM
-       < gdbarch_num_regs (get_regcache_arch (regcache)))
-    regcache_raw_supply (regcache, I386_LINUX_ORIG_EAX_REGNUM, regp
-                        + i386_linux_gregset_reg_offset[I386_LINUX_ORIG_EAX_REGNUM]);
+       < gdbarch_num_regs (regcache->arch ()))
+    regcache->raw_supply
+      (I386_LINUX_ORIG_EAX_REGNUM,
+       regp + i386_linux_gregset_reg_offset[I386_LINUX_ORIG_EAX_REGNUM]);
 }
 
 /* Fill register REGNO (if it is a general-purpose register) in
@@ -183,14 +189,14 @@ fill_gregset (const struct regcache *regcache,
 
   for (i = 0; i < I386_NUM_GREGS; i++)
     if (regno == -1 || regno == i)
-      regcache_raw_collect (regcache, i,
-                           regp + i386_linux_gregset_reg_offset[i]);
+      regcache->raw_collect (i, regp + i386_linux_gregset_reg_offset[i]);
 
   if ((regno == -1 || regno == I386_LINUX_ORIG_EAX_REGNUM)
       && I386_LINUX_ORIG_EAX_REGNUM
-          < gdbarch_num_regs (get_regcache_arch (regcache)))
-    regcache_raw_collect (regcache, I386_LINUX_ORIG_EAX_REGNUM, regp
-                         + i386_linux_gregset_reg_offset[I386_LINUX_ORIG_EAX_REGNUM]);
+          < gdbarch_num_regs (regcache->arch ()))
+    regcache->raw_collect
+      (I386_LINUX_ORIG_EAX_REGNUM,
+       regp + i386_linux_gregset_reg_offset[I386_LINUX_ORIG_EAX_REGNUM]);
 }
 
 #ifdef HAVE_PTRACE_GETREGS
@@ -451,11 +457,10 @@ store_fpxregs (const struct regcache *regcache, int tid, int regno)
    this for all registers (including the floating point and SSE
    registers).  */
 
-static void
-i386_linux_fetch_inferior_registers (struct target_ops *ops,
-                                    struct regcache *regcache, int regno)
+void
+i386_linux_nat_target::fetch_registers (struct regcache *regcache, int regno)
 {
-  int tid;
+  pid_t tid;
 
   /* Use the old method of peeking around in `struct user' if the
      GETREGS request isn't available.  */
@@ -463,17 +468,14 @@ i386_linux_fetch_inferior_registers (struct target_ops *ops,
     {
       int i;
 
-      for (i = 0; i < gdbarch_num_regs (get_regcache_arch (regcache)); i++)
+      for (i = 0; i < gdbarch_num_regs (regcache->arch ()); i++)
        if (regno == -1 || regno == i)
          fetch_register (regcache, i);
 
       return;
     }
 
-  /* GNU/Linux LWP ID's are process ID's.  */
-  tid = ptid_get_lwp (inferior_ptid);
-  if (tid == 0)
-    tid = ptid_get_pid (inferior_ptid); /* Not a threaded program.  */
+  tid = get_ptrace_pid (regcache->ptid ());
 
   /* Use the PTRACE_GETFPXREGS request whenever possible, since it
      transfers more registers in one system call, and we'll cache the
@@ -486,7 +488,7 @@ i386_linux_fetch_inferior_registers (struct target_ops *ops,
       /* The call above might reset `have_ptrace_getregs'.  */
       if (!have_ptrace_getregs)
        {
-         i386_linux_fetch_inferior_registers (ops, regcache, regno);
+         fetch_registers (regcache, regno);
          return;
        }
 
@@ -532,11 +534,10 @@ i386_linux_fetch_inferior_registers (struct target_ops *ops,
 /* Store register REGNO back into the child process.  If REGNO is -1,
    do this for all registers (including the floating point and SSE
    registers).  */
-static void
-i386_linux_store_inferior_registers (struct target_ops *ops,
-                                    struct regcache *regcache, int regno)
+void
+i386_linux_nat_target::store_registers (struct regcache *regcache, int regno)
 {
-  int tid;
+  pid_t tid;
 
   /* Use the old method of poking around in `struct user' if the
      SETREGS request isn't available.  */
@@ -544,17 +545,14 @@ i386_linux_store_inferior_registers (struct target_ops *ops,
     {
       int i;
 
-      for (i = 0; i < gdbarch_num_regs (get_regcache_arch (regcache)); i++)
+      for (i = 0; i < gdbarch_num_regs (regcache->arch ()); i++)
        if (regno == -1 || regno == i)
          store_register (regcache, i);
 
       return;
     }
 
-  /* GNU/Linux LWP ID's are process ID's.  */
-  tid = ptid_get_lwp (inferior_ptid);
-  if (tid == 0)
-    tid = ptid_get_pid (inferior_ptid); /* Not a threaded program.  */
+  tid = get_ptrace_pid (regcache->ptid ());
 
   /* Use the PTRACE_SETFPXREGS requests whenever possible, since it
      transfers more registers in one system call.  But remember that
@@ -646,11 +644,10 @@ static const unsigned char linux_syscall[] = { 0xcd, 0x80 };
    If STEP is nonzero, single-step it.
    If SIGNAL is nonzero, give it that signal.  */
 
-static void
-i386_linux_resume (struct target_ops *ops,
-                  ptid_t ptid, int step, enum gdb_signal signal)
+void
+i386_linux_nat_target::low_resume (ptid_t ptid, int step, enum gdb_signal signal)
 {
-  int pid = ptid_get_lwp (ptid);
+  int pid = ptid.lwp ();
   int request;
 
   if (catch_syscall_enabled () > 0)
@@ -660,8 +657,8 @@ i386_linux_resume (struct target_ops *ops,
 
   if (step)
     {
-      struct regcache *regcache = get_thread_regcache (ptid);
-      struct gdbarch *gdbarch = get_regcache_arch (regcache);
+      struct regcache *regcache = get_thread_regcache (this, ptid);
+      struct gdbarch *gdbarch = regcache->arch ();
       enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
       ULONGEST pc;
       gdb_byte buf[LINUX_SYSCALL_LEN];
@@ -713,24 +710,13 @@ i386_linux_resume (struct target_ops *ops,
   if (ptrace (request, pid, 0, gdb_signal_to_host (signal)) == -1)
     perror_with_name (("ptrace"));
 }
-\f
-
-/* -Wmissing-prototypes */
-extern initialize_file_ftype _initialize_i386_linux_nat;
 
+void _initialize_i386_linux_nat ();
 void
-_initialize_i386_linux_nat (void)
+_initialize_i386_linux_nat ()
 {
-  /* Create a generic x86 GNU/Linux target.  */
-  struct target_ops *t = x86_linux_create_target ();
-
-  /* Override the default ptrace resume method.  */
-  t->to_resume = i386_linux_resume;
-
-  /* Add our register access methods.  */
-  t->to_fetch_registers = i386_linux_fetch_inferior_registers;
-  t->to_store_registers = i386_linux_store_inferior_registers;
+  linux_target = &the_i386_linux_nat_target;
 
   /* Add the target.  */
-  x86_linux_add_target (t);
+  add_inf_child_target (linux_target);
 }
This page took 0.040085 seconds and 4 git commands to generate.