* hppa-hpux-tdep.c: New file.
[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"
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 };
b70d2aee 97 static char zerobuf[ALPHA_MAX_REGISTER_RAW_SIZE] =
c5aa993b 98 {0};
c906108c
SS
99
100 for (regno = 0; regno < NUM_REGS; regno++)
101 {
102 if (CANNOT_FETCH_REGISTER (regno))
103 {
104 supply_register (regno, zerobuf);
105 continue;
106 }
107 addr = 8 * core_reg_mapping[regno];
108 if (addr < 0 || addr >= core_reg_size)
109 {
110 if (bad_reg < 0)
111 bad_reg = regno;
112 }
113 else
114 {
115 supply_register (regno, core_reg_sect + addr);
116 }
117 }
118 if (bad_reg >= 0)
119 {
120 error ("Register %s not found in core file.", REGISTER_NAME (bad_reg));
121 }
122}
123
124static void
fba45db2
KB
125fetch_elf_core_registers (char *core_reg_sect, unsigned core_reg_size,
126 int which, CORE_ADDR reg_addr)
c906108c 127{
c5aa993b 128 if (core_reg_size < 32 * 8)
c906108c
SS
129 {
130 error ("Core file register section too small (%u bytes).", core_reg_size);
131 return;
132 }
133
134 if (which == 2)
135 {
136 /* The FPU Registers. */
524d7c18
AC
137 memcpy (&deprecated_registers[REGISTER_BYTE (FP0_REGNUM)],
138 core_reg_sect, 31 * 8);
139 memset (&deprecated_registers[REGISTER_BYTE (FP0_REGNUM + 31)], 0, 8);
8262ee23 140 memset (&deprecated_register_valid[FP0_REGNUM], 1, 32);
c906108c
SS
141 }
142 else
143 {
144 /* The General Registers. */
524d7c18
AC
145 memcpy (&deprecated_registers[REGISTER_BYTE (ALPHA_V0_REGNUM)],
146 core_reg_sect, 31 * 8);
147 memcpy (&deprecated_registers[REGISTER_BYTE (PC_REGNUM)],
148 core_reg_sect + 31 * 8, 8);
149 memset (&deprecated_registers[REGISTER_BYTE (ALPHA_ZERO_REGNUM)], 0, 8);
8262ee23
AC
150 memset (&deprecated_register_valid[ALPHA_V0_REGNUM], 1, 32);
151 deprecated_register_valid[PC_REGNUM] = 1;
c906108c
SS
152 }
153}
154
155
156/* Map gdb internal register number to a ptrace ``address''.
157 These ``addresses'' are defined in <sys/ptrace.h> */
158
159#define REGISTER_PTRACE_ADDR(regno) \
160 (regno < FP0_REGNUM ? GPR_BASE + (regno) \
161 : regno == PC_REGNUM ? PC \
162 : regno >= FP0_REGNUM ? FPR_BASE + ((regno) - FP0_REGNUM) \
163 : 0)
164
165/* Return the ptrace ``address'' of register REGNO. */
166
167CORE_ADDR
fba45db2 168register_addr (int regno, CORE_ADDR blockend)
c906108c
SS
169{
170 return REGISTER_PTRACE_ADDR (regno);
171}
172
173int
fba45db2 174kernel_u_size (void)
c906108c
SS
175{
176 return (sizeof (struct user));
177}
178
179#if defined(USE_PROC_FS) || defined(HAVE_GREGSET_T)
180#include <sys/procfs.h>
181
c60c0f5f
MS
182/* Prototypes for supply_gregset etc. */
183#include "gregset.h"
184
c906108c
SS
185/*
186 * See the comment in m68k-tdep.c regarding the utility of these functions.
187 */
188
c5aa993b 189void
ce589877 190supply_gregset (gdb_gregset_t *gregsetp)
c906108c
SS
191{
192 register int regi;
193 register long *regp = ALPHA_REGSET_BASE (gregsetp);
b70d2aee 194 static char zerobuf[ALPHA_MAX_REGISTER_RAW_SIZE] =
c5aa993b 195 {0};
c906108c
SS
196
197 for (regi = 0; regi < 31; regi++)
c5aa993b 198 supply_register (regi, (char *) (regp + regi));
c906108c 199
c5aa993b 200 supply_register (PC_REGNUM, (char *) (regp + 31));
c906108c
SS
201
202 /* Fill inaccessible registers with zero. */
dc129d82 203 supply_register (ALPHA_ZERO_REGNUM, zerobuf);
c906108c
SS
204 supply_register (FP_REGNUM, zerobuf);
205}
206
207void
ce589877 208fill_gregset (gdb_gregset_t *gregsetp, int regno)
c906108c
SS
209{
210 int regi;
211 register long *regp = ALPHA_REGSET_BASE (gregsetp);
212
213 for (regi = 0; regi < 31; regi++)
214 if ((regno == -1) || (regno == regi))
524d7c18 215 *(regp + regi) = *(long *) &deprecated_registers[REGISTER_BYTE (regi)];
c906108c
SS
216
217 if ((regno == -1) || (regno == PC_REGNUM))
524d7c18 218 *(regp + 31) = *(long *) &deprecated_registers[REGISTER_BYTE (PC_REGNUM)];
c906108c
SS
219}
220
221/*
222 * Now we do the same thing for floating-point registers.
223 * Again, see the comments in m68k-tdep.c.
224 */
225
226void
ce589877 227supply_fpregset (gdb_fpregset_t *fpregsetp)
c906108c
SS
228{
229 register int regi;
230 register long *regp = ALPHA_REGSET_BASE (fpregsetp);
231
232 for (regi = 0; regi < 32; regi++)
c5aa993b 233 supply_register (regi + FP0_REGNUM, (char *) (regp + regi));
c906108c
SS
234}
235
236void
ce589877 237fill_fpregset (gdb_fpregset_t *fpregsetp, int regno)
c906108c
SS
238{
239 int regi;
240 register long *regp = ALPHA_REGSET_BASE (fpregsetp);
241
242 for (regi = FP0_REGNUM; regi < FP0_REGNUM + 32; regi++)
243 {
244 if ((regno == -1) || (regno == regi))
245 {
246 *(regp + regi - FP0_REGNUM) =
524d7c18 247 *(long *) &deprecated_registers[REGISTER_BYTE (regi)];
c906108c
SS
248 }
249 }
250}
251#endif
c906108c 252\f
c5aa993b 253
c906108c
SS
254/* Register that we are able to handle alpha core file formats. */
255
256static struct core_fns alpha_osf_core_fns =
257{
258 /* This really is bfd_target_unknown_flavour. */
259
2acceee2
JM
260 bfd_target_unknown_flavour, /* core_flavour */
261 default_check_format, /* check_format */
262 default_core_sniffer, /* core_sniffer */
263 fetch_osf_core_registers, /* core_read_registers */
264 NULL /* next */
c906108c
SS
265};
266
267static struct core_fns alpha_elf_core_fns =
268{
2acceee2
JM
269 bfd_target_elf_flavour, /* core_flavour */
270 default_check_format, /* check_format */
271 default_core_sniffer, /* core_sniffer */
272 fetch_elf_core_registers, /* core_read_registers */
273 NULL /* next */
c906108c
SS
274};
275
276void
fba45db2 277_initialize_core_alpha (void)
c906108c
SS
278{
279 add_core_fns (&alpha_osf_core_fns);
280 add_core_fns (&alpha_elf_core_fns);
281}
This page took 0.22132 seconds and 4 git commands to generate.