Convert struct target_ops to C++
[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];
bcc0c096 122 pid_t tid = get_ptrace_pid (regcache_get_ptid (regcache));
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 }
56be3814 136 regcache_raw_supply (regcache, 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];
bcc0c096 170 pid_t tid = get_ptrace_pid (regcache_get_ptid (regcache));
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++)
7f7fe91e 227 regcache_raw_supply (regcache, regi, &regp[regmap[regi]]);
c984b7ff 228 regcache_raw_supply (regcache, gdbarch_ps_regnum (gdbarch),
3e8c568d
UW
229 &regp[PT_SR]);
230 regcache_raw_supply (regcache,
c984b7ff 231 gdbarch_pc_regnum (gdbarch), &regp[PT_PC]);
0280a90a
AS
232}
233
234/* Fill register REGNO (if it is a general-purpose register) in
235 *GREGSETPS with the value in GDB's register array. If REGNO is -1,
236 do this for all registers. */
237void
7f7fe91e
UW
238fill_gregset (const struct regcache *regcache,
239 elf_gregset_t *gregsetp, int regno)
0280a90a
AS
240{
241 elf_greg_t *regp = (elf_greg_t *) gregsetp;
242 int i;
243
244 for (i = 0; i < NUM_GREGS; i++)
8de307e0 245 if (regno == -1 || regno == i)
7f7fe91e 246 regcache_raw_collect (regcache, i, regp + regmap[i]);
0280a90a
AS
247}
248
249#ifdef HAVE_PTRACE_GETREGS
250
251/* Fetch all general-purpose registers from process/thread TID and
252 store their values in GDB's register array. */
253
254static void
56be3814 255fetch_regs (struct regcache *regcache, int tid)
0280a90a
AS
256{
257 elf_gregset_t regs;
258
259 if (ptrace (PTRACE_GETREGS, tid, 0, (int) &regs) < 0)
260 {
261 if (errno == EIO)
262 {
263 /* The kernel we're running on doesn't support the GETREGS
264 request. Reset `have_ptrace_getregs'. */
265 have_ptrace_getregs = 0;
266 return;
267 }
268
e2e0b3e5 269 perror_with_name (_("Couldn't get registers"));
0280a90a
AS
270 }
271
56be3814 272 supply_gregset (regcache, (const elf_gregset_t *) &regs);
c906108c
SS
273}
274
0280a90a
AS
275/* Store all valid general-purpose registers in GDB's register array
276 into the process/thread specified by TID. */
277
278static void
56be3814 279store_regs (const struct regcache *regcache, int tid, int regno)
0280a90a
AS
280{
281 elf_gregset_t regs;
282
283 if (ptrace (PTRACE_GETREGS, tid, 0, (int) &regs) < 0)
e2e0b3e5 284 perror_with_name (_("Couldn't get registers"));
0280a90a 285
56be3814 286 fill_gregset (regcache, &regs, regno);
0280a90a
AS
287
288 if (ptrace (PTRACE_SETREGS, tid, 0, (int) &regs) < 0)
e2e0b3e5 289 perror_with_name (_("Couldn't write registers"));
0280a90a
AS
290}
291
292#else
293
025bb325
MS
294static void fetch_regs (struct regcache *regcache, int tid)
295{
296}
297
298static void store_regs (const struct regcache *regcache, int tid, int regno)
299{
300}
0280a90a
AS
301
302#endif
303
304\f
305/* Transfering floating-point registers between GDB, inferiors and cores. */
306
307/* What is the address of fpN within the floating-point register set F? */
7f7fe91e 308#define FPREG_ADDR(f, n) (&(f)->fpregs[(n) * 3])
0280a90a
AS
309
310/* Fill GDB's register array with the floating-point register values in
311 *FPREGSETP. */
c906108c 312
c5aa993b 313void
7f7fe91e 314supply_fpregset (struct regcache *regcache, const elf_fpregset_t *fpregsetp)
c906108c 315{
ac7936df 316 struct gdbarch *gdbarch = regcache->arch ();
c906108c
SS
317 int regi;
318
c984b7ff
UW
319 for (regi = gdbarch_fp0_regnum (gdbarch);
320 regi < gdbarch_fp0_regnum (gdbarch) + 8; regi++)
7f7fe91e 321 regcache_raw_supply (regcache, regi,
3e8c568d 322 FPREG_ADDR (fpregsetp,
c984b7ff 323 regi - gdbarch_fp0_regnum (gdbarch)));
7f7fe91e
UW
324 regcache_raw_supply (regcache, M68K_FPC_REGNUM, &fpregsetp->fpcntl[0]);
325 regcache_raw_supply (regcache, M68K_FPS_REGNUM, &fpregsetp->fpcntl[1]);
326 regcache_raw_supply (regcache, M68K_FPI_REGNUM, &fpregsetp->fpcntl[2]);
c906108c
SS
327}
328
0280a90a
AS
329/* Fill register REGNO (if it is a floating-point register) in
330 *FPREGSETP with the value in GDB's register array. If REGNO is -1,
331 do this for all registers. */
332
333void
7f7fe91e
UW
334fill_fpregset (const struct regcache *regcache,
335 elf_fpregset_t *fpregsetp, int regno)
0280a90a 336{
ac7936df 337 struct gdbarch *gdbarch = regcache->arch ();
0280a90a
AS
338 int i;
339
340 /* Fill in the floating-point registers. */
c984b7ff
UW
341 for (i = gdbarch_fp0_regnum (gdbarch);
342 i < gdbarch_fp0_regnum (gdbarch) + 8; i++)
0280a90a 343 if (regno == -1 || regno == i)
7f7fe91e 344 regcache_raw_collect (regcache, i,
3e8c568d 345 FPREG_ADDR (fpregsetp,
c984b7ff 346 i - gdbarch_fp0_regnum (gdbarch)));
0280a90a
AS
347
348 /* Fill in the floating-point control registers. */
32eeb91a 349 for (i = M68K_FPC_REGNUM; i <= M68K_FPI_REGNUM; i++)
0280a90a 350 if (regno == -1 || regno == i)
7f7fe91e
UW
351 regcache_raw_collect (regcache, i,
352 &fpregsetp->fpcntl[i - M68K_FPC_REGNUM]);
0280a90a
AS
353}
354
355#ifdef HAVE_PTRACE_GETREGS
356
357/* Fetch all floating-point registers from process/thread TID and store
358 thier values in GDB's register array. */
359
360static void
56be3814 361fetch_fpregs (struct regcache *regcache, int tid)
0280a90a
AS
362{
363 elf_fpregset_t fpregs;
364
365 if (ptrace (PTRACE_GETFPREGS, tid, 0, (int) &fpregs) < 0)
e2e0b3e5 366 perror_with_name (_("Couldn't get floating point status"));
0280a90a 367
56be3814 368 supply_fpregset (regcache, (const elf_fpregset_t *) &fpregs);
0280a90a
AS
369}
370
371/* Store all valid floating-point registers in GDB's register array
372 into the process/thread specified by TID. */
373
374static void
56be3814 375store_fpregs (const struct regcache *regcache, int tid, int regno)
0280a90a
AS
376{
377 elf_fpregset_t fpregs;
378
379 if (ptrace (PTRACE_GETFPREGS, tid, 0, (int) &fpregs) < 0)
e2e0b3e5 380 perror_with_name (_("Couldn't get floating point status"));
0280a90a 381
56be3814 382 fill_fpregset (regcache, &fpregs, regno);
0280a90a
AS
383
384 if (ptrace (PTRACE_SETFPREGS, tid, 0, (int) &fpregs) < 0)
e2e0b3e5 385 perror_with_name (_("Couldn't write floating point status"));
0280a90a
AS
386}
387
388#else
389
025bb325
MS
390static void fetch_fpregs (struct regcache *regcache, int tid)
391{
392}
393
394static void store_fpregs (const struct regcache *regcache, int tid, int regno)
395{
396}
0280a90a 397
c906108c 398#endif
0280a90a
AS
399\f
400/* Transferring arbitrary registers between GDB and inferior. */
401
402/* Fetch register REGNO from the child process. If REGNO is -1, do
403 this for all registers (including the floating point and SSE
404 registers). */
405
f6ac5f3d
PA
406void
407m68k_linux_nat_target::fetch_registers (struct regcache *regcache, int regno)
0280a90a 408{
bcc0c096 409 pid_t tid;
0280a90a
AS
410
411 /* Use the old method of peeking around in `struct user' if the
412 GETREGS request isn't available. */
413 if (! have_ptrace_getregs)
414 {
56be3814 415 old_fetch_inferior_registers (regcache, regno);
0280a90a
AS
416 return;
417 }
418
bcc0c096 419 tid = get_ptrace_pid (regcache_get_ptid (regcache));
f175af98 420
0280a90a
AS
421 /* Use the PTRACE_GETFPXREGS request whenever possible, since it
422 transfers more registers in one system call, and we'll cache the
423 results. But remember that fetch_fpxregs can fail, and return
424 zero. */
425 if (regno == -1)
426 {
56be3814 427 fetch_regs (regcache, tid);
0280a90a
AS
428
429 /* The call above might reset `have_ptrace_getregs'. */
430 if (! have_ptrace_getregs)
431 {
56be3814 432 old_fetch_inferior_registers (regcache, -1);
0280a90a
AS
433 return;
434 }
435
56be3814 436 fetch_fpregs (regcache, tid);
0280a90a
AS
437 return;
438 }
439
440 if (getregs_supplies (regno))
441 {
56be3814 442 fetch_regs (regcache, tid);
0280a90a
AS
443 return;
444 }
445
446 if (getfpregs_supplies (regno))
447 {
56be3814 448 fetch_fpregs (regcache, tid);
0280a90a
AS
449 return;
450 }
451
452 internal_error (__FILE__, __LINE__,
e2e0b3e5 453 _("Got request for bad register number %d."), regno);
0280a90a
AS
454}
455
456/* Store register REGNO back into the child process. If REGNO is -1,
457 do this for all registers (including the floating point and SSE
458 registers). */
f6ac5f3d
PA
459void
460m68k_linux_nat_target::store_registers (struct regcache *regcache, int regno)
0280a90a 461{
bcc0c096 462 pid_t tid;
0280a90a
AS
463
464 /* Use the old method of poking around in `struct user' if the
465 SETREGS request isn't available. */
466 if (! have_ptrace_getregs)
467 {
56be3814 468 old_store_inferior_registers (regcache, regno);
0280a90a
AS
469 return;
470 }
471
bcc0c096 472 tid = get_ptrace_pid (regcache_get_ptid (regcache));
0280a90a
AS
473
474 /* Use the PTRACE_SETFPREGS requests whenever possible, since it
475 transfers more registers in one system call. But remember that
476 store_fpregs can fail, and return zero. */
477 if (regno == -1)
478 {
56be3814
UW
479 store_regs (regcache, tid, regno);
480 store_fpregs (regcache, tid, regno);
0280a90a
AS
481 return;
482 }
483
484 if (getregs_supplies (regno))
485 {
56be3814 486 store_regs (regcache, tid, regno);
0280a90a
AS
487 return;
488 }
489
490 if (getfpregs_supplies (regno))
491 {
56be3814 492 store_fpregs (regcache, tid, regno);
0280a90a
AS
493 return;
494 }
495
496 internal_error (__FILE__, __LINE__,
e2e0b3e5 497 _("Got request to store bad register number %d."), regno);
0280a90a 498}
f175af98 499\f
c5aa993b 500
7b8b6d6d
AS
501/* Fetch the thread-local storage pointer for libthread_db. */
502
503ps_err_e
754653a7 504ps_get_thread_area (struct ps_prochandle *ph,
7b8b6d6d
AS
505 lwpid_t lwpid, int idx, void **base)
506{
507 if (ptrace (PTRACE_GET_THREAD_AREA, lwpid, NULL, base) < 0)
508 return PS_ERR;
509
510 /* IDX is the bias from the thread pointer to the beginning of the
511 thread descriptor. It has to be subtracted due to implementation
512 quirks in libthread_db. */
513 *base = (char *) *base - idx;
514
515 return PS_OK;
516}
10d6c8cd 517
f175af98 518void
5ae5f592 519_initialize_m68k_linux_nat (void)
f175af98 520{
10d6c8cd 521 /* Register the target. */
f6ac5f3d
PA
522 linux_target = &the_m68k_linux_nat_target;
523 add_target (&the_m68k_linux_nat_target);
f175af98 524}
This page took 2.827841 seconds and 4 git commands to generate.