xref: /openbsd-src/gnu/usr.bin/binutils/gdb/amd64bsd-nat.c (revision f6714ce20be20dff4d46fca3924a4ebcef3ccdb6)
1b725ae77Skettenis /* Native-dependent code for AMD64 BSD's.
2b725ae77Skettenis 
3b725ae77Skettenis    Copyright 2003, 2004 Free Software Foundation, Inc.
4b725ae77Skettenis 
5b725ae77Skettenis    This file is part of GDB.
6b725ae77Skettenis 
7b725ae77Skettenis    This program is free software; you can redistribute it and/or modify
8b725ae77Skettenis    it under the terms of the GNU General Public License as published by
9b725ae77Skettenis    the Free Software Foundation; either version 2 of the License, or
10b725ae77Skettenis    (at your option) any later version.
11b725ae77Skettenis 
12b725ae77Skettenis    This program is distributed in the hope that it will be useful,
13b725ae77Skettenis    but WITHOUT ANY WARRANTY; without even the implied warranty of
14b725ae77Skettenis    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15b725ae77Skettenis    GNU General Public License for more details.
16b725ae77Skettenis 
17b725ae77Skettenis    You should have received a copy of the GNU General Public License
18b725ae77Skettenis    along with this program; if not, write to the Free Software
19b725ae77Skettenis    Foundation, Inc., 59 Temple Place - Suite 330,
20b725ae77Skettenis    Boston, MA 02111-1307, USA.  */
21b725ae77Skettenis 
22b725ae77Skettenis #include "defs.h"
23b725ae77Skettenis #include "inferior.h"
24b725ae77Skettenis #include "regcache.h"
2511efff7fSkettenis #include "target.h"
26b725ae77Skettenis 
27b725ae77Skettenis /* We include <signal.h> to make sure `struct fxsave64' is defined on
28b725ae77Skettenis    NetBSD, since NetBSD's <machine/reg.h> needs it.  */
29b725ae77Skettenis #include "gdb_assert.h"
30b725ae77Skettenis #include <signal.h>
31b725ae77Skettenis #include <sys/types.h>
32b725ae77Skettenis #include <sys/ptrace.h>
33b725ae77Skettenis #include <machine/reg.h>
34b725ae77Skettenis 
35b725ae77Skettenis #include "amd64-tdep.h"
36b725ae77Skettenis #include "amd64-nat.h"
3711efff7fSkettenis #include "inf-ptrace.h"
38b725ae77Skettenis 
39b725ae77Skettenis 
40b725ae77Skettenis /* Fetch register REGNUM from the inferior.  If REGNUM is -1, do this
41b725ae77Skettenis    for all registers (including the floating-point registers).  */
42b725ae77Skettenis 
4311efff7fSkettenis static void
amd64bsd_fetch_inferior_registers(int regnum)4411efff7fSkettenis amd64bsd_fetch_inferior_registers (int regnum)
45b725ae77Skettenis {
46*f6714ce2Skettenis   int pid;
47*f6714ce2Skettenis 
48*f6714ce2Skettenis   /* Cater for systems like OpenBSD, that implement threads as
49*f6714ce2Skettenis      separate processes.  */
50*f6714ce2Skettenis   pid = ptid_get_lwp (inferior_ptid);
51*f6714ce2Skettenis   if (pid == 0)
52*f6714ce2Skettenis     pid = ptid_get_pid (inferior_ptid);
53*f6714ce2Skettenis 
54b725ae77Skettenis   if (regnum == -1 || amd64_native_gregset_supplies_p (regnum))
55b725ae77Skettenis     {
56b725ae77Skettenis       struct reg regs;
57b725ae77Skettenis 
58*f6714ce2Skettenis       if (ptrace (PT_GETREGS, pid, (PTRACE_TYPE_ARG3) &regs, 0) == -1)
59b725ae77Skettenis 	perror_with_name ("Couldn't get registers");
60b725ae77Skettenis 
61b725ae77Skettenis       amd64_supply_native_gregset (current_regcache, &regs, -1);
62b725ae77Skettenis       if (regnum != -1)
63b725ae77Skettenis 	return;
64b725ae77Skettenis     }
65b725ae77Skettenis 
6611efff7fSkettenis   if (regnum == -1 || !amd64_native_gregset_supplies_p (regnum))
67b725ae77Skettenis     {
68b725ae77Skettenis       struct fpreg fpregs;
69b725ae77Skettenis 
70*f6714ce2Skettenis       if (ptrace (PT_GETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
71b725ae77Skettenis 	perror_with_name ("Couldn't get floating point status");
72b725ae77Skettenis 
73b725ae77Skettenis       amd64_supply_fxsave (current_regcache, -1, &fpregs);
74b725ae77Skettenis     }
75b725ae77Skettenis }
76b725ae77Skettenis 
77b725ae77Skettenis /* Store register REGNUM back into the inferior.  If REGNUM is -1, do
78b725ae77Skettenis    this for all registers (including the floating-point registers).  */
79b725ae77Skettenis 
8011efff7fSkettenis static void
amd64bsd_store_inferior_registers(int regnum)8111efff7fSkettenis amd64bsd_store_inferior_registers (int regnum)
82b725ae77Skettenis {
83*f6714ce2Skettenis   int pid;
84*f6714ce2Skettenis 
85*f6714ce2Skettenis   /* Cater for systems like OpenBSD, that implement threads as
86*f6714ce2Skettenis      separate processes.  */
87*f6714ce2Skettenis   pid = ptid_get_lwp (inferior_ptid);
88*f6714ce2Skettenis   if (pid == 0)
89*f6714ce2Skettenis     pid = ptid_get_pid (inferior_ptid);
90*f6714ce2Skettenis 
91b725ae77Skettenis   if (regnum == -1 || amd64_native_gregset_supplies_p (regnum))
92b725ae77Skettenis     {
93b725ae77Skettenis       struct reg regs;
94b725ae77Skettenis 
95*f6714ce2Skettenis       if (ptrace (PT_GETREGS, pid, (PTRACE_TYPE_ARG3) &regs, 0) == -1)
96b725ae77Skettenis         perror_with_name ("Couldn't get registers");
97b725ae77Skettenis 
98b725ae77Skettenis       amd64_collect_native_gregset (current_regcache, &regs, regnum);
99b725ae77Skettenis 
100*f6714ce2Skettenis       if (ptrace (PT_SETREGS, pid, (PTRACE_TYPE_ARG3) &regs, 0) == -1)
101b725ae77Skettenis         perror_with_name ("Couldn't write registers");
102b725ae77Skettenis 
103b725ae77Skettenis       if (regnum != -1)
104b725ae77Skettenis 	return;
105b725ae77Skettenis     }
106b725ae77Skettenis 
10711efff7fSkettenis   if (regnum == -1 || !amd64_native_gregset_supplies_p (regnum))
108b725ae77Skettenis     {
109b725ae77Skettenis       struct fpreg fpregs;
110b725ae77Skettenis 
111*f6714ce2Skettenis       if (ptrace (PT_GETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
112b725ae77Skettenis 	perror_with_name ("Couldn't get floating point status");
113b725ae77Skettenis 
11411efff7fSkettenis       amd64_collect_fxsave (current_regcache, regnum, &fpregs);
115b725ae77Skettenis 
116*f6714ce2Skettenis       if (ptrace (PT_SETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
117b725ae77Skettenis 	perror_with_name ("Couldn't write floating point status");
118b725ae77Skettenis     }
119b725ae77Skettenis }
12011efff7fSkettenis 
12111efff7fSkettenis /* Create a prototype *BSD/amd64 target.  The client can override it
12211efff7fSkettenis    with local methods.  */
12311efff7fSkettenis 
12411efff7fSkettenis struct target_ops *
amd64bsd_target(void)12511efff7fSkettenis amd64bsd_target (void)
12611efff7fSkettenis {
12711efff7fSkettenis   struct target_ops *t;
12811efff7fSkettenis 
12911efff7fSkettenis   t = inf_ptrace_target ();
13011efff7fSkettenis   t->to_fetch_registers = amd64bsd_fetch_inferior_registers;
13111efff7fSkettenis   t->to_store_registers = amd64bsd_store_inferior_registers;
13211efff7fSkettenis   return t;
13311efff7fSkettenis }
134