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