gdb/amd64bsd-nat.c - gdb

Functions defined

Source code

  1. /* Native-dependent code for AMD64 BSD's.

  2.    Copyright (C) 2003-2015 Free Software Foundation, Inc.

  3.    This file is part of GDB.

  4.    This program is free software; you can redistribute it and/or modify
  5.    it under the terms of the GNU General Public License as published by
  6.    the Free Software Foundation; either version 3 of the License, or
  7.    (at your option) any later version.

  8.    This program is distributed in the hope that it will be useful,
  9.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  10.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  11.    GNU General Public License for more details.

  12.    You should have received a copy of the GNU General Public License
  13.    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

  14. #include "defs.h"
  15. #include "inferior.h"
  16. #include "regcache.h"
  17. #include "target.h"

  18. /* We include <signal.h> to make sure `struct fxsave64' is defined on
  19.    NetBSD, since NetBSD's <machine/reg.h> needs it.  */
  20. #include <signal.h>
  21. #include <sys/types.h>
  22. #include <sys/ptrace.h>
  23. #include <machine/reg.h>

  24. #include "amd64-tdep.h"
  25. #include "amd64-nat.h"
  26. #include "amd64bsd-nat.h"
  27. #include "inf-ptrace.h"


  28. /* Fetch register REGNUM from the inferior.  If REGNUM is -1, do this
  29.    for all registers (including the floating-point registers).  */

  30. static void
  31. amd64bsd_fetch_inferior_registers (struct target_ops *ops,
  32.                                    struct regcache *regcache, int regnum)
  33. {
  34.   struct gdbarch *gdbarch = get_regcache_arch (regcache);

  35.   if (regnum == -1 || amd64_native_gregset_supplies_p (gdbarch, regnum))
  36.     {
  37.       struct reg regs;

  38.       if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
  39.                   (PTRACE_TYPE_ARG3) &regs, 0) == -1)
  40.         perror_with_name (_("Couldn't get registers"));

  41.       amd64_supply_native_gregset (regcache, &regs, -1);
  42.       if (regnum != -1)
  43.         return;
  44.     }

  45.   if (regnum == -1 || !amd64_native_gregset_supplies_p (gdbarch, regnum))
  46.     {
  47.       struct fpreg fpregs;

  48.       if (ptrace (PT_GETFPREGS, ptid_get_pid (inferior_ptid),
  49.                   (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
  50.         perror_with_name (_("Couldn't get floating point status"));

  51.       amd64_supply_fxsave (regcache, -1, &fpregs);
  52.     }
  53. }

  54. /* Store register REGNUM back into the inferior.  If REGNUM is -1, do
  55.    this for all registers (including the floating-point registers).  */

  56. static void
  57. amd64bsd_store_inferior_registers (struct target_ops *ops,
  58.                                    struct regcache *regcache, int regnum)
  59. {
  60.   struct gdbarch *gdbarch = get_regcache_arch (regcache);

  61.   if (regnum == -1 || amd64_native_gregset_supplies_p (gdbarch, regnum))
  62.     {
  63.       struct reg regs;

  64.       if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
  65.                   (PTRACE_TYPE_ARG3) &regs, 0) == -1)
  66.         perror_with_name (_("Couldn't get registers"));

  67.       amd64_collect_native_gregset (regcache, &regs, regnum);

  68.       if (ptrace (PT_SETREGS, ptid_get_pid (inferior_ptid),
  69.                   (PTRACE_TYPE_ARG3) &regs, 0) == -1)
  70.         perror_with_name (_("Couldn't write registers"));

  71.       if (regnum != -1)
  72.         return;
  73.     }

  74.   if (regnum == -1 || !amd64_native_gregset_supplies_p (gdbarch, regnum))
  75.     {
  76.       struct fpreg fpregs;

  77.       if (ptrace (PT_GETFPREGS, ptid_get_pid (inferior_ptid),
  78.                   (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
  79.         perror_with_name (_("Couldn't get floating point status"));

  80.       amd64_collect_fxsave (regcache, regnum, &fpregs);

  81.       if (ptrace (PT_SETFPREGS, ptid_get_pid (inferior_ptid),
  82.                   (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
  83.         perror_with_name (_("Couldn't write floating point status"));
  84.     }
  85. }

  86. /* Create a prototype *BSD/amd64 target.  The client can override it
  87.    with local methods.  */

  88. struct target_ops *
  89. amd64bsd_target (void)
  90. {
  91.   struct target_ops *t;

  92.   t = inf_ptrace_target ();
  93.   t->to_fetch_registers = amd64bsd_fetch_inferior_registers;
  94.   t->to_store_registers = amd64bsd_store_inferior_registers;
  95.   return t;
  96. }


  97. /* Support for debug registers.  */

  98. #ifdef HAVE_PT_GETDBREGS

  99. static unsigned long
  100. amd64bsd_dr_get (ptid_t ptid, int regnum)
  101. {
  102.   struct dbreg dbregs;

  103.   if (ptrace (PT_GETDBREGS, ptid_get_pid (inferior_ptid),
  104.               (PTRACE_TYPE_ARG3) &dbregs, 0) == -1)
  105.     perror_with_name (_("Couldn't read debug registers"));

  106.   return DBREG_DRX ((&dbregs), regnum);
  107. }

  108. static void
  109. amd64bsd_dr_set (int regnum, unsigned long value)
  110. {
  111.   struct dbreg dbregs;

  112.   if (ptrace (PT_GETDBREGS, ptid_get_pid (inferior_ptid),
  113.               (PTRACE_TYPE_ARG3) &dbregs, 0) == -1)
  114.     perror_with_name (_("Couldn't get debug registers"));

  115.   /* For some mysterious reason, some of the reserved bits in the
  116.      debug control register get set.  Mask these off, otherwise the
  117.      ptrace call below will fail.  */
  118.   DBREG_DRX ((&dbregs), 7) &= ~(0xffffffff0000fc00);

  119.   DBREG_DRX ((&dbregs), regnum) = value;

  120.   if (ptrace (PT_SETDBREGS, ptid_get_pid (inferior_ptid),
  121.               (PTRACE_TYPE_ARG3) &dbregs, 0) == -1)
  122.     perror_with_name (_("Couldn't write debug registers"));
  123. }

  124. void
  125. amd64bsd_dr_set_control (unsigned long control)
  126. {
  127.   amd64bsd_dr_set (7, control);
  128. }

  129. void
  130. amd64bsd_dr_set_addr (int regnum, CORE_ADDR addr)
  131. {
  132.   gdb_assert (regnum >= 0 && regnum <= 4);

  133.   amd64bsd_dr_set (regnum, addr);
  134. }

  135. CORE_ADDR
  136. amd64bsd_dr_get_addr (int regnum)
  137. {
  138.   return amd64bsd_dr_get (inferior_ptid, regnum);
  139. }

  140. unsigned long
  141. amd64bsd_dr_get_status (void)
  142. {
  143.   return amd64bsd_dr_get (inferior_ptid, 6);
  144. }

  145. unsigned long
  146. amd64bsd_dr_get_control (void)
  147. {
  148.   return amd64bsd_dr_get (inferior_ptid, 7);
  149. }

  150. #endif /* PT_GETDBREGS */