2011-01-08 Michael Snyder <msnyder@vmware.com>
[deliverable/binutils-gdb.git] / gdb / m32r-linux-nat.c
CommitLineData
9b32d526
KI
1/* Native-dependent code for GNU/Linux m32r.
2
7b6bb8da 3 Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
0fb0cc75 4 Free Software Foundation, Inc.
9b32d526
KI
5
6 This file is part of GDB.
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
a9762ec7 10 the Free Software Foundation; either version 3 of the License, or
9b32d526
KI
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
a9762ec7 19 along with this program. If not, see <http://www.gnu.org/licenses/>. */
9b32d526
KI
20
21#include "defs.h"
22#include "inferior.h"
23#include "gdbcore.h"
24#include "regcache.h"
25#include "linux-nat.h"
10d6c8cd 26#include "target.h"
9b32d526
KI
27
28#include "gdb_assert.h"
29#include "gdb_string.h"
30#include <sys/ptrace.h>
31#include <sys/user.h>
32#include <sys/procfs.h>
33
34/* Prototypes for supply_gregset etc. */
35#include "gregset.h"
36
37#include "m32r-tdep.h"
38\f
39
40
41
42/* Since EVB register is not available for native debug, we reduce
43 the number of registers. */
44#define M32R_LINUX_NUM_REGS (M32R_NUM_REGS - 1)
45
46/* Mapping between the general-purpose registers in `struct user'
47 format and GDB's register array layout. */
48static int regmap[] = {
49 4, 5, 6, 7, 0, 1, 2, 8,
50 9, 10, 11, 12, 13, 24, 25, 23,
51 19, 19, 26, 23, 22, 20, 16, 15
52};
53
54#define PSW_REGMAP 19
55#define BBPSW_REGMAP 21
56#define SPU_REGMAP 23
57#define SPI_REGMAP 26
58
025bb325
MS
59/* Doee (??) apply to the corresponding SET requests as well. */
60#define GETREGS_SUPPLIES(regno) (0 <= (regno) \
61 && (regno) <= M32R_LINUX_NUM_REGS)
9b32d526
KI
62\f
63
64
65/* Transfering the general-purpose registers between GDB, inferiors
66 and core files. */
67
68/* Fill GDB's register array with the general-purpose register values
69 in *GREGSETP. */
70
71void
7f7fe91e 72supply_gregset (struct regcache *regcache, const elf_gregset_t * gregsetp)
9b32d526 73{
7f7fe91e 74 const elf_greg_t *regp = (const elf_greg_t *) gregsetp;
9b32d526
KI
75 int i;
76 unsigned long psw, bbpsw;
77
78 psw = *(regp + PSW_REGMAP);
79 bbpsw = *(regp + BBPSW_REGMAP);
80
81 for (i = 0; i < M32R_LINUX_NUM_REGS; i++)
82 {
d817e083
UW
83 elf_greg_t regval;
84
9b32d526
KI
85 switch (i)
86 {
87 case PSW_REGNUM:
d817e083 88 regval = ((0x00c1 & bbpsw) << 8) | ((0xc100 & psw) >> 8);
9b32d526
KI
89 break;
90 case CBR_REGNUM:
d817e083
UW
91 regval = ((psw >> 8) & 1);
92 break;
93 default:
94 regval = *(regp + regmap[i]);
9b32d526
KI
95 break;
96 }
97
98 if (i != M32R_SP_REGNUM)
7f7fe91e 99 regcache_raw_supply (regcache, i, &regval);
9b32d526 100 else if (psw & 0x8000)
7f7fe91e 101 regcache_raw_supply (regcache, i, regp + SPU_REGMAP);
9b32d526 102 else
7f7fe91e 103 regcache_raw_supply (regcache, i, regp + SPI_REGMAP);
9b32d526
KI
104 }
105}
106
107/* Fetch all general-purpose registers from process/thread TID and
108 store their values in GDB's register array. */
109
110static void
56be3814 111fetch_regs (struct regcache *regcache, int tid)
9b32d526
KI
112{
113 elf_gregset_t regs;
114
115 if (ptrace (PTRACE_GETREGS, tid, 0, (int) &regs) < 0)
e2e0b3e5 116 perror_with_name (_("Couldn't get registers"));
9b32d526 117
56be3814 118 supply_gregset (regcache, (const elf_gregset_t *) &regs);
9b32d526
KI
119}
120
121/* Fill register REGNO (if it is a general-purpose register) in
122 *GREGSETPS with the value in GDB's register array. If REGNO is -1,
123 do this for all registers. */
124
125void
7f7fe91e
UW
126fill_gregset (const struct regcache *regcache,
127 elf_gregset_t * gregsetp, int regno)
9b32d526
KI
128{
129 elf_greg_t *regp = (elf_greg_t *) gregsetp;
130 int i;
131 unsigned long psw, bbpsw, tmp;
132
133 psw = *(regp + PSW_REGMAP);
134 bbpsw = *(regp + BBPSW_REGMAP);
135
136 for (i = 0; i < M32R_LINUX_NUM_REGS; i++)
137 {
138 if (regno != -1 && regno != i)
139 continue;
140
141 if (i == CBR_REGNUM || i == PSW_REGNUM)
142 continue;
143
144 if (i == SPU_REGNUM || i == SPI_REGNUM)
145 continue;
146
147 if (i != M32R_SP_REGNUM)
7f7fe91e 148 regcache_raw_collect (regcache, i, regp + regmap[i]);
9b32d526 149 else if (psw & 0x8000)
7f7fe91e 150 regcache_raw_collect (regcache, i, regp + SPU_REGMAP);
9b32d526 151 else
7f7fe91e 152 regcache_raw_collect (regcache, i, regp + SPI_REGMAP);
9b32d526
KI
153 }
154}
155
156/* Store all valid general-purpose registers in GDB's register array
157 into the process/thread specified by TID. */
158
159static void
56be3814 160store_regs (const struct regcache *regcache, int tid, int regno)
9b32d526
KI
161{
162 elf_gregset_t regs;
163
164 if (ptrace (PTRACE_GETREGS, tid, 0, (int) &regs) < 0)
e2e0b3e5 165 perror_with_name (_("Couldn't get registers"));
9b32d526 166
56be3814 167 fill_gregset (regcache, &regs, regno);
9b32d526
KI
168
169 if (ptrace (PTRACE_SETREGS, tid, 0, (int) &regs) < 0)
e2e0b3e5 170 perror_with_name (_("Couldn't write registers"));
9b32d526
KI
171}
172\f
173
174
175/* Transfering floating-point registers between GDB, inferiors and cores.
176 Since M32R has no floating-point registers, these functions do nothing. */
177
178void
7f7fe91e 179supply_fpregset (struct regcache *regcache, const gdb_fpregset_t *fpregs)
9b32d526
KI
180{
181}
182
183void
7f7fe91e
UW
184fill_fpregset (const struct regcache *regcache,
185 gdb_fpregset_t *fpregs, int regno)
9b32d526
KI
186{
187}
188\f
189
190
191/* Transferring arbitrary registers between GDB and inferior. */
192
193/* Fetch register REGNO from the child process. If REGNO is -1, do
194 this for all registers (including the floating point and SSE
195 registers). */
196
10d6c8cd 197static void
28439f5e
PA
198m32r_linux_fetch_inferior_registers (struct target_ops *ops,
199 struct regcache *regcache, int regno)
9b32d526
KI
200{
201 int tid;
202
203 /* GNU/Linux LWP ID's are process ID's. */
204 tid = TIDGET (inferior_ptid);
205 if (tid == 0)
206 tid = PIDGET (inferior_ptid); /* Not a threaded program. */
207
208 /* Use the PTRACE_GETREGS request whenever possible, since it
209 transfers more registers in one system call, and we'll cache the
210 results. */
211 if (regno == -1 || GETREGS_SUPPLIES (regno))
212 {
56be3814 213 fetch_regs (regcache, tid);
9b32d526
KI
214 return;
215 }
216
217 internal_error (__FILE__, __LINE__,
e2e0b3e5 218 _("Got request for bad register number %d."), regno);
9b32d526
KI
219}
220
221/* Store register REGNO back into the child process. If REGNO is -1,
222 do this for all registers (including the floating point and SSE
223 registers). */
10d6c8cd 224static void
28439f5e
PA
225m32r_linux_store_inferior_registers (struct target_ops *ops,
226 struct regcache *regcache, int regno)
9b32d526
KI
227{
228 int tid;
229
230 /* GNU/Linux LWP ID's are process ID's. */
231 if ((tid = TIDGET (inferior_ptid)) == 0)
232 tid = PIDGET (inferior_ptid); /* Not a threaded program. */
233
234 /* Use the PTRACE_SETREGS request whenever possible, since it
235 transfers more registers in one system call. */
236 if (regno == -1 || GETREGS_SUPPLIES (regno))
237 {
56be3814 238 store_regs (regcache, tid, regno);
9b32d526
KI
239 return;
240 }
241
242 internal_error (__FILE__, __LINE__,
e2e0b3e5 243 _("Got request to store bad register number %d."), regno);
9b32d526 244}
10d6c8cd
DJ
245
246void _initialize_m32r_linux_nat (void);
247
248void
249_initialize_m32r_linux_nat (void)
250{
251 struct target_ops *t;
252
253 /* Fill in the generic GNU/Linux methods. */
254 t = linux_target ();
255
256 /* Add our register access methods. */
257 t->to_fetch_registers = m32r_linux_fetch_inferior_registers;
258 t->to_store_registers = m32r_linux_store_inferior_registers;
259
260 /* Register the target. */
f973ed9c 261 linux_nat_add_target (t);
10d6c8cd 262}
This page took 0.544805 seconds and 4 git commands to generate.