Add testcase for PR/24065.
[deliverable/binutils-gdb.git] / gdb / m32r-linux-nat.c
CommitLineData
9b32d526
KI
1/* Native-dependent code for GNU/Linux m32r.
2
42a4f53d 3 Copyright (C) 2004-2019 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"
5826e159 26#include "nat/gdb_ptrace.h"
9b32d526
KI
27#include <sys/user.h>
28#include <sys/procfs.h>
bcc0c096 29#include "inf-ptrace.h"
9b32d526
KI
30
31/* Prototypes for supply_gregset etc. */
32#include "gregset.h"
33
34#include "m32r-tdep.h"
35\f
36
f6ac5f3d
PA
37class m32r_linux_nat_target final : public linux_nat_target
38{
39public:
40 /* Add our register access methods. */
41 void fetch_registers (struct regcache *, int) override;
42 void store_registers (struct regcache *, int) override;
43};
9b32d526 44
f6ac5f3d 45static m32r_linux_nat_target the_m32r_linux_nat_target;
9b32d526
KI
46
47/* Since EVB register is not available for native debug, we reduce
48 the number of registers. */
49#define M32R_LINUX_NUM_REGS (M32R_NUM_REGS - 1)
50
51/* Mapping between the general-purpose registers in `struct user'
52 format and GDB's register array layout. */
53static int regmap[] = {
54 4, 5, 6, 7, 0, 1, 2, 8,
55 9, 10, 11, 12, 13, 24, 25, 23,
56 19, 19, 26, 23, 22, 20, 16, 15
57};
58
59#define PSW_REGMAP 19
60#define BBPSW_REGMAP 21
61#define SPU_REGMAP 23
62#define SPI_REGMAP 26
63
025bb325
MS
64/* Doee (??) apply to the corresponding SET requests as well. */
65#define GETREGS_SUPPLIES(regno) (0 <= (regno) \
66 && (regno) <= M32R_LINUX_NUM_REGS)
9b32d526
KI
67\f
68
69
70/* Transfering the general-purpose registers between GDB, inferiors
71 and core files. */
72
73/* Fill GDB's register array with the general-purpose register values
74 in *GREGSETP. */
75
76void
7f7fe91e 77supply_gregset (struct regcache *regcache, const elf_gregset_t * gregsetp)
9b32d526 78{
7f7fe91e 79 const elf_greg_t *regp = (const elf_greg_t *) gregsetp;
9b32d526
KI
80 int i;
81 unsigned long psw, bbpsw;
82
83 psw = *(regp + PSW_REGMAP);
84 bbpsw = *(regp + BBPSW_REGMAP);
85
86 for (i = 0; i < M32R_LINUX_NUM_REGS; i++)
87 {
d817e083
UW
88 elf_greg_t regval;
89
9b32d526
KI
90 switch (i)
91 {
92 case PSW_REGNUM:
d817e083 93 regval = ((0x00c1 & bbpsw) << 8) | ((0xc100 & psw) >> 8);
9b32d526
KI
94 break;
95 case CBR_REGNUM:
d817e083
UW
96 regval = ((psw >> 8) & 1);
97 break;
98 default:
99 regval = *(regp + regmap[i]);
9b32d526
KI
100 break;
101 }
102
103 if (i != M32R_SP_REGNUM)
73e1c03f 104 regcache->raw_supply (i, &regval);
9b32d526 105 else if (psw & 0x8000)
73e1c03f 106 regcache->raw_supply (i, regp + SPU_REGMAP);
9b32d526 107 else
73e1c03f 108 regcache->raw_supply (i, regp + SPI_REGMAP);
9b32d526
KI
109 }
110}
111
112/* Fetch all general-purpose registers from process/thread TID and
113 store their values in GDB's register array. */
114
115static void
56be3814 116fetch_regs (struct regcache *regcache, int tid)
9b32d526
KI
117{
118 elf_gregset_t regs;
119
120 if (ptrace (PTRACE_GETREGS, tid, 0, (int) &regs) < 0)
e2e0b3e5 121 perror_with_name (_("Couldn't get registers"));
9b32d526 122
56be3814 123 supply_gregset (regcache, (const elf_gregset_t *) &regs);
9b32d526
KI
124}
125
126/* Fill register REGNO (if it is a general-purpose register) in
127 *GREGSETPS with the value in GDB's register array. If REGNO is -1,
128 do this for all registers. */
129
130void
7f7fe91e
UW
131fill_gregset (const struct regcache *regcache,
132 elf_gregset_t * gregsetp, int regno)
9b32d526
KI
133{
134 elf_greg_t *regp = (elf_greg_t *) gregsetp;
135 int i;
136 unsigned long psw, bbpsw, tmp;
137
138 psw = *(regp + PSW_REGMAP);
139 bbpsw = *(regp + BBPSW_REGMAP);
140
141 for (i = 0; i < M32R_LINUX_NUM_REGS; i++)
142 {
143 if (regno != -1 && regno != i)
144 continue;
145
146 if (i == CBR_REGNUM || i == PSW_REGNUM)
147 continue;
148
149 if (i == SPU_REGNUM || i == SPI_REGNUM)
150 continue;
151
152 if (i != M32R_SP_REGNUM)
34a79281 153 regcache->raw_collect (i, regp + regmap[i]);
9b32d526 154 else if (psw & 0x8000)
34a79281 155 regcache->raw_collect (i, regp + SPU_REGMAP);
9b32d526 156 else
34a79281 157 regcache->raw_collect (i, regp + SPI_REGMAP);
9b32d526
KI
158 }
159}
160
161/* Store all valid general-purpose registers in GDB's register array
162 into the process/thread specified by TID. */
163
164static void
56be3814 165store_regs (const struct regcache *regcache, int tid, int regno)
9b32d526
KI
166{
167 elf_gregset_t regs;
168
169 if (ptrace (PTRACE_GETREGS, tid, 0, (int) &regs) < 0)
e2e0b3e5 170 perror_with_name (_("Couldn't get registers"));
9b32d526 171
56be3814 172 fill_gregset (regcache, &regs, regno);
9b32d526
KI
173
174 if (ptrace (PTRACE_SETREGS, tid, 0, (int) &regs) < 0)
e2e0b3e5 175 perror_with_name (_("Couldn't write registers"));
9b32d526
KI
176}
177\f
178
179
180/* Transfering floating-point registers between GDB, inferiors and cores.
181 Since M32R has no floating-point registers, these functions do nothing. */
182
183void
7f7fe91e 184supply_fpregset (struct regcache *regcache, const gdb_fpregset_t *fpregs)
9b32d526
KI
185{
186}
187
188void
7f7fe91e
UW
189fill_fpregset (const struct regcache *regcache,
190 gdb_fpregset_t *fpregs, int regno)
9b32d526
KI
191{
192}
193\f
194
195
196/* Transferring arbitrary registers between GDB and inferior. */
197
198/* Fetch register REGNO from the child process. If REGNO is -1, do
199 this for all registers (including the floating point and SSE
200 registers). */
201
f6ac5f3d
PA
202void
203m32r_linux_nat_target::fetch_registers (struct regcache *regcache, int regno)
9b32d526 204{
222312d3 205 pid_t tid = get_ptrace_pid (regcache->ptid ());
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). */
f6ac5f3d
PA
223void
224m32r_linux_nat_target::store_registers (struct regcache *regcache, int regno)
9b32d526 225{
222312d3 226 pid_t tid = get_ptrace_pid (regcache->ptid ());
9b32d526
KI
227
228 /* Use the PTRACE_SETREGS request whenever possible, since it
229 transfers more registers in one system call. */
230 if (regno == -1 || GETREGS_SUPPLIES (regno))
231 {
56be3814 232 store_regs (regcache, tid, regno);
9b32d526
KI
233 return;
234 }
235
236 internal_error (__FILE__, __LINE__,
e2e0b3e5 237 _("Got request to store bad register number %d."), regno);
9b32d526 238}
10d6c8cd 239
10d6c8cd
DJ
240void
241_initialize_m32r_linux_nat (void)
242{
10d6c8cd 243 /* Register the target. */
f6ac5f3d 244 linux_target = &the_m32r_linux_nat_target;
d9f719f1 245 add_inf_child_target (&the_m32r_linux_nat_target);
10d6c8cd 246}
This page took 1.204234 seconds and 4 git commands to generate.