]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/s390-nat.c
Clean up whitespace in S/390 -tdep and -nat files.
[thirdparty/binutils-gdb.git] / gdb / s390-nat.c
CommitLineData
5769d3cd 1/* S390 native-dependent code for GDB, the GNU debugger.
28e7fd62 2 Copyright (C) 2001-2013 Free Software Foundation, Inc.
d0f54f9d 3
5769d3cd
AC
4 Contributed by D.J. Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com)
5 for IBM Deutschland Entwicklung GmbH, IBM Corporation.
d0f54f9d 6
5769d3cd
AC
7 This file is part of GDB.
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
a9762ec7 11 the Free Software Foundation; either version 3 of the License, or
5769d3cd
AC
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
a9762ec7 20 along with this program. If not, see <http://www.gnu.org/licenses/>. */
5769d3cd
AC
21
22#include "defs.h"
3ecc0ae2 23#include "regcache.h"
d0f54f9d 24#include "inferior.h"
10d6c8cd
DJ
25#include "target.h"
26#include "linux-nat.h"
7803799a 27#include "auxv.h"
5538f557 28#include "gregset.h"
d0f54f9d
JB
29
30#include "s390-tdep.h"
c642a434 31#include "elf/common.h"
d0f54f9d 32
5769d3cd
AC
33#include <asm/ptrace.h>
34#include <sys/ptrace.h>
2d0c7962 35#include <asm/types.h>
5769d3cd 36#include <sys/procfs.h>
5769d3cd 37#include <sys/ucontext.h>
7803799a
UW
38#include <elf.h>
39
c642a434
UW
40#ifndef PTRACE_GETREGSET
41#define PTRACE_GETREGSET 0x4204
42#endif
43
44#ifndef PTRACE_SETREGSET
45#define PTRACE_SETREGSET 0x4205
46#endif
47
48static int have_regset_last_break = 0;
49static int have_regset_system_call = 0;
4ac33720 50static int have_regset_tdb = 0;
5769d3cd 51
d0f54f9d
JB
52/* Map registers to gregset/ptrace offsets.
53 These arrays are defined in s390-tdep.c. */
54
55#ifdef __s390x__
56#define regmap_gregset s390x_regmap_gregset
5769d3cd 57#else
d0f54f9d 58#define regmap_gregset s390_regmap_gregset
5769d3cd 59#endif
d0f54f9d
JB
60
61#define regmap_fpregset s390_regmap_fpregset
62
2ccd1468
UW
63/* Fill the regset described by MAP into REGCACHE, using the values
64 from REGP. The MAP array represents each register as a pair
65 (offset, regno) of short integers and is terminated with -1. */
d6db1fab
UW
66
67static void
2ccd1468
UW
68s390_native_supply (struct regcache *regcache, const short *map,
69 const gdb_byte *regp)
d6db1fab 70{
2ccd1468 71 for (; map[0] >= 0; map += 2)
4ac33720 72 regcache_raw_supply (regcache, map[1], regp ? regp + map[0] : NULL);
2ccd1468
UW
73}
74
75/* Collect the register REGNO out of the regset described by MAP from
76 REGCACHE into REGP. If REGNO == -1, do this for all registers in
77 this regset. */
78
79static void
80s390_native_collect (const struct regcache *regcache, const short *map,
81 int regno, gdb_byte *regp)
82{
83 for (; map[0] >= 0; map += 2)
84 if (regno == -1 || regno == map[1])
85 regcache_raw_collect (regcache, map[1], regp + map[0]);
86}
87
88/* Fill GDB's register array with the general-purpose register values
89 in *REGP.
90
91 When debugging a 32-bit executable running under a 64-bit kernel,
92 we have to fix up the 64-bit registers we get from the kernel to
93 make them look like 32-bit registers. */
d6db1fab 94
2ccd1468
UW
95void
96supply_gregset (struct regcache *regcache, const gregset_t *regp)
97{
9cbd5950 98#ifdef __s390x__
d6db1fab 99 struct gdbarch *gdbarch = get_regcache_arch (regcache);
2ccd1468 100 if (gdbarch_ptr_bit (gdbarch) == 32)
d6db1fab
UW
101 {
102 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
2ccd1468
UW
103 ULONGEST pswm = 0, pswa = 0;
104 gdb_byte buf[4];
105 const short *map;
d6db1fab 106
2ccd1468 107 for (map = regmap_gregset; map[0] >= 0; map += 2)
d6db1fab 108 {
2ccd1468
UW
109 const gdb_byte *p = (const gdb_byte *) regp + map[0];
110 int regno = map[1];
111
112 if (regno == S390_PSWM_REGNUM)
113 pswm = extract_unsigned_integer (p, 8, byte_order);
114 else if (regno == S390_PSWA_REGNUM)
115 pswa = extract_unsigned_integer (p, 8, byte_order);
116 else
117 {
118 if ((regno >= S390_R0_REGNUM && regno <= S390_R15_REGNUM)
119 || regno == S390_ORIG_R2_REGNUM)
120 p += 4;
121 regcache_raw_supply (regcache, regno, p);
122 }
d6db1fab
UW
123 }
124
2ccd1468
UW
125 store_unsigned_integer (buf, 4, byte_order, (pswm >> 32) | 0x80000);
126 regcache_raw_supply (regcache, S390_PSWM_REGNUM, buf);
127 store_unsigned_integer (buf, 4, byte_order,
128 (pswa & 0x7fffffff) | (pswm & 0x80000000));
129 regcache_raw_supply (regcache, S390_PSWA_REGNUM, buf);
130 return;
d6db1fab
UW
131 }
132#endif
133
2ccd1468 134 s390_native_supply (regcache, regmap_gregset, (const gdb_byte *) regp);
d6db1fab
UW
135}
136
2ccd1468
UW
137/* Fill register REGNO (if it is a general-purpose register) in
138 *REGP with the value in GDB's register array. If REGNO is -1,
139 do this for all registers. */
d6db1fab 140
2ccd1468
UW
141void
142fill_gregset (const struct regcache *regcache, gregset_t *regp, int regno)
143{
d6db1fab
UW
144#ifdef __s390x__
145 struct gdbarch *gdbarch = get_regcache_arch (regcache);
2ccd1468 146 if (gdbarch_ptr_bit (gdbarch) == 32)
d6db1fab 147 {
2ccd1468
UW
148 gdb_byte *psw_p[2];
149 const short *map;
d6db1fab 150
2ccd1468 151 for (map = regmap_gregset; map[0] >= 0; map += 2)
d6db1fab 152 {
2ccd1468
UW
153 gdb_byte *p = (gdb_byte *) regp + map[0];
154 int reg = map[1];
155
156 if (reg >= S390_PSWM_REGNUM && reg <= S390_PSWA_REGNUM)
157 psw_p[reg - S390_PSWM_REGNUM] = p;
158
159 else if (regno == -1 || regno == reg)
160 {
161 if ((reg >= S390_R0_REGNUM && reg <= S390_R15_REGNUM)
162 || reg == S390_ORIG_R2_REGNUM)
163 {
164 memset (p, 0, 4);
165 p += 4;
166 }
167 regcache_raw_collect (regcache, reg, p + 4);
168 }
d6db1fab
UW
169 }
170
2ccd1468
UW
171 if (regno == -1
172 || regno == S390_PSWM_REGNUM || regno == S390_PSWA_REGNUM)
d6db1fab 173 {
2ccd1468
UW
174 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
175 ULONGEST pswa, pswm;
d6db1fab
UW
176 gdb_byte buf[4];
177
2ccd1468
UW
178 regcache_raw_collect (regcache, S390_PSWM_REGNUM, buf);
179 pswm = extract_unsigned_integer (buf, 4, byte_order);
180 regcache_raw_collect (regcache, S390_PSWA_REGNUM, buf);
d6db1fab
UW
181 pswa = extract_unsigned_integer (buf, 4, byte_order);
182
2ccd1468
UW
183 if (regno == -1 || regno == S390_PSWM_REGNUM)
184 store_unsigned_integer (psw_p[0], 8, byte_order,
185 ((pswm & 0xfff7ffff) << 32) |
186 (pswa & 0x80000000));
187 if (regno == -1 || regno == S390_PSWA_REGNUM)
188 store_unsigned_integer (psw_p[1], 8, byte_order,
189 pswa & 0x7fffffff);
d6db1fab 190 }
2ccd1468 191 return;
d6db1fab 192 }
9cbd5950
JB
193#endif
194
2ccd1468 195 s390_native_collect (regcache, regmap_gregset, regno, (gdb_byte *) regp);
d0f54f9d
JB
196}
197
198/* Fill GDB's register array with the floating-point register values
199 in *REGP. */
200void
7f7fe91e 201supply_fpregset (struct regcache *regcache, const fpregset_t *regp)
d0f54f9d 202{
2ccd1468 203 s390_native_supply (regcache, regmap_fpregset, (const gdb_byte *) regp);
d0f54f9d
JB
204}
205
206/* Fill register REGNO (if it is a general-purpose register) in
207 *REGP with the value in GDB's register array. If REGNO is -1,
208 do this for all registers. */
209void
7f7fe91e 210fill_fpregset (const struct regcache *regcache, fpregset_t *regp, int regno)
d0f54f9d 211{
2ccd1468 212 s390_native_collect (regcache, regmap_fpregset, regno, (gdb_byte *) regp);
d0f54f9d
JB
213}
214
215/* Find the TID for the current inferior thread to use with ptrace. */
216static int
217s390_inferior_tid (void)
218{
219 /* GNU/Linux LWP ID's are process ID's. */
dfd4cc63 220 int tid = ptid_get_lwp (inferior_ptid);
d0f54f9d 221 if (tid == 0)
dfd4cc63 222 tid = ptid_get_pid (inferior_ptid); /* Not a threaded program. */
d0f54f9d
JB
223
224 return tid;
225}
226
227/* Fetch all general-purpose registers from process/thread TID and
228 store their values in GDB's register cache. */
229static void
56be3814 230fetch_regs (struct regcache *regcache, int tid)
d0f54f9d
JB
231{
232 gregset_t regs;
233 ptrace_area parea;
234
235 parea.len = sizeof (regs);
236 parea.process_addr = (addr_t) &regs;
237 parea.kernel_addr = offsetof (struct user_regs_struct, psw);
238 if (ptrace (PTRACE_PEEKUSR_AREA, tid, (long) &parea) < 0)
e2e0b3e5 239 perror_with_name (_("Couldn't get registers"));
d0f54f9d 240
56be3814 241 supply_gregset (regcache, (const gregset_t *) &regs);
d0f54f9d
JB
242}
243
244/* Store all valid general-purpose registers in GDB's register cache
245 into the process/thread specified by TID. */
246static void
56be3814 247store_regs (const struct regcache *regcache, int tid, int regnum)
d0f54f9d
JB
248{
249 gregset_t regs;
250 ptrace_area parea;
251
252 parea.len = sizeof (regs);
253 parea.process_addr = (addr_t) &regs;
254 parea.kernel_addr = offsetof (struct user_regs_struct, psw);
255 if (ptrace (PTRACE_PEEKUSR_AREA, tid, (long) &parea) < 0)
e2e0b3e5 256 perror_with_name (_("Couldn't get registers"));
d0f54f9d 257
56be3814 258 fill_gregset (regcache, &regs, regnum);
d0f54f9d
JB
259
260 if (ptrace (PTRACE_POKEUSR_AREA, tid, (long) &parea) < 0)
e2e0b3e5 261 perror_with_name (_("Couldn't write registers"));
d0f54f9d
JB
262}
263
264/* Fetch all floating-point registers from process/thread TID and store
265 their values in GDB's register cache. */
266static void
56be3814 267fetch_fpregs (struct regcache *regcache, int tid)
d0f54f9d
JB
268{
269 fpregset_t fpregs;
270 ptrace_area parea;
271
272 parea.len = sizeof (fpregs);
273 parea.process_addr = (addr_t) &fpregs;
274 parea.kernel_addr = offsetof (struct user_regs_struct, fp_regs);
275 if (ptrace (PTRACE_PEEKUSR_AREA, tid, (long) &parea) < 0)
e2e0b3e5 276 perror_with_name (_("Couldn't get floating point status"));
d0f54f9d 277
56be3814 278 supply_fpregset (regcache, (const fpregset_t *) &fpregs);
d0f54f9d
JB
279}
280
281/* Store all valid floating-point registers in GDB's register cache
282 into the process/thread specified by TID. */
283static void
56be3814 284store_fpregs (const struct regcache *regcache, int tid, int regnum)
d0f54f9d
JB
285{
286 fpregset_t fpregs;
287 ptrace_area parea;
288
289 parea.len = sizeof (fpregs);
290 parea.process_addr = (addr_t) &fpregs;
291 parea.kernel_addr = offsetof (struct user_regs_struct, fp_regs);
292 if (ptrace (PTRACE_PEEKUSR_AREA, tid, (long) &parea) < 0)
e2e0b3e5 293 perror_with_name (_("Couldn't get floating point status"));
d0f54f9d 294
56be3814 295 fill_fpregset (regcache, &fpregs, regnum);
d0f54f9d
JB
296
297 if (ptrace (PTRACE_POKEUSR_AREA, tid, (long) &parea) < 0)
e2e0b3e5 298 perror_with_name (_("Couldn't write floating point status"));
d0f54f9d
JB
299}
300
c642a434
UW
301/* Fetch all registers in the kernel's register set whose number is REGSET,
302 whose size is REGSIZE, and whose layout is described by REGMAP, from
303 process/thread TID and store their values in GDB's register cache. */
304static void
305fetch_regset (struct regcache *regcache, int tid,
2ccd1468 306 int regset, int regsize, const short *regmap)
c642a434 307{
c642a434
UW
308 gdb_byte *buf = alloca (regsize);
309 struct iovec iov;
c642a434
UW
310
311 iov.iov_base = buf;
312 iov.iov_len = regsize;
313
314 if (ptrace (PTRACE_GETREGSET, tid, (long) regset, (long) &iov) < 0)
4ac33720
UW
315 {
316 if (errno == ENODATA)
317 s390_native_supply (regcache, regmap, NULL);
318 else
319 perror_with_name (_("Couldn't get register set"));
320 }
321 else
322 s390_native_supply (regcache, regmap, buf);
c642a434
UW
323}
324
325/* Store all registers in the kernel's register set whose number is REGSET,
326 whose size is REGSIZE, and whose layout is described by REGMAP, from
327 GDB's register cache back to process/thread TID. */
328static void
329store_regset (struct regcache *regcache, int tid,
2ccd1468 330 int regset, int regsize, const short *regmap)
c642a434 331{
c642a434
UW
332 gdb_byte *buf = alloca (regsize);
333 struct iovec iov;
c642a434
UW
334
335 iov.iov_base = buf;
336 iov.iov_len = regsize;
337
338 if (ptrace (PTRACE_GETREGSET, tid, (long) regset, (long) &iov) < 0)
339 perror_with_name (_("Couldn't get register set"));
340
2ccd1468 341 s390_native_collect (regcache, regmap, -1, buf);
c642a434
UW
342
343 if (ptrace (PTRACE_SETREGSET, tid, (long) regset, (long) &iov) < 0)
344 perror_with_name (_("Couldn't set register set"));
345}
346
347/* Check whether the kernel provides a register set with number REGSET
348 of size REGSIZE for process/thread TID. */
349static int
350check_regset (int tid, int regset, int regsize)
351{
352 gdb_byte *buf = alloca (regsize);
353 struct iovec iov;
354
355 iov.iov_base = buf;
356 iov.iov_len = regsize;
357
4ac33720
UW
358 if (ptrace (PTRACE_GETREGSET, tid, (long) regset, (long) &iov) >= 0
359 || errno == ENODATA)
c642a434 360 return 1;
4ac33720 361 return 0;
c642a434
UW
362}
363
d0f54f9d
JB
364/* Fetch register REGNUM from the child process. If REGNUM is -1, do
365 this for all registers. */
10d6c8cd 366static void
28439f5e
PA
367s390_linux_fetch_inferior_registers (struct target_ops *ops,
368 struct regcache *regcache, int regnum)
d0f54f9d
JB
369{
370 int tid = s390_inferior_tid ();
371
2ccd1468 372 if (regnum == -1 || S390_IS_GREGSET_REGNUM (regnum))
56be3814 373 fetch_regs (regcache, tid);
d0f54f9d 374
2ccd1468 375 if (regnum == -1 || S390_IS_FPREGSET_REGNUM (regnum))
56be3814 376 fetch_fpregs (regcache, tid);
c642a434
UW
377
378 if (have_regset_last_break)
379 if (regnum == -1 || regnum == S390_LAST_BREAK_REGNUM)
380 fetch_regset (regcache, tid, NT_S390_LAST_BREAK, 8,
381 (gdbarch_ptr_bit (get_regcache_arch (regcache)) == 32
382 ? s390_regmap_last_break : s390x_regmap_last_break));
383
384 if (have_regset_system_call)
385 if (regnum == -1 || regnum == S390_SYSTEM_CALL_REGNUM)
386 fetch_regset (regcache, tid, NT_S390_SYSTEM_CALL, 4,
387 s390_regmap_system_call);
4ac33720
UW
388
389 if (have_regset_tdb)
390 if (regnum == -1 || S390_IS_TDBREGSET_REGNUM (regnum))
391 fetch_regset (regcache, tid, NT_S390_TDB, s390_sizeof_tdbregset,
392 s390_regmap_tdb);
d0f54f9d
JB
393}
394
395/* Store register REGNUM back into the child process. If REGNUM is
396 -1, do this for all registers. */
10d6c8cd 397static void
28439f5e
PA
398s390_linux_store_inferior_registers (struct target_ops *ops,
399 struct regcache *regcache, int regnum)
d0f54f9d
JB
400{
401 int tid = s390_inferior_tid ();
402
2ccd1468 403 if (regnum == -1 || S390_IS_GREGSET_REGNUM (regnum))
56be3814 404 store_regs (regcache, tid, regnum);
d0f54f9d 405
2ccd1468 406 if (regnum == -1 || S390_IS_FPREGSET_REGNUM (regnum))
56be3814 407 store_fpregs (regcache, tid, regnum);
c642a434
UW
408
409 /* S390_LAST_BREAK_REGNUM is read-only. */
410
411 if (have_regset_system_call)
412 if (regnum == -1 || regnum == S390_SYSTEM_CALL_REGNUM)
413 store_regset (regcache, tid, NT_S390_SYSTEM_CALL, 4,
414 s390_regmap_system_call);
5769d3cd
AC
415}
416
d0f54f9d 417
e1457d83
JB
418/* Hardware-assisted watchpoint handling. */
419
420/* We maintain a list of all currently active watchpoints in order
421 to properly handle watchpoint removal.
422
423 The only thing we actually need is the total address space area
424 spanned by the watchpoints. */
425
5769d3cd
AC
426struct watch_area
427{
e1457d83 428 struct watch_area *next;
5769d3cd
AC
429 CORE_ADDR lo_addr;
430 CORE_ADDR hi_addr;
431};
432
e1457d83 433static struct watch_area *watch_base = NULL;
5769d3cd 434
fd7979d1 435static int
e1457d83 436s390_stopped_by_watchpoint (void)
5769d3cd
AC
437{
438 per_lowcore_bits per_lowcore;
439 ptrace_area parea;
9f0bdab8 440 int result;
5769d3cd 441
e1457d83
JB
442 /* Speed up common case. */
443 if (!watch_base)
444 return 0;
445
5769d3cd
AC
446 parea.len = sizeof (per_lowcore);
447 parea.process_addr = (addr_t) & per_lowcore;
448 parea.kernel_addr = offsetof (struct user_regs_struct, per_info.lowcore);
e1457d83 449 if (ptrace (PTRACE_PEEKUSR_AREA, s390_inferior_tid (), &parea) < 0)
e2e0b3e5 450 perror_with_name (_("Couldn't retrieve watchpoint status"));
5769d3cd 451
9f0bdab8
DJ
452 result = (per_lowcore.perc_storage_alteration == 1
453 && per_lowcore.perc_store_real_address == 0);
454
455 if (result)
456 {
457 /* Do not report this watchpoint again. */
458 memset (&per_lowcore, 0, sizeof (per_lowcore));
459 if (ptrace (PTRACE_POKEUSR_AREA, s390_inferior_tid (), &parea) < 0)
460 perror_with_name (_("Couldn't clear watchpoint status"));
461 }
462
463 return result;
e1457d83 464}
5769d3cd 465
e1457d83 466static void
7b50312a 467s390_fix_watch_points (struct lwp_info *lp)
5769d3cd 468{
9f0bdab8 469 int tid;
e1457d83 470
5769d3cd
AC
471 per_struct per_info;
472 ptrace_area parea;
473
e1457d83
JB
474 CORE_ADDR watch_lo_addr = (CORE_ADDR)-1, watch_hi_addr = 0;
475 struct watch_area *area;
476
dfd4cc63 477 tid = ptid_get_lwp (lp->ptid);
9f0bdab8 478 if (tid == 0)
dfd4cc63 479 tid = ptid_get_pid (lp->ptid);
9f0bdab8 480
e1457d83
JB
481 for (area = watch_base; area; area = area->next)
482 {
483 watch_lo_addr = min (watch_lo_addr, area->lo_addr);
484 watch_hi_addr = max (watch_hi_addr, area->hi_addr);
485 }
486
5769d3cd
AC
487 parea.len = sizeof (per_info);
488 parea.process_addr = (addr_t) & per_info;
e1457d83
JB
489 parea.kernel_addr = offsetof (struct user_regs_struct, per_info);
490 if (ptrace (PTRACE_PEEKUSR_AREA, tid, &parea) < 0)
e2e0b3e5 491 perror_with_name (_("Couldn't retrieve watchpoint status"));
e1457d83
JB
492
493 if (watch_base)
5769d3cd
AC
494 {
495 per_info.control_regs.bits.em_storage_alteration = 1;
496 per_info.control_regs.bits.storage_alt_space_ctl = 1;
497 }
498 else
499 {
500 per_info.control_regs.bits.em_storage_alteration = 0;
501 per_info.control_regs.bits.storage_alt_space_ctl = 0;
502 }
503 per_info.starting_addr = watch_lo_addr;
504 per_info.ending_addr = watch_hi_addr;
e1457d83
JB
505
506 if (ptrace (PTRACE_POKEUSR_AREA, tid, &parea) < 0)
e2e0b3e5 507 perror_with_name (_("Couldn't modify watchpoint status"));
5769d3cd
AC
508}
509
fd7979d1 510static int
0cf6dd15
TJB
511s390_insert_watchpoint (CORE_ADDR addr, int len, int type,
512 struct expression *cond)
5769d3cd 513{
9f0bdab8 514 struct lwp_info *lp;
e1457d83 515 struct watch_area *area = xmalloc (sizeof (struct watch_area));
9f0bdab8 516
e1457d83 517 if (!area)
34201ae3 518 return -1;
e1457d83
JB
519
520 area->lo_addr = addr;
521 area->hi_addr = addr + len - 1;
34201ae3 522
e1457d83
JB
523 area->next = watch_base;
524 watch_base = area;
525
4c38200f 526 ALL_LWPS (lp)
3e290cb1 527 s390_fix_watch_points (lp);
e1457d83 528 return 0;
5769d3cd
AC
529}
530
fd7979d1 531static int
0cf6dd15
TJB
532s390_remove_watchpoint (CORE_ADDR addr, int len, int type,
533 struct expression *cond)
5769d3cd 534{
9f0bdab8 535 struct lwp_info *lp;
e1457d83
JB
536 struct watch_area *area, **parea;
537
538 for (parea = &watch_base; *parea; parea = &(*parea)->next)
539 if ((*parea)->lo_addr == addr
540 && (*parea)->hi_addr == addr + len - 1)
541 break;
542
543 if (!*parea)
5769d3cd
AC
544 {
545 fprintf_unfiltered (gdb_stderr,
e1457d83 546 "Attempt to remove nonexistent watchpoint.\n");
5769d3cd
AC
547 return -1;
548 }
e1457d83
JB
549
550 area = *parea;
551 *parea = area->next;
552 xfree (area);
553
4c38200f 554 ALL_LWPS (lp)
3e290cb1 555 s390_fix_watch_points (lp);
e1457d83 556 return 0;
5769d3cd
AC
557}
558
fd7979d1
UW
559static int
560s390_can_use_hw_breakpoint (int type, int cnt, int othertype)
561{
b1798462 562 return type == bp_hardware_watchpoint;
fd7979d1 563}
e1457d83 564
fd7979d1 565static int
2a3cdf79 566s390_region_ok_for_hw_watchpoint (CORE_ADDR addr, int cnt)
5769d3cd 567{
fd7979d1 568 return 1;
5769d3cd
AC
569}
570
7803799a
UW
571static int
572s390_target_wordsize (void)
573{
574 int wordsize = 4;
575
576 /* Check for 64-bit inferior process. This is the case when the host is
577 64-bit, and in addition bit 32 of the PSW mask is set. */
578#ifdef __s390x__
579 long pswm;
580
581 errno = 0;
582 pswm = (long) ptrace (PTRACE_PEEKUSER, s390_inferior_tid (), PT_PSWMASK, 0);
583 if (errno == 0 && (pswm & 0x100000000ul) != 0)
584 wordsize = 8;
585#endif
586
587 return wordsize;
588}
589
590static int
591s390_auxv_parse (struct target_ops *ops, gdb_byte **readptr,
592 gdb_byte *endptr, CORE_ADDR *typep, CORE_ADDR *valp)
593{
594 int sizeof_auxv_field = s390_target_wordsize ();
f5656ead 595 enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
7803799a
UW
596 gdb_byte *ptr = *readptr;
597
598 if (endptr == ptr)
599 return 0;
600
601 if (endptr - ptr < sizeof_auxv_field * 2)
602 return -1;
603
604 *typep = extract_unsigned_integer (ptr, sizeof_auxv_field, byte_order);
605 ptr += sizeof_auxv_field;
606 *valp = extract_unsigned_integer (ptr, sizeof_auxv_field, byte_order);
607 ptr += sizeof_auxv_field;
608
609 *readptr = ptr;
610 return 1;
611}
612
613#ifdef __s390x__
614static unsigned long
615s390_get_hwcap (void)
616{
617 CORE_ADDR field;
618
619 if (target_auxv_search (&current_target, AT_HWCAP, &field))
620 return (unsigned long) field;
621
622 return 0;
623}
624#endif
625
626static const struct target_desc *
627s390_read_description (struct target_ops *ops)
628{
c642a434
UW
629 int tid = s390_inferior_tid ();
630
631 have_regset_last_break
632 = check_regset (tid, NT_S390_LAST_BREAK, 8);
633 have_regset_system_call
634 = check_regset (tid, NT_S390_SYSTEM_CALL, 4);
4ac33720
UW
635 have_regset_tdb
636 = check_regset (tid, NT_S390_TDB, s390_sizeof_tdbregset);
c642a434 637
7803799a
UW
638#ifdef __s390x__
639 /* If GDB itself is compiled as 64-bit, we are running on a machine in
640 z/Architecture mode. If the target is running in 64-bit addressing
641 mode, report s390x architecture. If the target is running in 31-bit
642 addressing mode, but the kernel supports using 64-bit registers in
643 that mode, report s390 architecture with 64-bit GPRs. */
644
645 if (s390_target_wordsize () == 8)
4ac33720
UW
646 return (have_regset_tdb ? tdesc_s390x_te_linux64 :
647 have_regset_system_call? tdesc_s390x_linux64v2 :
c642a434
UW
648 have_regset_last_break? tdesc_s390x_linux64v1 :
649 tdesc_s390x_linux64);
7803799a
UW
650
651 if (s390_get_hwcap () & HWCAP_S390_HIGH_GPRS)
4ac33720
UW
652 return (have_regset_tdb ? tdesc_s390_te_linux64 :
653 have_regset_system_call? tdesc_s390_linux64v2 :
c642a434
UW
654 have_regset_last_break? tdesc_s390_linux64v1 :
655 tdesc_s390_linux64);
7803799a
UW
656#endif
657
658 /* If GDB itself is compiled as 31-bit, or if we're running a 31-bit inferior
659 on a 64-bit kernel that does not support using 64-bit registers in 31-bit
660 mode, report s390 architecture with 32-bit GPRs. */
c642a434
UW
661 return (have_regset_system_call? tdesc_s390_linux32v2 :
662 have_regset_last_break? tdesc_s390_linux32v1 :
663 tdesc_s390_linux32);
7803799a 664}
fd7979d1 665
10d6c8cd
DJ
666void _initialize_s390_nat (void);
667
668void
669_initialize_s390_nat (void)
670{
671 struct target_ops *t;
672
673 /* Fill in the generic GNU/Linux methods. */
674 t = linux_target ();
675
676 /* Add our register access methods. */
677 t->to_fetch_registers = s390_linux_fetch_inferior_registers;
678 t->to_store_registers = s390_linux_store_inferior_registers;
679
fd7979d1
UW
680 /* Add our watchpoint methods. */
681 t->to_can_use_hw_breakpoint = s390_can_use_hw_breakpoint;
2a3cdf79 682 t->to_region_ok_for_hw_watchpoint = s390_region_ok_for_hw_watchpoint;
fd7979d1
UW
683 t->to_have_continuable_watchpoint = 1;
684 t->to_stopped_by_watchpoint = s390_stopped_by_watchpoint;
685 t->to_insert_watchpoint = s390_insert_watchpoint;
686 t->to_remove_watchpoint = s390_remove_watchpoint;
687
7803799a
UW
688 /* Detect target architecture. */
689 t->to_read_description = s390_read_description;
690 t->to_auxv_parse = s390_auxv_parse;
691
10d6c8cd 692 /* Register the target. */
f973ed9c 693 linux_nat_add_target (t);
9f0bdab8 694 linux_nat_set_new_thread (t, s390_fix_watch_points);
10d6c8cd 695}