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