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