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