*** empty log message ***
[deliverable/binutils-gdb.git] / gdb / m68klinux-nat.c
CommitLineData
a4b6fc86
AC
1/* Motorola m68k native support for GNU/Linux.
2
9b254dd1 3 Copyright (C) 1996, 1998, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
7b6bb8da 4 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
c906108c 5
c5aa993b 6 This file is part of GDB.
c906108c 7
c5aa993b
JM
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
a9762ec7 10 the Free Software Foundation; either version 3 of the License, or
c5aa993b 11 (at your option) any later version.
c906108c 12
c5aa993b
JM
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
c906108c 17
c5aa993b 18 You should have received a copy of the GNU General Public License
a9762ec7 19 along with this program. If not, see <http://www.gnu.org/licenses/>. */
c906108c
SS
20
21#include "defs.h"
22#include "frame.h"
23#include "inferior.h"
24#include "language.h"
25#include "gdbcore.h"
32eeb91a 26#include "gdb_string.h"
4e052eda 27#include "regcache.h"
10d6c8cd
DJ
28#include "target.h"
29#include "linux-nat.h"
c906108c 30
32eeb91a
AS
31#include "m68k-tdep.h"
32
c906108c
SS
33#include <sys/param.h>
34#include <sys/dir.h>
35#include <signal.h>
0280a90a 36#include <sys/ptrace.h>
c906108c
SS
37#include <sys/user.h>
38#include <sys/ioctl.h>
39#include <fcntl.h>
40#include <sys/procfs.h>
41
0280a90a
AS
42#ifdef HAVE_SYS_REG_H
43#include <sys/reg.h>
44#endif
45
c906108c
SS
46#include <sys/file.h>
47#include "gdb_stat.h"
48
49#include "floatformat.h"
50
51#include "target.h"
3e00823e 52
025bb325 53/* Prototypes for supply_gregset etc. */
3e00823e 54#include "gregset.h"
c906108c 55\f
c9f4d572 56/* This table must line up with gdbarch_register_name in "m68k-tdep.c". */
c5aa993b 57static const int regmap[] =
c906108c
SS
58{
59 PT_D0, PT_D1, PT_D2, PT_D3, PT_D4, PT_D5, PT_D6, PT_D7,
60 PT_A0, PT_A1, PT_A2, PT_A3, PT_A4, PT_A5, PT_A6, PT_USP,
61 PT_SR, PT_PC,
62 /* PT_FP0, ..., PT_FP7 */
63 21, 24, 27, 30, 33, 36, 39, 42,
64 /* PT_FPCR, PT_FPSR, PT_FPIAR */
65 45, 46, 47
66};
67
0280a90a
AS
68/* Which ptrace request retrieves which registers?
69 These apply to the corresponding SET requests as well. */
70#define NUM_GREGS (18)
71#define MAX_NUM_REGS (NUM_GREGS + 11)
72
73int
74getregs_supplies (int regno)
75{
76 return 0 <= regno && regno < NUM_GREGS;
77}
78
79int
80getfpregs_supplies (int regno)
81{
4ed226fe 82 return M68K_FP0_REGNUM <= regno && regno <= M68K_FPI_REGNUM;
0280a90a
AS
83}
84
85/* Does the current host support the GETREGS request? */
86int have_ptrace_getregs =
87#ifdef HAVE_PTRACE_GETREGS
88 1
89#else
90 0
91#endif
92;
93
94\f
95
0280a90a
AS
96/* Fetching registers directly from the U area, one at a time. */
97
0280a90a
AS
98/* Fetch one register. */
99
100static void
56be3814 101fetch_register (struct regcache *regcache, int regno)
0280a90a 102{
c984b7ff 103 struct gdbarch *gdbarch = get_regcache_arch (regcache);
335d71d6 104 long regaddr;
52f0bd74 105 int i;
123a958e 106 char buf[MAX_REGISTER_SIZE];
0280a90a
AS
107 int tid;
108
025bb325 109 /* Overload thread id onto process id. */
8de307e0
AS
110 tid = TIDGET (inferior_ptid);
111 if (tid == 0)
025bb325
MS
112 tid = PIDGET (inferior_ptid); /* no thread id, just use
113 process id. */
0280a90a 114
de732108 115 regaddr = 4 * regmap[regno];
335d71d6 116 for (i = 0; i < register_size (gdbarch, regno); i += sizeof (long))
0280a90a
AS
117 {
118 errno = 0;
335d71d6
AS
119 *(long *) &buf[i] = ptrace (PTRACE_PEEKUSER, tid, regaddr, 0);
120 regaddr += sizeof (long);
0280a90a 121 if (errno != 0)
335d71d6
AS
122 error (_("Couldn't read register %s (#%d): %s."),
123 gdbarch_register_name (gdbarch, regno),
124 regno, safe_strerror (errno));
0280a90a 125 }
56be3814 126 regcache_raw_supply (regcache, regno, buf);
0280a90a
AS
127}
128
129/* Fetch register values from the inferior.
130 If REGNO is negative, do this for all registers.
025bb325 131 Otherwise, REGNO specifies which register (so we can save time). */
c906108c 132
10d6c8cd 133static void
56be3814 134old_fetch_inferior_registers (struct regcache *regcache, int regno)
0280a90a
AS
135{
136 if (regno >= 0)
137 {
56be3814 138 fetch_register (regcache, regno);
0280a90a
AS
139 }
140 else
141 {
c984b7ff
UW
142 for (regno = 0;
143 regno < gdbarch_num_regs (get_regcache_arch (regcache));
144 regno++)
0280a90a 145 {
56be3814 146 fetch_register (regcache, regno);
0280a90a
AS
147 }
148 }
149}
150
025bb325 151/* Store one register. */
0280a90a
AS
152
153static void
56be3814 154store_register (const struct regcache *regcache, int regno)
0280a90a 155{
f36bf22c 156 struct gdbarch *gdbarch = get_regcache_arch (regcache);
335d71d6 157 long regaddr;
52f0bd74 158 int i;
0280a90a 159 int tid;
d9d9c31f 160 char buf[MAX_REGISTER_SIZE];
0280a90a 161
025bb325 162 /* Overload thread id onto process id. */
8de307e0
AS
163 tid = TIDGET (inferior_ptid);
164 if (tid == 0)
025bb325
MS
165 tid = PIDGET (inferior_ptid); /* no thread id, just use
166 process id. */
0280a90a 167
de732108 168 regaddr = 4 * regmap[regno];
9852326a 169
025bb325 170 /* Put the contents of regno into a local buffer. */
56be3814 171 regcache_raw_collect (regcache, regno, buf);
9852326a 172
025bb325 173 /* Store the local buffer into the inferior a chunk at the time. */
335d71d6 174 for (i = 0; i < register_size (gdbarch, regno); i += sizeof (long))
0280a90a
AS
175 {
176 errno = 0;
335d71d6
AS
177 ptrace (PTRACE_POKEUSER, tid, regaddr, *(long *) &buf[i]);
178 regaddr += sizeof (long);
0280a90a 179 if (errno != 0)
335d71d6
AS
180 error (_("Couldn't write register %s (#%d): %s."),
181 gdbarch_register_name (gdbarch, regno),
182 regno, safe_strerror (errno));
0280a90a
AS
183 }
184}
185
186/* Store our register values back into the inferior.
187 If REGNO is negative, do this for all registers.
188 Otherwise, REGNO specifies which register (so we can save time). */
189
10d6c8cd 190static void
56be3814 191old_store_inferior_registers (const struct regcache *regcache, int regno)
0280a90a
AS
192{
193 if (regno >= 0)
194 {
56be3814 195 store_register (regcache, regno);
0280a90a
AS
196 }
197 else
198 {
c984b7ff
UW
199 for (regno = 0;
200 regno < gdbarch_num_regs (get_regcache_arch (regcache));
201 regno++)
0280a90a 202 {
56be3814 203 store_register (regcache, regno);
0280a90a
AS
204 }
205 }
206}
207\f
f175af98
DJ
208/* Given a pointer to a general register set in /proc format
209 (elf_gregset_t *), unpack the register contents and supply
025bb325 210 them as gdb's idea of the current register values. */
c906108c 211
c906108c 212void
7f7fe91e 213supply_gregset (struct regcache *regcache, const elf_gregset_t *gregsetp)
c906108c 214{
c984b7ff 215 struct gdbarch *gdbarch = get_regcache_arch (regcache);
7f7fe91e 216 const elf_greg_t *regp = (const elf_greg_t *) gregsetp;
c906108c
SS
217 int regi;
218
3e8c568d 219 for (regi = M68K_D0_REGNUM;
c984b7ff 220 regi <= gdbarch_sp_regnum (gdbarch);
3e8c568d 221 regi++)
7f7fe91e 222 regcache_raw_supply (regcache, regi, &regp[regmap[regi]]);
c984b7ff 223 regcache_raw_supply (regcache, gdbarch_ps_regnum (gdbarch),
3e8c568d
UW
224 &regp[PT_SR]);
225 regcache_raw_supply (regcache,
c984b7ff 226 gdbarch_pc_regnum (gdbarch), &regp[PT_PC]);
0280a90a
AS
227}
228
229/* Fill register REGNO (if it is a general-purpose register) in
230 *GREGSETPS with the value in GDB's register array. If REGNO is -1,
231 do this for all registers. */
232void
7f7fe91e
UW
233fill_gregset (const struct regcache *regcache,
234 elf_gregset_t *gregsetp, int regno)
0280a90a
AS
235{
236 elf_greg_t *regp = (elf_greg_t *) gregsetp;
237 int i;
238
239 for (i = 0; i < NUM_GREGS; i++)
8de307e0 240 if (regno == -1 || regno == i)
7f7fe91e 241 regcache_raw_collect (regcache, i, regp + regmap[i]);
0280a90a
AS
242}
243
244#ifdef HAVE_PTRACE_GETREGS
245
246/* Fetch all general-purpose registers from process/thread TID and
247 store their values in GDB's register array. */
248
249static void
56be3814 250fetch_regs (struct regcache *regcache, int tid)
0280a90a
AS
251{
252 elf_gregset_t regs;
253
254 if (ptrace (PTRACE_GETREGS, tid, 0, (int) &regs) < 0)
255 {
256 if (errno == EIO)
257 {
258 /* The kernel we're running on doesn't support the GETREGS
259 request. Reset `have_ptrace_getregs'. */
260 have_ptrace_getregs = 0;
261 return;
262 }
263
e2e0b3e5 264 perror_with_name (_("Couldn't get registers"));
0280a90a
AS
265 }
266
56be3814 267 supply_gregset (regcache, (const elf_gregset_t *) &regs);
c906108c
SS
268}
269
0280a90a
AS
270/* Store all valid general-purpose registers in GDB's register array
271 into the process/thread specified by TID. */
272
273static void
56be3814 274store_regs (const struct regcache *regcache, int tid, int regno)
0280a90a
AS
275{
276 elf_gregset_t regs;
277
278 if (ptrace (PTRACE_GETREGS, tid, 0, (int) &regs) < 0)
e2e0b3e5 279 perror_with_name (_("Couldn't get registers"));
0280a90a 280
56be3814 281 fill_gregset (regcache, &regs, regno);
0280a90a
AS
282
283 if (ptrace (PTRACE_SETREGS, tid, 0, (int) &regs) < 0)
e2e0b3e5 284 perror_with_name (_("Couldn't write registers"));
0280a90a
AS
285}
286
287#else
288
025bb325
MS
289static void fetch_regs (struct regcache *regcache, int tid)
290{
291}
292
293static void store_regs (const struct regcache *regcache, int tid, int regno)
294{
295}
0280a90a
AS
296
297#endif
298
299\f
300/* Transfering floating-point registers between GDB, inferiors and cores. */
301
302/* What is the address of fpN within the floating-point register set F? */
7f7fe91e 303#define FPREG_ADDR(f, n) (&(f)->fpregs[(n) * 3])
0280a90a
AS
304
305/* Fill GDB's register array with the floating-point register values in
306 *FPREGSETP. */
c906108c 307
c5aa993b 308void
7f7fe91e 309supply_fpregset (struct regcache *regcache, const elf_fpregset_t *fpregsetp)
c906108c 310{
c984b7ff 311 struct gdbarch *gdbarch = get_regcache_arch (regcache);
c906108c
SS
312 int regi;
313
c984b7ff
UW
314 for (regi = gdbarch_fp0_regnum (gdbarch);
315 regi < gdbarch_fp0_regnum (gdbarch) + 8; regi++)
7f7fe91e 316 regcache_raw_supply (regcache, regi,
3e8c568d 317 FPREG_ADDR (fpregsetp,
c984b7ff 318 regi - gdbarch_fp0_regnum (gdbarch)));
7f7fe91e
UW
319 regcache_raw_supply (regcache, M68K_FPC_REGNUM, &fpregsetp->fpcntl[0]);
320 regcache_raw_supply (regcache, M68K_FPS_REGNUM, &fpregsetp->fpcntl[1]);
321 regcache_raw_supply (regcache, M68K_FPI_REGNUM, &fpregsetp->fpcntl[2]);
c906108c
SS
322}
323
0280a90a
AS
324/* Fill register REGNO (if it is a floating-point register) in
325 *FPREGSETP with the value in GDB's register array. If REGNO is -1,
326 do this for all registers. */
327
328void
7f7fe91e
UW
329fill_fpregset (const struct regcache *regcache,
330 elf_fpregset_t *fpregsetp, int regno)
0280a90a 331{
c984b7ff 332 struct gdbarch *gdbarch = get_regcache_arch (regcache);
0280a90a
AS
333 int i;
334
335 /* Fill in the floating-point registers. */
c984b7ff
UW
336 for (i = gdbarch_fp0_regnum (gdbarch);
337 i < gdbarch_fp0_regnum (gdbarch) + 8; i++)
0280a90a 338 if (regno == -1 || regno == i)
7f7fe91e 339 regcache_raw_collect (regcache, i,
3e8c568d 340 FPREG_ADDR (fpregsetp,
c984b7ff 341 i - gdbarch_fp0_regnum (gdbarch)));
0280a90a
AS
342
343 /* Fill in the floating-point control registers. */
32eeb91a 344 for (i = M68K_FPC_REGNUM; i <= M68K_FPI_REGNUM; i++)
0280a90a 345 if (regno == -1 || regno == i)
7f7fe91e
UW
346 regcache_raw_collect (regcache, i,
347 &fpregsetp->fpcntl[i - M68K_FPC_REGNUM]);
0280a90a
AS
348}
349
350#ifdef HAVE_PTRACE_GETREGS
351
352/* Fetch all floating-point registers from process/thread TID and store
353 thier values in GDB's register array. */
354
355static void
56be3814 356fetch_fpregs (struct regcache *regcache, int tid)
0280a90a
AS
357{
358 elf_fpregset_t fpregs;
359
360 if (ptrace (PTRACE_GETFPREGS, tid, 0, (int) &fpregs) < 0)
e2e0b3e5 361 perror_with_name (_("Couldn't get floating point status"));
0280a90a 362
56be3814 363 supply_fpregset (regcache, (const elf_fpregset_t *) &fpregs);
0280a90a
AS
364}
365
366/* Store all valid floating-point registers in GDB's register array
367 into the process/thread specified by TID. */
368
369static void
56be3814 370store_fpregs (const struct regcache *regcache, int tid, int regno)
0280a90a
AS
371{
372 elf_fpregset_t fpregs;
373
374 if (ptrace (PTRACE_GETFPREGS, tid, 0, (int) &fpregs) < 0)
e2e0b3e5 375 perror_with_name (_("Couldn't get floating point status"));
0280a90a 376
56be3814 377 fill_fpregset (regcache, &fpregs, regno);
0280a90a
AS
378
379 if (ptrace (PTRACE_SETFPREGS, tid, 0, (int) &fpregs) < 0)
e2e0b3e5 380 perror_with_name (_("Couldn't write floating point status"));
0280a90a
AS
381}
382
383#else
384
025bb325
MS
385static void fetch_fpregs (struct regcache *regcache, int tid)
386{
387}
388
389static void store_fpregs (const struct regcache *regcache, int tid, int regno)
390{
391}
0280a90a 392
c906108c 393#endif
0280a90a
AS
394\f
395/* Transferring arbitrary registers between GDB and inferior. */
396
397/* Fetch register REGNO from the child process. If REGNO is -1, do
398 this for all registers (including the floating point and SSE
399 registers). */
400
10d6c8cd 401static void
28439f5e
PA
402m68k_linux_fetch_inferior_registers (struct target_ops *ops,
403 struct regcache *regcache, int regno)
0280a90a
AS
404{
405 int tid;
406
407 /* Use the old method of peeking around in `struct user' if the
408 GETREGS request isn't available. */
409 if (! have_ptrace_getregs)
410 {
56be3814 411 old_fetch_inferior_registers (regcache, regno);
0280a90a
AS
412 return;
413 }
414
a4b6fc86 415 /* GNU/Linux LWP ID's are process ID's. */
8de307e0
AS
416 tid = TIDGET (inferior_ptid);
417 if (tid == 0)
025bb325 418 tid = PIDGET (inferior_ptid); /* Not a threaded program. */
f175af98 419
0280a90a
AS
420 /* Use the PTRACE_GETFPXREGS request whenever possible, since it
421 transfers more registers in one system call, and we'll cache the
422 results. But remember that fetch_fpxregs can fail, and return
423 zero. */
424 if (regno == -1)
425 {
56be3814 426 fetch_regs (regcache, tid);
0280a90a
AS
427
428 /* The call above might reset `have_ptrace_getregs'. */
429 if (! have_ptrace_getregs)
430 {
56be3814 431 old_fetch_inferior_registers (regcache, -1);
0280a90a
AS
432 return;
433 }
434
56be3814 435 fetch_fpregs (regcache, tid);
0280a90a
AS
436 return;
437 }
438
439 if (getregs_supplies (regno))
440 {
56be3814 441 fetch_regs (regcache, tid);
0280a90a
AS
442 return;
443 }
444
445 if (getfpregs_supplies (regno))
446 {
56be3814 447 fetch_fpregs (regcache, tid);
0280a90a
AS
448 return;
449 }
450
451 internal_error (__FILE__, __LINE__,
e2e0b3e5 452 _("Got request for bad register number %d."), regno);
0280a90a
AS
453}
454
455/* Store register REGNO back into the child process. If REGNO is -1,
456 do this for all registers (including the floating point and SSE
457 registers). */
10d6c8cd 458static void
28439f5e
PA
459m68k_linux_store_inferior_registers (struct target_ops *ops,
460 struct regcache *regcache, int regno)
0280a90a
AS
461{
462 int tid;
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
a4b6fc86 472 /* GNU/Linux LWP ID's are process ID's. */
8de307e0
AS
473 tid = TIDGET (inferior_ptid);
474 if (tid == 0)
0280a90a
AS
475 tid = PIDGET (inferior_ptid); /* Not a threaded program. */
476
477 /* Use the PTRACE_SETFPREGS requests whenever possible, since it
478 transfers more registers in one system call. But remember that
479 store_fpregs can fail, and return zero. */
480 if (regno == -1)
481 {
56be3814
UW
482 store_regs (regcache, tid, regno);
483 store_fpregs (regcache, tid, regno);
0280a90a
AS
484 return;
485 }
486
487 if (getregs_supplies (regno))
488 {
56be3814 489 store_regs (regcache, tid, regno);
0280a90a
AS
490 return;
491 }
492
493 if (getfpregs_supplies (regno))
494 {
56be3814 495 store_fpregs (regcache, tid, regno);
0280a90a
AS
496 return;
497 }
498
499 internal_error (__FILE__, __LINE__,
e2e0b3e5 500 _("Got request to store bad register number %d."), regno);
0280a90a 501}
f175af98
DJ
502\f
503/* Interpreting register set info found in core files. */
504
505/* Provide registers to GDB from a core file.
506
507 (We can't use the generic version of this function in
508 core-regset.c, because we need to use elf_gregset_t instead of
509 gregset_t.)
510
511 CORE_REG_SECT points to an array of bytes, which are the contents
512 of a `note' from a core file which BFD thinks might contain
513 register contents. CORE_REG_SIZE is its size.
514
515 WHICH says which register set corelow suspects this is:
516 0 --- the general-purpose register set, in elf_gregset_t format
517 2 --- the floating-point register set, in elf_fpregset_t format
518
a4b6fc86 519 REG_ADDR isn't used on GNU/Linux. */
f175af98
DJ
520
521static void
9eefc95f
UW
522fetch_core_registers (struct regcache *regcache,
523 char *core_reg_sect, unsigned core_reg_size,
f175af98
DJ
524 int which, CORE_ADDR reg_addr)
525{
526 elf_gregset_t gregset;
527 elf_fpregset_t fpregset;
528
529 switch (which)
530 {
531 case 0:
532 if (core_reg_size != sizeof (gregset))
8a3fe4f8 533 warning (_("Wrong size gregset in core file."));
f175af98
DJ
534 else
535 {
536 memcpy (&gregset, core_reg_sect, sizeof (gregset));
9eefc95f 537 supply_gregset (regcache, (const elf_gregset_t *) &gregset);
f175af98
DJ
538 }
539 break;
540
541 case 2:
542 if (core_reg_size != sizeof (fpregset))
8a3fe4f8 543 warning (_("Wrong size fpregset in core file."));
f175af98
DJ
544 else
545 {
546 memcpy (&fpregset, core_reg_sect, sizeof (fpregset));
9eefc95f 547 supply_fpregset (regcache, (const elf_fpregset_t *) &fpregset);
f175af98
DJ
548 }
549 break;
550
551 default:
552 /* We've covered all the kinds of registers we know about here,
553 so this must be something we wouldn't know what to do with
554 anyway. Just ignore it. */
555 break;
556 }
557}
c906108c 558\f
c5aa993b 559
a4b6fc86
AC
560/* Register that we are able to handle GNU/Linux ELF core file
561 formats. */
f175af98
DJ
562
563static struct core_fns linux_elf_core_fns =
564{
565 bfd_target_elf_flavour, /* core_flavour */
566 default_check_format, /* check_format */
567 default_core_sniffer, /* core_sniffer */
568 fetch_core_registers, /* core_read_registers */
569 NULL /* next */
570};
571
10d6c8cd
DJ
572void _initialize_m68k_linux_nat (void);
573
f175af98 574void
5ae5f592 575_initialize_m68k_linux_nat (void)
f175af98 576{
10d6c8cd
DJ
577 struct target_ops *t;
578
579 /* Fill in the generic GNU/Linux methods. */
580 t = linux_target ();
581
582 /* Add our register access methods. */
583 t->to_fetch_registers = m68k_linux_fetch_inferior_registers;
584 t->to_store_registers = m68k_linux_store_inferior_registers;
585
586 /* Register the target. */
f973ed9c 587 linux_nat_add_target (t);
10d6c8cd 588
00e32a35 589 deprecated_add_core_fns (&linux_elf_core_fns);
f175af98 590}
This page took 0.881296 seconds and 4 git commands to generate.