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