* aarch64-linux-nat.c: Replace PIDGET with ptid_get_pid.
[deliverable/binutils-gdb.git] / gdb / m32r-linux-nat.c
CommitLineData
9b32d526
KI
1/* Native-dependent code for GNU/Linux m32r.
2
28e7fd62 3 Copyright (C) 2004-2013 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
025bb325
MS
58/* Doee (??) apply to the corresponding SET requests as well. */
59#define GETREGS_SUPPLIES(regno) (0 <= (regno) \
60 && (regno) <= M32R_LINUX_NUM_REGS)
9b32d526
KI
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
28439f5e
PA
197m32r_linux_fetch_inferior_registers (struct target_ops *ops,
198 struct regcache *regcache, int regno)
9b32d526
KI
199{
200 int tid;
201
202 /* GNU/Linux LWP ID's are process ID's. */
dfd4cc63 203 tid = ptid_get_lwp (inferior_ptid);
9b32d526 204 if (tid == 0)
dfd4cc63 205 tid = ptid_get_pid (inferior_ptid); /* Not a threaded program. */
9b32d526
KI
206
207 /* Use the PTRACE_GETREGS request whenever possible, since it
208 transfers more registers in one system call, and we'll cache the
209 results. */
210 if (regno == -1 || GETREGS_SUPPLIES (regno))
211 {
56be3814 212 fetch_regs (regcache, tid);
9b32d526
KI
213 return;
214 }
215
216 internal_error (__FILE__, __LINE__,
e2e0b3e5 217 _("Got request for bad register number %d."), regno);
9b32d526
KI
218}
219
220/* Store register REGNO back into the child process. If REGNO is -1,
221 do this for all registers (including the floating point and SSE
222 registers). */
10d6c8cd 223static void
28439f5e
PA
224m32r_linux_store_inferior_registers (struct target_ops *ops,
225 struct regcache *regcache, int regno)
9b32d526
KI
226{
227 int tid;
228
229 /* GNU/Linux LWP ID's are process ID's. */
dfd4cc63
LM
230 if ((tid = ptid_get_lwp (inferior_ptid)) == 0)
231 tid = ptid_get_pid (inferior_ptid); /* Not a threaded program. */
9b32d526
KI
232
233 /* Use the PTRACE_SETREGS request whenever possible, since it
234 transfers more registers in one system call. */
235 if (regno == -1 || GETREGS_SUPPLIES (regno))
236 {
56be3814 237 store_regs (regcache, tid, regno);
9b32d526
KI
238 return;
239 }
240
241 internal_error (__FILE__, __LINE__,
e2e0b3e5 242 _("Got request to store bad register number %d."), regno);
9b32d526 243}
10d6c8cd
DJ
244
245void _initialize_m32r_linux_nat (void);
246
247void
248_initialize_m32r_linux_nat (void)
249{
250 struct target_ops *t;
251
252 /* Fill in the generic GNU/Linux methods. */
253 t = linux_target ();
254
255 /* Add our register access methods. */
256 t->to_fetch_registers = m32r_linux_fetch_inferior_registers;
257 t->to_store_registers = m32r_linux_store_inferior_registers;
258
259 /* Register the target. */
f973ed9c 260 linux_nat_add_target (t);
10d6c8cd 261}
This page took 0.71025 seconds and 4 git commands to generate.