gdb: add cmd_list_element::is_command_class_help
[deliverable/binutils-gdb.git] / gdb / rs6000-nat.c
index 833cf01619593f1f737405b53ea5fb05b8b15b89..50c96e281c64abb5590187a890f3ae3e60042794 100644 (file)
@@ -1,6 +1,6 @@
 /* IBM RS/6000 native-dependent code for GDB, the GNU debugger.
 
-   Copyright (C) 1986-2017 Free Software Foundation, Inc.
+   Copyright (C) 1986-2021 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -33,7 +33,7 @@
 #include "rs6000-tdep.h"
 #include "rs6000-aix-tdep.h"
 #include "exec.h"
-#include "observer.h"
+#include "observable.h"
 #include "xcoffread.h"
 
 #include <sys/ptrace.h>
 # define ARCH64() (register_size (target_gdbarch (), 0) == 8)
 #endif
 
-static target_xfer_partial_ftype rs6000_xfer_shared_libraries;
+class rs6000_nat_target final : public inf_ptrace_target
+{
+public:
+  void fetch_registers (struct regcache *, int) override;
+  void store_registers (struct regcache *, int) override;
+
+  enum target_xfer_status xfer_partial (enum target_object object,
+                                       const char *annex,
+                                       gdb_byte *readbuf,
+                                       const gdb_byte *writebuf,
+                                       ULONGEST offset, ULONGEST len,
+                                       ULONGEST *xfered_len) override;
+
+  void create_inferior (const char *, const std::string &,
+                       char **, int) override;
+
+  ptid_t wait (ptid_t, struct target_waitstatus *, target_wait_flags) override;
+
+private:
+  enum target_xfer_status
+    xfer_shared_libraries (enum target_object object,
+                          const char *annex, gdb_byte *readbuf,
+                          const gdb_byte *writebuf,
+                          ULONGEST offset, ULONGEST len,
+                          ULONGEST *xfered_len);
+};
+
+static rs6000_nat_target the_rs6000_nat_target;
 
 /* Given REGNO, a gdb register number, return the corresponding
    number suitable for use as a ptrace() parameter.  Return -1 if
@@ -91,8 +118,8 @@ regmap (struct gdbarch *gdbarch, int regno, int *isfloat)
       && regno < tdep->ppc_gp0_regnum + ppc_num_gprs)
     return regno;
   else if (tdep->ppc_fp0_regnum >= 0
-           && tdep->ppc_fp0_regnum <= regno
-           && regno < tdep->ppc_fp0_regnum + ppc_num_fprs)
+          && tdep->ppc_fp0_regnum <= regno
+          && regno < tdep->ppc_fp0_regnum + ppc_num_fprs)
     {
       *isfloat = 1;
       return regno - tdep->ppc_fp0_regnum + FPR0;
@@ -110,7 +137,7 @@ regmap (struct gdbarch *gdbarch, int regno, int *isfloat)
   else if (regno == tdep->ppc_xer_regnum)
     return XER;
   else if (tdep->ppc_fpscr_regnum >= 0
-           && regno == tdep->ppc_fpscr_regnum)
+          && regno == tdep->ppc_fpscr_regnum)
     return FPSCR;
   else if (tdep->ppc_mq_regnum >= 0 && regno == tdep->ppc_mq_regnum)
     return MQ;
@@ -161,10 +188,10 @@ rs6000_ptrace64 (int req, int id, long long addr, int data, void *buf)
 static void
 fetch_register (struct regcache *regcache, int regno)
 {
-  struct gdbarch *gdbarch = get_regcache_arch (regcache);
+  struct gdbarch *gdbarch = regcache->arch ();
   int addr[PPC_MAX_REGISTER_SIZE];
   int nr, isfloat;
-  pid_t pid = ptid_get_pid (regcache_get_ptid (regcache));
+  pid_t pid = regcache->ptid ().pid ();
 
   /* Retrieved values may be -1, so infer errors from errno.  */
   errno = 0;
@@ -204,7 +231,7 @@ fetch_register (struct regcache *regcache, int regno)
     }
 
   if (!errno)
-    regcache_raw_supply (regcache, regno, (char *) addr);
+    regcache->raw_supply (regno, (char *) addr);
   else
     {
 #if 0
@@ -220,13 +247,13 @@ fetch_register (struct regcache *regcache, int regno)
 static void
 store_register (struct regcache *regcache, int regno)
 {
-  struct gdbarch *gdbarch = get_regcache_arch (regcache);
+  struct gdbarch *gdbarch = regcache->arch ();
   int addr[PPC_MAX_REGISTER_SIZE];
   int nr, isfloat;
-  pid_t pid = ptid_get_pid (regcache_get_ptid (regcache));
+  pid_t pid = regcache->ptid ().pid ();
 
   /* Fetch the register's value from the register cache.  */
-  regcache_raw_collect (regcache, regno, addr);
+  regcache->raw_collect (regno, addr);
 
   /* -1 can be a successful return value, so infer errors from errno.  */
   errno = 0;
@@ -250,7 +277,7 @@ store_register (struct regcache *regcache, int regno)
   else
     {
       /* The PT_WRITE_GPR operation is rather odd.  For 32-bit inferiors,
-         the register's value is passed by value, but for 64-bit inferiors,
+        the register's value is passed by value, but for 64-bit inferiors,
         the address of a buffer containing the value is passed.  */
       if (!ARCH64 ())
        rs6000_ptrace32 (PT_WRITE_GPR, pid, (int *) nr, *addr, 0);
@@ -277,11 +304,10 @@ store_register (struct regcache *regcache, int regno)
 /* Read from the inferior all registers if REGNO == -1 and just register
    REGNO otherwise.  */
 
-static void
-rs6000_fetch_inferior_registers (struct target_ops *ops,
-                                struct regcache *regcache, int regno)
+void
+rs6000_nat_target::fetch_registers (struct regcache *regcache, int regno)
 {
-  struct gdbarch *gdbarch = get_regcache_arch (regcache);
+  struct gdbarch *gdbarch = regcache->arch ();
   if (regno != -1)
     fetch_register (regcache, regno);
 
@@ -291,7 +317,7 @@ rs6000_fetch_inferior_registers (struct target_ops *ops,
 
       /* Read 32 general purpose registers.  */
       for (regno = tdep->ppc_gp0_regnum;
-           regno < tdep->ppc_gp0_regnum + ppc_num_gprs;
+          regno < tdep->ppc_gp0_regnum + ppc_num_gprs;
           regno++)
        {
          fetch_register (regcache, regno);
@@ -299,8 +325,8 @@ rs6000_fetch_inferior_registers (struct target_ops *ops,
 
       /* Read general purpose floating point registers.  */
       if (tdep->ppc_fp0_regnum >= 0)
-        for (regno = 0; regno < ppc_num_fprs; regno++)
-          fetch_register (regcache, tdep->ppc_fp0_regnum + regno);
+       for (regno = 0; regno < ppc_num_fprs; regno++)
+         fetch_register (regcache, tdep->ppc_fp0_regnum + regno);
 
       /* Read special registers.  */
       fetch_register (regcache, gdbarch_pc_regnum (gdbarch));
@@ -310,7 +336,7 @@ rs6000_fetch_inferior_registers (struct target_ops *ops,
       fetch_register (regcache, tdep->ppc_ctr_regnum);
       fetch_register (regcache, tdep->ppc_xer_regnum);
       if (tdep->ppc_fpscr_regnum >= 0)
-        fetch_register (regcache, tdep->ppc_fpscr_regnum);
+       fetch_register (regcache, tdep->ppc_fpscr_regnum);
       if (tdep->ppc_mq_regnum >= 0)
        fetch_register (regcache, tdep->ppc_mq_regnum);
     }
@@ -320,11 +346,10 @@ rs6000_fetch_inferior_registers (struct target_ops *ops,
    If REGNO is -1, do this for all registers.
    Otherwise, REGNO specifies which register (so we can save time).  */
 
-static void
-rs6000_store_inferior_registers (struct target_ops *ops,
-                                struct regcache *regcache, int regno)
+void
+rs6000_nat_target::store_registers (struct regcache *regcache, int regno)
 {
-  struct gdbarch *gdbarch = get_regcache_arch (regcache);
+  struct gdbarch *gdbarch = regcache->arch ();
   if (regno != -1)
     store_register (regcache, regno);
 
@@ -334,7 +359,7 @@ rs6000_store_inferior_registers (struct target_ops *ops,
 
       /* Write general purpose registers first.  */
       for (regno = tdep->ppc_gp0_regnum;
-           regno < tdep->ppc_gp0_regnum + ppc_num_gprs;
+          regno < tdep->ppc_gp0_regnum + ppc_num_gprs;
           regno++)
        {
          store_register (regcache, regno);
@@ -342,8 +367,8 @@ rs6000_store_inferior_registers (struct target_ops *ops,
 
       /* Write floating point registers.  */
       if (tdep->ppc_fp0_regnum >= 0)
-        for (regno = 0; regno < ppc_num_fprs; regno++)
-          store_register (regcache, tdep->ppc_fp0_regnum + regno);
+       for (regno = 0; regno < ppc_num_fprs; regno++)
+         store_register (regcache, tdep->ppc_fp0_regnum + regno);
 
       /* Write special registers.  */
       store_register (regcache, gdbarch_pc_regnum (gdbarch));
@@ -353,7 +378,7 @@ rs6000_store_inferior_registers (struct target_ops *ops,
       store_register (regcache, tdep->ppc_ctr_regnum);
       store_register (regcache, tdep->ppc_xer_regnum);
       if (tdep->ppc_fpscr_regnum >= 0)
-        store_register (regcache, tdep->ppc_fpscr_regnum);
+       store_register (regcache, tdep->ppc_fpscr_regnum);
       if (tdep->ppc_mq_regnum >= 0)
        store_register (regcache, tdep->ppc_mq_regnum);
     }
@@ -361,21 +386,22 @@ rs6000_store_inferior_registers (struct target_ops *ops,
 
 /* Implement the to_xfer_partial target_ops method.  */
 
-static enum target_xfer_status
-rs6000_xfer_partial (struct target_ops *ops, enum target_object object,
-                    const char *annex, gdb_byte *readbuf,
-                    const gdb_byte *writebuf,
-                    ULONGEST offset, ULONGEST len, ULONGEST *xfered_len)
+enum target_xfer_status
+rs6000_nat_target::xfer_partial (enum target_object object,
+                                const char *annex, gdb_byte *readbuf,
+                                const gdb_byte *writebuf,
+                                ULONGEST offset, ULONGEST len,
+                                ULONGEST *xfered_len)
 {
-  pid_t pid = ptid_get_pid (inferior_ptid);
+  pid_t pid = inferior_ptid.pid ();
   int arch64 = ARCH64 ();
 
   switch (object)
     {
     case TARGET_OBJECT_LIBRARIES_AIX:
-      return rs6000_xfer_shared_libraries (ops, object, annex,
-                                          readbuf, writebuf,
-                                          offset, len, xfered_len);
+      return xfer_shared_libraries (object, annex,
+                                   readbuf, writebuf,
+                                   offset, len, xfered_len);
     case TARGET_OBJECT_MEMORY:
       {
        union
@@ -467,9 +493,9 @@ rs6000_xfer_partial (struct target_ops *ops, enum target_object object,
    process ID of the child, or MINUS_ONE_PTID in case of error; store
    the status in *OURSTATUS.  */
 
-static ptid_t
-rs6000_wait (struct target_ops *ops,
-            ptid_t ptid, struct target_waitstatus *ourstatus, int options)
+ptid_t
+rs6000_nat_target::wait (ptid_t ptid, struct target_waitstatus *ourstatus,
+                        target_wait_flags options)
 {
   pid_t pid;
   int status, save_errno;
@@ -480,7 +506,7 @@ rs6000_wait (struct target_ops *ops,
 
       do
        {
-         pid = waitpid (ptid_get_pid (ptid), &status, 0);
+         pid = waitpid (ptid.pid (), &status, 0);
          save_errno = errno;
        }
       while (pid == -1 && errno == EINTR);
@@ -500,7 +526,7 @@ rs6000_wait (struct target_ops *ops,
        }
 
       /* Ignore terminated detached child processes.  */
-      if (!WIFSTOPPED (status) && pid != ptid_get_pid (inferior_ptid))
+      if (!WIFSTOPPED (status) && pid != inferior_ptid.pid ())
        pid = -1;
     }
   while (pid == -1);
@@ -517,27 +543,24 @@ rs6000_wait (struct target_ops *ops,
   else
     store_waitstatus (ourstatus, status);
 
-  return pid_to_ptid (pid);
+  return ptid_t (pid);
 }
 \f
 
 /* Set the current architecture from the host running GDB.  Called when
    starting a child process.  */
 
-static void (*super_create_inferior) (struct target_ops *,
-                                     const char *exec_file,
-                                     const std::string &allargs,
-                                     char **env, int from_tty);
-static void
-rs6000_create_inferior (struct target_ops * ops, const char *exec_file,
-                       const std::string &allargs, char **env, int from_tty)
+void
+rs6000_nat_target::create_inferior (const char *exec_file,
+                                   const std::string &allargs,
+                                   char **env, int from_tty)
 {
   enum bfd_architecture arch;
   unsigned long mach;
   bfd abfd;
   struct gdbarch_info info;
 
-  super_create_inferior (ops, exec_file, allargs, env, from_tty);
+  inf_ptrace_target::create_inferior (exec_file, allargs, env, from_tty);
 
   if (__power_rs ())
     {
@@ -558,11 +581,12 @@ rs6000_create_inferior (struct target_ops * ops, const char *exec_file,
      Blindly calling rs6000_gdbarch_init used to work in older versions of
      GDB, as rs6000_gdbarch_init incorrectly used the previous tdep to
      determine the wordsize.  */
-  if (exec_bfd)
+  if (current_program_space->exec_bfd ())
     {
       const struct bfd_arch_info *exec_bfd_arch_info;
 
-      exec_bfd_arch_info = bfd_get_arch_info (exec_bfd);
+      exec_bfd_arch_info
+       = bfd_get_arch_info (current_program_space->exec_bfd ());
       if (arch == exec_bfd_arch_info->arch)
        return;
     }
@@ -571,7 +595,7 @@ rs6000_create_inferior (struct target_ops * ops, const char *exec_file,
 
   gdbarch_info_init (&info);
   info.bfd_arch_info = bfd_get_arch_info (&abfd);
-  info.abfd = exec_bfd;
+  info.abfd = current_program_space->exec_bfd ();
 
   if (!gdbarch_update_p (info))
     internal_error (__FILE__, __LINE__,
@@ -583,25 +607,23 @@ rs6000_create_inferior (struct target_ops * ops, const char *exec_file,
 /* Shared Object support.  */
 
 /* Return the LdInfo data for the given process.  Raises an error
-   if the data could not be obtained.
-
-   The returned value must be deallocated after use.  */
+   if the data could not be obtained.  */
 
-static gdb_byte *
+static gdb::byte_vector
 rs6000_ptrace_ldinfo (ptid_t ptid)
 {
-  const int pid = ptid_get_pid (ptid);
-  int ldi_size = 1024;
-  void *ldi = xmalloc (ldi_size);
+  const int pid = ptid.pid ();
+  gdb::byte_vector ldi (1024);
   int rc = -1;
 
   while (1)
     {
       if (ARCH64 ())
-       rc = rs6000_ptrace64 (PT_LDINFO, pid, (unsigned long) ldi, ldi_size,
-                             NULL);
+       rc = rs6000_ptrace64 (PT_LDINFO, pid, (unsigned long) ldi.data (),
+                             ldi.size (), NULL);
       else
-       rc = rs6000_ptrace32 (PT_LDINFO, pid, (int *) ldi, ldi_size, NULL);
+       rc = rs6000_ptrace32 (PT_LDINFO, pid, (int *) ldi.data (),
+                             ldi.size (), NULL);
 
       if (rc != -1)
        break; /* Success, we got the entire ld_info data.  */
@@ -610,41 +632,33 @@ rs6000_ptrace_ldinfo (ptid_t ptid)
        perror_with_name (_("ptrace ldinfo"));
 
       /* ldi is not big enough.  Double it and try again.  */
-      ldi_size *= 2;
-      ldi = xrealloc (ldi, ldi_size);
+      ldi.resize (ldi.size () * 2);
     }
 
-  return (gdb_byte *) ldi;
+  return ldi;
 }
 
 /* Implement the to_xfer_partial target_ops method for
    TARGET_OBJECT_LIBRARIES_AIX objects.  */
 
-static enum target_xfer_status
-rs6000_xfer_shared_libraries
-  (struct target_ops *ops, enum target_object object,
+enum target_xfer_status
+rs6000_nat_target::xfer_shared_libraries
+  (enum target_object object,
    const char *annex, gdb_byte *readbuf, const gdb_byte *writebuf,
    ULONGEST offset, ULONGEST len, ULONGEST *xfered_len)
 {
-  gdb_byte *ldi_buf;
   ULONGEST result;
-  struct cleanup *cleanup;
 
   /* This function assumes that it is being run with a live process.
      Core files are handled via gdbarch.  */
-  gdb_assert (target_has_execution);
+  gdb_assert (target_has_execution ());
 
   if (writebuf)
     return TARGET_XFER_E_IO;
 
-  ldi_buf = rs6000_ptrace_ldinfo (inferior_ptid);
-  gdb_assert (ldi_buf != NULL);
-  cleanup = make_cleanup (xfree, ldi_buf);
-  result = rs6000_aix_ld_info_to_xml (target_gdbarch (), ldi_buf,
+  gdb::byte_vector ldi_buf = rs6000_ptrace_ldinfo (inferior_ptid);
+  result = rs6000_aix_ld_info_to_xml (target_gdbarch (), ldi_buf.data (),
                                      readbuf, offset, len, 1);
-  xfree (ldi_buf);
-
-  do_cleanups (cleanup);
 
   if (result == 0)
     return TARGET_XFER_EOF;
@@ -655,22 +669,9 @@ rs6000_xfer_shared_libraries
     }
 }
 
-void _initialize_rs6000_nat (void);
-
+void _initialize_rs6000_nat ();
 void
-_initialize_rs6000_nat (void)
+_initialize_rs6000_nat ()
 {
-  struct target_ops *t;
-
-  t = inf_ptrace_target ();
-  t->to_fetch_registers = rs6000_fetch_inferior_registers;
-  t->to_store_registers = rs6000_store_inferior_registers;
-  t->to_xfer_partial = rs6000_xfer_partial;
-
-  super_create_inferior = t->to_create_inferior;
-  t->to_create_inferior = rs6000_create_inferior;
-
-  t->to_wait = rs6000_wait;
-
-  add_target (t);
+  add_inf_child_target (&the_rs6000_nat_target);
 }
This page took 0.031042 seconds and 4 git commands to generate.