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