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