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 *) ®p[regmap[regi]]);
282*11efff7fSkettenis regcache_raw_supply (current_regcache, PS_REGNUM, (char *) ®p[PT_SR]);
283*11efff7fSkettenis regcache_raw_supply (current_regcache, PC_REGNUM, (char *) ®p[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) ®s) < 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 (®s);
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) ®s) < 0)
335b725ae77Skettenis perror_with_name ("Couldn't get registers");
336b725ae77Skettenis
337b725ae77Skettenis fill_gregset (®s, regno);
338b725ae77Skettenis
339b725ae77Skettenis if (ptrace (PTRACE_SETREGS, tid, 0, (int) ®s) < 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