* linux-low.h (struct linux_target_ops): Replace left_pad_xfer field
[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.
9b254dd1
DJ
3 Copyright (C) 2001, 2002, 2005, 2006, 2007, 2008
4 Free Software Foundation, Inc.
265f716b
DJ
5
6 This file is part of GDB.
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
a9762ec7 10 the Free Software Foundation; either version 3 of the License, or
265f716b
DJ
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
a9762ec7 19 along with this program. If not, see <http://www.gnu.org/licenses/>. */
265f716b
DJ
20
21/* This file is used for both 31-bit and 64-bit S/390 systems. */
22
23#include "server.h"
24#include "linux-low.h"
25
26#include <asm/ptrace.h>
27
d05b4ac3
UW
28/* Defined in auto-generated file reg-s390.c. */
29void init_registers_s390 (void);
30/* Defined in auto-generated file reg-s390x.c. */
31void init_registers_s390x (void);
32
33
d0f54f9d 34#define s390_num_regs 51
265f716b 35
2ec06d2e 36static int s390_regmap[] = {
265f716b
DJ
37 PT_PSWMASK, PT_PSWADDR,
38
39 PT_GPR0, PT_GPR1, PT_GPR2, PT_GPR3,
40 PT_GPR4, PT_GPR5, PT_GPR6, PT_GPR7,
41 PT_GPR8, PT_GPR9, PT_GPR10, PT_GPR11,
42 PT_GPR12, PT_GPR13, PT_GPR14, PT_GPR15,
43
44 PT_ACR0, PT_ACR1, PT_ACR2, PT_ACR3,
45 PT_ACR4, PT_ACR5, PT_ACR6, PT_ACR7,
46 PT_ACR8, PT_ACR9, PT_ACR10, PT_ACR11,
47 PT_ACR12, PT_ACR13, PT_ACR14, PT_ACR15,
48
265f716b
DJ
49 PT_FPC,
50
d0f54f9d 51#ifndef __s390x__
265f716b
DJ
52 PT_FPR0_HI, PT_FPR1_HI, PT_FPR2_HI, PT_FPR3_HI,
53 PT_FPR4_HI, PT_FPR5_HI, PT_FPR6_HI, PT_FPR7_HI,
54 PT_FPR8_HI, PT_FPR9_HI, PT_FPR10_HI, PT_FPR11_HI,
55 PT_FPR12_HI, PT_FPR13_HI, PT_FPR14_HI, PT_FPR15_HI,
56#else
57 PT_FPR0, PT_FPR1, PT_FPR2, PT_FPR3,
58 PT_FPR4, PT_FPR5, PT_FPR6, PT_FPR7,
59 PT_FPR8, PT_FPR9, PT_FPR10, PT_FPR11,
60 PT_FPR12, PT_FPR13, PT_FPR14, PT_FPR15,
61#endif
62};
63
2ec06d2e
DJ
64static int
65s390_cannot_fetch_register (int regno)
265f716b 66{
2ec06d2e 67 if (s390_regmap[regno] == -1)
265f716b
DJ
68 return 1;
69
70 return 0;
71}
72
2ec06d2e
DJ
73static int
74s390_cannot_store_register (int regno)
265f716b 75{
2ec06d2e 76 if (s390_regmap[regno] == -1)
265f716b
DJ
77 return 1;
78
79 return 0;
80}
2ec06d2e 81
ee1a7ae4
UW
82static void
83s390_collect_ptrace_register (int regno, char *buf)
84{
85 int size = register_size (regno);
86 if (size < sizeof (long))
87 {
88 memset (buf, 0, sizeof (long));
89
90 if (regno == find_regno ("pswa")
91 || (regno >= find_regno ("r0") && regno <= find_regno ("r15")))
92 collect_register (regno, buf + sizeof (long) - size);
93 else
94 collect_register (regno, buf);
95
96 /* When debugging a 32-bit inferior on a 64-bit host, make sure
97 the 31-bit addressing mode bit is set in the PSW mask. */
98 if (regno == find_regno ("pswm"))
99 buf[size] |= 0x80;
100 }
101 else
102 collect_register (regno, buf);
103}
104
105static void
106s390_supply_ptrace_register (int regno, const char *buf)
107{
108 int size = register_size (regno);
109 if (size < sizeof (long))
110 {
111 if (regno == find_regno ("pswa")
112 || (regno >= find_regno ("r0") && regno <= find_regno ("r15")))
113 supply_register (regno, buf + sizeof (long) - size);
114 else
115 supply_register (regno, buf);
116 }
117 else
118 supply_register (regno, buf);
119}
120
b7149293
UW
121/* Provide only a fill function for the general register set. ps_lgetregs
122 will use this for NPTL support. */
123
124static void s390_fill_gregset (void *buf)
125{
126 int i;
127
128 for (i = 0; i < 34; i++)
ee1a7ae4 129 s390_collect_ptrace_register (i, (char *) buf + s390_regmap[i]);
b7149293
UW
130}
131
132struct regset_info target_regsets[] = {
133 { 0, 0, 0, GENERAL_REGS, s390_fill_gregset, NULL },
134 { 0, 0, -1, -1, NULL, NULL }
135};
136
b0ded00b 137
f450004a 138static const unsigned char s390_breakpoint[] = { 0, 1 };
b0ded00b
UW
139#define s390_breakpoint_len 2
140
141static CORE_ADDR
142s390_get_pc ()
143{
d61ddec4
UW
144 if (register_size (0) == 4)
145 {
146 unsigned int pc;
147 collect_register_by_name ("pswa", &pc);
b0ded00b 148#ifndef __s390x__
d61ddec4 149 pc &= 0x7fffffff;
b0ded00b 150#endif
d61ddec4
UW
151 return pc;
152 }
153 else
154 {
155 unsigned long pc;
156 collect_register_by_name ("pswa", &pc);
157 return pc;
158 }
b0ded00b
UW
159}
160
161static void
162s390_set_pc (CORE_ADDR newpc)
163{
d61ddec4
UW
164 if (register_size (0) == 4)
165 {
166 unsigned int pc = newpc;
b0ded00b 167#ifndef __s390x__
d61ddec4 168 pc |= 0x80000000;
b0ded00b 169#endif
d61ddec4
UW
170 supply_register_by_name ("pswa", &pc);
171 }
172 else
173 {
174 unsigned long pc = newpc;
175 supply_register_by_name ("pswa", &pc);
176 }
b0ded00b
UW
177}
178
d61ddec4
UW
179
180static void
181s390_arch_setup (void)
182{
183 /* Assume 31-bit inferior process. */
184 init_registers_s390 ();
185
186 /* On a 64-bit host, check the low bit of the (31-bit) PSWM
187 -- if this is one, we actually have a 64-bit inferior. */
188#ifdef __s390x__
189 {
190 unsigned int pswm;
191 collect_register_by_name ("pswm", &pswm);
192 if (pswm & 1)
193 init_registers_s390x ();
194 }
195#endif
196}
197
198
b0ded00b
UW
199static int
200s390_breakpoint_at (CORE_ADDR pc)
201{
202 unsigned char c[s390_breakpoint_len];
203 read_inferior_memory (pc, c, s390_breakpoint_len);
204 return memcmp (c, s390_breakpoint, s390_breakpoint_len) == 0;
205}
206
207
2ec06d2e 208struct linux_target_ops the_low_target = {
d61ddec4 209 s390_arch_setup,
2ec06d2e
DJ
210 s390_num_regs,
211 s390_regmap,
212 s390_cannot_fetch_register,
213 s390_cannot_store_register,
b0ded00b
UW
214 s390_get_pc,
215 s390_set_pc,
216 s390_breakpoint,
217 s390_breakpoint_len,
218 NULL,
219 s390_breakpoint_len,
220 s390_breakpoint_at,
ee1a7ae4
UW
221 NULL,
222 NULL,
223 NULL,
224 NULL,
225 s390_collect_ptrace_register,
226 s390_supply_ptrace_register,
2ec06d2e 227};
b0ded00b 228
This page took 0.432392 seconds and 4 git commands to generate.