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