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