Add self to MAINTAINERS.
[deliverable/binutils-gdb.git] / gdb / alpha-nat.c
CommitLineData
c906108c 1/* Low level Alpha interface, for GDB when running native.
b6ba6518
KB
2 Copyright 1993, 1995, 1996, 1998, 1999, 2000, 2001
3 Free Software Foundation, 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"
dc129d82
JT
27
28#include "alpha-tdep.h"
29
c906108c
SS
30#include <sys/ptrace.h>
31#ifdef __linux__
c5aa993b
JM
32#include <asm/reg.h>
33#include <alpha/ptrace.h>
c906108c 34#else
f1e3ec29 35#include <alpha/coreregs.h>
c906108c
SS
36#endif
37#include <sys/user.h>
38
39/* Prototypes for local functions. */
40
a14ed312
KB
41static void fetch_osf_core_registers (char *, unsigned, int, CORE_ADDR);
42static void fetch_elf_core_registers (char *, unsigned, int, CORE_ADDR);
c906108c 43
c906108c
SS
44/* Extract the register values out of the core file and store
45 them where `read_register' will find them.
46
47 CORE_REG_SECT points to the register values themselves, read into memory.
48 CORE_REG_SIZE is the size of that area.
49 WHICH says which set of registers we are handling (0 = int, 2 = float
c5aa993b 50 on machines where they are discontiguous).
c906108c 51 REG_ADDR is the offset from u.u_ar0 to the register values relative to
c5aa993b
JM
52 core_reg_sect. This is used with old-fashioned core files to
53 locate the registers in a large upage-plus-stack ".reg" section.
54 Original upage address X is at location core_reg_sect+x+reg_addr.
c906108c
SS
55 */
56
57static void
fba45db2
KB
58fetch_osf_core_registers (char *core_reg_sect, unsigned core_reg_size,
59 int which, CORE_ADDR reg_addr)
c906108c
SS
60{
61 register int regno;
62 register int addr;
63 int bad_reg = -1;
64
f1e3ec29
AC
65 /* Table to map a gdb regnum to an index in the core register
66 section. The floating point register values are garbage in
67 OSF/1.2 core files. OSF5 uses different names for the register
68 enum list, need to handle two cases. The actual values are the
69 same. */
b70d2aee 70 static int core_reg_mapping[ALPHA_NUM_REGS] =
c906108c 71 {
f1e3ec29
AC
72#ifdef NCF_REGS
73#define EFL NCF_REGS
74 CF_V0, CF_T0, CF_T1, CF_T2, CF_T3, CF_T4, CF_T5, CF_T6,
75 CF_T7, CF_S0, CF_S1, CF_S2, CF_S3, CF_S4, CF_S5, CF_S6,
76 CF_A0, CF_A1, CF_A2, CF_A3, CF_A4, CF_A5, CF_T8, CF_T9,
77 CF_T10, CF_T11, CF_RA, CF_T12, CF_AT, CF_GP, CF_SP, -1,
78 EFL + 0, EFL + 1, EFL + 2, EFL + 3, EFL + 4, EFL + 5, EFL + 6, EFL + 7,
79 EFL + 8, EFL + 9, EFL + 10, EFL + 11, EFL + 12, EFL + 13, EFL + 14, EFL + 15,
80 EFL + 16, EFL + 17, EFL + 18, EFL + 19, EFL + 20, EFL + 21, EFL + 22, EFL + 23,
81 EFL + 24, EFL + 25, EFL + 26, EFL + 27, EFL + 28, EFL + 29, EFL + 30, EFL + 31,
82 CF_PC, -1
83#else
c906108c 84#define EFL (EF_SIZE / 8)
c5aa993b
JM
85 EF_V0, EF_T0, EF_T1, EF_T2, EF_T3, EF_T4, EF_T5, EF_T6,
86 EF_T7, EF_S0, EF_S1, EF_S2, EF_S3, EF_S4, EF_S5, EF_S6,
87 EF_A0, EF_A1, EF_A2, EF_A3, EF_A4, EF_A5, EF_T8, EF_T9,
88 EF_T10, EF_T11, EF_RA, EF_T12, EF_AT, EF_GP, EF_SP, -1,
89 EFL + 0, EFL + 1, EFL + 2, EFL + 3, EFL + 4, EFL + 5, EFL + 6, EFL + 7,
90 EFL + 8, EFL + 9, EFL + 10, EFL + 11, EFL + 12, EFL + 13, EFL + 14, EFL + 15,
91 EFL + 16, EFL + 17, EFL + 18, EFL + 19, EFL + 20, EFL + 21, EFL + 22, EFL + 23,
92 EFL + 24, EFL + 25, EFL + 26, EFL + 27, EFL + 28, EFL + 29, EFL + 30, EFL + 31,
93 EF_PC, -1
f1e3ec29 94#endif
c906108c 95 };
b70d2aee 96 static char zerobuf[ALPHA_MAX_REGISTER_RAW_SIZE] =
c5aa993b 97 {0};
c906108c
SS
98
99 for (regno = 0; regno < NUM_REGS; regno++)
100 {
101 if (CANNOT_FETCH_REGISTER (regno))
102 {
103 supply_register (regno, zerobuf);
104 continue;
105 }
106 addr = 8 * core_reg_mapping[regno];
107 if (addr < 0 || addr >= core_reg_size)
108 {
109 if (bad_reg < 0)
110 bad_reg = regno;
111 }
112 else
113 {
114 supply_register (regno, core_reg_sect + addr);
115 }
116 }
117 if (bad_reg >= 0)
118 {
119 error ("Register %s not found in core file.", REGISTER_NAME (bad_reg));
120 }
121}
122
123static void
fba45db2
KB
124fetch_elf_core_registers (char *core_reg_sect, unsigned core_reg_size,
125 int which, CORE_ADDR reg_addr)
c906108c 126{
c5aa993b 127 if (core_reg_size < 32 * 8)
c906108c
SS
128 {
129 error ("Core file register section too small (%u bytes).", core_reg_size);
130 return;
131 }
132
133 if (which == 2)
134 {
135 /* The FPU Registers. */
c5aa993b
JM
136 memcpy (&registers[REGISTER_BYTE (FP0_REGNUM)], core_reg_sect, 31 * 8);
137 memset (&registers[REGISTER_BYTE (FP0_REGNUM + 31)], 0, 8);
c906108c
SS
138 memset (&register_valid[FP0_REGNUM], 1, 32);
139 }
140 else
141 {
142 /* The General Registers. */
dc129d82
JT
143 memcpy (&registers[REGISTER_BYTE (ALPHA_V0_REGNUM)], core_reg_sect,
144 31 * 8);
c5aa993b 145 memcpy (&registers[REGISTER_BYTE (PC_REGNUM)], core_reg_sect + 31 * 8, 8);
dc129d82
JT
146 memset (&registers[REGISTER_BYTE (ALPHA_ZERO_REGNUM)], 0, 8);
147 memset (&register_valid[ALPHA_V0_REGNUM], 1, 32);
c906108c
SS
148 register_valid[PC_REGNUM] = 1;
149 }
150}
151
152
153/* Map gdb internal register number to a ptrace ``address''.
154 These ``addresses'' are defined in <sys/ptrace.h> */
155
156#define REGISTER_PTRACE_ADDR(regno) \
157 (regno < FP0_REGNUM ? GPR_BASE + (regno) \
158 : regno == PC_REGNUM ? PC \
159 : regno >= FP0_REGNUM ? FPR_BASE + ((regno) - FP0_REGNUM) \
160 : 0)
161
162/* Return the ptrace ``address'' of register REGNO. */
163
164CORE_ADDR
fba45db2 165register_addr (int regno, CORE_ADDR blockend)
c906108c
SS
166{
167 return REGISTER_PTRACE_ADDR (regno);
168}
169
170int
fba45db2 171kernel_u_size (void)
c906108c
SS
172{
173 return (sizeof (struct user));
174}
175
176#if defined(USE_PROC_FS) || defined(HAVE_GREGSET_T)
177#include <sys/procfs.h>
178
c60c0f5f
MS
179/* Prototypes for supply_gregset etc. */
180#include "gregset.h"
181
c906108c
SS
182/*
183 * See the comment in m68k-tdep.c regarding the utility of these functions.
184 */
185
c5aa993b 186void
ce589877 187supply_gregset (gdb_gregset_t *gregsetp)
c906108c
SS
188{
189 register int regi;
190 register long *regp = ALPHA_REGSET_BASE (gregsetp);
b70d2aee 191 static char zerobuf[ALPHA_MAX_REGISTER_RAW_SIZE] =
c5aa993b 192 {0};
c906108c
SS
193
194 for (regi = 0; regi < 31; regi++)
c5aa993b 195 supply_register (regi, (char *) (regp + regi));
c906108c 196
c5aa993b 197 supply_register (PC_REGNUM, (char *) (regp + 31));
c906108c
SS
198
199 /* Fill inaccessible registers with zero. */
dc129d82 200 supply_register (ALPHA_ZERO_REGNUM, zerobuf);
c906108c
SS
201 supply_register (FP_REGNUM, zerobuf);
202}
203
204void
ce589877 205fill_gregset (gdb_gregset_t *gregsetp, int regno)
c906108c
SS
206{
207 int regi;
208 register long *regp = ALPHA_REGSET_BASE (gregsetp);
209
210 for (regi = 0; regi < 31; regi++)
211 if ((regno == -1) || (regno == regi))
212 *(regp + regi) = *(long *) &registers[REGISTER_BYTE (regi)];
213
214 if ((regno == -1) || (regno == PC_REGNUM))
215 *(regp + 31) = *(long *) &registers[REGISTER_BYTE (PC_REGNUM)];
216}
217
218/*
219 * Now we do the same thing for floating-point registers.
220 * Again, see the comments in m68k-tdep.c.
221 */
222
223void
ce589877 224supply_fpregset (gdb_fpregset_t *fpregsetp)
c906108c
SS
225{
226 register int regi;
227 register long *regp = ALPHA_REGSET_BASE (fpregsetp);
228
229 for (regi = 0; regi < 32; regi++)
c5aa993b 230 supply_register (regi + FP0_REGNUM, (char *) (regp + regi));
c906108c
SS
231}
232
233void
ce589877 234fill_fpregset (gdb_fpregset_t *fpregsetp, int regno)
c906108c
SS
235{
236 int regi;
237 register long *regp = ALPHA_REGSET_BASE (fpregsetp);
238
239 for (regi = FP0_REGNUM; regi < FP0_REGNUM + 32; regi++)
240 {
241 if ((regno == -1) || (regno == regi))
242 {
243 *(regp + regi - FP0_REGNUM) =
244 *(long *) &registers[REGISTER_BYTE (regi)];
245 }
246 }
247}
248#endif
c906108c 249\f
c5aa993b 250
c906108c
SS
251/* Register that we are able to handle alpha core file formats. */
252
253static struct core_fns alpha_osf_core_fns =
254{
255 /* This really is bfd_target_unknown_flavour. */
256
2acceee2
JM
257 bfd_target_unknown_flavour, /* core_flavour */
258 default_check_format, /* check_format */
259 default_core_sniffer, /* core_sniffer */
260 fetch_osf_core_registers, /* core_read_registers */
261 NULL /* next */
c906108c
SS
262};
263
264static struct core_fns alpha_elf_core_fns =
265{
2acceee2
JM
266 bfd_target_elf_flavour, /* core_flavour */
267 default_check_format, /* check_format */
268 default_core_sniffer, /* core_sniffer */
269 fetch_elf_core_registers, /* core_read_registers */
270 NULL /* next */
c906108c
SS
271};
272
273void
fba45db2 274_initialize_core_alpha (void)
c906108c
SS
275{
276 add_core_fns (&alpha_osf_core_fns);
277 add_core_fns (&alpha_elf_core_fns);
278}
This page took 0.21506 seconds and 4 git commands to generate.