]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/s390-linux-nat.c
x86/Intel: fix i386_optab[] for vcvt{,u}si2s{d,s}
[thirdparty/binutils-gdb.git] / gdb / s390-linux-nat.c
CommitLineData
5769d3cd 1/* S390 native-dependent code for GDB, the GNU debugger.
32d0add0 2 Copyright (C) 2001-2015 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"
99b7da5d 29#include "regset.h"
d0f54f9d 30
0e5fae36 31#include "s390-linux-tdep.h"
c642a434 32#include "elf/common.h"
d0f54f9d 33
5769d3cd
AC
34#include <asm/ptrace.h>
35#include <sys/ptrace.h>
2d0c7962 36#include <asm/types.h>
5769d3cd 37#include <sys/procfs.h>
5769d3cd 38#include <sys/ucontext.h>
7803799a
UW
39#include <elf.h>
40
c642a434
UW
41#ifndef PTRACE_GETREGSET
42#define PTRACE_GETREGSET 0x4204
43#endif
44
45#ifndef PTRACE_SETREGSET
46#define PTRACE_SETREGSET 0x4205
47#endif
48
18396193
AA
49/* Per-thread arch-specific data. */
50
51struct arch_lwp_info
52{
53 /* Non-zero if the thread's PER info must be re-written. */
54 int per_info_changed;
55};
56
c642a434
UW
57static int have_regset_last_break = 0;
58static int have_regset_system_call = 0;
4ac33720 59static int have_regset_tdb = 0;
550bdf96 60static int have_regset_vxrs = 0;
5769d3cd 61
99b7da5d
AA
62/* Register map for 32-bit executables running under a 64-bit
63 kernel. */
d0f54f9d
JB
64
65#ifdef __s390x__
99b7da5d
AA
66static const struct regcache_map_entry s390_64_regmap_gregset[] =
67 {
68 /* Skip PSWM and PSWA, since they must be handled specially. */
69 { 2, REGCACHE_MAP_SKIP, 8 },
70 { 1, S390_R0_UPPER_REGNUM, 4 }, { 1, S390_R0_REGNUM, 4 },
71 { 1, S390_R1_UPPER_REGNUM, 4 }, { 1, S390_R1_REGNUM, 4 },
72 { 1, S390_R2_UPPER_REGNUM, 4 }, { 1, S390_R2_REGNUM, 4 },
73 { 1, S390_R3_UPPER_REGNUM, 4 }, { 1, S390_R3_REGNUM, 4 },
74 { 1, S390_R4_UPPER_REGNUM, 4 }, { 1, S390_R4_REGNUM, 4 },
75 { 1, S390_R5_UPPER_REGNUM, 4 }, { 1, S390_R5_REGNUM, 4 },
76 { 1, S390_R6_UPPER_REGNUM, 4 }, { 1, S390_R6_REGNUM, 4 },
77 { 1, S390_R7_UPPER_REGNUM, 4 }, { 1, S390_R7_REGNUM, 4 },
78 { 1, S390_R8_UPPER_REGNUM, 4 }, { 1, S390_R8_REGNUM, 4 },
79 { 1, S390_R9_UPPER_REGNUM, 4 }, { 1, S390_R9_REGNUM, 4 },
80 { 1, S390_R10_UPPER_REGNUM, 4 }, { 1, S390_R10_REGNUM, 4 },
81 { 1, S390_R11_UPPER_REGNUM, 4 }, { 1, S390_R11_REGNUM, 4 },
82 { 1, S390_R12_UPPER_REGNUM, 4 }, { 1, S390_R12_REGNUM, 4 },
83 { 1, S390_R13_UPPER_REGNUM, 4 }, { 1, S390_R13_REGNUM, 4 },
84 { 1, S390_R14_UPPER_REGNUM, 4 }, { 1, S390_R14_REGNUM, 4 },
85 { 1, S390_R15_UPPER_REGNUM, 4 }, { 1, S390_R15_REGNUM, 4 },
86 { 16, S390_A0_REGNUM, 4 },
87 { 1, REGCACHE_MAP_SKIP, 4 }, { 1, S390_ORIG_R2_REGNUM, 4 },
88 { 0 }
89 };
90
91static const struct regset s390_64_gregset =
92 {
93 s390_64_regmap_gregset,
94 regcache_supply_regset,
95 regcache_collect_regset
96 };
97
98#define S390_PSWM_OFFSET 0
99#define S390_PSWA_OFFSET 8
5769d3cd 100#endif
d0f54f9d 101
2ccd1468
UW
102/* Fill GDB's register array with the general-purpose register values
103 in *REGP.
104
105 When debugging a 32-bit executable running under a 64-bit kernel,
106 we have to fix up the 64-bit registers we get from the kernel to
107 make them look like 32-bit registers. */
d6db1fab 108
2ccd1468
UW
109void
110supply_gregset (struct regcache *regcache, const gregset_t *regp)
111{
9cbd5950 112#ifdef __s390x__
d6db1fab 113 struct gdbarch *gdbarch = get_regcache_arch (regcache);
2ccd1468 114 if (gdbarch_ptr_bit (gdbarch) == 32)
d6db1fab
UW
115 {
116 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
99b7da5d 117 ULONGEST pswm, pswa;
2ccd1468 118 gdb_byte buf[4];
d6db1fab 119
99b7da5d
AA
120 regcache_supply_regset (&s390_64_gregset, regcache, -1,
121 regp, sizeof (gregset_t));
122 pswm = extract_unsigned_integer ((const gdb_byte *) regp
123 + S390_PSWM_OFFSET, 8, byte_order);
124 pswa = extract_unsigned_integer ((const gdb_byte *) regp
125 + S390_PSWA_OFFSET, 8, byte_order);
2ccd1468
UW
126 store_unsigned_integer (buf, 4, byte_order, (pswm >> 32) | 0x80000);
127 regcache_raw_supply (regcache, S390_PSWM_REGNUM, buf);
128 store_unsigned_integer (buf, 4, byte_order,
129 (pswa & 0x7fffffff) | (pswm & 0x80000000));
130 regcache_raw_supply (regcache, S390_PSWA_REGNUM, buf);
131 return;
d6db1fab
UW
132 }
133#endif
134
99b7da5d
AA
135 regcache_supply_regset (&s390_gregset, regcache, -1, regp,
136 sizeof (gregset_t));
d6db1fab
UW
137}
138
2ccd1468
UW
139/* Fill register REGNO (if it is a general-purpose register) in
140 *REGP with the value in GDB's register array. If REGNO is -1,
141 do this for all registers. */
d6db1fab 142
2ccd1468
UW
143void
144fill_gregset (const struct regcache *regcache, gregset_t *regp, int regno)
145{
d6db1fab
UW
146#ifdef __s390x__
147 struct gdbarch *gdbarch = get_regcache_arch (regcache);
2ccd1468 148 if (gdbarch_ptr_bit (gdbarch) == 32)
d6db1fab 149 {
99b7da5d
AA
150 regcache_collect_regset (&s390_64_gregset, regcache, regno,
151 regp, sizeof (gregset_t));
d6db1fab 152
2ccd1468
UW
153 if (regno == -1
154 || regno == S390_PSWM_REGNUM || regno == S390_PSWA_REGNUM)
d6db1fab 155 {
2ccd1468
UW
156 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
157 ULONGEST pswa, pswm;
d6db1fab 158 gdb_byte buf[4];
2492f0d0
AA
159 gdb_byte *pswm_p = (gdb_byte *) regp + S390_PSWM_OFFSET;
160 gdb_byte *pswa_p = (gdb_byte *) regp + S390_PSWA_OFFSET;
d6db1fab 161
2492f0d0 162 pswm = extract_unsigned_integer (pswm_p, 8, byte_order);
d6db1fab 163
2ccd1468 164 if (regno == -1 || regno == S390_PSWM_REGNUM)
2492f0d0
AA
165 {
166 pswm &= 0x80000000;
167 regcache_raw_collect (regcache, S390_PSWM_REGNUM, buf);
168 pswm |= (extract_unsigned_integer (buf, 4, byte_order)
169 & 0xfff7ffff) << 32;
170 }
171
2ccd1468 172 if (regno == -1 || regno == S390_PSWA_REGNUM)
2492f0d0
AA
173 {
174 regcache_raw_collect (regcache, S390_PSWA_REGNUM, buf);
175 pswa = extract_unsigned_integer (buf, 4, byte_order);
176 pswm ^= (pswm ^ pswa) & 0x80000000;
177 pswa &= 0x7fffffff;
178 store_unsigned_integer (pswa_p, 8, byte_order, pswa);
179 }
180
181 store_unsigned_integer (pswm_p, 8, byte_order, pswm);
d6db1fab 182 }
2ccd1468 183 return;
d6db1fab 184 }
9cbd5950
JB
185#endif
186
99b7da5d
AA
187 regcache_collect_regset (&s390_gregset, regcache, regno, regp,
188 sizeof (gregset_t));
d0f54f9d
JB
189}
190
191/* Fill GDB's register array with the floating-point register values
192 in *REGP. */
193void
7f7fe91e 194supply_fpregset (struct regcache *regcache, const fpregset_t *regp)
d0f54f9d 195{
99b7da5d
AA
196 regcache_supply_regset (&s390_fpregset, regcache, -1, regp,
197 sizeof (fpregset_t));
d0f54f9d
JB
198}
199
200/* Fill register REGNO (if it is a general-purpose register) in
201 *REGP with the value in GDB's register array. If REGNO is -1,
202 do this for all registers. */
203void
7f7fe91e 204fill_fpregset (const struct regcache *regcache, fpregset_t *regp, int regno)
d0f54f9d 205{
99b7da5d
AA
206 regcache_collect_regset (&s390_fpregset, regcache, regno, regp,
207 sizeof (fpregset_t));
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. */
dfd4cc63 215 int tid = ptid_get_lwp (inferior_ptid);
d0f54f9d 216 if (tid == 0)
dfd4cc63 217 tid = ptid_get_pid (inferior_ptid); /* Not a threaded program. */
d0f54f9d
JB
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
99b7da5d
AA
296/* Fetch all registers in the kernel's register set whose number is
297 REGSET_ID, whose size is REGSIZE, and whose layout is described by
298 REGSET, from process/thread TID and store their values in GDB's
299 register cache. */
c642a434
UW
300static void
301fetch_regset (struct regcache *regcache, int tid,
99b7da5d 302 int regset_id, int regsize, const struct regset *regset)
c642a434 303{
c642a434
UW
304 gdb_byte *buf = alloca (regsize);
305 struct iovec iov;
c642a434
UW
306
307 iov.iov_base = buf;
308 iov.iov_len = regsize;
309
99b7da5d 310 if (ptrace (PTRACE_GETREGSET, tid, (long) regset_id, (long) &iov) < 0)
4ac33720
UW
311 {
312 if (errno == ENODATA)
99b7da5d 313 regcache_supply_regset (regset, regcache, -1, NULL, regsize);
4ac33720
UW
314 else
315 perror_with_name (_("Couldn't get register set"));
316 }
317 else
99b7da5d 318 regcache_supply_regset (regset, regcache, -1, buf, regsize);
c642a434
UW
319}
320
99b7da5d
AA
321/* Store all registers in the kernel's register set whose number is
322 REGSET_ID, whose size is REGSIZE, and whose layout is described by
323 REGSET, from GDB's register cache back to process/thread TID. */
c642a434
UW
324static void
325store_regset (struct regcache *regcache, int tid,
99b7da5d 326 int regset_id, int regsize, const struct regset *regset)
c642a434 327{
c642a434
UW
328 gdb_byte *buf = alloca (regsize);
329 struct iovec iov;
c642a434
UW
330
331 iov.iov_base = buf;
332 iov.iov_len = regsize;
333
99b7da5d 334 if (ptrace (PTRACE_GETREGSET, tid, (long) regset_id, (long) &iov) < 0)
c642a434
UW
335 perror_with_name (_("Couldn't get register set"));
336
99b7da5d 337 regcache_collect_regset (regset, regcache, -1, buf, regsize);
c642a434 338
99b7da5d 339 if (ptrace (PTRACE_SETREGSET, tid, (long) regset_id, (long) &iov) < 0)
c642a434
UW
340 perror_with_name (_("Couldn't set register set"));
341}
342
343/* Check whether the kernel provides a register set with number REGSET
344 of size REGSIZE for process/thread TID. */
345static int
346check_regset (int tid, int regset, int regsize)
347{
348 gdb_byte *buf = alloca (regsize);
349 struct iovec iov;
350
351 iov.iov_base = buf;
352 iov.iov_len = regsize;
353
4ac33720
UW
354 if (ptrace (PTRACE_GETREGSET, tid, (long) regset, (long) &iov) >= 0
355 || errno == ENODATA)
c642a434 356 return 1;
4ac33720 357 return 0;
c642a434
UW
358}
359
d0f54f9d
JB
360/* Fetch register REGNUM from the child process. If REGNUM is -1, do
361 this for all registers. */
10d6c8cd 362static void
28439f5e
PA
363s390_linux_fetch_inferior_registers (struct target_ops *ops,
364 struct regcache *regcache, int regnum)
d0f54f9d
JB
365{
366 int tid = s390_inferior_tid ();
367
2ccd1468 368 if (regnum == -1 || S390_IS_GREGSET_REGNUM (regnum))
56be3814 369 fetch_regs (regcache, tid);
d0f54f9d 370
2ccd1468 371 if (regnum == -1 || S390_IS_FPREGSET_REGNUM (regnum))
56be3814 372 fetch_fpregs (regcache, tid);
c642a434
UW
373
374 if (have_regset_last_break)
375 if (regnum == -1 || regnum == S390_LAST_BREAK_REGNUM)
376 fetch_regset (regcache, tid, NT_S390_LAST_BREAK, 8,
377 (gdbarch_ptr_bit (get_regcache_arch (regcache)) == 32
99b7da5d 378 ? &s390_last_break_regset : &s390x_last_break_regset));
c642a434
UW
379
380 if (have_regset_system_call)
381 if (regnum == -1 || regnum == S390_SYSTEM_CALL_REGNUM)
382 fetch_regset (regcache, tid, NT_S390_SYSTEM_CALL, 4,
99b7da5d 383 &s390_system_call_regset);
4ac33720
UW
384
385 if (have_regset_tdb)
386 if (regnum == -1 || S390_IS_TDBREGSET_REGNUM (regnum))
387 fetch_regset (regcache, tid, NT_S390_TDB, s390_sizeof_tdbregset,
99b7da5d 388 &s390_tdb_regset);
550bdf96
AA
389
390 if (have_regset_vxrs)
391 {
392 if (regnum == -1 || (regnum >= S390_V0_LOWER_REGNUM
393 && regnum <= S390_V15_LOWER_REGNUM))
394 fetch_regset (regcache, tid, NT_S390_VXRS_LOW, 16 * 8,
395 &s390_vxrs_low_regset);
396 if (regnum == -1 || (regnum >= S390_V16_REGNUM
397 && regnum <= S390_V31_REGNUM))
398 fetch_regset (regcache, tid, NT_S390_VXRS_HIGH, 16 * 16,
399 &s390_vxrs_high_regset);
400 }
d0f54f9d
JB
401}
402
403/* Store register REGNUM back into the child process. If REGNUM is
404 -1, do this for all registers. */
10d6c8cd 405static void
28439f5e
PA
406s390_linux_store_inferior_registers (struct target_ops *ops,
407 struct regcache *regcache, int regnum)
d0f54f9d
JB
408{
409 int tid = s390_inferior_tid ();
410
2ccd1468 411 if (regnum == -1 || S390_IS_GREGSET_REGNUM (regnum))
56be3814 412 store_regs (regcache, tid, regnum);
d0f54f9d 413
2ccd1468 414 if (regnum == -1 || S390_IS_FPREGSET_REGNUM (regnum))
56be3814 415 store_fpregs (regcache, tid, regnum);
c642a434
UW
416
417 /* S390_LAST_BREAK_REGNUM is read-only. */
418
419 if (have_regset_system_call)
420 if (regnum == -1 || regnum == S390_SYSTEM_CALL_REGNUM)
421 store_regset (regcache, tid, NT_S390_SYSTEM_CALL, 4,
99b7da5d 422 &s390_system_call_regset);
550bdf96
AA
423
424 if (have_regset_vxrs)
425 {
426 if (regnum == -1 || (regnum >= S390_V0_LOWER_REGNUM
427 && regnum <= S390_V15_LOWER_REGNUM))
428 store_regset (regcache, tid, NT_S390_VXRS_LOW, 16 * 8,
429 &s390_vxrs_low_regset);
430 if (regnum == -1 || (regnum >= S390_V16_REGNUM
431 && regnum <= S390_V31_REGNUM))
432 store_regset (regcache, tid, NT_S390_VXRS_HIGH, 16 * 16,
433 &s390_vxrs_high_regset);
434 }
5769d3cd
AC
435}
436
d0f54f9d 437
e1457d83
JB
438/* Hardware-assisted watchpoint handling. */
439
440/* We maintain a list of all currently active watchpoints in order
441 to properly handle watchpoint removal.
442
443 The only thing we actually need is the total address space area
444 spanned by the watchpoints. */
445
5769d3cd
AC
446struct watch_area
447{
e1457d83 448 struct watch_area *next;
5769d3cd
AC
449 CORE_ADDR lo_addr;
450 CORE_ADDR hi_addr;
451};
452
e1457d83 453static struct watch_area *watch_base = NULL;
5769d3cd 454
fd7979d1 455static int
6a109b6b 456s390_stopped_by_watchpoint (struct target_ops *ops)
5769d3cd
AC
457{
458 per_lowcore_bits per_lowcore;
459 ptrace_area parea;
9f0bdab8 460 int result;
5769d3cd 461
e1457d83
JB
462 /* Speed up common case. */
463 if (!watch_base)
464 return 0;
465
5769d3cd
AC
466 parea.len = sizeof (per_lowcore);
467 parea.process_addr = (addr_t) & per_lowcore;
468 parea.kernel_addr = offsetof (struct user_regs_struct, per_info.lowcore);
e1457d83 469 if (ptrace (PTRACE_PEEKUSR_AREA, s390_inferior_tid (), &parea) < 0)
e2e0b3e5 470 perror_with_name (_("Couldn't retrieve watchpoint status"));
5769d3cd 471
9f0bdab8
DJ
472 result = (per_lowcore.perc_storage_alteration == 1
473 && per_lowcore.perc_store_real_address == 0);
474
475 if (result)
476 {
477 /* Do not report this watchpoint again. */
478 memset (&per_lowcore, 0, sizeof (per_lowcore));
479 if (ptrace (PTRACE_POKEUSR_AREA, s390_inferior_tid (), &parea) < 0)
480 perror_with_name (_("Couldn't clear watchpoint status"));
481 }
482
483 return result;
e1457d83 484}
5769d3cd 485
18396193
AA
486/* Each time before resuming a thread, update its PER info. */
487
e1457d83 488static void
18396193 489s390_prepare_to_resume (struct lwp_info *lp)
5769d3cd 490{
9f0bdab8 491 int tid;
e1457d83 492
5769d3cd
AC
493 per_struct per_info;
494 ptrace_area parea;
495
e1457d83
JB
496 CORE_ADDR watch_lo_addr = (CORE_ADDR)-1, watch_hi_addr = 0;
497 struct watch_area *area;
498
18396193
AA
499 if (lp->arch_private == NULL
500 || !lp->arch_private->per_info_changed)
501 return;
502
503 lp->arch_private->per_info_changed = 0;
504
dfd4cc63 505 tid = ptid_get_lwp (lp->ptid);
9f0bdab8 506 if (tid == 0)
dfd4cc63 507 tid = ptid_get_pid (lp->ptid);
9f0bdab8 508
e1457d83
JB
509 for (area = watch_base; area; area = area->next)
510 {
511 watch_lo_addr = min (watch_lo_addr, area->lo_addr);
512 watch_hi_addr = max (watch_hi_addr, area->hi_addr);
513 }
514
5769d3cd
AC
515 parea.len = sizeof (per_info);
516 parea.process_addr = (addr_t) & per_info;
e1457d83
JB
517 parea.kernel_addr = offsetof (struct user_regs_struct, per_info);
518 if (ptrace (PTRACE_PEEKUSR_AREA, tid, &parea) < 0)
e2e0b3e5 519 perror_with_name (_("Couldn't retrieve watchpoint status"));
e1457d83
JB
520
521 if (watch_base)
5769d3cd
AC
522 {
523 per_info.control_regs.bits.em_storage_alteration = 1;
524 per_info.control_regs.bits.storage_alt_space_ctl = 1;
525 }
526 else
527 {
528 per_info.control_regs.bits.em_storage_alteration = 0;
529 per_info.control_regs.bits.storage_alt_space_ctl = 0;
530 }
531 per_info.starting_addr = watch_lo_addr;
532 per_info.ending_addr = watch_hi_addr;
e1457d83
JB
533
534 if (ptrace (PTRACE_POKEUSR_AREA, tid, &parea) < 0)
e2e0b3e5 535 perror_with_name (_("Couldn't modify watchpoint status"));
5769d3cd
AC
536}
537
18396193
AA
538/* Make sure that LP is stopped and mark its PER info as changed, so
539 the next resume will update it. */
540
541static void
542s390_refresh_per_info (struct lwp_info *lp)
543{
544 if (lp->arch_private == NULL)
545 lp->arch_private = XCNEW (struct arch_lwp_info);
546
547 lp->arch_private->per_info_changed = 1;
548
549 if (!lp->stopped)
550 linux_stop_lwp (lp);
551}
552
553/* When attaching to a new thread, mark its PER info as changed. */
554
555static void
556s390_new_thread (struct lwp_info *lp)
557{
558 lp->arch_private = XCNEW (struct arch_lwp_info);
559 lp->arch_private->per_info_changed = 1;
560}
561
fd7979d1 562static int
7bb99c53
TT
563s390_insert_watchpoint (struct target_ops *self,
564 CORE_ADDR addr, int len, int type,
0cf6dd15 565 struct expression *cond)
5769d3cd 566{
9f0bdab8 567 struct lwp_info *lp;
e1457d83 568 struct watch_area *area = xmalloc (sizeof (struct watch_area));
9f0bdab8 569
e1457d83 570 if (!area)
34201ae3 571 return -1;
e1457d83
JB
572
573 area->lo_addr = addr;
574 area->hi_addr = addr + len - 1;
34201ae3 575
e1457d83
JB
576 area->next = watch_base;
577 watch_base = area;
578
4c38200f 579 ALL_LWPS (lp)
18396193 580 s390_refresh_per_info (lp);
e1457d83 581 return 0;
5769d3cd
AC
582}
583
fd7979d1 584static int
11b5219a
TT
585s390_remove_watchpoint (struct target_ops *self,
586 CORE_ADDR addr, int len, int type,
0cf6dd15 587 struct expression *cond)
5769d3cd 588{
9f0bdab8 589 struct lwp_info *lp;
e1457d83
JB
590 struct watch_area *area, **parea;
591
592 for (parea = &watch_base; *parea; parea = &(*parea)->next)
593 if ((*parea)->lo_addr == addr
594 && (*parea)->hi_addr == addr + len - 1)
595 break;
596
597 if (!*parea)
5769d3cd
AC
598 {
599 fprintf_unfiltered (gdb_stderr,
e1457d83 600 "Attempt to remove nonexistent watchpoint.\n");
5769d3cd
AC
601 return -1;
602 }
e1457d83
JB
603
604 area = *parea;
605 *parea = area->next;
606 xfree (area);
607
4c38200f 608 ALL_LWPS (lp)
18396193 609 s390_refresh_per_info (lp);
e1457d83 610 return 0;
5769d3cd
AC
611}
612
fd7979d1 613static int
5461485a
TT
614s390_can_use_hw_breakpoint (struct target_ops *self,
615 int type, int cnt, int othertype)
fd7979d1 616{
b1798462 617 return type == bp_hardware_watchpoint;
fd7979d1 618}
e1457d83 619
fd7979d1 620static int
31568a15
TT
621s390_region_ok_for_hw_watchpoint (struct target_ops *self,
622 CORE_ADDR addr, int cnt)
5769d3cd 623{
fd7979d1 624 return 1;
5769d3cd
AC
625}
626
7803799a
UW
627static int
628s390_target_wordsize (void)
629{
630 int wordsize = 4;
631
632 /* Check for 64-bit inferior process. This is the case when the host is
633 64-bit, and in addition bit 32 of the PSW mask is set. */
634#ifdef __s390x__
635 long pswm;
636
637 errno = 0;
638 pswm = (long) ptrace (PTRACE_PEEKUSER, s390_inferior_tid (), PT_PSWMASK, 0);
639 if (errno == 0 && (pswm & 0x100000000ul) != 0)
640 wordsize = 8;
641#endif
642
643 return wordsize;
644}
645
646static int
647s390_auxv_parse (struct target_ops *ops, gdb_byte **readptr,
648 gdb_byte *endptr, CORE_ADDR *typep, CORE_ADDR *valp)
649{
650 int sizeof_auxv_field = s390_target_wordsize ();
f5656ead 651 enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
7803799a
UW
652 gdb_byte *ptr = *readptr;
653
654 if (endptr == ptr)
655 return 0;
656
657 if (endptr - ptr < sizeof_auxv_field * 2)
658 return -1;
659
660 *typep = extract_unsigned_integer (ptr, sizeof_auxv_field, byte_order);
661 ptr += sizeof_auxv_field;
662 *valp = extract_unsigned_integer (ptr, sizeof_auxv_field, byte_order);
663 ptr += sizeof_auxv_field;
664
665 *readptr = ptr;
666 return 1;
667}
668
7803799a
UW
669static const struct target_desc *
670s390_read_description (struct target_ops *ops)
671{
c642a434
UW
672 int tid = s390_inferior_tid ();
673
674 have_regset_last_break
675 = check_regset (tid, NT_S390_LAST_BREAK, 8);
676 have_regset_system_call
677 = check_regset (tid, NT_S390_SYSTEM_CALL, 4);
678
7803799a
UW
679 /* If GDB itself is compiled as 64-bit, we are running on a machine in
680 z/Architecture mode. If the target is running in 64-bit addressing
681 mode, report s390x architecture. If the target is running in 31-bit
682 addressing mode, but the kernel supports using 64-bit registers in
683 that mode, report s390 architecture with 64-bit GPRs. */
550bdf96
AA
684#ifdef __s390x__
685 {
686 CORE_ADDR hwcap = 0;
687
688 target_auxv_search (&current_target, AT_HWCAP, &hwcap);
689 have_regset_tdb = (hwcap & HWCAP_S390_TE)
690 && check_regset (tid, NT_S390_TDB, s390_sizeof_tdbregset);
691
692 have_regset_vxrs = (hwcap & HWCAP_S390_VX)
693 && check_regset (tid, NT_S390_VXRS_LOW, 16 * 8)
694 && check_regset (tid, NT_S390_VXRS_HIGH, 16 * 16);
695
696 if (s390_target_wordsize () == 8)
697 return (have_regset_vxrs ?
698 (have_regset_tdb ? tdesc_s390x_tevx_linux64 :
699 tdesc_s390x_vx_linux64) :
700 have_regset_tdb ? tdesc_s390x_te_linux64 :
701 have_regset_system_call ? tdesc_s390x_linux64v2 :
702 have_regset_last_break ? tdesc_s390x_linux64v1 :
703 tdesc_s390x_linux64);
704
705 if (hwcap & HWCAP_S390_HIGH_GPRS)
706 return (have_regset_vxrs ?
707 (have_regset_tdb ? tdesc_s390_tevx_linux64 :
708 tdesc_s390_vx_linux64) :
709 have_regset_tdb ? tdesc_s390_te_linux64 :
710 have_regset_system_call ? tdesc_s390_linux64v2 :
711 have_regset_last_break ? tdesc_s390_linux64v1 :
712 tdesc_s390_linux64);
713 }
7803799a
UW
714#endif
715
716 /* If GDB itself is compiled as 31-bit, or if we're running a 31-bit inferior
717 on a 64-bit kernel that does not support using 64-bit registers in 31-bit
718 mode, report s390 architecture with 32-bit GPRs. */
c642a434
UW
719 return (have_regset_system_call? tdesc_s390_linux32v2 :
720 have_regset_last_break? tdesc_s390_linux32v1 :
721 tdesc_s390_linux32);
7803799a 722}
fd7979d1 723
10d6c8cd
DJ
724void _initialize_s390_nat (void);
725
726void
727_initialize_s390_nat (void)
728{
729 struct target_ops *t;
730
731 /* Fill in the generic GNU/Linux methods. */
732 t = linux_target ();
733
734 /* Add our register access methods. */
735 t->to_fetch_registers = s390_linux_fetch_inferior_registers;
736 t->to_store_registers = s390_linux_store_inferior_registers;
737
fd7979d1
UW
738 /* Add our watchpoint methods. */
739 t->to_can_use_hw_breakpoint = s390_can_use_hw_breakpoint;
2a3cdf79 740 t->to_region_ok_for_hw_watchpoint = s390_region_ok_for_hw_watchpoint;
fd7979d1
UW
741 t->to_have_continuable_watchpoint = 1;
742 t->to_stopped_by_watchpoint = s390_stopped_by_watchpoint;
743 t->to_insert_watchpoint = s390_insert_watchpoint;
744 t->to_remove_watchpoint = s390_remove_watchpoint;
745
7803799a
UW
746 /* Detect target architecture. */
747 t->to_read_description = s390_read_description;
748 t->to_auxv_parse = s390_auxv_parse;
749
10d6c8cd 750 /* Register the target. */
f973ed9c 751 linux_nat_add_target (t);
18396193
AA
752 linux_nat_set_new_thread (t, s390_new_thread);
753 linux_nat_set_prepare_to_resume (t, s390_prepare_to_resume);
10d6c8cd 754}