GDB (xrefs)
/tmp/gdb-7.10/gdb/m68klinux-nat.c
Go to the documentation of this file.
1 /* Motorola m68k native support for GNU/Linux.
2 
3  Copyright (C) 1996-2015 Free Software Foundation, Inc.
4 
5  This file is part of GDB.
6 
7  This program is free software; you can redistribute it and/or modify
8  it under the terms of the GNU General Public License as published by
9  the Free Software Foundation; either version 3 of the License, or
10  (at your option) any later version.
11 
12  This program is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with this program. If not, see <http://www.gnu.org/licenses/>. */
19 
20 #include "defs.h"
21 #include "frame.h"
22 #include "inferior.h"
23 #include "language.h"
24 #include "gdbcore.h"
25 #include "regcache.h"
26 #include "target.h"
27 #include "linux-nat.h"
28 
29 #include "m68k-tdep.h"
30 
31 #include <sys/dir.h>
32 #include <signal.h>
33 #include <sys/ptrace.h>
34 #include <sys/user.h>
35 #include <sys/ioctl.h>
36 #include <fcntl.h>
37 #include <sys/procfs.h>
38 
39 #ifdef HAVE_SYS_REG_H
40 #include <sys/reg.h>
41 #endif
42 
43 #include <sys/file.h>
44 #include <sys/stat.h>
45 
46 #include "floatformat.h"
47 
48 /* Prototypes for supply_gregset etc. */
49 #include "gregset.h"
50 
51 /* Defines ps_err_e, struct ps_prochandle. */
52 #include "gdb_proc_service.h"
53 
54 #ifndef PTRACE_GET_THREAD_AREA
55 #define PTRACE_GET_THREAD_AREA 25
56 #endif
57 
58 /* This table must line up with gdbarch_register_name in "m68k-tdep.c". */
59 static const int regmap[] =
60 {
61  PT_D0, PT_D1, PT_D2, PT_D3, PT_D4, PT_D5, PT_D6, PT_D7,
62  PT_A0, PT_A1, PT_A2, PT_A3, PT_A4, PT_A5, PT_A6, PT_USP,
63  PT_SR, PT_PC,
64  /* PT_FP0, ..., PT_FP7 */
65  21, 24, 27, 30, 33, 36, 39, 42,
66  /* PT_FPCR, PT_FPSR, PT_FPIAR */
67  45, 46, 47
68 };
69 
70 /* Which ptrace request retrieves which registers?
71  These apply to the corresponding SET requests as well. */
72 #define NUM_GREGS (18)
73 #define MAX_NUM_REGS (NUM_GREGS + 11)
74 
75 static int
76 getregs_supplies (int regno)
77 {
78  return 0 <= regno && regno < NUM_GREGS;
79 }
80 
81 static int
82 getfpregs_supplies (int regno)
83 {
84  return M68K_FP0_REGNUM <= regno && regno <= M68K_FPI_REGNUM;
85 }
86 
87 /* Does the current host support the GETREGS request? */
88 static int have_ptrace_getregs =
89 #ifdef HAVE_PTRACE_GETREGS
90  1
91 #else
92  0
93 #endif
94 ;
95 
96 
97 
98 /* Fetching registers directly from the U area, one at a time. */
99 
100 /* Fetch one register. */
101 
102 static void
103 fetch_register (struct regcache *regcache, int regno)
104 {
105  struct gdbarch *gdbarch = get_regcache_arch (regcache);
106  long regaddr, val;
107  int i;
109  int tid;
110 
111  /* Overload thread id onto process id. */
112  tid = ptid_get_lwp (inferior_ptid);
113  if (tid == 0)
114  tid = ptid_get_pid (inferior_ptid); /* no thread id, just use
115  process id. */
116 
117  regaddr = 4 * regmap[regno];
118  for (i = 0; i < register_size (gdbarch, regno); i += sizeof (long))
119  {
120  errno = 0;
121  val = ptrace (PTRACE_PEEKUSER, tid, regaddr, 0);
122  memcpy (&buf[i], &val, sizeof (long));
123  regaddr += sizeof (long);
124  if (errno != 0)
125  error (_("Couldn't read register %s (#%d): %s."),
126  gdbarch_register_name (gdbarch, regno),
127  regno, safe_strerror (errno));
128  }
129  regcache_raw_supply (regcache, regno, buf);
130 }
131 
132 /* Fetch register values from the inferior.
133  If REGNO is negative, do this for all registers.
134  Otherwise, REGNO specifies which register (so we can save time). */
135 
136 static void
138 {
139  if (regno >= 0)
140  {
141  fetch_register (regcache, regno);
142  }
143  else
144  {
145  for (regno = 0;
146  regno < gdbarch_num_regs (get_regcache_arch (regcache));
147  regno++)
148  {
149  fetch_register (regcache, regno);
150  }
151  }
152 }
153 
154 /* Store one register. */
155 
156 static void
157 store_register (const struct regcache *regcache, int regno)
158 {
159  struct gdbarch *gdbarch = get_regcache_arch (regcache);
160  long regaddr, val;
161  int i;
162  int tid;
164 
165  /* Overload thread id onto process id. */
166  tid = ptid_get_lwp (inferior_ptid);
167  if (tid == 0)
168  tid = ptid_get_pid (inferior_ptid); /* no thread id, just use
169  process id. */
170 
171  regaddr = 4 * regmap[regno];
172 
173  /* Put the contents of regno into a local buffer. */
174  regcache_raw_collect (regcache, regno, buf);
175 
176  /* Store the local buffer into the inferior a chunk at the time. */
177  for (i = 0; i < register_size (gdbarch, regno); i += sizeof (long))
178  {
179  errno = 0;
180  memcpy (&val, &buf[i], sizeof (long));
181  ptrace (PTRACE_POKEUSER, tid, regaddr, val);
182  regaddr += sizeof (long);
183  if (errno != 0)
184  error (_("Couldn't write register %s (#%d): %s."),
185  gdbarch_register_name (gdbarch, regno),
186  regno, safe_strerror (errno));
187  }
188 }
189 
190 /* Store our register values back into the inferior.
191  If REGNO is negative, do this for all registers.
192  Otherwise, REGNO specifies which register (so we can save time). */
193 
194 static void
196 {
197  if (regno >= 0)
198  {
199  store_register (regcache, regno);
200  }
201  else
202  {
203  for (regno = 0;
204  regno < gdbarch_num_regs (get_regcache_arch (regcache));
205  regno++)
206  {
207  store_register (regcache, regno);
208  }
209  }
210 }
211 
212 /* Given a pointer to a general register set in /proc format
213  (elf_gregset_t *), unpack the register contents and supply
214  them as gdb's idea of the current register values. */
215 
216 void
217 supply_gregset (struct regcache *regcache, const elf_gregset_t *gregsetp)
218 {
219  struct gdbarch *gdbarch = get_regcache_arch (regcache);
220  const elf_greg_t *regp = (const elf_greg_t *) gregsetp;
221  int regi;
222 
223  for (regi = M68K_D0_REGNUM;
224  regi <= gdbarch_sp_regnum (gdbarch);
225  regi++)
226  regcache_raw_supply (regcache, regi, &regp[regmap[regi]]);
227  regcache_raw_supply (regcache, gdbarch_ps_regnum (gdbarch),
228  &regp[PT_SR]);
229  regcache_raw_supply (regcache,
230  gdbarch_pc_regnum (gdbarch), &regp[PT_PC]);
231 }
232 
233 /* Fill register REGNO (if it is a general-purpose register) in
234  *GREGSETPS with the value in GDB's register array. If REGNO is -1,
235  do this for all registers. */
236 void
238  elf_gregset_t *gregsetp, int regno)
239 {
240  elf_greg_t *regp = (elf_greg_t *) gregsetp;
241  int i;
242 
243  for (i = 0; i < NUM_GREGS; i++)
244  if (regno == -1 || regno == i)
245  regcache_raw_collect (regcache, i, regp + regmap[i]);
246 }
247 
248 #ifdef HAVE_PTRACE_GETREGS
249 
250 /* Fetch all general-purpose registers from process/thread TID and
251  store their values in GDB's register array. */
252 
253 static void
254 fetch_regs (struct regcache *regcache, int tid)
255 {
256  elf_gregset_t regs;
257 
258  if (ptrace (PTRACE_GETREGS, tid, 0, (int) &regs) < 0)
259  {
260  if (errno == EIO)
261  {
262  /* The kernel we're running on doesn't support the GETREGS
263  request. Reset `have_ptrace_getregs'. */
265  return;
266  }
267 
268  perror_with_name (_("Couldn't get registers"));
269  }
270 
271  supply_gregset (regcache, (const elf_gregset_t *) &regs);
272 }
273 
274 /* Store all valid general-purpose registers in GDB's register array
275  into the process/thread specified by TID. */
276 
277 static void
278 store_regs (const struct regcache *regcache, int tid, int regno)
279 {
280  elf_gregset_t regs;
281 
282  if (ptrace (PTRACE_GETREGS, tid, 0, (int) &regs) < 0)
283  perror_with_name (_("Couldn't get registers"));
284 
285  fill_gregset (regcache, &regs, regno);
286 
287  if (ptrace (PTRACE_SETREGS, tid, 0, (int) &regs) < 0)
288  perror_with_name (_("Couldn't write registers"));
289 }
290 
291 #else
292 
293 static void fetch_regs (struct regcache *regcache, int tid)
294 {
295 }
296 
297 static void store_regs (const struct regcache *regcache, int tid, int regno)
298 {
299 }
300 
301 #endif
302 
303 
304 /* Transfering floating-point registers between GDB, inferiors and cores. */
305 
306 /* What is the address of fpN within the floating-point register set F? */
307 #define FPREG_ADDR(f, n) (&(f)->fpregs[(n) * 3])
308 
309 /* Fill GDB's register array with the floating-point register values in
310  *FPREGSETP. */
311 
312 void
313 supply_fpregset (struct regcache *regcache, const elf_fpregset_t *fpregsetp)
314 {
315  struct gdbarch *gdbarch = get_regcache_arch (regcache);
316  int regi;
317 
318  for (regi = gdbarch_fp0_regnum (gdbarch);
319  regi < gdbarch_fp0_regnum (gdbarch) + 8; regi++)
320  regcache_raw_supply (regcache, regi,
321  FPREG_ADDR (fpregsetp,
322  regi - gdbarch_fp0_regnum (gdbarch)));
323  regcache_raw_supply (regcache, M68K_FPC_REGNUM, &fpregsetp->fpcntl[0]);
324  regcache_raw_supply (regcache, M68K_FPS_REGNUM, &fpregsetp->fpcntl[1]);
325  regcache_raw_supply (regcache, M68K_FPI_REGNUM, &fpregsetp->fpcntl[2]);
326 }
327 
328 /* Fill register REGNO (if it is a floating-point register) in
329  *FPREGSETP with the value in GDB's register array. If REGNO is -1,
330  do this for all registers. */
331 
332 void
334  elf_fpregset_t *fpregsetp, int regno)
335 {
336  struct gdbarch *gdbarch = get_regcache_arch (regcache);
337  int i;
338 
339  /* Fill in the floating-point registers. */
340  for (i = gdbarch_fp0_regnum (gdbarch);
341  i < gdbarch_fp0_regnum (gdbarch) + 8; i++)
342  if (regno == -1 || regno == i)
343  regcache_raw_collect (regcache, i,
344  FPREG_ADDR (fpregsetp,
345  i - gdbarch_fp0_regnum (gdbarch)));
346 
347  /* Fill in the floating-point control registers. */
348  for (i = M68K_FPC_REGNUM; i <= M68K_FPI_REGNUM; i++)
349  if (regno == -1 || regno == i)
350  regcache_raw_collect (regcache, i,
351  &fpregsetp->fpcntl[i - M68K_FPC_REGNUM]);
352 }
353 
354 #ifdef HAVE_PTRACE_GETREGS
355 
356 /* Fetch all floating-point registers from process/thread TID and store
357  thier values in GDB's register array. */
358 
359 static void
360 fetch_fpregs (struct regcache *regcache, int tid)
361 {
362  elf_fpregset_t fpregs;
363 
364  if (ptrace (PTRACE_GETFPREGS, tid, 0, (int) &fpregs) < 0)
365  perror_with_name (_("Couldn't get floating point status"));
366 
367  supply_fpregset (regcache, (const elf_fpregset_t *) &fpregs);
368 }
369 
370 /* Store all valid floating-point registers in GDB's register array
371  into the process/thread specified by TID. */
372 
373 static void
374 store_fpregs (const struct regcache *regcache, int tid, int regno)
375 {
376  elf_fpregset_t fpregs;
377 
378  if (ptrace (PTRACE_GETFPREGS, tid, 0, (int) &fpregs) < 0)
379  perror_with_name (_("Couldn't get floating point status"));
380 
381  fill_fpregset (regcache, &fpregs, regno);
382 
383  if (ptrace (PTRACE_SETFPREGS, tid, 0, (int) &fpregs) < 0)
384  perror_with_name (_("Couldn't write floating point status"));
385 }
386 
387 #else
388 
389 static void fetch_fpregs (struct regcache *regcache, int tid)
390 {
391 }
392 
393 static void store_fpregs (const struct regcache *regcache, int tid, int regno)
394 {
395 }
396 
397 #endif
398 
399 /* Transferring arbitrary registers between GDB and inferior. */
400 
401 /* Fetch register REGNO from the child process. If REGNO is -1, do
402  this for all registers (including the floating point and SSE
403  registers). */
404 
405 static void
407  struct regcache *regcache, int regno)
408 {
409  int tid;
410 
411  /* Use the old method of peeking around in `struct user' if the
412  GETREGS request isn't available. */
413  if (! have_ptrace_getregs)
414  {
415  old_fetch_inferior_registers (regcache, regno);
416  return;
417  }
418 
419  /* GNU/Linux LWP ID's are process ID's. */
420  tid = ptid_get_lwp (inferior_ptid);
421  if (tid == 0)
422  tid = ptid_get_pid (inferior_ptid); /* Not a threaded program. */
423 
424  /* Use the PTRACE_GETFPXREGS request whenever possible, since it
425  transfers more registers in one system call, and we'll cache the
426  results. But remember that fetch_fpxregs can fail, and return
427  zero. */
428  if (regno == -1)
429  {
430  fetch_regs (regcache, tid);
431 
432  /* The call above might reset `have_ptrace_getregs'. */
433  if (! have_ptrace_getregs)
434  {
435  old_fetch_inferior_registers (regcache, -1);
436  return;
437  }
438 
439  fetch_fpregs (regcache, tid);
440  return;
441  }
442 
443  if (getregs_supplies (regno))
444  {
445  fetch_regs (regcache, tid);
446  return;
447  }
448 
449  if (getfpregs_supplies (regno))
450  {
451  fetch_fpregs (regcache, tid);
452  return;
453  }
454 
455  internal_error (__FILE__, __LINE__,
456  _("Got request for bad register number %d."), regno);
457 }
458 
459 /* Store register REGNO back into the child process. If REGNO is -1,
460  do this for all registers (including the floating point and SSE
461  registers). */
462 static void
464  struct regcache *regcache, int regno)
465 {
466  int tid;
467 
468  /* Use the old method of poking around in `struct user' if the
469  SETREGS request isn't available. */
470  if (! have_ptrace_getregs)
471  {
472  old_store_inferior_registers (regcache, regno);
473  return;
474  }
475 
476  /* GNU/Linux LWP ID's are process ID's. */
477  tid = ptid_get_lwp (inferior_ptid);
478  if (tid == 0)
479  tid = ptid_get_pid (inferior_ptid); /* Not a threaded program. */
480 
481  /* Use the PTRACE_SETFPREGS requests whenever possible, since it
482  transfers more registers in one system call. But remember that
483  store_fpregs can fail, and return zero. */
484  if (regno == -1)
485  {
486  store_regs (regcache, tid, regno);
487  store_fpregs (regcache, tid, regno);
488  return;
489  }
490 
491  if (getregs_supplies (regno))
492  {
493  store_regs (regcache, tid, regno);
494  return;
495  }
496 
497  if (getfpregs_supplies (regno))
498  {
499  store_fpregs (regcache, tid, regno);
500  return;
501  }
502 
503  internal_error (__FILE__, __LINE__,
504  _("Got request to store bad register number %d."), regno);
505 }
506 
507 
508 /* Fetch the thread-local storage pointer for libthread_db. */
509 
510 ps_err_e
512  lwpid_t lwpid, int idx, void **base)
513 {
514  if (ptrace (PTRACE_GET_THREAD_AREA, lwpid, NULL, base) < 0)
515  return PS_ERR;
516 
517  /* IDX is the bias from the thread pointer to the beginning of the
518  thread descriptor. It has to be subtracted due to implementation
519  quirks in libthread_db. */
520  *base = (char *) *base - idx;
521 
522  return PS_OK;
523 }
524 
525 
526 void _initialize_m68k_linux_nat (void);
527 
528 void
530 {
531  struct target_ops *t;
532 
533  /* Fill in the generic GNU/Linux methods. */
534  t = linux_target ();
535 
536  /* Add our register access methods. */
539 
540  /* Register the target. */
542 }
unsigned int lwpid_t
static void store_regs(const struct regcache *regcache, int tid, int regno)
struct gdbarch * get_regcache_arch(const struct regcache *regcache)
Definition: regcache.c:297
#define FPREG_ADDR(f, n)
static int getregs_supplies(int regno)
Definition: m68klinux-nat.c:76
void internal_error(const char *file, int line, const char *fmt,...)
Definition: errors.c:50
static void m68k_linux_fetch_inferior_registers(struct target_ops *ops, struct regcache *regcache, int regno)
static void old_fetch_inferior_registers(struct regcache *regcache, int regno)
void fill_gregset(const struct regcache *regcache, elf_gregset_t *gregsetp, int regno)
ps_err_e
int gdbarch_num_regs(struct gdbarch *gdbarch)
Definition: gdbarch.c:1898
#define PTRACE_SETFPREGS
#define _(String)
Definition: gdb_locale.h:40
int gdbarch_ps_regnum(struct gdbarch *gdbarch)
Definition: gdbarch.c:2015
PTRACE_TYPE_RET ptrace()
void fill_fpregset(const struct regcache *regcache, elf_fpregset_t *fpregsetp, int regno)
void supply_gregset(struct regcache *regcache, const elf_gregset_t *gregsetp)
static void store_register(const struct regcache *regcache, int regno)
static void fetch_regs(struct regcache *regcache, int tid)
#define PTRACE_GETFPREGS
int gdbarch_sp_regnum(struct gdbarch *gdbarch)
Definition: gdbarch.c:1981
static void m68k_linux_store_inferior_registers(struct target_ops *ops, struct regcache *regcache, int regno)
static void fetch_register(struct regcache *regcache, int regno)
#define PTRACE_GET_THREAD_AREA
Definition: m68klinux-nat.c:55
const char * gdbarch_register_name(struct gdbarch *gdbarch, int regnr)
Definition: gdbarch.c:2117
void linux_nat_add_target(struct target_ops *t)
Definition: linux-nat.c:4972
static int have_ptrace_getregs
Definition: m68klinux-nat.c:88
struct target_ops * linux_target(void)
Definition: linux-nat.c:4544
int ptid_get_pid(ptid_t ptid)
Definition: ptid.c:52
static void fetch_fpregs(struct regcache *regcache, int tid)
bfd_byte gdb_byte
Definition: common-types.h:38
void(* to_fetch_registers)(struct target_ops *, struct regcache *, int) TARGET_DEFAULT_IGNORE()
Definition: target.h:472
void void void void void void void void void perror_with_name(const char *string) ATTRIBUTE_NORETURN
Definition: utils.c:979
int gdbarch_fp0_regnum(struct gdbarch *gdbarch)
Definition: gdbarch.c:2032
ptid_t inferior_ptid
Definition: infcmd.c:124
char * safe_strerror(int)
#define PTRACE_SETREGS
#define NUM_GREGS
Definition: m68klinux-nat.c:72
void regcache_raw_supply(struct regcache *regcache, int regnum, const void *buf)
Definition: regcache.c:1041
void _initialize_m68k_linux_nat(void)
static void old_store_inferior_registers(const struct regcache *regcache, int regno)
int register_size(struct gdbarch *gdbarch, int regnum)
Definition: regcache.c:169
long ptid_get_lwp(ptid_t ptid)
Definition: ptid.c:60
void regcache_raw_collect(const struct regcache *regcache, int regnum, void *buf)
Definition: regcache.c:1071
int gdbarch_pc_regnum(struct gdbarch *gdbarch)
Definition: gdbarch.c:1998
void supply_fpregset(struct regcache *regcache, const elf_fpregset_t *fpregsetp)
static int getfpregs_supplies(int regno)
Definition: m68klinux-nat.c:82
void(* to_store_registers)(struct target_ops *, struct regcache *, int) TARGET_DEFAULT_NORETURN(noprocess())
Definition: target.h:474
void error(const char *fmt,...)
Definition: errors.c:38
static const int regmap[]
Definition: m68klinux-nat.c:59
ps_err_e ps_get_thread_area(const struct ps_prochandle *ph, lwpid_t lwpid, int idx, void **base)
static void store_fpregs(const struct regcache *regcache, int tid, int regno)
#define PTRACE_GETREGS