GDB (xrefs)
/tmp/gdb-7.10/gdb/hppa-linux-nat.c
Go to the documentation of this file.
1 /* Functions specific to running GDB native on HPPA running GNU/Linux.
2 
3  Copyright (C) 2004-2015 Free Software Foundation, Inc.
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
9  the Free Software Foundation; either version 3 of the License, or
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
18  along with this program. If not, see <http://www.gnu.org/licenses/>. */
19 
20 #include "defs.h"
21 #include "gdbcore.h"
22 #include "regcache.h"
23 #include "inferior.h"
24 #include "target.h"
25 #include "linux-nat.h"
26 
27 #include <sys/procfs.h>
28 #include <sys/ptrace.h>
29 #include <linux/version.h>
30 
31 #include <asm/ptrace.h>
32 #include "hppa-linux-offsets.h"
33 
34 #include "hppa-tdep.h"
35 
36 /* Prototypes for supply_gregset etc. */
37 #include "gregset.h"
38 
39 /* These must match the order of the register names.
40 
41  Some sort of lookup table is needed because the offsets associated
42  with the registers are all over the board. */
43 
44 static const int u_offsets[] =
45  {
46  /* general registers */
47  -1,
48  PT_GR1,
49  PT_GR2,
50  PT_GR3,
51  PT_GR4,
52  PT_GR5,
53  PT_GR6,
54  PT_GR7,
55  PT_GR8,
56  PT_GR9,
57  PT_GR10,
58  PT_GR11,
59  PT_GR12,
60  PT_GR13,
61  PT_GR14,
62  PT_GR15,
63  PT_GR16,
64  PT_GR17,
65  PT_GR18,
66  PT_GR19,
67  PT_GR20,
68  PT_GR21,
69  PT_GR22,
70  PT_GR23,
71  PT_GR24,
72  PT_GR25,
73  PT_GR26,
74  PT_GR27,
75  PT_GR28,
76  PT_GR29,
77  PT_GR30,
78  PT_GR31,
79 
80  PT_SAR,
81  PT_IAOQ0,
82  PT_IASQ0,
83  PT_IAOQ1,
84  PT_IASQ1,
85  -1, /* eiem */
86  PT_IIR,
87  PT_ISR,
88  PT_IOR,
89  PT_PSW,
90  -1, /* goto */
91 
92  PT_SR4,
93  PT_SR0,
94  PT_SR1,
95  PT_SR2,
96  PT_SR3,
97  PT_SR5,
98  PT_SR6,
99  PT_SR7,
100 
101  -1, /* cr0 */
102  -1, /* pid0 */
103  -1, /* pid1 */
104  -1, /* ccr */
105  -1, /* pid2 */
106  -1, /* pid3 */
107  -1, /* cr24 */
108  -1, /* cr25 */
109  -1, /* cr26 */
110  PT_CR27,
111  -1, /* cr28 */
112  -1, /* cr29 */
113  -1, /* cr30 */
114 
115  /* Floating point regs. */
116  PT_FR0, PT_FR0 + 4,
117  PT_FR1, PT_FR1 + 4,
118  PT_FR2, PT_FR2 + 4,
119  PT_FR3, PT_FR3 + 4,
120  PT_FR4, PT_FR4 + 4,
121  PT_FR5, PT_FR5 + 4,
122  PT_FR6, PT_FR6 + 4,
123  PT_FR7, PT_FR7 + 4,
124  PT_FR8, PT_FR8 + 4,
125  PT_FR9, PT_FR9 + 4,
126  PT_FR10, PT_FR10 + 4,
127  PT_FR11, PT_FR11 + 4,
128  PT_FR12, PT_FR12 + 4,
129  PT_FR13, PT_FR13 + 4,
130  PT_FR14, PT_FR14 + 4,
131  PT_FR15, PT_FR15 + 4,
132  PT_FR16, PT_FR16 + 4,
133  PT_FR17, PT_FR17 + 4,
134  PT_FR18, PT_FR18 + 4,
135  PT_FR19, PT_FR19 + 4,
136  PT_FR20, PT_FR20 + 4,
137  PT_FR21, PT_FR21 + 4,
138  PT_FR22, PT_FR22 + 4,
139  PT_FR23, PT_FR23 + 4,
140  PT_FR24, PT_FR24 + 4,
141  PT_FR25, PT_FR25 + 4,
142  PT_FR26, PT_FR26 + 4,
143  PT_FR27, PT_FR27 + 4,
144  PT_FR28, PT_FR28 + 4,
145  PT_FR29, PT_FR29 + 4,
146  PT_FR30, PT_FR30 + 4,
147  PT_FR31, PT_FR31 + 4,
148  };
149 
150 static CORE_ADDR
151 hppa_linux_register_addr (int regno, CORE_ADDR blockend)
152 {
153  CORE_ADDR addr;
154 
155  if ((unsigned) regno >= ARRAY_SIZE (u_offsets))
156  error (_("Invalid register number %d."), regno);
157 
158  if (u_offsets[regno] == -1)
159  addr = 0;
160  else
161  {
162  addr = (CORE_ADDR) u_offsets[regno];
163  }
164 
165  return addr;
166 }
167 
168 /*
169  * Registers saved in a coredump:
170  * gr0..gr31
171  * sr0..sr7
172  * iaoq0..iaoq1
173  * iasq0..iasq1
174  * sar, iir, isr, ior, ipsw
175  * cr0, cr24..cr31
176  * cr8,9,12,13
177  * cr10, cr15
178  */
179 #define GR_REGNUM(_n) (HPPA_R0_REGNUM+_n)
180 #define TR_REGNUM(_n) (HPPA_TR0_REGNUM+_n)
181 static const int greg_map[] =
182  {
183  GR_REGNUM(0), GR_REGNUM(1), GR_REGNUM(2), GR_REGNUM(3),
184  GR_REGNUM(4), GR_REGNUM(5), GR_REGNUM(6), GR_REGNUM(7),
185  GR_REGNUM(8), GR_REGNUM(9), GR_REGNUM(10), GR_REGNUM(11),
186  GR_REGNUM(12), GR_REGNUM(13), GR_REGNUM(14), GR_REGNUM(15),
187  GR_REGNUM(16), GR_REGNUM(17), GR_REGNUM(18), GR_REGNUM(19),
188  GR_REGNUM(20), GR_REGNUM(21), GR_REGNUM(22), GR_REGNUM(23),
189  GR_REGNUM(24), GR_REGNUM(25), GR_REGNUM(26), GR_REGNUM(27),
190  GR_REGNUM(28), GR_REGNUM(29), GR_REGNUM(30), GR_REGNUM(31),
191 
192  HPPA_SR4_REGNUM+1, HPPA_SR4_REGNUM+2, HPPA_SR4_REGNUM+3, HPPA_SR4_REGNUM+4,
193  HPPA_SR4_REGNUM, HPPA_SR4_REGNUM+5, HPPA_SR4_REGNUM+6, HPPA_SR4_REGNUM+7,
194 
197 
200 
201  TR_REGNUM(0), TR_REGNUM(1), TR_REGNUM(2), TR_REGNUM(3),
202  TR_REGNUM(4), TR_REGNUM(5), TR_REGNUM(6), TR_REGNUM(7),
203 
206  };
207 
208 
209 
210 /* Fetch one register. */
211 
212 static void
213 fetch_register (struct regcache *regcache, int regno)
214 {
215  struct gdbarch *gdbarch = get_regcache_arch (regcache);
216  int tid;
217  int val;
218 
219  if (gdbarch_cannot_fetch_register (gdbarch, regno))
220  {
221  regcache_raw_supply (regcache, regno, NULL);
222  return;
223  }
224 
225  /* GNU/Linux LWP ID's are process ID's. */
226  tid = ptid_get_lwp (inferior_ptid);
227  if (tid == 0)
228  tid = ptid_get_pid (inferior_ptid); /* Not a threaded program. */
229 
230  errno = 0;
231  val = ptrace (PTRACE_PEEKUSER, tid, hppa_linux_register_addr (regno, 0), 0);
232  if (errno != 0)
233  error (_("Couldn't read register %s (#%d): %s."),
234  gdbarch_register_name (gdbarch, regno),
235  regno, safe_strerror (errno));
236 
237  regcache_raw_supply (regcache, regno, &val);
238 }
239 
240 /* Store one register. */
241 
242 static void
243 store_register (const struct regcache *regcache, int regno)
244 {
245  struct gdbarch *gdbarch = get_regcache_arch (regcache);
246  int tid;
247  int val;
248 
249  if (gdbarch_cannot_store_register (gdbarch, regno))
250  return;
251 
252  /* GNU/Linux LWP ID's are process ID's. */
253  tid = ptid_get_lwp (inferior_ptid);
254  if (tid == 0)
255  tid = ptid_get_pid (inferior_ptid); /* Not a threaded program. */
256 
257  errno = 0;
258  regcache_raw_collect (regcache, regno, &val);
259  ptrace (PTRACE_POKEUSER, tid, hppa_linux_register_addr (regno, 0), val);
260  if (errno != 0)
261  error (_("Couldn't write register %s (#%d): %s."),
262  gdbarch_register_name (gdbarch, regno),
263  regno, safe_strerror (errno));
264 }
265 
266 /* Fetch registers from the child process. Fetch all registers if
267  regno == -1, otherwise fetch all general registers or all floating
268  point registers depending upon the value of regno. */
269 
270 static void
272  struct regcache *regcache, int regno)
273 {
274  if (-1 == regno)
275  {
276  for (regno = 0;
277  regno < gdbarch_num_regs (get_regcache_arch (regcache));
278  regno++)
279  fetch_register (regcache, regno);
280  }
281  else
282  {
283  fetch_register (regcache, regno);
284  }
285 }
286 
287 /* Store registers back into the inferior. Store all registers if
288  regno == -1, otherwise store all general registers or all floating
289  point registers depending upon the value of regno. */
290 
291 static void
293  struct regcache *regcache, int regno)
294 {
295  if (-1 == regno)
296  {
297  for (regno = 0;
298  regno < gdbarch_num_regs (get_regcache_arch (regcache));
299  regno++)
300  store_register (regcache, regno);
301  }
302  else
303  {
304  store_register (regcache, regno);
305  }
306 }
307 
308 /* Fill GDB's register array with the general-purpose register values
309  in *gregsetp. */
310 
311 void
312 supply_gregset (struct regcache *regcache, const gdb_gregset_t *gregsetp)
313 {
314  int i;
315  const greg_t *regp = (const elf_greg_t *) gregsetp;
316 
317  for (i = 0; i < sizeof (greg_map) / sizeof (greg_map[0]); i++, regp++)
318  {
319  int regno = greg_map[i];
320  regcache_raw_supply (regcache, regno, regp);
321  }
322 }
323 
324 /* Fill register regno (if it is a general-purpose register) in
325  *gregsetp with the appropriate value from GDB's register array.
326  If regno is -1, do this for all registers. */
327 
328 void
330  gdb_gregset_t *gregsetp, int regno)
331 {
332  int i;
333 
334  for (i = 0; i < sizeof (greg_map) / sizeof (greg_map[0]); i++)
335  {
336  int mregno = greg_map[i];
337 
338  if (regno == -1 || regno == mregno)
339  {
340  regcache_raw_collect(regcache, mregno, &(*gregsetp)[i]);
341  }
342  }
343 }
344 
345 /* Given a pointer to a floating point register set in /proc format
346  (fpregset_t *), unpack the register contents and supply them as gdb's
347  idea of the current floating point register values. */
348 
349 void
350 supply_fpregset (struct regcache *regcache, const gdb_fpregset_t *fpregsetp)
351 {
352  int regi;
353  const char *from;
354 
355  for (regi = 0; regi <= 31; regi++)
356  {
357  from = (const char *) &((*fpregsetp)[regi]);
358  regcache_raw_supply (regcache, 2*regi + HPPA_FP0_REGNUM, from);
359  regcache_raw_supply (regcache, 2*regi + HPPA_FP0_REGNUM + 1, from + 4);
360  }
361 }
362 
363 /* Given a pointer to a floating point register set in /proc format
364  (fpregset_t *), update the register specified by REGNO from gdb's idea
365  of the current floating point register set. If REGNO is -1, update
366  them all. */
367 
368 void
370  gdb_fpregset_t *fpregsetp, int regno)
371 {
372  int i;
373 
374  for (i = HPPA_FP0_REGNUM; i < HPPA_FP0_REGNUM + 32 * 2; i++)
375  {
376  /* Gross. fpregset_t is double, registers[x] has single
377  precision reg. */
378  char *to = (char *) &((*fpregsetp)[(i - HPPA_FP0_REGNUM) / 2]);
379  if ((i - HPPA_FP0_REGNUM) & 1)
380  to += 4;
381  regcache_raw_collect (regcache, i, to);
382  }
383 }
384 
385 void _initialize_hppa_linux_nat (void);
386 
387 void
389 {
390  struct target_ops *t;
391 
392  /* Fill in the generic GNU/Linux methods. */
393  t = linux_target ();
394 
395  /* Add our register access methods. */
398 
399  /* Register the target. */
401 }
void _initialize_hppa_linux_nat(void)
#define PT_GR26
#define PT_FR26
#define PT_GR3
#define PT_GR19
void supply_fpregset(struct regcache *regcache, const gdb_fpregset_t *fpregsetp)
#define PT_GR20
#define PT_GR16
bfd_vma CORE_ADDR
Definition: common-types.h:41
#define PT_GR14
#define PT_FR6
struct gdbarch * get_regcache_arch(const struct regcache *regcache)
Definition: regcache.c:297
static void store_register(const struct regcache *regcache, int regno)
#define PT_SR2
#define PT_FR23
#define PT_FR1
#define PT_PSW
#define PT_FR19
#define PT_GR31
#define PT_FR28
#define PT_SR4
#define PT_FR20
#define PT_FR0
void fill_gregset(const struct regcache *regcache, gdb_gregset_t *gregsetp, int regno)
static const int u_offsets[]
int gdbarch_num_regs(struct gdbarch *gdbarch)
Definition: gdbarch.c:1898
#define _(String)
Definition: gdb_locale.h:40
#define PT_FR21
#define PT_GR9
#define PT_GR24
PTRACE_TYPE_RET ptrace()
#define PT_GR7
#define PT_GR8
#define PT_FR3
void supply_gregset(struct regcache *regcache, const gdb_gregset_t *gregsetp)
#define PT_FR15
#define PT_GR21
#define PT_FR5
int * from
Definition: varobj.h:282
#define PT_FR31
#define GR_REGNUM(_n)
#define PT_GR25
static const int greg_map[]
#define PT_GR12
#define PT_GR15
#define PT_FR30
#define PT_GR18
#define PT_GR11
#define PT_FR29
#define PT_SR1
GDB_GREGSET_T gdb_gregset_t
Definition: gregset.h:34
int gdbarch_cannot_store_register(struct gdbarch *gdbarch, int regnum)
Definition: gdbarch.c:2356
#define PT_IOR
int gdbarch_cannot_fetch_register(struct gdbarch *gdbarch, int regnum)
Definition: gdbarch.c:2339
GDB_FPREGSET_T gdb_fpregset_t
Definition: gregset.h:35
#define PT_FR8
#define PT_GR22
#define PT_FR25
#define PT_SR0
#define PT_SR6
#define PT_FR12
#define PT_GR6
#define PT_GR4
const char * gdbarch_register_name(struct gdbarch *gdbarch, int regnr)
Definition: gdbarch.c:2117
void linux_nat_add_target(struct target_ops *t)
Definition: linux-nat.c:4972
#define PT_GR29
#define PT_FR17
void fill_fpregset(const struct regcache *regcache, gdb_fpregset_t *fpregsetp, int regno)
#define PT_FR11
static void fetch_register(struct regcache *regcache, int regno)
#define PT_FR24
#define PT_GR13
static CORE_ADDR hppa_linux_register_addr(int regno, CORE_ADDR blockend)
struct target_ops * linux_target(void)
Definition: linux-nat.c:4544
#define PT_GR10
#define PT_IIR
#define PT_GR30
static void hppa_linux_store_inferior_registers(struct target_ops *ops, struct regcache *regcache, int regno)
int ptid_get_pid(ptid_t ptid)
Definition: ptid.c:52
#define PT_FR14
#define PT_FR7
#define PT_FR10
#define PT_IASQ0
#define TR_REGNUM(_n)
#define PT_IASQ1
void(* to_fetch_registers)(struct target_ops *, struct regcache *, int) TARGET_DEFAULT_IGNORE()
Definition: target.h:472
#define PT_FR9
#define PT_SAR
#define PT_FR18
#define PT_FR2
#define PT_SR7
#define PT_GR17
#define PT_GR5
ptid_t inferior_ptid
Definition: infcmd.c:124
char * safe_strerror(int)
static void hppa_linux_fetch_inferior_registers(struct target_ops *ops, struct regcache *regcache, int regno)
#define PT_IAOQ0
#define PT_FR4
#define PT_FR13
#define PT_GR1
#define PT_GR28
#define PT_GR23
#define PT_SR5
void regcache_raw_supply(struct regcache *regcache, int regnum, const void *buf)
Definition: regcache.c:1041
#define PT_FR22
#define PT_FR27
long ptid_get_lwp(ptid_t ptid)
Definition: ptid.c:60
void regcache_raw_collect(const struct regcache *regcache, int regnum, void *buf)
Definition: regcache.c:1071
#define PT_FR16
int int * to
Definition: varobj.h:282
#define PT_IAOQ1
void(* to_store_registers)(struct target_ops *, struct regcache *, int) TARGET_DEFAULT_NORETURN(noprocess())
Definition: target.h:474
#define PT_CR27
#define PT_GR27
void error(const char *fmt,...)
Definition: errors.c:38
#define PT_ISR
#define PT_SR3
#define PT_GR2