GDB (API)
/home/stan/gdb/src/gdb/amd64bsd-nat.c
Go to the documentation of this file.
00001 /* Native-dependent code for AMD64 BSD's.
00002 
00003    Copyright (C) 2003-2013 Free Software Foundation, Inc.
00004 
00005    This file is part of GDB.
00006 
00007    This program is free software; you can redistribute it and/or modify
00008    it under the terms of the GNU General Public License as published by
00009    the Free Software Foundation; either version 3 of the License, or
00010    (at your option) any later version.
00011 
00012    This program is distributed in the hope that it will be useful,
00013    but WITHOUT ANY WARRANTY; without even the implied warranty of
00014    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015    GNU General Public License for more details.
00016 
00017    You should have received a copy of the GNU General Public License
00018    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
00019 
00020 #include "defs.h"
00021 #include "inferior.h"
00022 #include "regcache.h"
00023 #include "target.h"
00024 
00025 /* We include <signal.h> to make sure `struct fxsave64' is defined on
00026    NetBSD, since NetBSD's <machine/reg.h> needs it.  */
00027 #include "gdb_assert.h"
00028 #include <signal.h>
00029 #include <sys/types.h>
00030 #include <sys/ptrace.h>
00031 #include <machine/reg.h>
00032 
00033 #include "amd64-tdep.h"
00034 #include "amd64-nat.h"
00035 #include "amd64bsd-nat.h"
00036 #include "inf-ptrace.h"
00037 
00038 
00039 /* Fetch register REGNUM from the inferior.  If REGNUM is -1, do this
00040    for all registers (including the floating-point registers).  */
00041 
00042 static void
00043 amd64bsd_fetch_inferior_registers (struct target_ops *ops,
00044                                    struct regcache *regcache, int regnum)
00045 {
00046   struct gdbarch *gdbarch = get_regcache_arch (regcache);
00047 
00048   if (regnum == -1 || amd64_native_gregset_supplies_p (gdbarch, regnum))
00049     {
00050       struct reg regs;
00051 
00052       if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
00053                   (PTRACE_TYPE_ARG3) &regs, 0) == -1)
00054         perror_with_name (_("Couldn't get registers"));
00055 
00056       amd64_supply_native_gregset (regcache, &regs, -1);
00057       if (regnum != -1)
00058         return;
00059     }
00060 
00061   if (regnum == -1 || !amd64_native_gregset_supplies_p (gdbarch, regnum))
00062     {
00063       struct fpreg fpregs;
00064 
00065       if (ptrace (PT_GETFPREGS, ptid_get_pid (inferior_ptid),
00066                   (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
00067         perror_with_name (_("Couldn't get floating point status"));
00068 
00069       amd64_supply_fxsave (regcache, -1, &fpregs);
00070     }
00071 }
00072 
00073 /* Store register REGNUM back into the inferior.  If REGNUM is -1, do
00074    this for all registers (including the floating-point registers).  */
00075 
00076 static void
00077 amd64bsd_store_inferior_registers (struct target_ops *ops,
00078                                    struct regcache *regcache, int regnum)
00079 {
00080   struct gdbarch *gdbarch = get_regcache_arch (regcache);
00081 
00082   if (regnum == -1 || amd64_native_gregset_supplies_p (gdbarch, regnum))
00083     {
00084       struct reg regs;
00085 
00086       if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
00087                   (PTRACE_TYPE_ARG3) &regs, 0) == -1)
00088         perror_with_name (_("Couldn't get registers"));
00089 
00090       amd64_collect_native_gregset (regcache, &regs, regnum);
00091 
00092       if (ptrace (PT_SETREGS, ptid_get_pid (inferior_ptid),
00093                   (PTRACE_TYPE_ARG3) &regs, 0) == -1)
00094         perror_with_name (_("Couldn't write registers"));
00095 
00096       if (regnum != -1)
00097         return;
00098     }
00099 
00100   if (regnum == -1 || !amd64_native_gregset_supplies_p (gdbarch, regnum))
00101     {
00102       struct fpreg fpregs;
00103 
00104       if (ptrace (PT_GETFPREGS, ptid_get_pid (inferior_ptid),
00105                   (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
00106         perror_with_name (_("Couldn't get floating point status"));
00107 
00108       amd64_collect_fxsave (regcache, regnum, &fpregs);
00109 
00110       if (ptrace (PT_SETFPREGS, ptid_get_pid (inferior_ptid),
00111                   (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
00112         perror_with_name (_("Couldn't write floating point status"));
00113     }
00114 }
00115 
00116 /* Create a prototype *BSD/amd64 target.  The client can override it
00117    with local methods.  */
00118 
00119 struct target_ops *
00120 amd64bsd_target (void)
00121 {
00122   struct target_ops *t;
00123 
00124   t = inf_ptrace_target ();
00125   t->to_fetch_registers = amd64bsd_fetch_inferior_registers;
00126   t->to_store_registers = amd64bsd_store_inferior_registers;
00127   return t;
00128 }
00129 
00130 
00131 /* Support for debug registers.  */
00132 
00133 #ifdef HAVE_PT_GETDBREGS
00134 
00135 static unsigned long
00136 amd64bsd_dr_get (ptid_t ptid, int regnum)
00137 {
00138   struct dbreg dbregs;
00139 
00140   if (ptrace (PT_GETDBREGS, ptid_get_pid (inferior_ptid),
00141               (PTRACE_TYPE_ARG3) &dbregs, 0) == -1)
00142     perror_with_name (_("Couldn't read debug registers"));
00143 
00144   return DBREG_DRX ((&dbregs), regnum);
00145 }
00146 
00147 static void
00148 amd64bsd_dr_set (int regnum, unsigned long value)
00149 {
00150   struct dbreg dbregs;
00151 
00152   if (ptrace (PT_GETDBREGS, ptid_get_pid (inferior_ptid),
00153               (PTRACE_TYPE_ARG3) &dbregs, 0) == -1)
00154     perror_with_name (_("Couldn't get debug registers"));
00155 
00156   /* For some mysterious reason, some of the reserved bits in the
00157      debug control register get set.  Mask these off, otherwise the
00158      ptrace call below will fail.  */
00159   DBREG_DRX ((&dbregs), 7) &= ~(0xffffffff0000fc00);
00160 
00161   DBREG_DRX ((&dbregs), regnum) = value;
00162 
00163   if (ptrace (PT_SETDBREGS, ptid_get_pid (inferior_ptid),
00164               (PTRACE_TYPE_ARG3) &dbregs, 0) == -1)
00165     perror_with_name (_("Couldn't write debug registers"));
00166 }
00167 
00168 void
00169 amd64bsd_dr_set_control (unsigned long control)
00170 {
00171   amd64bsd_dr_set (7, control);
00172 }
00173 
00174 void
00175 amd64bsd_dr_set_addr (int regnum, CORE_ADDR addr)
00176 {
00177   gdb_assert (regnum >= 0 && regnum <= 4);
00178 
00179   amd64bsd_dr_set (regnum, addr);
00180 }
00181 
00182 CORE_ADDR
00183 amd64bsd_dr_get_addr (int regnum)
00184 {
00185   return amd64bsd_dr_get (inferior_ptid, regnum);
00186 }
00187 
00188 unsigned long
00189 amd64bsd_dr_get_status (void)
00190 {
00191   return amd64bsd_dr_get (inferior_ptid, 6);
00192 }
00193 
00194 unsigned long
00195 amd64bsd_dr_get_control (void)
00196 {
00197   return amd64bsd_dr_get (inferior_ptid, 7);
00198 }
00199 
00200 #endif /* PT_GETDBREGS */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines