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