]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/alpha-nat.c
Create new file regcache.h. Update all uses.
[thirdparty/binutils-gdb.git] / gdb / alpha-nat.c
CommitLineData
c906108c 1/* Low level Alpha interface, for GDB when running native.
4e052eda
AC
2 Copyright 1993, 1995, 1996, 1998, 2001 Free Software Foundation,
3 Inc.
c906108c 4
c5aa993b 5 This file is part of GDB.
c906108c 6
c5aa993b
JM
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.
c906108c 11
c5aa993b
JM
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.
c906108c 16
c5aa993b
JM
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. */
c906108c
SS
21
22#include "defs.h"
23#include "inferior.h"
24#include "gdbcore.h"
25#include "target.h"
4e052eda 26#include "regcache.h"
c906108c
SS
27#include <sys/ptrace.h>
28#ifdef __linux__
c5aa993b
JM
29#include <asm/reg.h>
30#include <alpha/ptrace.h>
c906108c 31#else
c5aa993b 32#include <machine/reg.h>
c906108c
SS
33#endif
34#include <sys/user.h>
35
36/* Prototypes for local functions. */
37
a14ed312
KB
38static void fetch_osf_core_registers (char *, unsigned, int, CORE_ADDR);
39static void fetch_elf_core_registers (char *, unsigned, int, CORE_ADDR);
c906108c
SS
40
41/* Size of elements in jmpbuf */
42
43#define JB_ELEMENT_SIZE 8
44
45/* The definition for JB_PC in machine/reg.h is wrong.
46 And we can't get at the correct definition in setjmp.h as it is
47 not always available (eg. if _POSIX_SOURCE is defined which is the
48 default). As the defintion is unlikely to change (see comment
49 in <setjmp.h>, define the correct value here. */
50
51#undef JB_PC
52#define JB_PC 2
53
54/* Figure out where the longjmp will land.
55 We expect the first arg to be a pointer to the jmp_buf structure from which
56 we extract the pc (JB_PC) that we will land at. The pc is copied into PC.
57 This routine returns true on success. */
58
59int
fba45db2 60get_longjmp_target (CORE_ADDR *pc)
c906108c
SS
61{
62 CORE_ADDR jb_addr;
63 char raw_buffer[MAX_REGISTER_RAW_SIZE];
64
c5aa993b 65 jb_addr = read_register (A0_REGNUM);
c906108c 66
c5aa993b
JM
67 if (target_read_memory (jb_addr + JB_PC * JB_ELEMENT_SIZE, raw_buffer,
68 sizeof (CORE_ADDR)))
c906108c
SS
69 return 0;
70
c5aa993b 71 *pc = extract_address (raw_buffer, sizeof (CORE_ADDR));
c906108c
SS
72 return 1;
73}
74
75/* Extract the register values out of the core file and store
76 them where `read_register' will find them.
77
78 CORE_REG_SECT points to the register values themselves, read into memory.
79 CORE_REG_SIZE is the size of that area.
80 WHICH says which set of registers we are handling (0 = int, 2 = float
c5aa993b 81 on machines where they are discontiguous).
c906108c 82 REG_ADDR is the offset from u.u_ar0 to the register values relative to
c5aa993b
JM
83 core_reg_sect. This is used with old-fashioned core files to
84 locate the registers in a large upage-plus-stack ".reg" section.
85 Original upage address X is at location core_reg_sect+x+reg_addr.
c906108c
SS
86 */
87
88static void
fba45db2
KB
89fetch_osf_core_registers (char *core_reg_sect, unsigned core_reg_size,
90 int which, CORE_ADDR reg_addr)
c906108c
SS
91{
92 register int regno;
93 register int addr;
94 int bad_reg = -1;
95
96 /* Table to map a gdb regnum to an index in the core register section.
97 The floating point register values are garbage in OSF/1.2 core files. */
98 static int core_reg_mapping[NUM_REGS] =
99 {
100#define EFL (EF_SIZE / 8)
c5aa993b
JM
101 EF_V0, EF_T0, EF_T1, EF_T2, EF_T3, EF_T4, EF_T5, EF_T6,
102 EF_T7, EF_S0, EF_S1, EF_S2, EF_S3, EF_S4, EF_S5, EF_S6,
103 EF_A0, EF_A1, EF_A2, EF_A3, EF_A4, EF_A5, EF_T8, EF_T9,
104 EF_T10, EF_T11, EF_RA, EF_T12, EF_AT, EF_GP, EF_SP, -1,
105 EFL + 0, EFL + 1, EFL + 2, EFL + 3, EFL + 4, EFL + 5, EFL + 6, EFL + 7,
106 EFL + 8, EFL + 9, EFL + 10, EFL + 11, EFL + 12, EFL + 13, EFL + 14, EFL + 15,
107 EFL + 16, EFL + 17, EFL + 18, EFL + 19, EFL + 20, EFL + 21, EFL + 22, EFL + 23,
108 EFL + 24, EFL + 25, EFL + 26, EFL + 27, EFL + 28, EFL + 29, EFL + 30, EFL + 31,
109 EF_PC, -1
c906108c 110 };
c5aa993b
JM
111 static char zerobuf[MAX_REGISTER_RAW_SIZE] =
112 {0};
c906108c
SS
113
114 for (regno = 0; regno < NUM_REGS; regno++)
115 {
116 if (CANNOT_FETCH_REGISTER (regno))
117 {
118 supply_register (regno, zerobuf);
119 continue;
120 }
121 addr = 8 * core_reg_mapping[regno];
122 if (addr < 0 || addr >= core_reg_size)
123 {
124 if (bad_reg < 0)
125 bad_reg = regno;
126 }
127 else
128 {
129 supply_register (regno, core_reg_sect + addr);
130 }
131 }
132 if (bad_reg >= 0)
133 {
134 error ("Register %s not found in core file.", REGISTER_NAME (bad_reg));
135 }
136}
137
138static void
fba45db2
KB
139fetch_elf_core_registers (char *core_reg_sect, unsigned core_reg_size,
140 int which, CORE_ADDR reg_addr)
c906108c 141{
c5aa993b 142 if (core_reg_size < 32 * 8)
c906108c
SS
143 {
144 error ("Core file register section too small (%u bytes).", core_reg_size);
145 return;
146 }
147
148 if (which == 2)
149 {
150 /* The FPU Registers. */
c5aa993b
JM
151 memcpy (&registers[REGISTER_BYTE (FP0_REGNUM)], core_reg_sect, 31 * 8);
152 memset (&registers[REGISTER_BYTE (FP0_REGNUM + 31)], 0, 8);
c906108c
SS
153 memset (&register_valid[FP0_REGNUM], 1, 32);
154 }
155 else
156 {
157 /* The General Registers. */
c5aa993b
JM
158 memcpy (&registers[REGISTER_BYTE (V0_REGNUM)], core_reg_sect, 31 * 8);
159 memcpy (&registers[REGISTER_BYTE (PC_REGNUM)], core_reg_sect + 31 * 8, 8);
c906108c
SS
160 memset (&registers[REGISTER_BYTE (ZERO_REGNUM)], 0, 8);
161 memset (&register_valid[V0_REGNUM], 1, 32);
162 register_valid[PC_REGNUM] = 1;
163 }
164}
165
166
167/* Map gdb internal register number to a ptrace ``address''.
168 These ``addresses'' are defined in <sys/ptrace.h> */
169
170#define REGISTER_PTRACE_ADDR(regno) \
171 (regno < FP0_REGNUM ? GPR_BASE + (regno) \
172 : regno == PC_REGNUM ? PC \
173 : regno >= FP0_REGNUM ? FPR_BASE + ((regno) - FP0_REGNUM) \
174 : 0)
175
176/* Return the ptrace ``address'' of register REGNO. */
177
178CORE_ADDR
fba45db2 179register_addr (int regno, CORE_ADDR blockend)
c906108c
SS
180{
181 return REGISTER_PTRACE_ADDR (regno);
182}
183
184int
fba45db2 185kernel_u_size (void)
c906108c
SS
186{
187 return (sizeof (struct user));
188}
189
190#if defined(USE_PROC_FS) || defined(HAVE_GREGSET_T)
191#include <sys/procfs.h>
192
c60c0f5f
MS
193/* Prototypes for supply_gregset etc. */
194#include "gregset.h"
195
c906108c
SS
196/*
197 * See the comment in m68k-tdep.c regarding the utility of these functions.
198 */
199
c5aa993b 200void
ce589877 201supply_gregset (gdb_gregset_t *gregsetp)
c906108c
SS
202{
203 register int regi;
204 register long *regp = ALPHA_REGSET_BASE (gregsetp);
c5aa993b
JM
205 static char zerobuf[MAX_REGISTER_RAW_SIZE] =
206 {0};
c906108c
SS
207
208 for (regi = 0; regi < 31; regi++)
c5aa993b 209 supply_register (regi, (char *) (regp + regi));
c906108c 210
c5aa993b 211 supply_register (PC_REGNUM, (char *) (regp + 31));
c906108c
SS
212
213 /* Fill inaccessible registers with zero. */
214 supply_register (ZERO_REGNUM, zerobuf);
215 supply_register (FP_REGNUM, zerobuf);
216}
217
218void
ce589877 219fill_gregset (gdb_gregset_t *gregsetp, int regno)
c906108c
SS
220{
221 int regi;
222 register long *regp = ALPHA_REGSET_BASE (gregsetp);
223
224 for (regi = 0; regi < 31; regi++)
225 if ((regno == -1) || (regno == regi))
226 *(regp + regi) = *(long *) &registers[REGISTER_BYTE (regi)];
227
228 if ((regno == -1) || (regno == PC_REGNUM))
229 *(regp + 31) = *(long *) &registers[REGISTER_BYTE (PC_REGNUM)];
230}
231
232/*
233 * Now we do the same thing for floating-point registers.
234 * Again, see the comments in m68k-tdep.c.
235 */
236
237void
ce589877 238supply_fpregset (gdb_fpregset_t *fpregsetp)
c906108c
SS
239{
240 register int regi;
241 register long *regp = ALPHA_REGSET_BASE (fpregsetp);
242
243 for (regi = 0; regi < 32; regi++)
c5aa993b 244 supply_register (regi + FP0_REGNUM, (char *) (regp + regi));
c906108c
SS
245}
246
247void
ce589877 248fill_fpregset (gdb_fpregset_t *fpregsetp, int regno)
c906108c
SS
249{
250 int regi;
251 register long *regp = ALPHA_REGSET_BASE (fpregsetp);
252
253 for (regi = FP0_REGNUM; regi < FP0_REGNUM + 32; regi++)
254 {
255 if ((regno == -1) || (regno == regi))
256 {
257 *(regp + regi - FP0_REGNUM) =
258 *(long *) &registers[REGISTER_BYTE (regi)];
259 }
260 }
261}
262#endif
c906108c 263\f
c5aa993b 264
c906108c
SS
265/* Register that we are able to handle alpha core file formats. */
266
267static struct core_fns alpha_osf_core_fns =
268{
269 /* This really is bfd_target_unknown_flavour. */
270
2acceee2
JM
271 bfd_target_unknown_flavour, /* core_flavour */
272 default_check_format, /* check_format */
273 default_core_sniffer, /* core_sniffer */
274 fetch_osf_core_registers, /* core_read_registers */
275 NULL /* next */
c906108c
SS
276};
277
278static struct core_fns alpha_elf_core_fns =
279{
2acceee2
JM
280 bfd_target_elf_flavour, /* core_flavour */
281 default_check_format, /* check_format */
282 default_core_sniffer, /* core_sniffer */
283 fetch_elf_core_registers, /* core_read_registers */
284 NULL /* next */
c906108c
SS
285};
286
287void
fba45db2 288_initialize_core_alpha (void)
c906108c
SS
289{
290 add_core_fns (&alpha_osf_core_fns);
291 add_core_fns (&alpha_elf_core_fns);
292}