Fix typo in spelling of author's name.
[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>
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 },
1570b33e 393 { 0, 0, 0, -1, -1, NULL, NULL }
b7149293
UW
394};
395
b0ded00b 396
f450004a 397static const unsigned char s390_breakpoint[] = { 0, 1 };
b0ded00b
UW
398#define s390_breakpoint_len 2
399
400static CORE_ADDR
442ea881 401s390_get_pc (struct regcache *regcache)
b0ded00b 402{
3aee8918 403 if (register_size (regcache->tdesc, 0) == 4)
d61ddec4 404 {
d6db1fab
UW
405 unsigned int pswa;
406 collect_register_by_name (regcache, "pswa", &pswa);
407 return pswa & 0x7fffffff;
d61ddec4
UW
408 }
409 else
410 {
411 unsigned long pc;
442ea881 412 collect_register_by_name (regcache, "pswa", &pc);
d61ddec4
UW
413 return pc;
414 }
b0ded00b
UW
415}
416
417static void
442ea881 418s390_set_pc (struct regcache *regcache, CORE_ADDR newpc)
b0ded00b 419{
3aee8918 420 if (register_size (regcache->tdesc, 0) == 4)
d61ddec4 421 {
d6db1fab
UW
422 unsigned int pswa;
423 collect_register_by_name (regcache, "pswa", &pswa);
424 pswa = (pswa & 0x80000000) | (newpc & 0x7fffffff);
425 supply_register_by_name (regcache, "pswa", &pswa);
d61ddec4
UW
426 }
427 else
428 {
429 unsigned long pc = newpc;
442ea881 430 supply_register_by_name (regcache, "pswa", &pc);
d61ddec4 431 }
b0ded00b
UW
432}
433
7803799a
UW
434#ifdef __s390x__
435static unsigned long
3aee8918 436s390_get_hwcap (const struct target_desc *tdesc)
7803799a 437{
3aee8918 438 int wordsize = register_size (tdesc, 0);
7803799a
UW
439 unsigned char *data = alloca (2 * wordsize);
440 int offset = 0;
441
442 while ((*the_target->read_auxv) (offset, data, 2 * wordsize) == 2 * wordsize)
443 {
444 if (wordsize == 4)
445 {
446 unsigned int *data_p = (unsigned int *)data;
447 if (data_p[0] == AT_HWCAP)
448 return data_p[1];
449 }
450 else
451 {
452 unsigned long *data_p = (unsigned long *)data;
453 if (data_p[0] == AT_HWCAP)
454 return data_p[1];
455 }
456
457 offset += 2 * wordsize;
458 }
459
460 return 0;
461}
462#endif
d61ddec4 463
c642a434
UW
464static int
465s390_check_regset (int pid, int regset, int regsize)
466{
467 gdb_byte *buf = alloca (regsize);
468 struct iovec iov;
469
470 iov.iov_base = buf;
471 iov.iov_len = regsize;
472
4ac33720
UW
473 if (ptrace (PTRACE_GETREGSET, pid, (long) regset, (long) &iov) >= 0
474 || errno == ENODATA)
c642a434 475 return 1;
4ac33720 476 return 0;
c642a434
UW
477}
478
3aee8918
PA
479#ifdef __s390x__
480/* For a 31-bit inferior, whether the kernel supports using the full
481 64-bit GPRs. */
482static int have_hwcap_s390_high_gprs = 0;
483#endif
484
d61ddec4
UW
485static void
486s390_arch_setup (void)
487{
3aee8918 488 const struct target_desc *tdesc;
c642a434
UW
489 struct regset_info *regset;
490
491 /* Check whether the kernel supports extra register sets. */
0bfdf32f 492 int pid = pid_of (current_thread);
c642a434
UW
493 int have_regset_last_break
494 = s390_check_regset (pid, NT_S390_LAST_BREAK, 8);
495 int have_regset_system_call
496 = s390_check_regset (pid, NT_S390_SYSTEM_CALL, 4);
4ac33720 497 int have_regset_tdb = s390_check_regset (pid, NT_S390_TDB, 256);
bf2d68ab
AA
498 int have_regset_vxrs = s390_check_regset (pid, NT_S390_VXRS_LOW, 128)
499 && s390_check_regset (pid, NT_S390_VXRS_HIGH, 256);
c642a434 500
d61ddec4 501 /* Assume 31-bit inferior process. */
c642a434 502 if (have_regset_system_call)
3aee8918 503 tdesc = tdesc_s390_linux32v2;
c642a434 504 else if (have_regset_last_break)
3aee8918 505 tdesc = tdesc_s390_linux32v1;
c642a434 506 else
3aee8918 507 tdesc = tdesc_s390_linux32;
d61ddec4
UW
508
509 /* On a 64-bit host, check the low bit of the (31-bit) PSWM
510 -- if this is one, we actually have a 64-bit inferior. */
511#ifdef __s390x__
512 {
513 unsigned int pswm;
3aee8918 514 struct regcache *regcache = new_register_cache (tdesc);
6682d959 515
3aee8918 516 fetch_inferior_registers (regcache, find_regno (tdesc, "pswm"));
442ea881 517 collect_register_by_name (regcache, "pswm", &pswm);
92b72907
UW
518 free_register_cache (regcache);
519
d61ddec4 520 if (pswm & 1)
c642a434 521 {
6682d959
AA
522 if (have_regset_tdb)
523 have_regset_tdb =
524 (s390_get_hwcap (tdesc_s390x_linux64v2) & HWCAP_S390_TE) != 0;
bf2d68ab
AA
525 if (have_regset_vxrs)
526 have_regset_vxrs =
527 (s390_get_hwcap (tdesc_s390x_linux64v2) & HWCAP_S390_VX) != 0;
528
529 if (have_regset_vxrs)
530 tdesc = (have_regset_tdb ? tdesc_s390x_tevx_linux64 :
531 tdesc_s390x_vx_linux64);
532 else if (have_regset_tdb)
4ac33720 533 tdesc = tdesc_s390x_te_linux64;
6682d959 534 else if (have_regset_system_call)
3aee8918 535 tdesc = tdesc_s390x_linux64v2;
c642a434 536 else if (have_regset_last_break)
3aee8918 537 tdesc = tdesc_s390x_linux64v1;
c642a434 538 else
3aee8918 539 tdesc = tdesc_s390x_linux64;
c642a434 540 }
7803799a
UW
541
542 /* For a 31-bit inferior, check whether the kernel supports
543 using the full 64-bit GPRs. */
3aee8918 544 else if (s390_get_hwcap (tdesc) & HWCAP_S390_HIGH_GPRS)
7803799a 545 {
3aee8918 546 have_hwcap_s390_high_gprs = 1;
6682d959
AA
547 if (have_regset_tdb)
548 have_regset_tdb = (s390_get_hwcap (tdesc) & HWCAP_S390_TE) != 0;
bf2d68ab
AA
549 if (have_regset_vxrs)
550 have_regset_vxrs = (s390_get_hwcap (tdesc) & HWCAP_S390_VX) != 0;
3aee8918 551
bf2d68ab
AA
552 if (have_regset_vxrs)
553 tdesc = (have_regset_tdb ? tdesc_s390_tevx_linux64 :
554 tdesc_s390_vx_linux64);
555 else if (have_regset_tdb)
4ac33720
UW
556 tdesc = tdesc_s390_te_linux64;
557 else if (have_regset_system_call)
3aee8918 558 tdesc = tdesc_s390_linux64v2;
c642a434 559 else if (have_regset_last_break)
3aee8918 560 tdesc = tdesc_s390_linux64v1;
c642a434 561 else
3aee8918 562 tdesc = tdesc_s390_linux64;
7803799a 563 }
d61ddec4
UW
564 }
565#endif
6682d959
AA
566
567 /* Update target_regsets according to available register sets. */
feea5f36 568 for (regset = s390_regsets; regset->size >= 0; regset++)
6682d959
AA
569 if (regset->get_request == PTRACE_GETREGSET)
570 switch (regset->nt_type)
571 {
572 case NT_S390_LAST_BREAK:
573 regset->size = have_regset_last_break? 8 : 0;
574 break;
575 case NT_S390_SYSTEM_CALL:
576 regset->size = have_regset_system_call? 4 : 0;
577 break;
578 case NT_S390_TDB:
579 regset->size = have_regset_tdb ? 256 : 0;
bf2d68ab
AA
580 break;
581 case NT_S390_VXRS_LOW:
582 regset->size = have_regset_vxrs ? 128 : 0;
583 break;
584 case NT_S390_VXRS_HIGH:
585 regset->size = have_regset_vxrs ? 256 : 0;
586 break;
6682d959
AA
587 default:
588 break;
589 }
590
3aee8918 591 current_process ()->tdesc = tdesc;
d61ddec4
UW
592}
593
594
b0ded00b
UW
595static int
596s390_breakpoint_at (CORE_ADDR pc)
597{
598 unsigned char c[s390_breakpoint_len];
599 read_inferior_memory (pc, c, s390_breakpoint_len);
600 return memcmp (c, s390_breakpoint, s390_breakpoint_len) == 0;
601}
602
3aee8918
PA
603static struct usrregs_info s390_usrregs_info =
604 {
605 s390_num_regs,
606 s390_regmap,
607 };
608
609static struct regsets_info s390_regsets_info =
610 {
611 s390_regsets, /* regsets */
612 0, /* num_regsets */
613 NULL, /* disabled_regsets */
614 };
615
616static struct regs_info regs_info =
617 {
618 NULL, /* regset_bitmap */
619 &s390_usrregs_info,
620 &s390_regsets_info
621 };
622
623#ifdef __s390x__
624static struct usrregs_info s390_usrregs_info_3264 =
625 {
626 s390_num_regs_3264,
627 s390_regmap_3264
628 };
629
630static struct regsets_info s390_regsets_info_3264 =
631 {
632 s390_regsets, /* regsets */
633 0, /* num_regsets */
634 NULL, /* disabled_regsets */
635 };
636
637static struct regs_info regs_info_3264 =
638 {
639 NULL, /* regset_bitmap */
640 &s390_usrregs_info_3264,
641 &s390_regsets_info_3264
642 };
643#endif
644
645static const struct regs_info *
646s390_regs_info (void)
647{
648#ifdef __s390x__
649 if (have_hwcap_s390_high_gprs)
650 {
651 const struct target_desc *tdesc = current_process ()->tdesc;
652
653 if (register_size (tdesc, 0) == 4)
654 return &regs_info_3264;
655 }
656#endif
657 return &regs_info;
658}
b0ded00b 659
2ec06d2e 660struct linux_target_ops the_low_target = {
d61ddec4 661 s390_arch_setup,
3aee8918 662 s390_regs_info,
2ec06d2e
DJ
663 s390_cannot_fetch_register,
664 s390_cannot_store_register,
c14dfd32 665 NULL, /* fetch_register */
b0ded00b
UW
666 s390_get_pc,
667 s390_set_pc,
668 s390_breakpoint,
669 s390_breakpoint_len,
670 NULL,
671 s390_breakpoint_len,
672 s390_breakpoint_at,
802e8e6d 673 NULL, /* supports_z_point_type */
ee1a7ae4
UW
674 NULL,
675 NULL,
676 NULL,
677 NULL,
678 s390_collect_ptrace_register,
679 s390_supply_ptrace_register,
2ec06d2e 680};
3aee8918
PA
681
682void
683initialize_low_arch (void)
684{
685 /* Initialize the Linux target descriptions. */
686
687 init_registers_s390_linux32 ();
688 init_registers_s390_linux32v1 ();
689 init_registers_s390_linux32v2 ();
690 init_registers_s390_linux64 ();
691 init_registers_s390_linux64v1 ();
692 init_registers_s390_linux64v2 ();
4ac33720 693 init_registers_s390_te_linux64 ();
bf2d68ab
AA
694 init_registers_s390_vx_linux64 ();
695 init_registers_s390_tevx_linux64 ();
3aee8918
PA
696 init_registers_s390x_linux64 ();
697 init_registers_s390x_linux64v1 ();
698 init_registers_s390x_linux64v2 ();
4ac33720 699 init_registers_s390x_te_linux64 ();
bf2d68ab
AA
700 init_registers_s390x_vx_linux64 ();
701 init_registers_s390x_tevx_linux64 ();
3aee8918
PA
702
703 initialize_regsets_info (&s390_regsets_info);
704#ifdef __s390x__
705 initialize_regsets_info (&s390_regsets_info_3264);
706#endif
707}
This page took 1.06293 seconds and 4 git commands to generate.