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