avoid compiler warnings in remote-m32r-sdi.c
[deliverable/binutils-gdb.git] / gdb / gdbserver / linux-s390-low.c
CommitLineData
265f716b
DJ
1/* GNU/Linux S/390 specific low level interface, for the remote server
2 for GDB.
618f726f 3 Copyright (C) 2001-2016 Free Software Foundation, Inc.
265f716b
DJ
4
5 This file is part of GDB.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
a9762ec7 9 the Free Software Foundation; either version 3 of the License, or
265f716b
DJ
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
a9762ec7 18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
265f716b
DJ
19
20/* This file is used for both 31-bit and 64-bit S/390 systems. */
21
22#include "server.h"
23#include "linux-low.h"
c642a434 24#include "elf/common.h"
265f716b
DJ
25
26#include <asm/ptrace.h>
5826e159 27#include "nat/gdb_ptrace.h"
c642a434 28#include <sys/uio.h>
7803799a 29#include <elf.h>
265f716b 30
7803799a
UW
31#ifndef HWCAP_S390_HIGH_GPRS
32#define HWCAP_S390_HIGH_GPRS 512
33#endif
d05b4ac3 34
6682d959
AA
35#ifndef HWCAP_S390_TE
36#define HWCAP_S390_TE 1024
37#endif
38
bf2d68ab
AA
39#ifndef HWCAP_S390_VX
40#define HWCAP_S390_VX 2048
41#endif
42
7803799a
UW
43/* Defined in auto-generated file s390-linux32.c. */
44void init_registers_s390_linux32 (void);
3aee8918
PA
45extern const struct target_desc *tdesc_s390_linux32;
46
c642a434
UW
47/* Defined in auto-generated file s390-linux32v1.c. */
48void init_registers_s390_linux32v1 (void);
3aee8918
PA
49extern const struct target_desc *tdesc_s390_linux32v1;
50
c642a434
UW
51/* Defined in auto-generated file s390-linux32v2.c. */
52void init_registers_s390_linux32v2 (void);
3aee8918
PA
53extern const struct target_desc *tdesc_s390_linux32v2;
54
7803799a
UW
55/* Defined in auto-generated file s390-linux64.c. */
56void init_registers_s390_linux64 (void);
3aee8918
PA
57extern const struct target_desc *tdesc_s390_linux64;
58
c642a434
UW
59/* Defined in auto-generated file s390-linux64v1.c. */
60void init_registers_s390_linux64v1 (void);
3aee8918
PA
61extern const struct target_desc *tdesc_s390_linux64v1;
62
c642a434
UW
63/* Defined in auto-generated file s390-linux64v2.c. */
64void init_registers_s390_linux64v2 (void);
3aee8918
PA
65extern const struct target_desc *tdesc_s390_linux64v2;
66
4ac33720
UW
67/* Defined in auto-generated file s390-te-linux64.c. */
68void init_registers_s390_te_linux64 (void);
69extern const struct target_desc *tdesc_s390_te_linux64;
70
bf2d68ab
AA
71/* Defined in auto-generated file s390-vx-linux64.c. */
72void init_registers_s390_vx_linux64 (void);
73extern const struct target_desc *tdesc_s390_vx_linux64;
74
75/* Defined in auto-generated file s390-tevx-linux64.c. */
76void init_registers_s390_tevx_linux64 (void);
77extern const struct target_desc *tdesc_s390_tevx_linux64;
78
7803799a
UW
79/* Defined in auto-generated file s390x-linux64.c. */
80void init_registers_s390x_linux64 (void);
3aee8918
PA
81extern const struct target_desc *tdesc_s390x_linux64;
82
c642a434
UW
83/* Defined in auto-generated file s390x-linux64v1.c. */
84void init_registers_s390x_linux64v1 (void);
3aee8918
PA
85extern const struct target_desc *tdesc_s390x_linux64v1;
86
c642a434
UW
87/* Defined in auto-generated file s390x-linux64v2.c. */
88void init_registers_s390x_linux64v2 (void);
3aee8918 89extern const struct target_desc *tdesc_s390x_linux64v2;
d05b4ac3 90
4ac33720
UW
91/* Defined in auto-generated file s390x-te-linux64.c. */
92void init_registers_s390x_te_linux64 (void);
93extern const struct target_desc *tdesc_s390x_te_linux64;
94
bf2d68ab
AA
95/* Defined in auto-generated file s390x-vx-linux64.c. */
96void init_registers_s390x_vx_linux64 (void);
97extern const struct target_desc *tdesc_s390x_vx_linux64;
98
99/* Defined in auto-generated file s390x-tevx-linux64.c. */
100void init_registers_s390x_tevx_linux64 (void);
101extern const struct target_desc *tdesc_s390x_tevx_linux64;
102
c642a434 103#define s390_num_regs 52
265f716b 104
2ec06d2e 105static int s390_regmap[] = {
265f716b
DJ
106 PT_PSWMASK, PT_PSWADDR,
107
108 PT_GPR0, PT_GPR1, PT_GPR2, PT_GPR3,
109 PT_GPR4, PT_GPR5, PT_GPR6, PT_GPR7,
110 PT_GPR8, PT_GPR9, PT_GPR10, PT_GPR11,
111 PT_GPR12, PT_GPR13, PT_GPR14, PT_GPR15,
112
113 PT_ACR0, PT_ACR1, PT_ACR2, PT_ACR3,
114 PT_ACR4, PT_ACR5, PT_ACR6, PT_ACR7,
115 PT_ACR8, PT_ACR9, PT_ACR10, PT_ACR11,
116 PT_ACR12, PT_ACR13, PT_ACR14, PT_ACR15,
117
265f716b
DJ
118 PT_FPC,
119
d0f54f9d 120#ifndef __s390x__
265f716b
DJ
121 PT_FPR0_HI, PT_FPR1_HI, PT_FPR2_HI, PT_FPR3_HI,
122 PT_FPR4_HI, PT_FPR5_HI, PT_FPR6_HI, PT_FPR7_HI,
123 PT_FPR8_HI, PT_FPR9_HI, PT_FPR10_HI, PT_FPR11_HI,
124 PT_FPR12_HI, PT_FPR13_HI, PT_FPR14_HI, PT_FPR15_HI,
125#else
126 PT_FPR0, PT_FPR1, PT_FPR2, PT_FPR3,
127 PT_FPR4, PT_FPR5, PT_FPR6, PT_FPR7,
128 PT_FPR8, PT_FPR9, PT_FPR10, PT_FPR11,
129 PT_FPR12, PT_FPR13, PT_FPR14, PT_FPR15,
130#endif
c642a434
UW
131
132 PT_ORIGGPR2,
265f716b
DJ
133};
134
7803799a 135#ifdef __s390x__
c642a434 136#define s390_num_regs_3264 68
7803799a
UW
137
138static int s390_regmap_3264[] = {
139 PT_PSWMASK, PT_PSWADDR,
140
493e2a69
MS
141 PT_GPR0, PT_GPR0, PT_GPR1, PT_GPR1,
142 PT_GPR2, PT_GPR2, PT_GPR3, PT_GPR3,
143 PT_GPR4, PT_GPR4, PT_GPR5, PT_GPR5,
144 PT_GPR6, PT_GPR6, PT_GPR7, PT_GPR7,
145 PT_GPR8, PT_GPR8, PT_GPR9, PT_GPR9,
146 PT_GPR10, PT_GPR10, PT_GPR11, PT_GPR11,
147 PT_GPR12, PT_GPR12, PT_GPR13, PT_GPR13,
148 PT_GPR14, PT_GPR14, PT_GPR15, PT_GPR15,
7803799a
UW
149
150 PT_ACR0, PT_ACR1, PT_ACR2, PT_ACR3,
151 PT_ACR4, PT_ACR5, PT_ACR6, PT_ACR7,
152 PT_ACR8, PT_ACR9, PT_ACR10, PT_ACR11,
153 PT_ACR12, PT_ACR13, PT_ACR14, PT_ACR15,
154
155 PT_FPC,
156
157 PT_FPR0, PT_FPR1, PT_FPR2, PT_FPR3,
158 PT_FPR4, PT_FPR5, PT_FPR6, PT_FPR7,
159 PT_FPR8, PT_FPR9, PT_FPR10, PT_FPR11,
160 PT_FPR12, PT_FPR13, PT_FPR14, PT_FPR15,
c642a434
UW
161
162 PT_ORIGGPR2,
7803799a
UW
163};
164#endif
165
166
2ec06d2e
DJ
167static int
168s390_cannot_fetch_register (int regno)
265f716b 169{
265f716b
DJ
170 return 0;
171}
172
2ec06d2e
DJ
173static int
174s390_cannot_store_register (int regno)
265f716b 175{
265f716b
DJ
176 return 0;
177}
2ec06d2e 178
ee1a7ae4 179static void
442ea881 180s390_collect_ptrace_register (struct regcache *regcache, int regno, char *buf)
ee1a7ae4 181{
3aee8918 182 int size = register_size (regcache->tdesc, regno);
ee1a7ae4
UW
183 if (size < sizeof (long))
184 {
3aee8918
PA
185 const struct regs_info *regs_info = (*the_low_target.regs_info) ();
186 struct usrregs_info *usr = regs_info->usrregs;
187 int regaddr = usr->regmap[regno];
7803799a 188
ee1a7ae4
UW
189 memset (buf, 0, sizeof (long));
190
3aee8918
PA
191 if ((regno ^ 1) < usr->num_regs
192 && usr->regmap[regno ^ 1] == regaddr)
7803799a 193 {
18f5de3b
JK
194 collect_register (regcache, regno & ~1, buf);
195 collect_register (regcache, (regno & ~1) + 1,
196 buf + sizeof (long) - size);
7803799a 197 }
d6db1fab
UW
198 else if (regaddr == PT_PSWMASK)
199 {
200 /* Convert 4-byte PSW mask to 8 bytes by clearing bit 12 and copying
201 the basic addressing mode bit from the PSW address. */
3aee8918 202 char *addr = alloca (register_size (regcache->tdesc, regno ^ 1));
d6db1fab
UW
203 collect_register (regcache, regno, buf);
204 collect_register (regcache, regno ^ 1, addr);
205 buf[1] &= ~0x8;
206 buf[size] |= (addr[0] & 0x80);
207 }
208 else if (regaddr == PT_PSWADDR)
209 {
210 /* Convert 4-byte PSW address to 8 bytes by clearing the addressing
211 mode bit (which gets copied to the PSW mask instead). */
212 collect_register (regcache, regno, buf + sizeof (long) - size);
213 buf[sizeof (long) - size] &= ~0x80;
214 }
c642a434
UW
215 else if ((regaddr >= PT_GPR0 && regaddr <= PT_GPR15)
216 || regaddr == PT_ORIGGPR2)
442ea881 217 collect_register (regcache, regno, buf + sizeof (long) - size);
ee1a7ae4 218 else
442ea881 219 collect_register (regcache, regno, buf);
ee1a7ae4
UW
220 }
221 else
18f5de3b 222 collect_register (regcache, regno, buf);
ee1a7ae4
UW
223}
224
225static void
493e2a69
MS
226s390_supply_ptrace_register (struct regcache *regcache,
227 int regno, const char *buf)
ee1a7ae4 228{
3aee8918 229 int size = register_size (regcache->tdesc, regno);
ee1a7ae4
UW
230 if (size < sizeof (long))
231 {
3aee8918
PA
232 const struct regs_info *regs_info = (*the_low_target.regs_info) ();
233 struct usrregs_info *usr = regs_info->usrregs;
234 int regaddr = usr->regmap[regno];
7803799a 235
3aee8918
PA
236 if ((regno ^ 1) < usr->num_regs
237 && usr->regmap[regno ^ 1] == regaddr)
7803799a 238 {
18f5de3b
JK
239 supply_register (regcache, regno & ~1, buf);
240 supply_register (regcache, (regno & ~1) + 1,
241 buf + sizeof (long) - size);
7803799a 242 }
d6db1fab
UW
243 else if (regaddr == PT_PSWMASK)
244 {
245 /* Convert 8-byte PSW mask to 4 bytes by setting bit 12 and copying
246 the basic addressing mode into the PSW address. */
247 char *mask = alloca (size);
3aee8918 248 char *addr = alloca (register_size (regcache->tdesc, regno ^ 1));
d6db1fab
UW
249 memcpy (mask, buf, size);
250 mask[1] |= 0x8;
251 supply_register (regcache, regno, mask);
252
253 collect_register (regcache, regno ^ 1, addr);
254 addr[0] &= ~0x80;
255 addr[0] |= (buf[size] & 0x80);
256 supply_register (regcache, regno ^ 1, addr);
257 }
258 else if (regaddr == PT_PSWADDR)
259 {
260 /* Convert 8-byte PSW address to 4 bytes by truncating, but
261 keeping the addressing mode bit (which was set from the mask). */
262 char *addr = alloca (size);
263 char amode;
264 collect_register (regcache, regno, addr);
265 amode = addr[0] & 0x80;
266 memcpy (addr, buf + sizeof (long) - size, size);
267 addr[0] &= ~0x80;
268 addr[0] |= amode;
269 supply_register (regcache, regno, addr);
270 }
c642a434
UW
271 else if ((regaddr >= PT_GPR0 && regaddr <= PT_GPR15)
272 || regaddr == PT_ORIGGPR2)
442ea881 273 supply_register (regcache, regno, buf + sizeof (long) - size);
ee1a7ae4 274 else
442ea881 275 supply_register (regcache, regno, buf);
ee1a7ae4
UW
276 }
277 else
442ea881 278 supply_register (regcache, regno, buf);
ee1a7ae4
UW
279}
280
b7149293
UW
281/* Provide only a fill function for the general register set. ps_lgetregs
282 will use this for NPTL support. */
283
3aee8918
PA
284static void
285s390_fill_gregset (struct regcache *regcache, void *buf)
b7149293
UW
286{
287 int i;
3aee8918
PA
288 const struct regs_info *regs_info = (*the_low_target.regs_info) ();
289 struct usrregs_info *usr = regs_info->usrregs;
b7149293 290
3aee8918 291 for (i = 0; i < usr->num_regs; i++)
7803799a 292 {
3aee8918
PA
293 if (usr->regmap[i] < PT_PSWMASK
294 || usr->regmap[i] > PT_ACR15)
7803799a
UW
295 continue;
296
3aee8918
PA
297 s390_collect_ptrace_register (regcache, i,
298 (char *) buf + usr->regmap[i]);
7803799a 299 }
b7149293
UW
300}
301
c642a434
UW
302/* Fill and store functions for extended register sets. */
303
c642a434
UW
304static void
305s390_store_last_break (struct regcache *regcache, const void *buf)
306{
3aee8918
PA
307 const char *p;
308
309 p = (const char *) buf + 8 - register_size (regcache->tdesc, 0);
310 supply_register_by_name (regcache, "last_break", p);
c642a434
UW
311}
312
313static void
314s390_fill_system_call (struct regcache *regcache, void *buf)
315{
316 collect_register_by_name (regcache, "system_call", buf);
317}
318
319static void
320s390_store_system_call (struct regcache *regcache, const void *buf)
321{
322 supply_register_by_name (regcache, "system_call", buf);
323}
324
e5a9158d
AA
325static void
326s390_store_tdb (struct regcache *regcache, const void *buf)
327{
328 int tdb0 = find_regno (regcache->tdesc, "tdb0");
329 int tr0 = find_regno (regcache->tdesc, "tr0");
330 int i;
331
332 for (i = 0; i < 4; i++)
333 supply_register (regcache, tdb0 + i, (const char *) buf + 8 * i);
334
335 for (i = 0; i < 16; i++)
336 supply_register (regcache, tr0 + i, (const char *) buf + 8 * (16 + i));
337}
338
bf2d68ab
AA
339static void
340s390_fill_vxrs_low (struct regcache *regcache, void *buf)
341{
342 int v0 = find_regno (regcache->tdesc, "v0l");
343 int i;
344
345 for (i = 0; i < 16; i++)
346 collect_register (regcache, v0 + i, (char *) buf + 8 * i);
347}
348
349static void
350s390_store_vxrs_low (struct regcache *regcache, const void *buf)
351{
352 int v0 = find_regno (regcache->tdesc, "v0l");
353 int i;
354
355 for (i = 0; i < 16; i++)
356 supply_register (regcache, v0 + i, (const char *) buf + 8 * i);
357}
358
359static void
360s390_fill_vxrs_high (struct regcache *regcache, void *buf)
361{
362 int v16 = find_regno (regcache->tdesc, "v16");
363 int i;
364
365 for (i = 0; i < 16; i++)
366 collect_register (regcache, v16 + i, (char *) buf + 16 * i);
367}
368
369static void
370s390_store_vxrs_high (struct regcache *regcache, const void *buf)
371{
372 int v16 = find_regno (regcache->tdesc, "v16");
373 int i;
374
375 for (i = 0; i < 16; i++)
376 supply_register (regcache, v16 + i, (const char *) buf + 16 * i);
377}
378
3aee8918 379static struct regset_info s390_regsets[] = {
1570b33e 380 { 0, 0, 0, 0, GENERAL_REGS, s390_fill_gregset, NULL },
feea5f36
AA
381 /* Last break address is read-only; no fill function. */
382 { PTRACE_GETREGSET, -1, NT_S390_LAST_BREAK, 0, EXTENDED_REGS,
383 NULL, s390_store_last_break },
c642a434
UW
384 { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_S390_SYSTEM_CALL, 0,
385 EXTENDED_REGS, s390_fill_system_call, s390_store_system_call },
e5a9158d
AA
386 /* TDB is read-only. */
387 { PTRACE_GETREGSET, -1, NT_S390_TDB, 0, EXTENDED_REGS,
388 NULL, s390_store_tdb },
bf2d68ab
AA
389 { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_S390_VXRS_LOW, 0,
390 EXTENDED_REGS, s390_fill_vxrs_low, s390_store_vxrs_low },
391 { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_S390_VXRS_HIGH, 0,
392 EXTENDED_REGS, s390_fill_vxrs_high, s390_store_vxrs_high },
50bc912a 393 NULL_REGSET
b7149293
UW
394};
395
b0ded00b 396
dd373349 397static const gdb_byte s390_breakpoint[] = { 0, 1 };
b0ded00b
UW
398#define s390_breakpoint_len 2
399
dd373349
AT
400/* Implementation of linux_target_ops method "sw_breakpoint_from_kind". */
401
402static const gdb_byte *
403s390_sw_breakpoint_from_kind (int kind, int *size)
404{
405 *size = s390_breakpoint_len;
406 return s390_breakpoint;
407}
408
b0ded00b 409static CORE_ADDR
442ea881 410s390_get_pc (struct regcache *regcache)
b0ded00b 411{
3aee8918 412 if (register_size (regcache->tdesc, 0) == 4)
d61ddec4 413 {
d6db1fab
UW
414 unsigned int pswa;
415 collect_register_by_name (regcache, "pswa", &pswa);
416 return pswa & 0x7fffffff;
d61ddec4
UW
417 }
418 else
419 {
420 unsigned long pc;
442ea881 421 collect_register_by_name (regcache, "pswa", &pc);
d61ddec4
UW
422 return pc;
423 }
b0ded00b
UW
424}
425
426static void
442ea881 427s390_set_pc (struct regcache *regcache, CORE_ADDR newpc)
b0ded00b 428{
3aee8918 429 if (register_size (regcache->tdesc, 0) == 4)
d61ddec4 430 {
d6db1fab
UW
431 unsigned int pswa;
432 collect_register_by_name (regcache, "pswa", &pswa);
433 pswa = (pswa & 0x80000000) | (newpc & 0x7fffffff);
434 supply_register_by_name (regcache, "pswa", &pswa);
d61ddec4
UW
435 }
436 else
437 {
438 unsigned long pc = newpc;
442ea881 439 supply_register_by_name (regcache, "pswa", &pc);
d61ddec4 440 }
b0ded00b
UW
441}
442
7803799a
UW
443#ifdef __s390x__
444static unsigned long
3aee8918 445s390_get_hwcap (const struct target_desc *tdesc)
7803799a 446{
3aee8918 447 int wordsize = register_size (tdesc, 0);
7803799a
UW
448 unsigned char *data = alloca (2 * wordsize);
449 int offset = 0;
450
451 while ((*the_target->read_auxv) (offset, data, 2 * wordsize) == 2 * wordsize)
452 {
453 if (wordsize == 4)
454 {
455 unsigned int *data_p = (unsigned int *)data;
456 if (data_p[0] == AT_HWCAP)
457 return data_p[1];
458 }
459 else
460 {
461 unsigned long *data_p = (unsigned long *)data;
462 if (data_p[0] == AT_HWCAP)
463 return data_p[1];
464 }
465
466 offset += 2 * wordsize;
467 }
468
469 return 0;
470}
471#endif
d61ddec4 472
c642a434
UW
473static int
474s390_check_regset (int pid, int regset, int regsize)
475{
476 gdb_byte *buf = alloca (regsize);
477 struct iovec iov;
478
479 iov.iov_base = buf;
480 iov.iov_len = regsize;
481
4ac33720
UW
482 if (ptrace (PTRACE_GETREGSET, pid, (long) regset, (long) &iov) >= 0
483 || errno == ENODATA)
c642a434 484 return 1;
4ac33720 485 return 0;
c642a434
UW
486}
487
3aee8918
PA
488#ifdef __s390x__
489/* For a 31-bit inferior, whether the kernel supports using the full
490 64-bit GPRs. */
491static int have_hwcap_s390_high_gprs = 0;
492#endif
493
d61ddec4
UW
494static void
495s390_arch_setup (void)
496{
3aee8918 497 const struct target_desc *tdesc;
c642a434
UW
498 struct regset_info *regset;
499
500 /* Check whether the kernel supports extra register sets. */
0bfdf32f 501 int pid = pid_of (current_thread);
c642a434
UW
502 int have_regset_last_break
503 = s390_check_regset (pid, NT_S390_LAST_BREAK, 8);
504 int have_regset_system_call
505 = s390_check_regset (pid, NT_S390_SYSTEM_CALL, 4);
4ac33720 506 int have_regset_tdb = s390_check_regset (pid, NT_S390_TDB, 256);
bf2d68ab
AA
507 int have_regset_vxrs = s390_check_regset (pid, NT_S390_VXRS_LOW, 128)
508 && s390_check_regset (pid, NT_S390_VXRS_HIGH, 256);
c642a434 509
d61ddec4 510 /* Assume 31-bit inferior process. */
c642a434 511 if (have_regset_system_call)
3aee8918 512 tdesc = tdesc_s390_linux32v2;
c642a434 513 else if (have_regset_last_break)
3aee8918 514 tdesc = tdesc_s390_linux32v1;
c642a434 515 else
3aee8918 516 tdesc = tdesc_s390_linux32;
d61ddec4
UW
517
518 /* On a 64-bit host, check the low bit of the (31-bit) PSWM
519 -- if this is one, we actually have a 64-bit inferior. */
520#ifdef __s390x__
521 {
522 unsigned int pswm;
3aee8918 523 struct regcache *regcache = new_register_cache (tdesc);
6682d959 524
3aee8918 525 fetch_inferior_registers (regcache, find_regno (tdesc, "pswm"));
442ea881 526 collect_register_by_name (regcache, "pswm", &pswm);
92b72907
UW
527 free_register_cache (regcache);
528
d61ddec4 529 if (pswm & 1)
c642a434 530 {
6682d959
AA
531 if (have_regset_tdb)
532 have_regset_tdb =
533 (s390_get_hwcap (tdesc_s390x_linux64v2) & HWCAP_S390_TE) != 0;
bf2d68ab
AA
534 if (have_regset_vxrs)
535 have_regset_vxrs =
536 (s390_get_hwcap (tdesc_s390x_linux64v2) & HWCAP_S390_VX) != 0;
537
538 if (have_regset_vxrs)
539 tdesc = (have_regset_tdb ? tdesc_s390x_tevx_linux64 :
540 tdesc_s390x_vx_linux64);
541 else if (have_regset_tdb)
4ac33720 542 tdesc = tdesc_s390x_te_linux64;
6682d959 543 else if (have_regset_system_call)
3aee8918 544 tdesc = tdesc_s390x_linux64v2;
c642a434 545 else if (have_regset_last_break)
3aee8918 546 tdesc = tdesc_s390x_linux64v1;
c642a434 547 else
3aee8918 548 tdesc = tdesc_s390x_linux64;
c642a434 549 }
7803799a
UW
550
551 /* For a 31-bit inferior, check whether the kernel supports
552 using the full 64-bit GPRs. */
3aee8918 553 else if (s390_get_hwcap (tdesc) & HWCAP_S390_HIGH_GPRS)
7803799a 554 {
3aee8918 555 have_hwcap_s390_high_gprs = 1;
6682d959
AA
556 if (have_regset_tdb)
557 have_regset_tdb = (s390_get_hwcap (tdesc) & HWCAP_S390_TE) != 0;
bf2d68ab
AA
558 if (have_regset_vxrs)
559 have_regset_vxrs = (s390_get_hwcap (tdesc) & HWCAP_S390_VX) != 0;
3aee8918 560
bf2d68ab
AA
561 if (have_regset_vxrs)
562 tdesc = (have_regset_tdb ? tdesc_s390_tevx_linux64 :
563 tdesc_s390_vx_linux64);
564 else if (have_regset_tdb)
4ac33720
UW
565 tdesc = tdesc_s390_te_linux64;
566 else if (have_regset_system_call)
3aee8918 567 tdesc = tdesc_s390_linux64v2;
c642a434 568 else if (have_regset_last_break)
3aee8918 569 tdesc = tdesc_s390_linux64v1;
c642a434 570 else
3aee8918 571 tdesc = tdesc_s390_linux64;
7803799a 572 }
d61ddec4
UW
573 }
574#endif
6682d959
AA
575
576 /* Update target_regsets according to available register sets. */
feea5f36 577 for (regset = s390_regsets; regset->size >= 0; regset++)
6682d959
AA
578 if (regset->get_request == PTRACE_GETREGSET)
579 switch (regset->nt_type)
580 {
581 case NT_S390_LAST_BREAK:
582 regset->size = have_regset_last_break? 8 : 0;
583 break;
584 case NT_S390_SYSTEM_CALL:
585 regset->size = have_regset_system_call? 4 : 0;
586 break;
587 case NT_S390_TDB:
588 regset->size = have_regset_tdb ? 256 : 0;
bf2d68ab
AA
589 break;
590 case NT_S390_VXRS_LOW:
591 regset->size = have_regset_vxrs ? 128 : 0;
592 break;
593 case NT_S390_VXRS_HIGH:
594 regset->size = have_regset_vxrs ? 256 : 0;
595 break;
6682d959
AA
596 default:
597 break;
598 }
599
3aee8918 600 current_process ()->tdesc = tdesc;
d61ddec4
UW
601}
602
603
b0ded00b
UW
604static int
605s390_breakpoint_at (CORE_ADDR pc)
606{
607 unsigned char c[s390_breakpoint_len];
608 read_inferior_memory (pc, c, s390_breakpoint_len);
609 return memcmp (c, s390_breakpoint, s390_breakpoint_len) == 0;
610}
611
b00b61e1
MK
612/* Breakpoint/Watchpoint support. */
613
614/* The "supports_z_point_type" linux_target_ops method. */
615
616static int
617s390_supports_z_point_type (char z_type)
618{
619 switch (z_type)
620 {
621 case Z_PACKET_SW_BP:
622 return 1;
623 default:
624 return 0;
625 }
626}
627
7d00775e
AT
628/* Support for hardware single step. */
629
630static int
631s390_supports_hardware_single_step (void)
632{
633 return 1;
634}
635
3aee8918
PA
636static struct usrregs_info s390_usrregs_info =
637 {
638 s390_num_regs,
639 s390_regmap,
640 };
641
642static struct regsets_info s390_regsets_info =
643 {
644 s390_regsets, /* regsets */
645 0, /* num_regsets */
646 NULL, /* disabled_regsets */
647 };
648
649static struct regs_info regs_info =
650 {
651 NULL, /* regset_bitmap */
652 &s390_usrregs_info,
653 &s390_regsets_info
654 };
655
656#ifdef __s390x__
657static struct usrregs_info s390_usrregs_info_3264 =
658 {
659 s390_num_regs_3264,
660 s390_regmap_3264
661 };
662
663static struct regsets_info s390_regsets_info_3264 =
664 {
665 s390_regsets, /* regsets */
666 0, /* num_regsets */
667 NULL, /* disabled_regsets */
668 };
669
670static struct regs_info regs_info_3264 =
671 {
672 NULL, /* regset_bitmap */
673 &s390_usrregs_info_3264,
674 &s390_regsets_info_3264
675 };
676#endif
677
678static const struct regs_info *
679s390_regs_info (void)
680{
681#ifdef __s390x__
682 if (have_hwcap_s390_high_gprs)
683 {
684 const struct target_desc *tdesc = current_process ()->tdesc;
685
686 if (register_size (tdesc, 0) == 4)
687 return &regs_info_3264;
688 }
689#endif
690 return &regs_info;
691}
b0ded00b 692
2ec06d2e 693struct linux_target_ops the_low_target = {
d61ddec4 694 s390_arch_setup,
3aee8918 695 s390_regs_info,
2ec06d2e
DJ
696 s390_cannot_fetch_register,
697 s390_cannot_store_register,
c14dfd32 698 NULL, /* fetch_register */
b0ded00b
UW
699 s390_get_pc,
700 s390_set_pc,
dd373349
AT
701 NULL, /* breakpoint_kind_from_pc */
702 s390_sw_breakpoint_from_kind,
b0ded00b
UW
703 NULL,
704 s390_breakpoint_len,
705 s390_breakpoint_at,
b00b61e1 706 s390_supports_z_point_type,
ee1a7ae4
UW
707 NULL,
708 NULL,
709 NULL,
710 NULL,
711 s390_collect_ptrace_register,
712 s390_supply_ptrace_register,
7d00775e
AT
713 NULL, /* siginfo_fixup */
714 NULL, /* new_process */
715 NULL, /* new_thread */
716 NULL, /* new_fork */
717 NULL, /* prepare_to_resume */
718 NULL, /* process_qsupported */
719 NULL, /* supports_tracepoints */
720 NULL, /* get_thread_area */
721 NULL, /* install_fast_tracepoint_jump_pad */
722 NULL, /* emit_ops */
723 NULL, /* get_min_fast_tracepoint_insn_len */
724 NULL, /* supports_range_stepping */
725 NULL, /* breakpoint_kind_from_current_state */
726 s390_supports_hardware_single_step,
2ec06d2e 727};
3aee8918
PA
728
729void
730initialize_low_arch (void)
731{
732 /* Initialize the Linux target descriptions. */
733
734 init_registers_s390_linux32 ();
735 init_registers_s390_linux32v1 ();
736 init_registers_s390_linux32v2 ();
737 init_registers_s390_linux64 ();
738 init_registers_s390_linux64v1 ();
739 init_registers_s390_linux64v2 ();
4ac33720 740 init_registers_s390_te_linux64 ();
bf2d68ab
AA
741 init_registers_s390_vx_linux64 ();
742 init_registers_s390_tevx_linux64 ();
3aee8918
PA
743 init_registers_s390x_linux64 ();
744 init_registers_s390x_linux64v1 ();
745 init_registers_s390x_linux64v2 ();
4ac33720 746 init_registers_s390x_te_linux64 ();
bf2d68ab
AA
747 init_registers_s390x_vx_linux64 ();
748 init_registers_s390x_tevx_linux64 ();
3aee8918
PA
749
750 initialize_regsets_info (&s390_regsets_info);
751#ifdef __s390x__
752 initialize_regsets_info (&s390_regsets_info_3264);
753#endif
754}
This page took 1.104827 seconds and 4 git commands to generate.