2002-11-14 Andrew Cagney <ac131313@redhat.com>
[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. */
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;
c906108c
SS
151 }
152}
153
154
155/* Map gdb internal register number to a ptrace ``address''.
156 These ``addresses'' are defined in <sys/ptrace.h> */
157
158#define REGISTER_PTRACE_ADDR(regno) \
159 (regno < FP0_REGNUM ? GPR_BASE + (regno) \
160 : regno == PC_REGNUM ? PC \
161 : regno >= FP0_REGNUM ? FPR_BASE + ((regno) - FP0_REGNUM) \
162 : 0)
163
164/* Return the ptrace ``address'' of register REGNO. */
165
166CORE_ADDR
fba45db2 167register_addr (int regno, CORE_ADDR blockend)
c906108c
SS
168{
169 return REGISTER_PTRACE_ADDR (regno);
170}
171
172int
fba45db2 173kernel_u_size (void)
c906108c
SS
174{
175 return (sizeof (struct user));
176}
177
178#if defined(USE_PROC_FS) || defined(HAVE_GREGSET_T)
179#include <sys/procfs.h>
180
c60c0f5f
MS
181/* Prototypes for supply_gregset etc. */
182#include "gregset.h"
183
c906108c
SS
184/*
185 * See the comment in m68k-tdep.c regarding the utility of these functions.
186 */
187
c5aa993b 188void
ce589877 189supply_gregset (gdb_gregset_t *gregsetp)
c906108c
SS
190{
191 register int regi;
192 register long *regp = ALPHA_REGSET_BASE (gregsetp);
b70d2aee 193 static char zerobuf[ALPHA_MAX_REGISTER_RAW_SIZE] =
c5aa993b 194 {0};
c906108c
SS
195
196 for (regi = 0; regi < 31; regi++)
c5aa993b 197 supply_register (regi, (char *) (regp + regi));
c906108c 198
c5aa993b 199 supply_register (PC_REGNUM, (char *) (regp + 31));
c906108c
SS
200
201 /* Fill inaccessible registers with zero. */
dc129d82 202 supply_register (ALPHA_ZERO_REGNUM, zerobuf);
c906108c
SS
203 supply_register (FP_REGNUM, zerobuf);
204}
205
206void
ce589877 207fill_gregset (gdb_gregset_t *gregsetp, int regno)
c906108c
SS
208{
209 int regi;
210 register long *regp = ALPHA_REGSET_BASE (gregsetp);
211
212 for (regi = 0; regi < 31; regi++)
213 if ((regno == -1) || (regno == regi))
524d7c18 214 *(regp + regi) = *(long *) &deprecated_registers[REGISTER_BYTE (regi)];
c906108c
SS
215
216 if ((regno == -1) || (regno == PC_REGNUM))
524d7c18 217 *(regp + 31) = *(long *) &deprecated_registers[REGISTER_BYTE (PC_REGNUM)];
c906108c
SS
218}
219
220/*
221 * Now we do the same thing for floating-point registers.
222 * Again, see the comments in m68k-tdep.c.
223 */
224
225void
ce589877 226supply_fpregset (gdb_fpregset_t *fpregsetp)
c906108c
SS
227{
228 register int regi;
229 register long *regp = ALPHA_REGSET_BASE (fpregsetp);
230
231 for (regi = 0; regi < 32; regi++)
c5aa993b 232 supply_register (regi + FP0_REGNUM, (char *) (regp + regi));
c906108c
SS
233}
234
235void
ce589877 236fill_fpregset (gdb_fpregset_t *fpregsetp, int regno)
c906108c
SS
237{
238 int regi;
239 register long *regp = ALPHA_REGSET_BASE (fpregsetp);
240
241 for (regi = FP0_REGNUM; regi < FP0_REGNUM + 32; regi++)
242 {
243 if ((regno == -1) || (regno == regi))
244 {
245 *(regp + regi - FP0_REGNUM) =
524d7c18 246 *(long *) &deprecated_registers[REGISTER_BYTE (regi)];
c906108c
SS
247 }
248 }
249}
250#endif
c906108c 251\f
c5aa993b 252
c906108c
SS
253/* Register that we are able to handle alpha core file formats. */
254
255static struct core_fns alpha_osf_core_fns =
256{
257 /* This really is bfd_target_unknown_flavour. */
258
2acceee2
JM
259 bfd_target_unknown_flavour, /* core_flavour */
260 default_check_format, /* check_format */
261 default_core_sniffer, /* core_sniffer */
262 fetch_osf_core_registers, /* core_read_registers */
263 NULL /* next */
c906108c
SS
264};
265
266static struct core_fns alpha_elf_core_fns =
267{
2acceee2
JM
268 bfd_target_elf_flavour, /* core_flavour */
269 default_check_format, /* check_format */
270 default_core_sniffer, /* core_sniffer */
271 fetch_elf_core_registers, /* core_read_registers */
272 NULL /* next */
c906108c
SS
273};
274
275void
fba45db2 276_initialize_core_alpha (void)
c906108c
SS
277{
278 add_core_fns (&alpha_osf_core_fns);
279 add_core_fns (&alpha_elf_core_fns);
280}
This page took 0.203186 seconds and 4 git commands to generate.