1/* Motorola m68k native support for GNU/Linux.
2
3   Copyright 1996, 1998, 2000, 2001, 2002 Free Software Foundation,
4   Inc.
5
6   This file is part of GDB.
7
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.
12
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.
17
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.  */
22
23#include "defs.h"
24#include "frame.h"
25#include "inferior.h"
26#include "language.h"
27#include "gdbcore.h"
28#include "gdb_string.h"
29#include "regcache.h"
30
31#include "m68k-tdep.h"
32
33#include <sys/param.h>
34#include <sys/dir.h>
35#include <signal.h>
36#include <sys/ptrace.h>
37#include <sys/user.h>
38#include <sys/ioctl.h>
39#include <fcntl.h>
40#include <sys/procfs.h>
41
42#ifdef HAVE_SYS_REG_H
43#include <sys/reg.h>
44#endif
45
46#include <sys/file.h>
47#include "gdb_stat.h"
48
49#include "floatformat.h"
50
51#include "target.h"
52
53/* This table must line up with REGISTER_NAME in "m68k-tdep.c".  */
54static const int regmap[] =
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
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{
79  return FP0_REGNUM <= regno && regno <= M68K_FPI_REGNUM;
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
92
93/* BLOCKEND is the value of u.u_ar0, and points to the place where GS
94   is stored.  */
95
96int
97m68k_linux_register_u_addr (int blockend, int regnum)
98{
99  return (blockend + 4 * regmap[regnum]);
100}
101
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 */
132  int i;
133  unsigned int offset;		/* Offset of registers within the u area.  */
134  char buf[MAX_REGISTER_SIZE];
135  int tid;
136
137  if (CANNOT_FETCH_REGISTER (regno))
138    {
139      memset (buf, '\0', register_size (current_gdbarch, regno));	/* Supply zeroes */
140      regcache_raw_supply (current_regcache, regno, buf);
141      return;
142    }
143
144  /* Overload thread id onto process id */
145  tid = TIDGET (inferior_ptid);
146  if (tid == 0)
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);
152  for (i = 0; i < register_size (current_gdbarch, regno);
153       i += sizeof (PTRACE_XFER_TYPE))
154    {
155      errno = 0;
156      *(PTRACE_XFER_TYPE *) &buf[i] = ptrace (PT_READ_U, tid,
157					      (PTRACE_ARG3_TYPE) regaddr, 0);
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    }
166  regcache_raw_supply (current_regcache, regno, buf);
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). */
172
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 */
197  int i;
198  unsigned int offset;		/* Offset of registers within the u area.  */
199  int tid;
200  char buf[MAX_REGISTER_SIZE];
201
202  if (CANNOT_STORE_REGISTER (regno))
203    {
204      return;
205    }
206
207  /* Overload thread id onto process id */
208  tid = TIDGET (inferior_ptid);
209  if (tid == 0)
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);
215
216  /* Put the contents of regno into a local buffer */
217  regcache_raw_collect (current_regcache, regno, buf);
218
219  /* Store the local buffer into the inferior a chunk at the time. */
220  for (i = 0; i < register_size (current_gdbarch, regno);
221       i += sizeof (PTRACE_XFER_TYPE))
222    {
223      errno = 0;
224      ptrace (PT_WRITE_U, tid, (PTRACE_ARG3_TYPE) regaddr,
225	      *(PTRACE_XFER_TYPE *) (buf + i));
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
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. */
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
267   depend on these definitions. */
268
269#ifndef USE_PROC_FS
270
271/* Prototypes for supply_gregset etc. */
272#include "gregset.h"
273
274void
275supply_gregset (elf_gregset_t *gregsetp)
276{
277  elf_greg_t *regp = (elf_greg_t *) gregsetp;
278  int regi;
279
280  for (regi = M68K_D0_REGNUM; regi <= SP_REGNUM; regi++)
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]);
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++)
296    if (regno == -1 || regno == i)
297      regcache_raw_collect (current_regcache, i, regp + regmap[i]);
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
320      perror_with_name ("Couldn't get registers");
321    }
322
323  supply_gregset (&regs);
324}
325
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)
335    perror_with_name ("Couldn't get registers");
336
337  fill_gregset (&regs, regno);
338
339  if (ptrace (PTRACE_SETREGS, tid, 0, (int) &regs) < 0)
340    perror_with_name ("Couldn't write registers");
341}
342
343#else
344
345static void fetch_regs (int tid) {}
346static void store_regs (int tid, int regno) {}
347
348#endif
349
350
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.  */
358
359void
360supply_fpregset (elf_fpregset_t *fpregsetp)
361{
362  int regi;
363
364  for (regi = FP0_REGNUM; regi < FP0_REGNUM + 8; regi++)
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]);
373}
374
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)
387      regcache_raw_collect (current_regcache, i,
388			    FPREG_ADDR (fpregsetp, i - FP0_REGNUM));
389
390  /* Fill in the floating-point control registers.  */
391  for (i = M68K_FPC_REGNUM; i <= M68K_FPI_REGNUM; i++)
392    if (regno == -1 || regno == i)
393      regcache_raw_collect (current_regcache, i,
394			    (char *) &fpregsetp->fpcntl[i - M68K_FPC_REGNUM]);
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)
408    perror_with_name ("Couldn't get floating point status");
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)
422    perror_with_name ("Couldn't get floating point status");
423
424  fill_fpregset (&fpregs, regno);
425
426  if (ptrace (PTRACE_SETFPREGS, tid, 0, (int) &fpregs) < 0)
427    perror_with_name ("Couldn't write floating point status");
428}
429
430#else
431
432static void fetch_fpregs (int tid) {}
433static void store_fpregs (int tid, int regno) {}
434
435#endif
436
437#endif
438
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
458  /* GNU/Linux LWP ID's are process ID's.  */
459  tid = TIDGET (inferior_ptid);
460  if (tid == 0)
461    tid = PIDGET (inferior_ptid);		/* Not a threaded program.  */
462
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__,
495		  "Got request for bad register number %d.", regno);
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
514  /* GNU/Linux LWP ID's are process ID's.  */
515  tid = TIDGET (inferior_ptid);
516  if (tid == 0)
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__,
542		  "Got request to store bad register number %d.", regno);
543}
544
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
561   REG_ADDR isn't used on GNU/Linux.  */
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))
574	warning ("Wrong size gregset in core file.");
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))
584	warning ("Wrong size fpregset in core file.");
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}
599
600
601int
602kernel_u_size (void)
603{
604  return (sizeof (struct user));
605}
606
607/* Register that we are able to handle GNU/Linux ELF core file
608   formats.  */
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
620_initialize_m68k_linux_nat (void)
621{
622  deprecated_add_core_fns (&linux_elf_core_fns);
623}
624