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