Update copyright year in gdb/gdbserver/gdbreplay version output.
[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.
0b302171 3 Copyright (C) 2001-2002, 2005-2012 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
c642a434
UW
35#ifndef PTRACE_GETREGSET
36#define PTRACE_GETREGSET 0x4204
37#endif
38
39#ifndef PTRACE_SETREGSET
40#define PTRACE_SETREGSET 0x4205
41#endif
42
7803799a
UW
43/* Defined in auto-generated file s390-linux32.c. */
44void init_registers_s390_linux32 (void);
c642a434
UW
45/* Defined in auto-generated file s390-linux32v1.c. */
46void init_registers_s390_linux32v1 (void);
47/* Defined in auto-generated file s390-linux32v2.c. */
48void init_registers_s390_linux32v2 (void);
7803799a
UW
49/* Defined in auto-generated file s390-linux64.c. */
50void init_registers_s390_linux64 (void);
c642a434
UW
51/* Defined in auto-generated file s390-linux64v1.c. */
52void init_registers_s390_linux64v1 (void);
53/* Defined in auto-generated file s390-linux64v2.c. */
54void init_registers_s390_linux64v2 (void);
7803799a
UW
55/* Defined in auto-generated file s390x-linux64.c. */
56void init_registers_s390x_linux64 (void);
c642a434
UW
57/* Defined in auto-generated file s390x-linux64v1.c. */
58void init_registers_s390x_linux64v1 (void);
59/* Defined in auto-generated file s390x-linux64v2.c. */
60void init_registers_s390x_linux64v2 (void);
d05b4ac3 61
c642a434 62#define s390_num_regs 52
265f716b 63
2ec06d2e 64static int s390_regmap[] = {
265f716b
DJ
65 PT_PSWMASK, PT_PSWADDR,
66
67 PT_GPR0, PT_GPR1, PT_GPR2, PT_GPR3,
68 PT_GPR4, PT_GPR5, PT_GPR6, PT_GPR7,
69 PT_GPR8, PT_GPR9, PT_GPR10, PT_GPR11,
70 PT_GPR12, PT_GPR13, PT_GPR14, PT_GPR15,
71
72 PT_ACR0, PT_ACR1, PT_ACR2, PT_ACR3,
73 PT_ACR4, PT_ACR5, PT_ACR6, PT_ACR7,
74 PT_ACR8, PT_ACR9, PT_ACR10, PT_ACR11,
75 PT_ACR12, PT_ACR13, PT_ACR14, PT_ACR15,
76
265f716b
DJ
77 PT_FPC,
78
d0f54f9d 79#ifndef __s390x__
265f716b
DJ
80 PT_FPR0_HI, PT_FPR1_HI, PT_FPR2_HI, PT_FPR3_HI,
81 PT_FPR4_HI, PT_FPR5_HI, PT_FPR6_HI, PT_FPR7_HI,
82 PT_FPR8_HI, PT_FPR9_HI, PT_FPR10_HI, PT_FPR11_HI,
83 PT_FPR12_HI, PT_FPR13_HI, PT_FPR14_HI, PT_FPR15_HI,
84#else
85 PT_FPR0, PT_FPR1, PT_FPR2, PT_FPR3,
86 PT_FPR4, PT_FPR5, PT_FPR6, PT_FPR7,
87 PT_FPR8, PT_FPR9, PT_FPR10, PT_FPR11,
88 PT_FPR12, PT_FPR13, PT_FPR14, PT_FPR15,
89#endif
c642a434
UW
90
91 PT_ORIGGPR2,
265f716b
DJ
92};
93
7803799a 94#ifdef __s390x__
c642a434 95#define s390_num_regs_3264 68
7803799a
UW
96
97static int s390_regmap_3264[] = {
98 PT_PSWMASK, PT_PSWADDR,
99
493e2a69
MS
100 PT_GPR0, PT_GPR0, PT_GPR1, PT_GPR1,
101 PT_GPR2, PT_GPR2, PT_GPR3, PT_GPR3,
102 PT_GPR4, PT_GPR4, PT_GPR5, PT_GPR5,
103 PT_GPR6, PT_GPR6, PT_GPR7, PT_GPR7,
104 PT_GPR8, PT_GPR8, PT_GPR9, PT_GPR9,
105 PT_GPR10, PT_GPR10, PT_GPR11, PT_GPR11,
106 PT_GPR12, PT_GPR12, PT_GPR13, PT_GPR13,
107 PT_GPR14, PT_GPR14, PT_GPR15, PT_GPR15,
7803799a
UW
108
109 PT_ACR0, PT_ACR1, PT_ACR2, PT_ACR3,
110 PT_ACR4, PT_ACR5, PT_ACR6, PT_ACR7,
111 PT_ACR8, PT_ACR9, PT_ACR10, PT_ACR11,
112 PT_ACR12, PT_ACR13, PT_ACR14, PT_ACR15,
113
114 PT_FPC,
115
116 PT_FPR0, PT_FPR1, PT_FPR2, PT_FPR3,
117 PT_FPR4, PT_FPR5, PT_FPR6, PT_FPR7,
118 PT_FPR8, PT_FPR9, PT_FPR10, PT_FPR11,
119 PT_FPR12, PT_FPR13, PT_FPR14, PT_FPR15,
c642a434
UW
120
121 PT_ORIGGPR2,
7803799a
UW
122};
123#endif
124
125
2ec06d2e
DJ
126static int
127s390_cannot_fetch_register (int regno)
265f716b 128{
265f716b
DJ
129 return 0;
130}
131
2ec06d2e
DJ
132static int
133s390_cannot_store_register (int regno)
265f716b 134{
265f716b
DJ
135 return 0;
136}
2ec06d2e 137
ee1a7ae4 138static void
442ea881 139s390_collect_ptrace_register (struct regcache *regcache, int regno, char *buf)
ee1a7ae4
UW
140{
141 int size = register_size (regno);
142 if (size < sizeof (long))
143 {
7803799a
UW
144 int regaddr = the_low_target.regmap[regno];
145
ee1a7ae4
UW
146 memset (buf, 0, sizeof (long));
147
7803799a
UW
148 if ((regno ^ 1) < the_low_target.num_regs
149 && the_low_target.regmap[regno ^ 1] == regaddr)
150 {
18f5de3b
JK
151 collect_register (regcache, regno & ~1, buf);
152 collect_register (regcache, (regno & ~1) + 1,
153 buf + sizeof (long) - size);
7803799a 154 }
d6db1fab
UW
155 else if (regaddr == PT_PSWMASK)
156 {
157 /* Convert 4-byte PSW mask to 8 bytes by clearing bit 12 and copying
158 the basic addressing mode bit from the PSW address. */
159 char *addr = alloca (register_size (regno ^ 1));
160 collect_register (regcache, regno, buf);
161 collect_register (regcache, regno ^ 1, addr);
162 buf[1] &= ~0x8;
163 buf[size] |= (addr[0] & 0x80);
164 }
165 else if (regaddr == PT_PSWADDR)
166 {
167 /* Convert 4-byte PSW address to 8 bytes by clearing the addressing
168 mode bit (which gets copied to the PSW mask instead). */
169 collect_register (regcache, regno, buf + sizeof (long) - size);
170 buf[sizeof (long) - size] &= ~0x80;
171 }
c642a434
UW
172 else if ((regaddr >= PT_GPR0 && regaddr <= PT_GPR15)
173 || regaddr == PT_ORIGGPR2)
442ea881 174 collect_register (regcache, regno, buf + sizeof (long) - size);
ee1a7ae4 175 else
442ea881 176 collect_register (regcache, regno, buf);
ee1a7ae4
UW
177 }
178 else
18f5de3b 179 collect_register (regcache, regno, buf);
ee1a7ae4
UW
180}
181
182static void
493e2a69
MS
183s390_supply_ptrace_register (struct regcache *regcache,
184 int regno, const char *buf)
ee1a7ae4
UW
185{
186 int size = register_size (regno);
187 if (size < sizeof (long))
188 {
7803799a
UW
189 int regaddr = the_low_target.regmap[regno];
190
191 if ((regno ^ 1) < the_low_target.num_regs
192 && the_low_target.regmap[regno ^ 1] == regaddr)
193 {
18f5de3b
JK
194 supply_register (regcache, regno & ~1, buf);
195 supply_register (regcache, (regno & ~1) + 1,
196 buf + sizeof (long) - size);
7803799a 197 }
d6db1fab
UW
198 else if (regaddr == PT_PSWMASK)
199 {
200 /* Convert 8-byte PSW mask to 4 bytes by setting bit 12 and copying
201 the basic addressing mode into the PSW address. */
202 char *mask = alloca (size);
203 char *addr = alloca (register_size (regno ^ 1));
204 memcpy (mask, buf, size);
205 mask[1] |= 0x8;
206 supply_register (regcache, regno, mask);
207
208 collect_register (regcache, regno ^ 1, addr);
209 addr[0] &= ~0x80;
210 addr[0] |= (buf[size] & 0x80);
211 supply_register (regcache, regno ^ 1, addr);
212 }
213 else if (regaddr == PT_PSWADDR)
214 {
215 /* Convert 8-byte PSW address to 4 bytes by truncating, but
216 keeping the addressing mode bit (which was set from the mask). */
217 char *addr = alloca (size);
218 char amode;
219 collect_register (regcache, regno, addr);
220 amode = addr[0] & 0x80;
221 memcpy (addr, buf + sizeof (long) - size, size);
222 addr[0] &= ~0x80;
223 addr[0] |= amode;
224 supply_register (regcache, regno, addr);
225 }
c642a434
UW
226 else if ((regaddr >= PT_GPR0 && regaddr <= PT_GPR15)
227 || regaddr == PT_ORIGGPR2)
442ea881 228 supply_register (regcache, regno, buf + sizeof (long) - size);
ee1a7ae4 229 else
442ea881 230 supply_register (regcache, regno, buf);
ee1a7ae4
UW
231 }
232 else
442ea881 233 supply_register (regcache, regno, buf);
ee1a7ae4
UW
234}
235
b7149293
UW
236/* Provide only a fill function for the general register set. ps_lgetregs
237 will use this for NPTL support. */
238
442ea881 239static void s390_fill_gregset (struct regcache *regcache, void *buf)
b7149293
UW
240{
241 int i;
242
7803799a
UW
243 for (i = 0; i < the_low_target.num_regs; i++)
244 {
245 if (the_low_target.regmap[i] < PT_PSWMASK
246 || the_low_target.regmap[i] > PT_ACR15)
247 continue;
248
442ea881 249 s390_collect_ptrace_register (regcache, i, (char *) buf
7803799a
UW
250 + the_low_target.regmap[i]);
251 }
b7149293
UW
252}
253
c642a434
UW
254/* Fill and store functions for extended register sets. */
255
256static void
257s390_fill_last_break (struct regcache *regcache, void *buf)
258{
259 /* Last break address is read-only. */
260}
261
262static void
263s390_store_last_break (struct regcache *regcache, const void *buf)
264{
265 supply_register_by_name (regcache, "last_break",
266 (const char *)buf + 8 - register_size (0));
267}
268
269static void
270s390_fill_system_call (struct regcache *regcache, void *buf)
271{
272 collect_register_by_name (regcache, "system_call", buf);
273}
274
275static void
276s390_store_system_call (struct regcache *regcache, const void *buf)
277{
278 supply_register_by_name (regcache, "system_call", buf);
279}
280
b7149293 281struct regset_info target_regsets[] = {
1570b33e 282 { 0, 0, 0, 0, GENERAL_REGS, s390_fill_gregset, NULL },
c642a434
UW
283 /* Last break address is read-only; do not attempt PTRACE_SETREGSET. */
284 { PTRACE_GETREGSET, PTRACE_GETREGSET, NT_S390_LAST_BREAK, 0,
285 EXTENDED_REGS, s390_fill_last_break, s390_store_last_break },
286 { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_S390_SYSTEM_CALL, 0,
287 EXTENDED_REGS, s390_fill_system_call, s390_store_system_call },
1570b33e 288 { 0, 0, 0, -1, -1, NULL, NULL }
b7149293
UW
289};
290
b0ded00b 291
f450004a 292static const unsigned char s390_breakpoint[] = { 0, 1 };
b0ded00b
UW
293#define s390_breakpoint_len 2
294
295static CORE_ADDR
442ea881 296s390_get_pc (struct regcache *regcache)
b0ded00b 297{
d61ddec4
UW
298 if (register_size (0) == 4)
299 {
d6db1fab
UW
300 unsigned int pswa;
301 collect_register_by_name (regcache, "pswa", &pswa);
302 return pswa & 0x7fffffff;
d61ddec4
UW
303 }
304 else
305 {
306 unsigned long pc;
442ea881 307 collect_register_by_name (regcache, "pswa", &pc);
d61ddec4
UW
308 return pc;
309 }
b0ded00b
UW
310}
311
312static void
442ea881 313s390_set_pc (struct regcache *regcache, CORE_ADDR newpc)
b0ded00b 314{
d61ddec4
UW
315 if (register_size (0) == 4)
316 {
d6db1fab
UW
317 unsigned int pswa;
318 collect_register_by_name (regcache, "pswa", &pswa);
319 pswa = (pswa & 0x80000000) | (newpc & 0x7fffffff);
320 supply_register_by_name (regcache, "pswa", &pswa);
d61ddec4
UW
321 }
322 else
323 {
324 unsigned long pc = newpc;
442ea881 325 supply_register_by_name (regcache, "pswa", &pc);
d61ddec4 326 }
b0ded00b
UW
327}
328
7803799a
UW
329#ifdef __s390x__
330static unsigned long
331s390_get_hwcap (void)
332{
333 int wordsize = register_size (0);
334 unsigned char *data = alloca (2 * wordsize);
335 int offset = 0;
336
337 while ((*the_target->read_auxv) (offset, data, 2 * wordsize) == 2 * wordsize)
338 {
339 if (wordsize == 4)
340 {
341 unsigned int *data_p = (unsigned int *)data;
342 if (data_p[0] == AT_HWCAP)
343 return data_p[1];
344 }
345 else
346 {
347 unsigned long *data_p = (unsigned long *)data;
348 if (data_p[0] == AT_HWCAP)
349 return data_p[1];
350 }
351
352 offset += 2 * wordsize;
353 }
354
355 return 0;
356}
357#endif
d61ddec4 358
c642a434
UW
359static int
360s390_check_regset (int pid, int regset, int regsize)
361{
362 gdb_byte *buf = alloca (regsize);
363 struct iovec iov;
364
365 iov.iov_base = buf;
366 iov.iov_len = regsize;
367
368 if (ptrace (PTRACE_GETREGSET, pid, (long) regset, (long) &iov) < 0)
369 return 0;
370 else
371 return 1;
372}
373
d61ddec4
UW
374static void
375s390_arch_setup (void)
376{
c642a434
UW
377 struct regset_info *regset;
378
379 /* Check whether the kernel supports extra register sets. */
380 int pid = pid_of (get_thread_lwp (current_inferior));
381 int have_regset_last_break
382 = s390_check_regset (pid, NT_S390_LAST_BREAK, 8);
383 int have_regset_system_call
384 = s390_check_regset (pid, NT_S390_SYSTEM_CALL, 4);
385
386 /* Update target_regsets according to available register sets. */
387 for (regset = target_regsets; regset->fill_function != NULL; regset++)
388 if (regset->get_request == PTRACE_GETREGSET)
389 switch (regset->nt_type)
390 {
391 case NT_S390_LAST_BREAK:
392 regset->size = have_regset_last_break? 8 : 0;
393 break;
394 case NT_S390_SYSTEM_CALL:
395 regset->size = have_regset_system_call? 4 : 0;
396 break;
397 default:
398 break;
399 }
400
d61ddec4 401 /* Assume 31-bit inferior process. */
c642a434
UW
402 if (have_regset_system_call)
403 init_registers_s390_linux32v2 ();
404 else if (have_regset_last_break)
405 init_registers_s390_linux32v1 ();
406 else
407 init_registers_s390_linux32 ();
408
7803799a
UW
409 the_low_target.num_regs = s390_num_regs;
410 the_low_target.regmap = s390_regmap;
d61ddec4
UW
411
412 /* On a 64-bit host, check the low bit of the (31-bit) PSWM
413 -- if this is one, we actually have a 64-bit inferior. */
414#ifdef __s390x__
415 {
416 unsigned int pswm;
92b72907
UW
417 struct regcache *regcache = new_register_cache ();
418 fetch_inferior_registers (regcache, find_regno ("pswm"));
442ea881 419 collect_register_by_name (regcache, "pswm", &pswm);
92b72907
UW
420 free_register_cache (regcache);
421
d61ddec4 422 if (pswm & 1)
c642a434
UW
423 {
424 if (have_regset_system_call)
425 init_registers_s390x_linux64v2 ();
426 else if (have_regset_last_break)
427 init_registers_s390x_linux64v1 ();
428 else
429 init_registers_s390x_linux64 ();
430 }
7803799a
UW
431
432 /* For a 31-bit inferior, check whether the kernel supports
433 using the full 64-bit GPRs. */
434 else if (s390_get_hwcap () & HWCAP_S390_HIGH_GPRS)
435 {
c642a434
UW
436 if (have_regset_system_call)
437 init_registers_s390_linux64v2 ();
438 else if (have_regset_last_break)
439 init_registers_s390_linux64v1 ();
440 else
441 init_registers_s390_linux64 ();
442
7803799a
UW
443 the_low_target.num_regs = s390_num_regs_3264;
444 the_low_target.regmap = s390_regmap_3264;
445 }
d61ddec4
UW
446 }
447#endif
448}
449
450
b0ded00b
UW
451static int
452s390_breakpoint_at (CORE_ADDR pc)
453{
454 unsigned char c[s390_breakpoint_len];
455 read_inferior_memory (pc, c, s390_breakpoint_len);
456 return memcmp (c, s390_breakpoint, s390_breakpoint_len) == 0;
457}
458
459
2ec06d2e 460struct linux_target_ops the_low_target = {
d61ddec4 461 s390_arch_setup,
2ec06d2e
DJ
462 s390_num_regs,
463 s390_regmap,
1faeff08 464 NULL,
2ec06d2e
DJ
465 s390_cannot_fetch_register,
466 s390_cannot_store_register,
c14dfd32 467 NULL, /* fetch_register */
b0ded00b
UW
468 s390_get_pc,
469 s390_set_pc,
470 s390_breakpoint,
471 s390_breakpoint_len,
472 NULL,
473 s390_breakpoint_len,
474 s390_breakpoint_at,
ee1a7ae4
UW
475 NULL,
476 NULL,
477 NULL,
478 NULL,
479 s390_collect_ptrace_register,
480 s390_supply_ptrace_register,
2ec06d2e 481};
This page took 0.796245 seconds and 4 git commands to generate.