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