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