1 /* S390 native-dependent code for GDB, the GNU debugger.
2 Copyright (C) 2001, 2003, 2004, 2005, 2006, 2007, 2009
3 Free Software Foundation, Inc
6 for IBM Deutschland Entwicklung GmbH, IBM Corporation.
8 This file is part of GDB.
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 3 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program. If not, see <http://www.gnu.org/licenses/>. */
27 #include "linux-nat.h"
30 #include "s390-tdep.h"
32 #include <asm/ptrace.h>
33 #include <sys/ptrace.h>
34 #include <asm/types.h>
35 #include <sys/procfs.h>
36 #include <sys/ucontext.h>
39 #ifndef HWCAP_S390_HIGH_GPRS
40 #define HWCAP_S390_HIGH_GPRS 512
44 /* Map registers to gregset/ptrace offsets.
45 These arrays are defined in s390-tdep.c. */
48 #define regmap_gregset s390x_regmap_gregset
50 #define regmap_gregset s390_regmap_gregset
53 #define regmap_fpregset s390_regmap_fpregset
55 /* When debugging a 32-bit executable running under a 64-bit kernel,
56 we have to fix up the 64-bit registers we get from the kernel
57 to make them look like 32-bit registers. */
59 #define SUBOFF(gdbarch, i) \
60 ((gdbarch_ptr_bit (gdbarch) == 32 \
61 && ((i) == S390_PSWA_REGNUM \
62 || ((i) >= S390_R0_REGNUM && (i) <= S390_R15_REGNUM)))? 4 : 0)
64 #define SUBOFF(gdbarch, i) 0
68 /* Fill GDB's register array with the general-purpose register values
71 supply_gregset (struct regcache *regcache, const gregset_t *regp)
73 struct gdbarch *gdbarch = get_regcache_arch (regcache);
75 for (i = 0; i < S390_NUM_REGS; i++)
76 if (regmap_gregset[i] != -1)
77 regcache_raw_supply (regcache, i,
78 (const char *)regp + regmap_gregset[i]
79 + SUBOFF (gdbarch, i));
82 /* Fill register REGNO (if it is a general-purpose register) in
83 *REGP with the value in GDB's register array. If REGNO is -1,
84 do this for all registers. */
86 fill_gregset (const struct regcache *regcache, gregset_t *regp, int regno)
88 struct gdbarch *gdbarch = get_regcache_arch (regcache);
90 for (i = 0; i < S390_NUM_REGS; i++)
91 if (regmap_gregset[i] != -1)
92 if (regno == -1 || regno == i)
93 regcache_raw_collect (regcache, i,
94 (char *)regp + regmap_gregset[i]
95 + SUBOFF (gdbarch, i));
98 /* Fill GDB's register array with the floating-point register values
101 supply_fpregset (struct regcache *regcache, const fpregset_t *regp)
104 for (i = 0; i < S390_NUM_REGS; i++)
105 if (regmap_fpregset[i] != -1)
106 regcache_raw_supply (regcache, i,
107 (const char *)regp + regmap_fpregset[i]);
110 /* Fill register REGNO (if it is a general-purpose register) in
111 *REGP with the value in GDB's register array. If REGNO is -1,
112 do this for all registers. */
114 fill_fpregset (const struct regcache *regcache, fpregset_t *regp, int regno)
117 for (i = 0; i < S390_NUM_REGS; i++)
118 if (regmap_fpregset[i] != -1)
119 if (regno == -1 || regno == i)
120 regcache_raw_collect (regcache, i,
121 (char *)regp + regmap_fpregset[i]);
124 /* Find the TID for the current inferior thread to use with ptrace. */
126 s390_inferior_tid (void)
128 /* GNU/Linux LWP ID's are process ID's. */
129 int tid = TIDGET (inferior_ptid);
131 tid = PIDGET (inferior_ptid); /* Not a threaded program. */
136 /* Fetch all general-purpose registers from process/thread TID and
137 store their values in GDB's register cache. */
139 fetch_regs (struct regcache *regcache, int tid)
144 parea.len = sizeof (regs);
145 parea.process_addr = (addr_t) ®s;
146 parea.kernel_addr = offsetof (struct user_regs_struct, psw);
147 if (ptrace (PTRACE_PEEKUSR_AREA, tid, (long) &parea) < 0)
148 perror_with_name (_("Couldn't get registers"));
150 supply_gregset (regcache, (const gregset_t *) ®s);
153 /* Store all valid general-purpose registers in GDB's register cache
154 into the process/thread specified by TID. */
156 store_regs (const struct regcache *regcache, int tid, int regnum)
161 parea.len = sizeof (regs);
162 parea.process_addr = (addr_t) ®s;
163 parea.kernel_addr = offsetof (struct user_regs_struct, psw);
164 if (ptrace (PTRACE_PEEKUSR_AREA, tid, (long) &parea) < 0)
165 perror_with_name (_("Couldn't get registers"));
167 fill_gregset (regcache, ®s, regnum);
169 if (ptrace (PTRACE_POKEUSR_AREA, tid, (long) &parea) < 0)
170 perror_with_name (_("Couldn't write registers"));
173 /* Fetch all floating-point registers from process/thread TID and store
174 their values in GDB's register cache. */
176 fetch_fpregs (struct regcache *regcache, int tid)
181 parea.len = sizeof (fpregs);
182 parea.process_addr = (addr_t) &fpregs;
183 parea.kernel_addr = offsetof (struct user_regs_struct, fp_regs);
184 if (ptrace (PTRACE_PEEKUSR_AREA, tid, (long) &parea) < 0)
185 perror_with_name (_("Couldn't get floating point status"));
187 supply_fpregset (regcache, (const fpregset_t *) &fpregs);
190 /* Store all valid floating-point registers in GDB's register cache
191 into the process/thread specified by TID. */
193 store_fpregs (const struct regcache *regcache, int tid, int regnum)
198 parea.len = sizeof (fpregs);
199 parea.process_addr = (addr_t) &fpregs;
200 parea.kernel_addr = offsetof (struct user_regs_struct, fp_regs);
201 if (ptrace (PTRACE_PEEKUSR_AREA, tid, (long) &parea) < 0)
202 perror_with_name (_("Couldn't get floating point status"));
204 fill_fpregset (regcache, &fpregs, regnum);
206 if (ptrace (PTRACE_POKEUSR_AREA, tid, (long) &parea) < 0)
207 perror_with_name (_("Couldn't write floating point status"));
210 /* Fetch register REGNUM from the child process. If REGNUM is -1, do
211 this for all registers. */
213 s390_linux_fetch_inferior_registers (struct target_ops *ops,
214 struct regcache *regcache, int regnum)
216 int tid = s390_inferior_tid ();
219 || (regnum < S390_NUM_REGS && regmap_gregset[regnum] != -1))
220 fetch_regs (regcache, tid);
223 || (regnum < S390_NUM_REGS && regmap_fpregset[regnum] != -1))
224 fetch_fpregs (regcache, tid);
227 /* Store register REGNUM back into the child process. If REGNUM is
228 -1, do this for all registers. */
230 s390_linux_store_inferior_registers (struct target_ops *ops,
231 struct regcache *regcache, int regnum)
233 int tid = s390_inferior_tid ();
236 || (regnum < S390_NUM_REGS && regmap_gregset[regnum] != -1))
237 store_regs (regcache, tid, regnum);
240 || (regnum < S390_NUM_REGS && regmap_fpregset[regnum] != -1))
241 store_fpregs (regcache, tid, regnum);
245 /* Hardware-assisted watchpoint handling. */
247 /* We maintain a list of all currently active watchpoints in order
248 to properly handle watchpoint removal.
250 The only thing we actually need is the total address space area
251 spanned by the watchpoints. */
255 struct watch_area *next;
260 static struct watch_area *watch_base = NULL;
263 s390_stopped_by_watchpoint (void)
265 per_lowcore_bits per_lowcore;
269 /* Speed up common case. */
273 parea.len = sizeof (per_lowcore);
274 parea.process_addr = (addr_t) & per_lowcore;
275 parea.kernel_addr = offsetof (struct user_regs_struct, per_info.lowcore);
276 if (ptrace (PTRACE_PEEKUSR_AREA, s390_inferior_tid (), &parea) < 0)
277 perror_with_name (_("Couldn't retrieve watchpoint status"));
279 result = (per_lowcore.perc_storage_alteration == 1
280 && per_lowcore.perc_store_real_address == 0);
284 /* Do not report this watchpoint again. */
285 memset (&per_lowcore, 0, sizeof (per_lowcore));
286 if (ptrace (PTRACE_POKEUSR_AREA, s390_inferior_tid (), &parea) < 0)
287 perror_with_name (_("Couldn't clear watchpoint status"));
294 s390_fix_watch_points (ptid_t ptid)
301 CORE_ADDR watch_lo_addr = (CORE_ADDR)-1, watch_hi_addr = 0;
302 struct watch_area *area;
308 for (area = watch_base; area; area = area->next)
310 watch_lo_addr = min (watch_lo_addr, area->lo_addr);
311 watch_hi_addr = max (watch_hi_addr, area->hi_addr);
314 parea.len = sizeof (per_info);
315 parea.process_addr = (addr_t) & per_info;
316 parea.kernel_addr = offsetof (struct user_regs_struct, per_info);
317 if (ptrace (PTRACE_PEEKUSR_AREA, tid, &parea) < 0)
318 perror_with_name (_("Couldn't retrieve watchpoint status"));
322 per_info.control_regs.bits.em_storage_alteration = 1;
323 per_info.control_regs.bits.storage_alt_space_ctl = 1;
327 per_info.control_regs.bits.em_storage_alteration = 0;
328 per_info.control_regs.bits.storage_alt_space_ctl = 0;
330 per_info.starting_addr = watch_lo_addr;
331 per_info.ending_addr = watch_hi_addr;
333 if (ptrace (PTRACE_POKEUSR_AREA, tid, &parea) < 0)
334 perror_with_name (_("Couldn't modify watchpoint status"));
338 s390_insert_watchpoint (CORE_ADDR addr, int len, int type,
339 struct expression *cond)
343 struct watch_area *area = xmalloc (sizeof (struct watch_area));
348 area->lo_addr = addr;
349 area->hi_addr = addr + len - 1;
351 area->next = watch_base;
355 s390_fix_watch_points (ptid);
360 s390_remove_watchpoint (CORE_ADDR addr, int len, int type,
361 struct expression *cond)
365 struct watch_area *area, **parea;
367 for (parea = &watch_base; *parea; parea = &(*parea)->next)
368 if ((*parea)->lo_addr == addr
369 && (*parea)->hi_addr == addr + len - 1)
374 fprintf_unfiltered (gdb_stderr,
375 "Attempt to remove nonexistent watchpoint.\n");
384 s390_fix_watch_points (ptid);
389 s390_can_use_hw_breakpoint (int type, int cnt, int othertype)
391 return type == bp_hardware_watchpoint;
395 s390_region_ok_for_hw_watchpoint (CORE_ADDR addr, int cnt)
401 s390_target_wordsize (void)
405 /* Check for 64-bit inferior process. This is the case when the host is
406 64-bit, and in addition bit 32 of the PSW mask is set. */
411 pswm = (long) ptrace (PTRACE_PEEKUSER, s390_inferior_tid (), PT_PSWMASK, 0);
412 if (errno == 0 && (pswm & 0x100000000ul) != 0)
420 s390_auxv_parse (struct target_ops *ops, gdb_byte **readptr,
421 gdb_byte *endptr, CORE_ADDR *typep, CORE_ADDR *valp)
423 int sizeof_auxv_field = s390_target_wordsize ();
424 enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch);
425 gdb_byte *ptr = *readptr;
430 if (endptr - ptr < sizeof_auxv_field * 2)
433 *typep = extract_unsigned_integer (ptr, sizeof_auxv_field, byte_order);
434 ptr += sizeof_auxv_field;
435 *valp = extract_unsigned_integer (ptr, sizeof_auxv_field, byte_order);
436 ptr += sizeof_auxv_field;
444 s390_get_hwcap (void)
448 if (target_auxv_search (¤t_target, AT_HWCAP, &field))
449 return (unsigned long) field;
455 static const struct target_desc *
456 s390_read_description (struct target_ops *ops)
459 /* If GDB itself is compiled as 64-bit, we are running on a machine in
460 z/Architecture mode. If the target is running in 64-bit addressing
461 mode, report s390x architecture. If the target is running in 31-bit
462 addressing mode, but the kernel supports using 64-bit registers in
463 that mode, report s390 architecture with 64-bit GPRs. */
465 if (s390_target_wordsize () == 8)
466 return tdesc_s390x_linux64;
468 if (s390_get_hwcap () & HWCAP_S390_HIGH_GPRS)
469 return tdesc_s390_linux64;
472 /* If GDB itself is compiled as 31-bit, or if we're running a 31-bit inferior
473 on a 64-bit kernel that does not support using 64-bit registers in 31-bit
474 mode, report s390 architecture with 32-bit GPRs. */
475 return tdesc_s390_linux32;
478 void _initialize_s390_nat (void);
481 _initialize_s390_nat (void)
483 struct target_ops *t;
485 /* Fill in the generic GNU/Linux methods. */
488 /* Add our register access methods. */
489 t->to_fetch_registers = s390_linux_fetch_inferior_registers;
490 t->to_store_registers = s390_linux_store_inferior_registers;
492 /* Add our watchpoint methods. */
493 t->to_can_use_hw_breakpoint = s390_can_use_hw_breakpoint;
494 t->to_region_ok_for_hw_watchpoint = s390_region_ok_for_hw_watchpoint;
495 t->to_have_continuable_watchpoint = 1;
496 t->to_stopped_by_watchpoint = s390_stopped_by_watchpoint;
497 t->to_insert_watchpoint = s390_insert_watchpoint;
498 t->to_remove_watchpoint = s390_remove_watchpoint;
500 /* Detect target architecture. */
501 t->to_read_description = s390_read_description;
502 t->to_auxv_parse = s390_auxv_parse;
504 /* Register the target. */
505 linux_nat_add_target (t);
506 linux_nat_set_new_thread (t, s390_fix_watch_points);