gdbserver/s390: Switch on tracepoint support.
[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
c642a434 135#define s390_num_regs_3264 68
7803799a 136
ab503087 137#ifdef __s390x__
7803799a
UW
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 163};
ab503087
MK
164#else
165static int s390_regmap_3264[] = {
166 PT_PSWMASK, PT_PSWADDR,
167
168 -1, PT_GPR0, -1, PT_GPR1,
169 -1, PT_GPR2, -1, PT_GPR3,
170 -1, PT_GPR4, -1, PT_GPR5,
171 -1, PT_GPR6, -1, PT_GPR7,
172 -1, PT_GPR8, -1, PT_GPR9,
173 -1, PT_GPR10, -1, PT_GPR11,
174 -1, PT_GPR12, -1, PT_GPR13,
175 -1, PT_GPR14, -1, PT_GPR15,
176
177 PT_ACR0, PT_ACR1, PT_ACR2, PT_ACR3,
178 PT_ACR4, PT_ACR5, PT_ACR6, PT_ACR7,
179 PT_ACR8, PT_ACR9, PT_ACR10, PT_ACR11,
180 PT_ACR12, PT_ACR13, PT_ACR14, PT_ACR15,
181
182 PT_FPC,
183
184 PT_FPR0_HI, PT_FPR1_HI, PT_FPR2_HI, PT_FPR3_HI,
185 PT_FPR4_HI, PT_FPR5_HI, PT_FPR6_HI, PT_FPR7_HI,
186 PT_FPR8_HI, PT_FPR9_HI, PT_FPR10_HI, PT_FPR11_HI,
187 PT_FPR12_HI, PT_FPR13_HI, PT_FPR14_HI, PT_FPR15_HI,
188
189 PT_ORIGGPR2,
190};
7803799a
UW
191#endif
192
193
2ec06d2e
DJ
194static int
195s390_cannot_fetch_register (int regno)
265f716b 196{
265f716b
DJ
197 return 0;
198}
199
2ec06d2e
DJ
200static int
201s390_cannot_store_register (int regno)
265f716b 202{
265f716b
DJ
203 return 0;
204}
2ec06d2e 205
ee1a7ae4 206static void
442ea881 207s390_collect_ptrace_register (struct regcache *regcache, int regno, char *buf)
ee1a7ae4 208{
3aee8918 209 int size = register_size (regcache->tdesc, regno);
ab503087
MK
210 const struct regs_info *regs_info = (*the_low_target.regs_info) ();
211 struct usrregs_info *usr = regs_info->usrregs;
212 int regaddr = usr->regmap[regno];
213
ee1a7ae4
UW
214 if (size < sizeof (long))
215 {
216 memset (buf, 0, sizeof (long));
217
3aee8918
PA
218 if ((regno ^ 1) < usr->num_regs
219 && usr->regmap[regno ^ 1] == regaddr)
7803799a 220 {
18f5de3b
JK
221 collect_register (regcache, regno & ~1, buf);
222 collect_register (regcache, (regno & ~1) + 1,
223 buf + sizeof (long) - size);
7803799a 224 }
d6db1fab
UW
225 else if (regaddr == PT_PSWMASK)
226 {
227 /* Convert 4-byte PSW mask to 8 bytes by clearing bit 12 and copying
228 the basic addressing mode bit from the PSW address. */
3aee8918 229 char *addr = alloca (register_size (regcache->tdesc, regno ^ 1));
d6db1fab
UW
230 collect_register (regcache, regno, buf);
231 collect_register (regcache, regno ^ 1, addr);
232 buf[1] &= ~0x8;
233 buf[size] |= (addr[0] & 0x80);
234 }
235 else if (regaddr == PT_PSWADDR)
236 {
237 /* Convert 4-byte PSW address to 8 bytes by clearing the addressing
238 mode bit (which gets copied to the PSW mask instead). */
239 collect_register (regcache, regno, buf + sizeof (long) - size);
240 buf[sizeof (long) - size] &= ~0x80;
241 }
c642a434
UW
242 else if ((regaddr >= PT_GPR0 && regaddr <= PT_GPR15)
243 || regaddr == PT_ORIGGPR2)
442ea881 244 collect_register (regcache, regno, buf + sizeof (long) - size);
ee1a7ae4 245 else
442ea881 246 collect_register (regcache, regno, buf);
ee1a7ae4 247 }
ab503087 248 else if (regaddr != -1)
18f5de3b 249 collect_register (regcache, regno, buf);
ee1a7ae4
UW
250}
251
252static void
493e2a69
MS
253s390_supply_ptrace_register (struct regcache *regcache,
254 int regno, const char *buf)
ee1a7ae4 255{
3aee8918 256 int size = register_size (regcache->tdesc, regno);
ab503087
MK
257 const struct regs_info *regs_info = (*the_low_target.regs_info) ();
258 struct usrregs_info *usr = regs_info->usrregs;
259 int regaddr = usr->regmap[regno];
260
ee1a7ae4
UW
261 if (size < sizeof (long))
262 {
3aee8918
PA
263 if ((regno ^ 1) < usr->num_regs
264 && usr->regmap[regno ^ 1] == regaddr)
7803799a 265 {
18f5de3b
JK
266 supply_register (regcache, regno & ~1, buf);
267 supply_register (regcache, (regno & ~1) + 1,
268 buf + sizeof (long) - size);
7803799a 269 }
d6db1fab
UW
270 else if (regaddr == PT_PSWMASK)
271 {
272 /* Convert 8-byte PSW mask to 4 bytes by setting bit 12 and copying
273 the basic addressing mode into the PSW address. */
274 char *mask = alloca (size);
3aee8918 275 char *addr = alloca (register_size (regcache->tdesc, regno ^ 1));
d6db1fab
UW
276 memcpy (mask, buf, size);
277 mask[1] |= 0x8;
278 supply_register (regcache, regno, mask);
279
280 collect_register (regcache, regno ^ 1, addr);
281 addr[0] &= ~0x80;
282 addr[0] |= (buf[size] & 0x80);
283 supply_register (regcache, regno ^ 1, addr);
284 }
285 else if (regaddr == PT_PSWADDR)
286 {
287 /* Convert 8-byte PSW address to 4 bytes by truncating, but
288 keeping the addressing mode bit (which was set from the mask). */
289 char *addr = alloca (size);
290 char amode;
291 collect_register (regcache, regno, addr);
292 amode = addr[0] & 0x80;
293 memcpy (addr, buf + sizeof (long) - size, size);
294 addr[0] &= ~0x80;
295 addr[0] |= amode;
296 supply_register (regcache, regno, addr);
297 }
c642a434
UW
298 else if ((regaddr >= PT_GPR0 && regaddr <= PT_GPR15)
299 || regaddr == PT_ORIGGPR2)
442ea881 300 supply_register (regcache, regno, buf + sizeof (long) - size);
ee1a7ae4 301 else
442ea881 302 supply_register (regcache, regno, buf);
ee1a7ae4 303 }
ab503087 304 else if (regaddr != -1)
442ea881 305 supply_register (regcache, regno, buf);
ee1a7ae4
UW
306}
307
b7149293
UW
308/* Provide only a fill function for the general register set. ps_lgetregs
309 will use this for NPTL support. */
310
3aee8918
PA
311static void
312s390_fill_gregset (struct regcache *regcache, void *buf)
b7149293
UW
313{
314 int i;
3aee8918
PA
315 const struct regs_info *regs_info = (*the_low_target.regs_info) ();
316 struct usrregs_info *usr = regs_info->usrregs;
b7149293 317
3aee8918 318 for (i = 0; i < usr->num_regs; i++)
7803799a 319 {
3aee8918
PA
320 if (usr->regmap[i] < PT_PSWMASK
321 || usr->regmap[i] > PT_ACR15)
7803799a
UW
322 continue;
323
3aee8918
PA
324 s390_collect_ptrace_register (regcache, i,
325 (char *) buf + usr->regmap[i]);
7803799a 326 }
b7149293
UW
327}
328
c642a434
UW
329/* Fill and store functions for extended register sets. */
330
ab503087
MK
331#ifndef __s390x__
332static void
333s390_fill_gprs_high (struct regcache *regcache, void *buf)
334{
335 int r0h = find_regno (regcache->tdesc, "r0h");
336 int i;
337
338 for (i = 0; i < 16; i++)
339 collect_register (regcache, r0h + 2 * i, (char *) buf + 4 * i);
340}
341
342static void
343s390_store_gprs_high (struct regcache *regcache, const void *buf)
344{
345 int r0h = find_regno (regcache->tdesc, "r0h");
346 int i;
347
348 for (i = 0; i < 16; i++)
349 supply_register (regcache, r0h + 2 * i, (const char *) buf + 4 * i);
350}
351#endif
352
c642a434
UW
353static void
354s390_store_last_break (struct regcache *regcache, const void *buf)
355{
3aee8918
PA
356 const char *p;
357
358 p = (const char *) buf + 8 - register_size (regcache->tdesc, 0);
359 supply_register_by_name (regcache, "last_break", p);
c642a434
UW
360}
361
362static void
363s390_fill_system_call (struct regcache *regcache, void *buf)
364{
365 collect_register_by_name (regcache, "system_call", buf);
366}
367
368static void
369s390_store_system_call (struct regcache *regcache, const void *buf)
370{
371 supply_register_by_name (regcache, "system_call", buf);
372}
373
e5a9158d
AA
374static void
375s390_store_tdb (struct regcache *regcache, const void *buf)
376{
377 int tdb0 = find_regno (regcache->tdesc, "tdb0");
378 int tr0 = find_regno (regcache->tdesc, "tr0");
379 int i;
380
381 for (i = 0; i < 4; i++)
382 supply_register (regcache, tdb0 + i, (const char *) buf + 8 * i);
383
384 for (i = 0; i < 16; i++)
385 supply_register (regcache, tr0 + i, (const char *) buf + 8 * (16 + i));
386}
387
bf2d68ab
AA
388static void
389s390_fill_vxrs_low (struct regcache *regcache, void *buf)
390{
391 int v0 = find_regno (regcache->tdesc, "v0l");
392 int i;
393
394 for (i = 0; i < 16; i++)
395 collect_register (regcache, v0 + i, (char *) buf + 8 * i);
396}
397
398static void
399s390_store_vxrs_low (struct regcache *regcache, const void *buf)
400{
401 int v0 = find_regno (regcache->tdesc, "v0l");
402 int i;
403
404 for (i = 0; i < 16; i++)
405 supply_register (regcache, v0 + i, (const char *) buf + 8 * i);
406}
407
408static void
409s390_fill_vxrs_high (struct regcache *regcache, void *buf)
410{
411 int v16 = find_regno (regcache->tdesc, "v16");
412 int i;
413
414 for (i = 0; i < 16; i++)
415 collect_register (regcache, v16 + i, (char *) buf + 16 * i);
416}
417
418static void
419s390_store_vxrs_high (struct regcache *regcache, const void *buf)
420{
421 int v16 = find_regno (regcache->tdesc, "v16");
422 int i;
423
424 for (i = 0; i < 16; i++)
425 supply_register (regcache, v16 + i, (const char *) buf + 16 * i);
426}
427
3aee8918 428static struct regset_info s390_regsets[] = {
1570b33e 429 { 0, 0, 0, 0, GENERAL_REGS, s390_fill_gregset, NULL },
ab503087
MK
430#ifndef __s390x__
431 { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_S390_HIGH_GPRS, 0,
432 EXTENDED_REGS, s390_fill_gprs_high, s390_store_gprs_high },
433#endif
feea5f36
AA
434 /* Last break address is read-only; no fill function. */
435 { PTRACE_GETREGSET, -1, NT_S390_LAST_BREAK, 0, EXTENDED_REGS,
436 NULL, s390_store_last_break },
c642a434
UW
437 { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_S390_SYSTEM_CALL, 0,
438 EXTENDED_REGS, s390_fill_system_call, s390_store_system_call },
e5a9158d
AA
439 /* TDB is read-only. */
440 { PTRACE_GETREGSET, -1, NT_S390_TDB, 0, EXTENDED_REGS,
441 NULL, s390_store_tdb },
bf2d68ab
AA
442 { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_S390_VXRS_LOW, 0,
443 EXTENDED_REGS, s390_fill_vxrs_low, s390_store_vxrs_low },
444 { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_S390_VXRS_HIGH, 0,
445 EXTENDED_REGS, s390_fill_vxrs_high, s390_store_vxrs_high },
50bc912a 446 NULL_REGSET
b7149293
UW
447};
448
b0ded00b 449
dd373349 450static const gdb_byte s390_breakpoint[] = { 0, 1 };
b0ded00b
UW
451#define s390_breakpoint_len 2
452
dd373349
AT
453/* Implementation of linux_target_ops method "sw_breakpoint_from_kind". */
454
455static const gdb_byte *
456s390_sw_breakpoint_from_kind (int kind, int *size)
457{
458 *size = s390_breakpoint_len;
459 return s390_breakpoint;
460}
461
b0ded00b 462static CORE_ADDR
442ea881 463s390_get_pc (struct regcache *regcache)
b0ded00b 464{
3aee8918 465 if (register_size (regcache->tdesc, 0) == 4)
d61ddec4 466 {
d6db1fab
UW
467 unsigned int pswa;
468 collect_register_by_name (regcache, "pswa", &pswa);
469 return pswa & 0x7fffffff;
d61ddec4
UW
470 }
471 else
472 {
473 unsigned long pc;
442ea881 474 collect_register_by_name (regcache, "pswa", &pc);
d61ddec4
UW
475 return pc;
476 }
b0ded00b
UW
477}
478
479static void
442ea881 480s390_set_pc (struct regcache *regcache, CORE_ADDR newpc)
b0ded00b 481{
3aee8918 482 if (register_size (regcache->tdesc, 0) == 4)
d61ddec4 483 {
d6db1fab
UW
484 unsigned int pswa;
485 collect_register_by_name (regcache, "pswa", &pswa);
486 pswa = (pswa & 0x80000000) | (newpc & 0x7fffffff);
487 supply_register_by_name (regcache, "pswa", &pswa);
d61ddec4
UW
488 }
489 else
490 {
491 unsigned long pc = newpc;
442ea881 492 supply_register_by_name (regcache, "pswa", &pc);
d61ddec4 493 }
b0ded00b
UW
494}
495
7803799a 496static unsigned long
3aee8918 497s390_get_hwcap (const struct target_desc *tdesc)
7803799a 498{
3aee8918 499 int wordsize = register_size (tdesc, 0);
7803799a
UW
500 unsigned char *data = alloca (2 * wordsize);
501 int offset = 0;
502
503 while ((*the_target->read_auxv) (offset, data, 2 * wordsize) == 2 * wordsize)
504 {
505 if (wordsize == 4)
506 {
507 unsigned int *data_p = (unsigned int *)data;
508 if (data_p[0] == AT_HWCAP)
509 return data_p[1];
510 }
511 else
512 {
513 unsigned long *data_p = (unsigned long *)data;
514 if (data_p[0] == AT_HWCAP)
515 return data_p[1];
516 }
517
518 offset += 2 * wordsize;
519 }
520
521 return 0;
522}
d61ddec4 523
c642a434
UW
524static int
525s390_check_regset (int pid, int regset, int regsize)
526{
527 gdb_byte *buf = alloca (regsize);
528 struct iovec iov;
529
530 iov.iov_base = buf;
531 iov.iov_len = regsize;
532
4ac33720
UW
533 if (ptrace (PTRACE_GETREGSET, pid, (long) regset, (long) &iov) >= 0
534 || errno == ENODATA)
c642a434 535 return 1;
4ac33720 536 return 0;
c642a434
UW
537}
538
3aee8918
PA
539/* For a 31-bit inferior, whether the kernel supports using the full
540 64-bit GPRs. */
541static int have_hwcap_s390_high_gprs = 0;
3aee8918 542
d61ddec4
UW
543static void
544s390_arch_setup (void)
545{
3aee8918 546 const struct target_desc *tdesc;
c642a434
UW
547 struct regset_info *regset;
548
549 /* Check whether the kernel supports extra register sets. */
0bfdf32f 550 int pid = pid_of (current_thread);
c642a434
UW
551 int have_regset_last_break
552 = s390_check_regset (pid, NT_S390_LAST_BREAK, 8);
553 int have_regset_system_call
554 = s390_check_regset (pid, NT_S390_SYSTEM_CALL, 4);
4ac33720 555 int have_regset_tdb = s390_check_regset (pid, NT_S390_TDB, 256);
bf2d68ab
AA
556 int have_regset_vxrs = s390_check_regset (pid, NT_S390_VXRS_LOW, 128)
557 && s390_check_regset (pid, NT_S390_VXRS_HIGH, 256);
c642a434 558
d61ddec4 559 /* Assume 31-bit inferior process. */
c642a434 560 if (have_regset_system_call)
3aee8918 561 tdesc = tdesc_s390_linux32v2;
c642a434 562 else if (have_regset_last_break)
3aee8918 563 tdesc = tdesc_s390_linux32v1;
c642a434 564 else
3aee8918 565 tdesc = tdesc_s390_linux32;
d61ddec4
UW
566
567 /* On a 64-bit host, check the low bit of the (31-bit) PSWM
568 -- if this is one, we actually have a 64-bit inferior. */
d61ddec4 569 {
ab503087 570#ifdef __s390x__
d61ddec4 571 unsigned int pswm;
3aee8918 572 struct regcache *regcache = new_register_cache (tdesc);
6682d959 573
3aee8918 574 fetch_inferior_registers (regcache, find_regno (tdesc, "pswm"));
442ea881 575 collect_register_by_name (regcache, "pswm", &pswm);
92b72907
UW
576 free_register_cache (regcache);
577
d61ddec4 578 if (pswm & 1)
c642a434 579 {
6682d959
AA
580 if (have_regset_tdb)
581 have_regset_tdb =
582 (s390_get_hwcap (tdesc_s390x_linux64v2) & HWCAP_S390_TE) != 0;
bf2d68ab
AA
583 if (have_regset_vxrs)
584 have_regset_vxrs =
585 (s390_get_hwcap (tdesc_s390x_linux64v2) & HWCAP_S390_VX) != 0;
586
587 if (have_regset_vxrs)
588 tdesc = (have_regset_tdb ? tdesc_s390x_tevx_linux64 :
589 tdesc_s390x_vx_linux64);
590 else if (have_regset_tdb)
4ac33720 591 tdesc = tdesc_s390x_te_linux64;
6682d959 592 else if (have_regset_system_call)
3aee8918 593 tdesc = tdesc_s390x_linux64v2;
c642a434 594 else if (have_regset_last_break)
3aee8918 595 tdesc = tdesc_s390x_linux64v1;
c642a434 596 else
3aee8918 597 tdesc = tdesc_s390x_linux64;
c642a434 598 }
7803799a
UW
599
600 /* For a 31-bit inferior, check whether the kernel supports
601 using the full 64-bit GPRs. */
ab503087
MK
602 else
603#endif
604 if (s390_get_hwcap (tdesc) & HWCAP_S390_HIGH_GPRS)
7803799a 605 {
3aee8918 606 have_hwcap_s390_high_gprs = 1;
6682d959
AA
607 if (have_regset_tdb)
608 have_regset_tdb = (s390_get_hwcap (tdesc) & HWCAP_S390_TE) != 0;
bf2d68ab
AA
609 if (have_regset_vxrs)
610 have_regset_vxrs = (s390_get_hwcap (tdesc) & HWCAP_S390_VX) != 0;
3aee8918 611
bf2d68ab
AA
612 if (have_regset_vxrs)
613 tdesc = (have_regset_tdb ? tdesc_s390_tevx_linux64 :
614 tdesc_s390_vx_linux64);
615 else if (have_regset_tdb)
4ac33720
UW
616 tdesc = tdesc_s390_te_linux64;
617 else if (have_regset_system_call)
3aee8918 618 tdesc = tdesc_s390_linux64v2;
c642a434 619 else if (have_regset_last_break)
3aee8918 620 tdesc = tdesc_s390_linux64v1;
c642a434 621 else
3aee8918 622 tdesc = tdesc_s390_linux64;
7803799a 623 }
d61ddec4 624 }
6682d959
AA
625
626 /* Update target_regsets according to available register sets. */
feea5f36 627 for (regset = s390_regsets; regset->size >= 0; regset++)
6682d959
AA
628 if (regset->get_request == PTRACE_GETREGSET)
629 switch (regset->nt_type)
630 {
ab503087
MK
631#ifndef __s390x__
632 case NT_S390_HIGH_GPRS:
633 regset->size = have_hwcap_s390_high_gprs ? 64 : 0;
634 break;
635#endif
6682d959 636 case NT_S390_LAST_BREAK:
ab503087 637 regset->size = have_regset_last_break ? 8 : 0;
6682d959
AA
638 break;
639 case NT_S390_SYSTEM_CALL:
ab503087 640 regset->size = have_regset_system_call ? 4 : 0;
6682d959
AA
641 break;
642 case NT_S390_TDB:
643 regset->size = have_regset_tdb ? 256 : 0;
bf2d68ab
AA
644 break;
645 case NT_S390_VXRS_LOW:
646 regset->size = have_regset_vxrs ? 128 : 0;
647 break;
648 case NT_S390_VXRS_HIGH:
649 regset->size = have_regset_vxrs ? 256 : 0;
650 break;
6682d959
AA
651 default:
652 break;
653 }
654
3aee8918 655 current_process ()->tdesc = tdesc;
d61ddec4
UW
656}
657
658
b0ded00b
UW
659static int
660s390_breakpoint_at (CORE_ADDR pc)
661{
662 unsigned char c[s390_breakpoint_len];
663 read_inferior_memory (pc, c, s390_breakpoint_len);
664 return memcmp (c, s390_breakpoint, s390_breakpoint_len) == 0;
665}
666
b00b61e1
MK
667/* Breakpoint/Watchpoint support. */
668
669/* The "supports_z_point_type" linux_target_ops method. */
670
671static int
672s390_supports_z_point_type (char z_type)
673{
674 switch (z_type)
675 {
676 case Z_PACKET_SW_BP:
677 return 1;
678 default:
679 return 0;
680 }
681}
682
7d00775e
AT
683/* Support for hardware single step. */
684
685static int
686s390_supports_hardware_single_step (void)
687{
688 return 1;
689}
690
3aee8918
PA
691static struct usrregs_info s390_usrregs_info =
692 {
693 s390_num_regs,
694 s390_regmap,
695 };
696
697static struct regsets_info s390_regsets_info =
698 {
699 s390_regsets, /* regsets */
700 0, /* num_regsets */
701 NULL, /* disabled_regsets */
702 };
703
704static struct regs_info regs_info =
705 {
706 NULL, /* regset_bitmap */
707 &s390_usrregs_info,
708 &s390_regsets_info
709 };
710
3aee8918
PA
711static struct usrregs_info s390_usrregs_info_3264 =
712 {
713 s390_num_regs_3264,
714 s390_regmap_3264
715 };
716
717static struct regsets_info s390_regsets_info_3264 =
718 {
719 s390_regsets, /* regsets */
720 0, /* num_regsets */
721 NULL, /* disabled_regsets */
722 };
723
724static struct regs_info regs_info_3264 =
725 {
726 NULL, /* regset_bitmap */
727 &s390_usrregs_info_3264,
728 &s390_regsets_info_3264
729 };
3aee8918
PA
730
731static const struct regs_info *
732s390_regs_info (void)
733{
3aee8918
PA
734 if (have_hwcap_s390_high_gprs)
735 {
ab503087 736#ifdef __s390x__
3aee8918
PA
737 const struct target_desc *tdesc = current_process ()->tdesc;
738
739 if (register_size (tdesc, 0) == 4)
740 return &regs_info_3264;
ab503087
MK
741#else
742 return &regs_info_3264;
3aee8918 743#endif
ab503087 744 }
3aee8918
PA
745 return &regs_info;
746}
b0ded00b 747
a4105d04
MK
748/* The "supports_tracepoints" linux_target_ops method. */
749
750static int
751s390_supports_tracepoints (void)
752{
753 return 1;
754}
755
2ec06d2e 756struct linux_target_ops the_low_target = {
d61ddec4 757 s390_arch_setup,
3aee8918 758 s390_regs_info,
2ec06d2e
DJ
759 s390_cannot_fetch_register,
760 s390_cannot_store_register,
c14dfd32 761 NULL, /* fetch_register */
b0ded00b
UW
762 s390_get_pc,
763 s390_set_pc,
dd373349
AT
764 NULL, /* breakpoint_kind_from_pc */
765 s390_sw_breakpoint_from_kind,
b0ded00b
UW
766 NULL,
767 s390_breakpoint_len,
768 s390_breakpoint_at,
b00b61e1 769 s390_supports_z_point_type,
ee1a7ae4
UW
770 NULL,
771 NULL,
772 NULL,
773 NULL,
774 s390_collect_ptrace_register,
775 s390_supply_ptrace_register,
7d00775e
AT
776 NULL, /* siginfo_fixup */
777 NULL, /* new_process */
778 NULL, /* new_thread */
779 NULL, /* new_fork */
780 NULL, /* prepare_to_resume */
781 NULL, /* process_qsupported */
a4105d04 782 s390_supports_tracepoints,
7d00775e
AT
783 NULL, /* get_thread_area */
784 NULL, /* install_fast_tracepoint_jump_pad */
785 NULL, /* emit_ops */
786 NULL, /* get_min_fast_tracepoint_insn_len */
787 NULL, /* supports_range_stepping */
788 NULL, /* breakpoint_kind_from_current_state */
789 s390_supports_hardware_single_step,
2ec06d2e 790};
3aee8918
PA
791
792void
793initialize_low_arch (void)
794{
795 /* Initialize the Linux target descriptions. */
796
797 init_registers_s390_linux32 ();
798 init_registers_s390_linux32v1 ();
799 init_registers_s390_linux32v2 ();
800 init_registers_s390_linux64 ();
801 init_registers_s390_linux64v1 ();
802 init_registers_s390_linux64v2 ();
4ac33720 803 init_registers_s390_te_linux64 ();
bf2d68ab
AA
804 init_registers_s390_vx_linux64 ();
805 init_registers_s390_tevx_linux64 ();
3aee8918
PA
806 init_registers_s390x_linux64 ();
807 init_registers_s390x_linux64v1 ();
808 init_registers_s390x_linux64v2 ();
4ac33720 809 init_registers_s390x_te_linux64 ();
bf2d68ab
AA
810 init_registers_s390x_vx_linux64 ();
811 init_registers_s390x_tevx_linux64 ();
3aee8918
PA
812
813 initialize_regsets_info (&s390_regsets_info);
3aee8918 814 initialize_regsets_info (&s390_regsets_info_3264);
3aee8918 815}
This page took 1.06301 seconds and 4 git commands to generate.