OSDN Git Service

modified: utilsrc/src/Admin/Makefile
[eos/others.git] / utilsrc / srcX86MAC64 / Admin / gdb-7.7.1 / gdb / ppcfbsd-nat.c
1 /* Native-dependent code for PowerPC's running FreeBSD, for GDB.
2
3    Copyright (C) 2013-2014 Free Software Foundation, Inc.
4
5    This file is part of GDB.
6
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 3 of the License, or
10    (at your option) any later version.
11
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
19
20 #include "defs.h"
21 #include "gdbcore.h"
22 #include "inferior.h"
23 #include "regcache.h"
24
25 #include "gdb_assert.h"
26 #include <stddef.h>
27 #include <sys/types.h>
28 #include <sys/procfs.h>
29 #include <sys/ptrace.h>
30 #include <sys/signal.h>
31 #include <machine/frame.h>
32 #include <machine/pcb.h>
33 #include <machine/reg.h>
34
35 #include "fbsd-nat.h"
36 #include "gregset.h"
37 #include "ppc-tdep.h"
38 #include "ppcfbsd-tdep.h"
39 #include "inf-ptrace.h"
40 #include "bsd-kvm.h"
41
42 /* Fill GDB's register array with the general-purpose register values
43    in *GREGSETP.  */
44
45 void
46 supply_gregset (struct regcache *regcache, const gdb_gregset_t *gregsetp)
47 {
48   const struct regset *regset = ppc_fbsd_gregset (sizeof (long));
49
50   ppc_supply_gregset (regset, regcache, -1, gregsetp, sizeof (*gregsetp));
51 }
52
53 /* Fill register REGNO (if a gpr) in *GREGSETP with the value in GDB's
54    register array. If REGNO is -1 do it for all registers.  */
55
56 void
57 fill_gregset (const struct regcache *regcache,
58               gdb_gregset_t *gregsetp, int regno)
59 {
60   const struct regset *regset = ppc_fbsd_gregset (sizeof (long));
61
62   if (regno == -1)
63     memset (gregsetp, 0, sizeof (*gregsetp));
64   ppc_collect_gregset (regset, regcache, regno, gregsetp, sizeof (*gregsetp));
65 }
66
67 /* Fill GDB's register array with the floating-point register values
68    in *FPREGSETP.  */
69
70 void
71 supply_fpregset (struct regcache *regcache, const gdb_fpregset_t * fpregsetp)
72 {
73   const struct regset *regset = ppc_fbsd_fpregset ();
74
75   ppc_supply_fpregset (regset, regcache, -1,
76                        fpregsetp, sizeof (*fpregsetp));
77 }
78
79 /* Fill register REGNO in *FGREGSETP with the value in GDB's
80    register array. If REGNO is -1 do it for all registers.  */
81
82 void
83 fill_fpregset (const struct regcache *regcache,
84                gdb_fpregset_t *fpregsetp, int regno)
85 {
86   const struct regset *regset = ppc_fbsd_fpregset ();
87
88   ppc_collect_fpregset (regset, regcache, regno,
89                         fpregsetp, sizeof (*fpregsetp));
90 }
91
92 /* Returns true if PT_GETFPREGS fetches this register.  */
93
94 static int
95 getfpregs_supplies (struct gdbarch *gdbarch, int regno)
96 {
97   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
98
99   /* FIXME: jimb/2004-05-05: Some PPC variants don't have floating
100          point registers.  Traditionally, GDB's register set has still
101          listed the floating point registers for such machines, so this
102          code is harmless.  However, the new E500 port actually omits the
103          floating point registers entirely from the register set --- they
104          don't even have register numbers assigned to them.
105
106          It's not clear to me how best to update this code, so this assert
107          will alert the first person to encounter the NetBSD/E500
108          combination to the problem.  */
109
110   gdb_assert (ppc_floating_point_unit_p (gdbarch));
111
112   return ((regno >= tdep->ppc_fp0_regnum
113            && regno < tdep->ppc_fp0_regnum + ppc_num_fprs)
114           || regno == tdep->ppc_fpscr_regnum);
115 }
116
117 /* Fetch register REGNO from the child process. If REGNO is -1, do it
118    for all registers.  */
119
120 static void
121 ppcfbsd_fetch_inferior_registers (struct target_ops *ops,
122                                   struct regcache *regcache, int regno)
123 {
124   gdb_gregset_t regs;
125
126   if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
127               (PTRACE_TYPE_ARG3) &regs, 0) == -1)
128     perror_with_name (_("Couldn't get registers"));
129
130   supply_gregset (regcache, &regs);
131
132   if (regno == -1 || getfpregs_supplies (get_regcache_arch (regcache), regno))
133     {
134       const struct regset *fpregset = ppc_fbsd_fpregset ();
135       gdb_fpregset_t fpregs;
136
137       if (ptrace (PT_GETFPREGS, ptid_get_pid (inferior_ptid),
138                   (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
139         perror_with_name (_("Couldn't get FP registers"));
140
141       ppc_supply_fpregset (fpregset, regcache, regno, &fpregs, sizeof fpregs);
142     }
143 }
144
145 /* Store register REGNO back into the child process. If REGNO is -1,
146    do this for all registers.  */
147
148 static void
149 ppcfbsd_store_inferior_registers (struct target_ops *ops,
150                                   struct regcache *regcache, int regno)
151 {
152   gdb_gregset_t regs;
153
154   if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
155               (PTRACE_TYPE_ARG3) &regs, 0) == -1)
156     perror_with_name (_("Couldn't get registers"));
157
158   fill_gregset (regcache, &regs, regno);
159
160   if (ptrace (PT_SETREGS, ptid_get_pid (inferior_ptid),
161               (PTRACE_TYPE_ARG3) &regs, 0) == -1)
162     perror_with_name (_("Couldn't write registers"));
163
164   if (regno == -1 || getfpregs_supplies (get_regcache_arch (regcache), regno))
165     {
166       gdb_fpregset_t fpregs;
167
168       if (ptrace (PT_GETFPREGS, ptid_get_pid (inferior_ptid),
169                   (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
170         perror_with_name (_("Couldn't get FP registers"));
171
172       fill_fpregset (regcache, &fpregs, regno);
173
174       if (ptrace (PT_SETFPREGS, ptid_get_pid (inferior_ptid),
175                   (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
176         perror_with_name (_("Couldn't set FP registers"));
177     }
178 }
179
180 /* Architecture specific function that reconstructs the
181    register state from PCB (Process Control Block) and supplies it
182    to REGCACHE.  */
183
184 static int
185 ppcfbsd_supply_pcb (struct regcache *regcache, struct pcb *pcb)
186 {
187   struct gdbarch *gdbarch = get_regcache_arch (regcache);
188   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
189   int i, regnum;
190
191   /* The stack pointer shouldn't be zero.  */
192   if (pcb->pcb_sp == 0)
193     return 0;
194
195   regcache_raw_supply (regcache, gdbarch_sp_regnum (gdbarch), &pcb->pcb_sp);
196   regcache_raw_supply (regcache, tdep->ppc_cr_regnum, &pcb->pcb_cr);
197   regcache_raw_supply (regcache, tdep->ppc_lr_regnum, &pcb->pcb_lr);
198   for (i = 0, regnum = tdep->ppc_gp0_regnum + 14; i < 20; i++, regnum++)
199     regcache_raw_supply (regcache, regnum, &pcb->pcb_context[i]);
200
201   return 1;
202 }
203
204 /* Provide a prototype to silence -Wmissing-prototypes.  */
205
206 void _initialize_ppcfbsd_nat (void);
207
208 void
209 _initialize_ppcfbsd_nat (void)
210 {
211   struct target_ops *t;
212
213   /* Add in local overrides.  */
214   t = inf_ptrace_target ();
215   t->to_fetch_registers = ppcfbsd_fetch_inferior_registers;
216   t->to_store_registers = ppcfbsd_store_inferior_registers;
217   t->to_pid_to_exec_file = fbsd_pid_to_exec_file;
218   t->to_find_memory_regions = fbsd_find_memory_regions;
219   t->to_make_corefile_notes = fbsd_make_corefile_notes;
220   add_target (t);
221
222   /* Support debugging kernel virtual memory images.  */
223   bsd_kvm_add_target (ppcfbsd_supply_pcb);
224 }