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