]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/s390-nat.c
ChangeLog:
[thirdparty/binutils-gdb.git] / gdb / s390-nat.c
CommitLineData
5769d3cd 1/* S390 native-dependent code for GDB, the GNU debugger.
1e061d1a 2 Copyright (C) 2001, 2003, 2004, 2005, 2006, 2007, 2009
c9dd6fef 3 Free Software Foundation, Inc
d0f54f9d 4
5769d3cd
AC
5 Contributed by D.J. Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com)
6 for IBM Deutschland Entwicklung GmbH, IBM Corporation.
d0f54f9d 7
5769d3cd
AC
8 This file is part of GDB.
9
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
a9762ec7 12 the Free Software Foundation; either version 3 of the License, or
5769d3cd
AC
13 (at your option) any later version.
14
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.
19
20 You should have received a copy of the GNU General Public License
a9762ec7 21 along with this program. If not, see <http://www.gnu.org/licenses/>. */
5769d3cd
AC
22
23#include "defs.h"
3ecc0ae2 24#include "regcache.h"
d0f54f9d 25#include "inferior.h"
10d6c8cd
DJ
26#include "target.h"
27#include "linux-nat.h"
7803799a 28#include "auxv.h"
d0f54f9d
JB
29
30#include "s390-tdep.h"
31
5769d3cd
AC
32#include <asm/ptrace.h>
33#include <sys/ptrace.h>
2d0c7962 34#include <asm/types.h>
5769d3cd 35#include <sys/procfs.h>
5769d3cd 36#include <sys/ucontext.h>
7803799a
UW
37#include <elf.h>
38
39#ifndef HWCAP_S390_HIGH_GPRS
40#define HWCAP_S390_HIGH_GPRS 512
41#endif
5769d3cd
AC
42
43
d0f54f9d
JB
44/* Map registers to gregset/ptrace offsets.
45 These arrays are defined in s390-tdep.c. */
46
47#ifdef __s390x__
48#define regmap_gregset s390x_regmap_gregset
5769d3cd 49#else
d0f54f9d 50#define regmap_gregset s390_regmap_gregset
5769d3cd 51#endif
d0f54f9d
JB
52
53#define regmap_fpregset s390_regmap_fpregset
54
9cbd5950
JB
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. */
d6db1fab
UW
58
59static void
60s390_native_supply (struct regcache *regcache, int regno,
61 const gdb_byte *regp, int *regmap)
62{
63 int offset = regmap[regno];
64
9cbd5950 65#ifdef __s390x__
d6db1fab
UW
66 struct gdbarch *gdbarch = get_regcache_arch (regcache);
67 if (offset != -1 && gdbarch_ptr_bit (gdbarch) == 32)
68 {
69 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
70
71 if (regno == S390_PSWM_REGNUM)
72 {
73 ULONGEST pswm;
74 gdb_byte buf[4];
75
76 pswm = extract_unsigned_integer (regp + regmap[S390_PSWM_REGNUM],
77 8, byte_order);
78
79 store_unsigned_integer (buf, 4, byte_order, (pswm >> 32) | 0x80000);
80 regcache_raw_supply (regcache, regno, buf);
81 return;
82 }
83
84 if (regno == S390_PSWA_REGNUM)
85 {
86 ULONGEST pswm, pswa;
87 gdb_byte buf[4];
88
89 pswa = extract_unsigned_integer (regp + regmap[S390_PSWA_REGNUM],
90 8, byte_order);
91 pswm = extract_unsigned_integer (regp + regmap[S390_PSWM_REGNUM],
92 8, byte_order);
93
94 store_unsigned_integer (buf, 4, byte_order,
95 (pswa & 0x7fffffff) | (pswm & 0x80000000));
96 regcache_raw_supply (regcache, regno, buf);
97 return;
98 }
99
100 if (regno >= S390_R0_REGNUM && regno <= S390_R15_REGNUM)
101 offset += 4;
102 }
103#endif
104
105 if (offset != -1)
106 regcache_raw_supply (regcache, regno, regp + offset);
107}
108
109static void
110s390_native_collect (const struct regcache *regcache, int regno,
111 gdb_byte *regp, int *regmap)
112{
113 int offset = regmap[regno];
114
115#ifdef __s390x__
116 struct gdbarch *gdbarch = get_regcache_arch (regcache);
117 if (offset != -1 && gdbarch_ptr_bit (gdbarch) == 32)
118 {
119 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
120
121 if (regno == S390_PSWM_REGNUM)
122 {
123 ULONGEST pswm;
124 gdb_byte buf[4];
125
126 regcache_raw_collect (regcache, regno, buf);
127 pswm = extract_unsigned_integer (buf, 4, byte_order);
128
129 /* We don't know the final addressing mode until the PSW address
130 is known, so leave it as-is. When the PSW address is collected
131 (below), the addressing mode will be updated. */
132 store_unsigned_integer (regp + regmap[S390_PSWM_REGNUM],
133 4, byte_order, pswm & 0xfff7ffff);
134 return;
135 }
136
137 if (regno == S390_PSWA_REGNUM)
138 {
139 ULONGEST pswa;
140 gdb_byte buf[4];
141
142 regcache_raw_collect (regcache, regno, buf);
143 pswa = extract_unsigned_integer (buf, 4, byte_order);
144
145 store_unsigned_integer (regp + regmap[S390_PSWA_REGNUM],
146 8, byte_order, pswa & 0x7fffffff);
147
148 /* Update basic addressing mode bit in PSW mask, see above. */
149 store_unsigned_integer (regp + regmap[S390_PSWM_REGNUM] + 4,
150 4, byte_order, pswa & 0x80000000);
151 return;
152 }
153
154 if (regno >= S390_R0_REGNUM && regno <= S390_R15_REGNUM)
155 {
156 memset (regp + offset, 0, 4);
157 offset += 4;
158 }
159 }
9cbd5950
JB
160#endif
161
d6db1fab
UW
162 if (offset != -1)
163 regcache_raw_collect (regcache, regno, regp + offset);
164}
d0f54f9d
JB
165
166/* Fill GDB's register array with the general-purpose register values
167 in *REGP. */
168void
7f7fe91e 169supply_gregset (struct regcache *regcache, const gregset_t *regp)
d0f54f9d
JB
170{
171 int i;
172 for (i = 0; i < S390_NUM_REGS; i++)
d6db1fab 173 s390_native_supply (regcache, i, (const gdb_byte *) regp, regmap_gregset);
d0f54f9d
JB
174}
175
176/* Fill register REGNO (if it is a general-purpose register) in
177 *REGP with the value in GDB's register array. If REGNO is -1,
178 do this for all registers. */
179void
7f7fe91e 180fill_gregset (const struct regcache *regcache, gregset_t *regp, int regno)
d0f54f9d
JB
181{
182 int i;
183 for (i = 0; i < S390_NUM_REGS; i++)
d6db1fab
UW
184 if (regno == -1 || regno == i)
185 s390_native_collect (regcache, i, (gdb_byte *) regp, regmap_gregset);
d0f54f9d
JB
186}
187
188/* Fill GDB's register array with the floating-point register values
189 in *REGP. */
190void
7f7fe91e 191supply_fpregset (struct regcache *regcache, const fpregset_t *regp)
d0f54f9d
JB
192{
193 int i;
194 for (i = 0; i < S390_NUM_REGS; i++)
d6db1fab 195 s390_native_supply (regcache, i, (const gdb_byte *) regp, regmap_fpregset);
d0f54f9d
JB
196}
197
198/* Fill register REGNO (if it is a general-purpose register) in
199 *REGP with the value in GDB's register array. If REGNO is -1,
200 do this for all registers. */
201void
7f7fe91e 202fill_fpregset (const struct regcache *regcache, fpregset_t *regp, int regno)
d0f54f9d
JB
203{
204 int i;
205 for (i = 0; i < S390_NUM_REGS; i++)
d6db1fab
UW
206 if (regno == -1 || regno == i)
207 s390_native_collect (regcache, i, (gdb_byte *) regp, regmap_fpregset);
d0f54f9d
JB
208}
209
210/* Find the TID for the current inferior thread to use with ptrace. */
211static int
212s390_inferior_tid (void)
213{
214 /* GNU/Linux LWP ID's are process ID's. */
215 int tid = TIDGET (inferior_ptid);
216 if (tid == 0)
217 tid = PIDGET (inferior_ptid); /* Not a threaded program. */
218
219 return tid;
220}
221
222/* Fetch all general-purpose registers from process/thread TID and
223 store their values in GDB's register cache. */
224static void
56be3814 225fetch_regs (struct regcache *regcache, int tid)
d0f54f9d
JB
226{
227 gregset_t regs;
228 ptrace_area parea;
229
230 parea.len = sizeof (regs);
231 parea.process_addr = (addr_t) &regs;
232 parea.kernel_addr = offsetof (struct user_regs_struct, psw);
233 if (ptrace (PTRACE_PEEKUSR_AREA, tid, (long) &parea) < 0)
e2e0b3e5 234 perror_with_name (_("Couldn't get registers"));
d0f54f9d 235
56be3814 236 supply_gregset (regcache, (const gregset_t *) &regs);
d0f54f9d
JB
237}
238
239/* Store all valid general-purpose registers in GDB's register cache
240 into the process/thread specified by TID. */
241static void
56be3814 242store_regs (const struct regcache *regcache, int tid, int regnum)
d0f54f9d
JB
243{
244 gregset_t regs;
245 ptrace_area parea;
246
247 parea.len = sizeof (regs);
248 parea.process_addr = (addr_t) &regs;
249 parea.kernel_addr = offsetof (struct user_regs_struct, psw);
250 if (ptrace (PTRACE_PEEKUSR_AREA, tid, (long) &parea) < 0)
e2e0b3e5 251 perror_with_name (_("Couldn't get registers"));
d0f54f9d 252
56be3814 253 fill_gregset (regcache, &regs, regnum);
d0f54f9d
JB
254
255 if (ptrace (PTRACE_POKEUSR_AREA, tid, (long) &parea) < 0)
e2e0b3e5 256 perror_with_name (_("Couldn't write registers"));
d0f54f9d
JB
257}
258
259/* Fetch all floating-point registers from process/thread TID and store
260 their values in GDB's register cache. */
261static void
56be3814 262fetch_fpregs (struct regcache *regcache, int tid)
d0f54f9d
JB
263{
264 fpregset_t fpregs;
265 ptrace_area parea;
266
267 parea.len = sizeof (fpregs);
268 parea.process_addr = (addr_t) &fpregs;
269 parea.kernel_addr = offsetof (struct user_regs_struct, fp_regs);
270 if (ptrace (PTRACE_PEEKUSR_AREA, tid, (long) &parea) < 0)
e2e0b3e5 271 perror_with_name (_("Couldn't get floating point status"));
d0f54f9d 272
56be3814 273 supply_fpregset (regcache, (const fpregset_t *) &fpregs);
d0f54f9d
JB
274}
275
276/* Store all valid floating-point registers in GDB's register cache
277 into the process/thread specified by TID. */
278static void
56be3814 279store_fpregs (const struct regcache *regcache, int tid, int regnum)
d0f54f9d
JB
280{
281 fpregset_t fpregs;
282 ptrace_area parea;
283
284 parea.len = sizeof (fpregs);
285 parea.process_addr = (addr_t) &fpregs;
286 parea.kernel_addr = offsetof (struct user_regs_struct, fp_regs);
287 if (ptrace (PTRACE_PEEKUSR_AREA, tid, (long) &parea) < 0)
e2e0b3e5 288 perror_with_name (_("Couldn't get floating point status"));
d0f54f9d 289
56be3814 290 fill_fpregset (regcache, &fpregs, regnum);
d0f54f9d
JB
291
292 if (ptrace (PTRACE_POKEUSR_AREA, tid, (long) &parea) < 0)
e2e0b3e5 293 perror_with_name (_("Couldn't write floating point status"));
d0f54f9d
JB
294}
295
296/* Fetch register REGNUM from the child process. If REGNUM is -1, do
297 this for all registers. */
10d6c8cd 298static void
28439f5e
PA
299s390_linux_fetch_inferior_registers (struct target_ops *ops,
300 struct regcache *regcache, int regnum)
d0f54f9d
JB
301{
302 int tid = s390_inferior_tid ();
303
304 if (regnum == -1
305 || (regnum < S390_NUM_REGS && regmap_gregset[regnum] != -1))
56be3814 306 fetch_regs (regcache, tid);
d0f54f9d
JB
307
308 if (regnum == -1
309 || (regnum < S390_NUM_REGS && regmap_fpregset[regnum] != -1))
56be3814 310 fetch_fpregs (regcache, tid);
d0f54f9d
JB
311}
312
313/* Store register REGNUM back into the child process. If REGNUM is
314 -1, do this for all registers. */
10d6c8cd 315static void
28439f5e
PA
316s390_linux_store_inferior_registers (struct target_ops *ops,
317 struct regcache *regcache, int regnum)
d0f54f9d
JB
318{
319 int tid = s390_inferior_tid ();
320
321 if (regnum == -1
322 || (regnum < S390_NUM_REGS && regmap_gregset[regnum] != -1))
56be3814 323 store_regs (regcache, tid, regnum);
d0f54f9d
JB
324
325 if (regnum == -1
326 || (regnum < S390_NUM_REGS && regmap_fpregset[regnum] != -1))
56be3814 327 store_fpregs (regcache, tid, regnum);
5769d3cd
AC
328}
329
d0f54f9d 330
e1457d83
JB
331/* Hardware-assisted watchpoint handling. */
332
333/* We maintain a list of all currently active watchpoints in order
334 to properly handle watchpoint removal.
335
336 The only thing we actually need is the total address space area
337 spanned by the watchpoints. */
338
5769d3cd
AC
339struct watch_area
340{
e1457d83 341 struct watch_area *next;
5769d3cd
AC
342 CORE_ADDR lo_addr;
343 CORE_ADDR hi_addr;
344};
345
e1457d83 346static struct watch_area *watch_base = NULL;
5769d3cd 347
fd7979d1 348static int
e1457d83 349s390_stopped_by_watchpoint (void)
5769d3cd
AC
350{
351 per_lowcore_bits per_lowcore;
352 ptrace_area parea;
9f0bdab8 353 int result;
5769d3cd 354
e1457d83
JB
355 /* Speed up common case. */
356 if (!watch_base)
357 return 0;
358
5769d3cd
AC
359 parea.len = sizeof (per_lowcore);
360 parea.process_addr = (addr_t) & per_lowcore;
361 parea.kernel_addr = offsetof (struct user_regs_struct, per_info.lowcore);
e1457d83 362 if (ptrace (PTRACE_PEEKUSR_AREA, s390_inferior_tid (), &parea) < 0)
e2e0b3e5 363 perror_with_name (_("Couldn't retrieve watchpoint status"));
5769d3cd 364
9f0bdab8
DJ
365 result = (per_lowcore.perc_storage_alteration == 1
366 && per_lowcore.perc_store_real_address == 0);
367
368 if (result)
369 {
370 /* Do not report this watchpoint again. */
371 memset (&per_lowcore, 0, sizeof (per_lowcore));
372 if (ptrace (PTRACE_POKEUSR_AREA, s390_inferior_tid (), &parea) < 0)
373 perror_with_name (_("Couldn't clear watchpoint status"));
374 }
375
376 return result;
e1457d83 377}
5769d3cd 378
e1457d83 379static void
9f0bdab8 380s390_fix_watch_points (ptid_t ptid)
5769d3cd 381{
9f0bdab8 382 int tid;
e1457d83 383
5769d3cd
AC
384 per_struct per_info;
385 ptrace_area parea;
386
e1457d83
JB
387 CORE_ADDR watch_lo_addr = (CORE_ADDR)-1, watch_hi_addr = 0;
388 struct watch_area *area;
389
9f0bdab8
DJ
390 tid = TIDGET (ptid);
391 if (tid == 0)
392 tid = PIDGET (ptid);
393
e1457d83
JB
394 for (area = watch_base; area; area = area->next)
395 {
396 watch_lo_addr = min (watch_lo_addr, area->lo_addr);
397 watch_hi_addr = max (watch_hi_addr, area->hi_addr);
398 }
399
5769d3cd
AC
400 parea.len = sizeof (per_info);
401 parea.process_addr = (addr_t) & per_info;
e1457d83
JB
402 parea.kernel_addr = offsetof (struct user_regs_struct, per_info);
403 if (ptrace (PTRACE_PEEKUSR_AREA, tid, &parea) < 0)
e2e0b3e5 404 perror_with_name (_("Couldn't retrieve watchpoint status"));
e1457d83
JB
405
406 if (watch_base)
5769d3cd
AC
407 {
408 per_info.control_regs.bits.em_storage_alteration = 1;
409 per_info.control_regs.bits.storage_alt_space_ctl = 1;
410 }
411 else
412 {
413 per_info.control_regs.bits.em_storage_alteration = 0;
414 per_info.control_regs.bits.storage_alt_space_ctl = 0;
415 }
416 per_info.starting_addr = watch_lo_addr;
417 per_info.ending_addr = watch_hi_addr;
e1457d83
JB
418
419 if (ptrace (PTRACE_POKEUSR_AREA, tid, &parea) < 0)
e2e0b3e5 420 perror_with_name (_("Couldn't modify watchpoint status"));
5769d3cd
AC
421}
422
fd7979d1 423static int
0cf6dd15
TJB
424s390_insert_watchpoint (CORE_ADDR addr, int len, int type,
425 struct expression *cond)
5769d3cd 426{
9f0bdab8 427 struct lwp_info *lp;
e1457d83 428 struct watch_area *area = xmalloc (sizeof (struct watch_area));
9f0bdab8 429
e1457d83
JB
430 if (!area)
431 return -1;
432
433 area->lo_addr = addr;
434 area->hi_addr = addr + len - 1;
435
436 area->next = watch_base;
437 watch_base = area;
438
4c38200f
PA
439 ALL_LWPS (lp)
440 s390_fix_watch_points (lp->ptid);
e1457d83 441 return 0;
5769d3cd
AC
442}
443
fd7979d1 444static int
0cf6dd15
TJB
445s390_remove_watchpoint (CORE_ADDR addr, int len, int type,
446 struct expression *cond)
5769d3cd 447{
9f0bdab8 448 struct lwp_info *lp;
e1457d83
JB
449 struct watch_area *area, **parea;
450
451 for (parea = &watch_base; *parea; parea = &(*parea)->next)
452 if ((*parea)->lo_addr == addr
453 && (*parea)->hi_addr == addr + len - 1)
454 break;
455
456 if (!*parea)
5769d3cd
AC
457 {
458 fprintf_unfiltered (gdb_stderr,
e1457d83 459 "Attempt to remove nonexistent watchpoint.\n");
5769d3cd
AC
460 return -1;
461 }
e1457d83
JB
462
463 area = *parea;
464 *parea = area->next;
465 xfree (area);
466
4c38200f
PA
467 ALL_LWPS (lp)
468 s390_fix_watch_points (lp->ptid);
e1457d83 469 return 0;
5769d3cd
AC
470}
471
fd7979d1
UW
472static int
473s390_can_use_hw_breakpoint (int type, int cnt, int othertype)
474{
b1798462 475 return type == bp_hardware_watchpoint;
fd7979d1 476}
e1457d83 477
fd7979d1 478static int
2a3cdf79 479s390_region_ok_for_hw_watchpoint (CORE_ADDR addr, int cnt)
5769d3cd 480{
fd7979d1 481 return 1;
5769d3cd
AC
482}
483
7803799a
UW
484static int
485s390_target_wordsize (void)
486{
487 int wordsize = 4;
488
489 /* Check for 64-bit inferior process. This is the case when the host is
490 64-bit, and in addition bit 32 of the PSW mask is set. */
491#ifdef __s390x__
492 long pswm;
493
494 errno = 0;
495 pswm = (long) ptrace (PTRACE_PEEKUSER, s390_inferior_tid (), PT_PSWMASK, 0);
496 if (errno == 0 && (pswm & 0x100000000ul) != 0)
497 wordsize = 8;
498#endif
499
500 return wordsize;
501}
502
503static int
504s390_auxv_parse (struct target_ops *ops, gdb_byte **readptr,
505 gdb_byte *endptr, CORE_ADDR *typep, CORE_ADDR *valp)
506{
507 int sizeof_auxv_field = s390_target_wordsize ();
508 enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch);
509 gdb_byte *ptr = *readptr;
510
511 if (endptr == ptr)
512 return 0;
513
514 if (endptr - ptr < sizeof_auxv_field * 2)
515 return -1;
516
517 *typep = extract_unsigned_integer (ptr, sizeof_auxv_field, byte_order);
518 ptr += sizeof_auxv_field;
519 *valp = extract_unsigned_integer (ptr, sizeof_auxv_field, byte_order);
520 ptr += sizeof_auxv_field;
521
522 *readptr = ptr;
523 return 1;
524}
525
526#ifdef __s390x__
527static unsigned long
528s390_get_hwcap (void)
529{
530 CORE_ADDR field;
531
532 if (target_auxv_search (&current_target, AT_HWCAP, &field))
533 return (unsigned long) field;
534
535 return 0;
536}
537#endif
538
539static const struct target_desc *
540s390_read_description (struct target_ops *ops)
541{
542#ifdef __s390x__
543 /* If GDB itself is compiled as 64-bit, we are running on a machine in
544 z/Architecture mode. If the target is running in 64-bit addressing
545 mode, report s390x architecture. If the target is running in 31-bit
546 addressing mode, but the kernel supports using 64-bit registers in
547 that mode, report s390 architecture with 64-bit GPRs. */
548
549 if (s390_target_wordsize () == 8)
550 return tdesc_s390x_linux64;
551
552 if (s390_get_hwcap () & HWCAP_S390_HIGH_GPRS)
553 return tdesc_s390_linux64;
554#endif
555
556 /* If GDB itself is compiled as 31-bit, or if we're running a 31-bit inferior
557 on a 64-bit kernel that does not support using 64-bit registers in 31-bit
558 mode, report s390 architecture with 32-bit GPRs. */
559 return tdesc_s390_linux32;
560}
fd7979d1 561
10d6c8cd
DJ
562void _initialize_s390_nat (void);
563
564void
565_initialize_s390_nat (void)
566{
567 struct target_ops *t;
568
569 /* Fill in the generic GNU/Linux methods. */
570 t = linux_target ();
571
572 /* Add our register access methods. */
573 t->to_fetch_registers = s390_linux_fetch_inferior_registers;
574 t->to_store_registers = s390_linux_store_inferior_registers;
575
fd7979d1
UW
576 /* Add our watchpoint methods. */
577 t->to_can_use_hw_breakpoint = s390_can_use_hw_breakpoint;
2a3cdf79 578 t->to_region_ok_for_hw_watchpoint = s390_region_ok_for_hw_watchpoint;
fd7979d1
UW
579 t->to_have_continuable_watchpoint = 1;
580 t->to_stopped_by_watchpoint = s390_stopped_by_watchpoint;
581 t->to_insert_watchpoint = s390_insert_watchpoint;
582 t->to_remove_watchpoint = s390_remove_watchpoint;
583
7803799a
UW
584 /* Detect target architecture. */
585 t->to_read_description = s390_read_description;
586 t->to_auxv_parse = s390_auxv_parse;
587
10d6c8cd 588 /* Register the target. */
f973ed9c 589 linux_nat_add_target (t);
9f0bdab8 590 linux_nat_set_new_thread (t, s390_fix_watch_points);
10d6c8cd 591}