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