Remove regcache_raw_supply
[deliverable/binutils-gdb.git] / gdb / m68k-linux-nat.c
CommitLineData
a4b6fc86
AC
1/* Motorola m68k native support for GNU/Linux.
2
e2882c85 3 Copyright (C) 1996-2018 Free Software Foundation, Inc.
c906108c 4
c5aa993b 5 This file is part of GDB.
c906108c 6
c5aa993b
JM
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
c5aa993b 10 (at your option) any later version.
c906108c 11
c5aa993b
JM
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.
c906108c 16
c5aa993b 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/>. */
c906108c
SS
19
20#include "defs.h"
21#include "frame.h"
22#include "inferior.h"
23#include "language.h"
24#include "gdbcore.h"
4e052eda 25#include "regcache.h"
10d6c8cd
DJ
26#include "target.h"
27#include "linux-nat.h"
c906108c 28
32eeb91a
AS
29#include "m68k-tdep.h"
30
c906108c
SS
31#include <sys/dir.h>
32#include <signal.h>
5826e159 33#include "nat/gdb_ptrace.h"
c906108c
SS
34#include <sys/user.h>
35#include <sys/ioctl.h>
36#include <fcntl.h>
37#include <sys/procfs.h>
38
0280a90a
AS
39#ifdef HAVE_SYS_REG_H
40#include <sys/reg.h>
41#endif
42
c906108c 43#include <sys/file.h>
53ce3c39 44#include <sys/stat.h>
c906108c
SS
45
46#include "floatformat.h"
47
025bb325 48/* Prototypes for supply_gregset etc. */
3e00823e 49#include "gregset.h"
7b8b6d6d
AS
50
51/* Defines ps_err_e, struct ps_prochandle. */
52#include "gdb_proc_service.h"
53
bcc0c096
SM
54#include "inf-ptrace.h"
55
7b8b6d6d
AS
56#ifndef PTRACE_GET_THREAD_AREA
57#define PTRACE_GET_THREAD_AREA 25
58#endif
c906108c 59\f
f6ac5f3d
PA
60
61class m68k_linux_nat_target final : public linux_nat_target
62{
63public:
64 /* Add our register access methods. */
65 void fetch_registers (struct regcache *, int) override;
66 void store_registers (struct regcache *, int) override;
67};
68
69static m68k_linux_nat_target the_m68k_linux_nat_target;
70
c9f4d572 71/* This table must line up with gdbarch_register_name in "m68k-tdep.c". */
c5aa993b 72static const int regmap[] =
c906108c
SS
73{
74 PT_D0, PT_D1, PT_D2, PT_D3, PT_D4, PT_D5, PT_D6, PT_D7,
75 PT_A0, PT_A1, PT_A2, PT_A3, PT_A4, PT_A5, PT_A6, PT_USP,
76 PT_SR, PT_PC,
77 /* PT_FP0, ..., PT_FP7 */
78 21, 24, 27, 30, 33, 36, 39, 42,
79 /* PT_FPCR, PT_FPSR, PT_FPIAR */
80 45, 46, 47
81};
82
0280a90a
AS
83/* Which ptrace request retrieves which registers?
84 These apply to the corresponding SET requests as well. */
85#define NUM_GREGS (18)
86#define MAX_NUM_REGS (NUM_GREGS + 11)
87
0c13fc49 88static int
0280a90a
AS
89getregs_supplies (int regno)
90{
91 return 0 <= regno && regno < NUM_GREGS;
92}
93
0c13fc49 94static int
0280a90a
AS
95getfpregs_supplies (int regno)
96{
4ed226fe 97 return M68K_FP0_REGNUM <= regno && regno <= M68K_FPI_REGNUM;
0280a90a
AS
98}
99
100/* Does the current host support the GETREGS request? */
0c13fc49 101static int have_ptrace_getregs =
0280a90a
AS
102#ifdef HAVE_PTRACE_GETREGS
103 1
104#else
105 0
106#endif
107;
108
109\f
110
0280a90a
AS
111/* Fetching registers directly from the U area, one at a time. */
112
0280a90a
AS
113/* Fetch one register. */
114
115static void
56be3814 116fetch_register (struct regcache *regcache, int regno)
0280a90a 117{
ac7936df 118 struct gdbarch *gdbarch = regcache->arch ();
89e028e2 119 long regaddr, val;
52f0bd74 120 int i;
975c21ab 121 gdb_byte buf[M68K_MAX_REGISTER_SIZE];
222312d3 122 pid_t tid = get_ptrace_pid (regcache->ptid ());
0280a90a 123
de732108 124 regaddr = 4 * regmap[regno];
335d71d6 125 for (i = 0; i < register_size (gdbarch, regno); i += sizeof (long))
0280a90a
AS
126 {
127 errno = 0;
89e028e2
AS
128 val = ptrace (PTRACE_PEEKUSER, tid, regaddr, 0);
129 memcpy (&buf[i], &val, sizeof (long));
335d71d6 130 regaddr += sizeof (long);
0280a90a 131 if (errno != 0)
335d71d6
AS
132 error (_("Couldn't read register %s (#%d): %s."),
133 gdbarch_register_name (gdbarch, regno),
134 regno, safe_strerror (errno));
0280a90a 135 }
73e1c03f 136 regcache->raw_supply (regno, buf);
0280a90a
AS
137}
138
139/* Fetch register values from the inferior.
140 If REGNO is negative, do this for all registers.
025bb325 141 Otherwise, REGNO specifies which register (so we can save time). */
c906108c 142
10d6c8cd 143static void
56be3814 144old_fetch_inferior_registers (struct regcache *regcache, int regno)
0280a90a
AS
145{
146 if (regno >= 0)
147 {
56be3814 148 fetch_register (regcache, regno);
0280a90a
AS
149 }
150 else
151 {
c984b7ff 152 for (regno = 0;
ac7936df 153 regno < gdbarch_num_regs (regcache->arch ());
c984b7ff 154 regno++)
0280a90a 155 {
56be3814 156 fetch_register (regcache, regno);
0280a90a
AS
157 }
158 }
159}
160
025bb325 161/* Store one register. */
0280a90a
AS
162
163static void
56be3814 164store_register (const struct regcache *regcache, int regno)
0280a90a 165{
ac7936df 166 struct gdbarch *gdbarch = regcache->arch ();
89e028e2 167 long regaddr, val;
52f0bd74 168 int i;
975c21ab 169 gdb_byte buf[M68K_MAX_REGISTER_SIZE];
222312d3 170 pid_t tid = get_ptrace_pid (regcache->ptid ());
0280a90a 171
de732108 172 regaddr = 4 * regmap[regno];
9852326a 173
025bb325 174 /* Put the contents of regno into a local buffer. */
56be3814 175 regcache_raw_collect (regcache, regno, buf);
9852326a 176
025bb325 177 /* Store the local buffer into the inferior a chunk at the time. */
335d71d6 178 for (i = 0; i < register_size (gdbarch, regno); i += sizeof (long))
0280a90a
AS
179 {
180 errno = 0;
89e028e2
AS
181 memcpy (&val, &buf[i], sizeof (long));
182 ptrace (PTRACE_POKEUSER, tid, regaddr, val);
335d71d6 183 regaddr += sizeof (long);
0280a90a 184 if (errno != 0)
335d71d6
AS
185 error (_("Couldn't write register %s (#%d): %s."),
186 gdbarch_register_name (gdbarch, regno),
187 regno, safe_strerror (errno));
0280a90a
AS
188 }
189}
190
191/* Store our register values back into the inferior.
192 If REGNO is negative, do this for all registers.
193 Otherwise, REGNO specifies which register (so we can save time). */
194
10d6c8cd 195static void
56be3814 196old_store_inferior_registers (const struct regcache *regcache, int regno)
0280a90a
AS
197{
198 if (regno >= 0)
199 {
56be3814 200 store_register (regcache, regno);
0280a90a
AS
201 }
202 else
203 {
c984b7ff 204 for (regno = 0;
ac7936df 205 regno < gdbarch_num_regs (regcache->arch ());
c984b7ff 206 regno++)
0280a90a 207 {
56be3814 208 store_register (regcache, regno);
0280a90a
AS
209 }
210 }
211}
212\f
f175af98
DJ
213/* Given a pointer to a general register set in /proc format
214 (elf_gregset_t *), unpack the register contents and supply
025bb325 215 them as gdb's idea of the current register values. */
c906108c 216
c906108c 217void
7f7fe91e 218supply_gregset (struct regcache *regcache, const elf_gregset_t *gregsetp)
c906108c 219{
ac7936df 220 struct gdbarch *gdbarch = regcache->arch ();
7f7fe91e 221 const elf_greg_t *regp = (const elf_greg_t *) gregsetp;
c906108c
SS
222 int regi;
223
3e8c568d 224 for (regi = M68K_D0_REGNUM;
c984b7ff 225 regi <= gdbarch_sp_regnum (gdbarch);
3e8c568d 226 regi++)
73e1c03f
SM
227 regcache->raw_supply (regi, &regp[regmap[regi]]);
228 regcache->raw_supply (gdbarch_ps_regnum (gdbarch), &regp[PT_SR]);
229 regcache->raw_supply (gdbarch_pc_regnum (gdbarch), &regp[PT_PC]);
0280a90a
AS
230}
231
232/* Fill register REGNO (if it is a general-purpose register) in
233 *GREGSETPS with the value in GDB's register array. If REGNO is -1,
234 do this for all registers. */
235void
7f7fe91e
UW
236fill_gregset (const struct regcache *regcache,
237 elf_gregset_t *gregsetp, int regno)
0280a90a
AS
238{
239 elf_greg_t *regp = (elf_greg_t *) gregsetp;
240 int i;
241
242 for (i = 0; i < NUM_GREGS; i++)
8de307e0 243 if (regno == -1 || regno == i)
7f7fe91e 244 regcache_raw_collect (regcache, i, regp + regmap[i]);
0280a90a
AS
245}
246
247#ifdef HAVE_PTRACE_GETREGS
248
249/* Fetch all general-purpose registers from process/thread TID and
250 store their values in GDB's register array. */
251
252static void
56be3814 253fetch_regs (struct regcache *regcache, int tid)
0280a90a
AS
254{
255 elf_gregset_t regs;
256
257 if (ptrace (PTRACE_GETREGS, tid, 0, (int) &regs) < 0)
258 {
259 if (errno == EIO)
260 {
261 /* The kernel we're running on doesn't support the GETREGS
262 request. Reset `have_ptrace_getregs'. */
263 have_ptrace_getregs = 0;
264 return;
265 }
266
e2e0b3e5 267 perror_with_name (_("Couldn't get registers"));
0280a90a
AS
268 }
269
56be3814 270 supply_gregset (regcache, (const elf_gregset_t *) &regs);
c906108c
SS
271}
272
0280a90a
AS
273/* Store all valid general-purpose registers in GDB's register array
274 into the process/thread specified by TID. */
275
276static void
56be3814 277store_regs (const struct regcache *regcache, int tid, int regno)
0280a90a
AS
278{
279 elf_gregset_t regs;
280
281 if (ptrace (PTRACE_GETREGS, tid, 0, (int) &regs) < 0)
e2e0b3e5 282 perror_with_name (_("Couldn't get registers"));
0280a90a 283
56be3814 284 fill_gregset (regcache, &regs, regno);
0280a90a
AS
285
286 if (ptrace (PTRACE_SETREGS, tid, 0, (int) &regs) < 0)
e2e0b3e5 287 perror_with_name (_("Couldn't write registers"));
0280a90a
AS
288}
289
290#else
291
025bb325
MS
292static void fetch_regs (struct regcache *regcache, int tid)
293{
294}
295
296static void store_regs (const struct regcache *regcache, int tid, int regno)
297{
298}
0280a90a
AS
299
300#endif
301
302\f
303/* Transfering floating-point registers between GDB, inferiors and cores. */
304
305/* What is the address of fpN within the floating-point register set F? */
7f7fe91e 306#define FPREG_ADDR(f, n) (&(f)->fpregs[(n) * 3])
0280a90a
AS
307
308/* Fill GDB's register array with the floating-point register values in
309 *FPREGSETP. */
c906108c 310
c5aa993b 311void
7f7fe91e 312supply_fpregset (struct regcache *regcache, const elf_fpregset_t *fpregsetp)
c906108c 313{
ac7936df 314 struct gdbarch *gdbarch = regcache->arch ();
c906108c
SS
315 int regi;
316
c984b7ff
UW
317 for (regi = gdbarch_fp0_regnum (gdbarch);
318 regi < gdbarch_fp0_regnum (gdbarch) + 8; regi++)
73e1c03f
SM
319 regcache->raw_supply
320 (regi, FPREG_ADDR (fpregsetp, regi - gdbarch_fp0_regnum (gdbarch)));
321 regcache->raw_supply (M68K_FPC_REGNUM, &fpregsetp->fpcntl[0]);
322 regcache->raw_supply (M68K_FPS_REGNUM, &fpregsetp->fpcntl[1]);
323 regcache->raw_supply (M68K_FPI_REGNUM, &fpregsetp->fpcntl[2]);
c906108c
SS
324}
325
0280a90a
AS
326/* Fill register REGNO (if it is a floating-point register) in
327 *FPREGSETP with the value in GDB's register array. If REGNO is -1,
328 do this for all registers. */
329
330void
7f7fe91e
UW
331fill_fpregset (const struct regcache *regcache,
332 elf_fpregset_t *fpregsetp, int regno)
0280a90a 333{
ac7936df 334 struct gdbarch *gdbarch = regcache->arch ();
0280a90a
AS
335 int i;
336
337 /* Fill in the floating-point registers. */
c984b7ff
UW
338 for (i = gdbarch_fp0_regnum (gdbarch);
339 i < gdbarch_fp0_regnum (gdbarch) + 8; i++)
0280a90a 340 if (regno == -1 || regno == i)
7f7fe91e 341 regcache_raw_collect (regcache, i,
3e8c568d 342 FPREG_ADDR (fpregsetp,
c984b7ff 343 i - gdbarch_fp0_regnum (gdbarch)));
0280a90a
AS
344
345 /* Fill in the floating-point control registers. */
32eeb91a 346 for (i = M68K_FPC_REGNUM; i <= M68K_FPI_REGNUM; i++)
0280a90a 347 if (regno == -1 || regno == i)
7f7fe91e
UW
348 regcache_raw_collect (regcache, i,
349 &fpregsetp->fpcntl[i - M68K_FPC_REGNUM]);
0280a90a
AS
350}
351
352#ifdef HAVE_PTRACE_GETREGS
353
354/* Fetch all floating-point registers from process/thread TID and store
355 thier values in GDB's register array. */
356
357static void
56be3814 358fetch_fpregs (struct regcache *regcache, int tid)
0280a90a
AS
359{
360 elf_fpregset_t fpregs;
361
362 if (ptrace (PTRACE_GETFPREGS, tid, 0, (int) &fpregs) < 0)
e2e0b3e5 363 perror_with_name (_("Couldn't get floating point status"));
0280a90a 364
56be3814 365 supply_fpregset (regcache, (const elf_fpregset_t *) &fpregs);
0280a90a
AS
366}
367
368/* Store all valid floating-point registers in GDB's register array
369 into the process/thread specified by TID. */
370
371static void
56be3814 372store_fpregs (const struct regcache *regcache, int tid, int regno)
0280a90a
AS
373{
374 elf_fpregset_t fpregs;
375
376 if (ptrace (PTRACE_GETFPREGS, tid, 0, (int) &fpregs) < 0)
e2e0b3e5 377 perror_with_name (_("Couldn't get floating point status"));
0280a90a 378
56be3814 379 fill_fpregset (regcache, &fpregs, regno);
0280a90a
AS
380
381 if (ptrace (PTRACE_SETFPREGS, tid, 0, (int) &fpregs) < 0)
e2e0b3e5 382 perror_with_name (_("Couldn't write floating point status"));
0280a90a
AS
383}
384
385#else
386
025bb325
MS
387static void fetch_fpregs (struct regcache *regcache, int tid)
388{
389}
390
391static void store_fpregs (const struct regcache *regcache, int tid, int regno)
392{
393}
0280a90a 394
c906108c 395#endif
0280a90a
AS
396\f
397/* Transferring arbitrary registers between GDB and inferior. */
398
399/* Fetch register REGNO from the child process. If REGNO is -1, do
400 this for all registers (including the floating point and SSE
401 registers). */
402
f6ac5f3d
PA
403void
404m68k_linux_nat_target::fetch_registers (struct regcache *regcache, int regno)
0280a90a 405{
bcc0c096 406 pid_t tid;
0280a90a
AS
407
408 /* Use the old method of peeking around in `struct user' if the
409 GETREGS request isn't available. */
410 if (! have_ptrace_getregs)
411 {
56be3814 412 old_fetch_inferior_registers (regcache, regno);
0280a90a
AS
413 return;
414 }
415
222312d3 416 tid = get_ptrace_pid (regcache->ptid ());
f175af98 417
0280a90a
AS
418 /* Use the PTRACE_GETFPXREGS request whenever possible, since it
419 transfers more registers in one system call, and we'll cache the
420 results. But remember that fetch_fpxregs can fail, and return
421 zero. */
422 if (regno == -1)
423 {
56be3814 424 fetch_regs (regcache, tid);
0280a90a
AS
425
426 /* The call above might reset `have_ptrace_getregs'. */
427 if (! have_ptrace_getregs)
428 {
56be3814 429 old_fetch_inferior_registers (regcache, -1);
0280a90a
AS
430 return;
431 }
432
56be3814 433 fetch_fpregs (regcache, tid);
0280a90a
AS
434 return;
435 }
436
437 if (getregs_supplies (regno))
438 {
56be3814 439 fetch_regs (regcache, tid);
0280a90a
AS
440 return;
441 }
442
443 if (getfpregs_supplies (regno))
444 {
56be3814 445 fetch_fpregs (regcache, tid);
0280a90a
AS
446 return;
447 }
448
449 internal_error (__FILE__, __LINE__,
e2e0b3e5 450 _("Got request for bad register number %d."), regno);
0280a90a
AS
451}
452
453/* Store register REGNO back into the child process. If REGNO is -1,
454 do this for all registers (including the floating point and SSE
455 registers). */
f6ac5f3d
PA
456void
457m68k_linux_nat_target::store_registers (struct regcache *regcache, int regno)
0280a90a 458{
bcc0c096 459 pid_t tid;
0280a90a
AS
460
461 /* Use the old method of poking around in `struct user' if the
462 SETREGS request isn't available. */
463 if (! have_ptrace_getregs)
464 {
56be3814 465 old_store_inferior_registers (regcache, regno);
0280a90a
AS
466 return;
467 }
468
222312d3 469 tid = get_ptrace_pid (regcache->ptid ());
0280a90a
AS
470
471 /* Use the PTRACE_SETFPREGS requests whenever possible, since it
472 transfers more registers in one system call. But remember that
473 store_fpregs can fail, and return zero. */
474 if (regno == -1)
475 {
56be3814
UW
476 store_regs (regcache, tid, regno);
477 store_fpregs (regcache, tid, regno);
0280a90a
AS
478 return;
479 }
480
481 if (getregs_supplies (regno))
482 {
56be3814 483 store_regs (regcache, tid, regno);
0280a90a
AS
484 return;
485 }
486
487 if (getfpregs_supplies (regno))
488 {
56be3814 489 store_fpregs (regcache, tid, regno);
0280a90a
AS
490 return;
491 }
492
493 internal_error (__FILE__, __LINE__,
e2e0b3e5 494 _("Got request to store bad register number %d."), regno);
0280a90a 495}
f175af98 496\f
c5aa993b 497
7b8b6d6d
AS
498/* Fetch the thread-local storage pointer for libthread_db. */
499
500ps_err_e
754653a7 501ps_get_thread_area (struct ps_prochandle *ph,
7b8b6d6d
AS
502 lwpid_t lwpid, int idx, void **base)
503{
504 if (ptrace (PTRACE_GET_THREAD_AREA, lwpid, NULL, base) < 0)
505 return PS_ERR;
506
507 /* IDX is the bias from the thread pointer to the beginning of the
508 thread descriptor. It has to be subtracted due to implementation
509 quirks in libthread_db. */
510 *base = (char *) *base - idx;
511
512 return PS_OK;
513}
10d6c8cd 514
f175af98 515void
5ae5f592 516_initialize_m68k_linux_nat (void)
f175af98 517{
10d6c8cd 518 /* Register the target. */
f6ac5f3d 519 linux_target = &the_m68k_linux_nat_target;
d9f719f1 520 add_inf_child_target (&the_m68k_linux_nat_target);
f175af98 521}
This page took 2.376468 seconds and 4 git commands to generate.