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