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