2003-04-15 David Carlton <carlton@math.stanford.edu>
[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 };
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;
87d1b352
RH
152
153 if (core_reg_size >= 33 * 8)
154 {
155 memcpy (&deprecated_registers[REGISTER_BYTE (ALPHA_UNIQUE_REGNUM)],
156 core_reg_sect + 32 * 8, 8);
157 deprecated_register_valid[ALPHA_UNIQUE_REGNUM] = 1;
158 }
c906108c
SS
159 }
160}
161
162
163/* Map gdb internal register number to a ptrace ``address''.
87d1b352
RH
164 These ``addresses'' are defined in <sys/ptrace.h>, with
165 the exception of ALPHA_UNIQUE_PTRACE_ADDR. */
c906108c 166
87d1b352
RH
167#ifndef ALPHA_UNIQUE_PTRACE_ADDR
168#define ALPHA_UNIQUE_PTRACE_ADDR 0
169#endif
c906108c
SS
170
171CORE_ADDR
fba45db2 172register_addr (int regno, CORE_ADDR blockend)
c906108c 173{
87d1b352
RH
174 if (regno == PC_REGNUM)
175 return PC;
176 if (regno == ALPHA_UNIQUE_REGNUM)
177 return ALPHA_UNIQUE_PTRACE_ADDR;
178 if (regno < FP0_REGNUM)
179 return GPR_BASE + regno;
180 else
181 return FPR_BASE + regno - FP0_REGNUM;
c906108c
SS
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);
b70d2aee 205 static char zerobuf[ALPHA_MAX_REGISTER_RAW_SIZE] =
c5aa993b 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. */
dc129d82 214 supply_register (ALPHA_ZERO_REGNUM, zerobuf);
c906108c
SS
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))
524d7c18 226 *(regp + regi) = *(long *) &deprecated_registers[REGISTER_BYTE (regi)];
c906108c
SS
227
228 if ((regno == -1) || (regno == PC_REGNUM))
524d7c18 229 *(regp + 31) = *(long *) &deprecated_registers[REGISTER_BYTE (PC_REGNUM)];
c906108c
SS
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) =
524d7c18 258 *(long *) &deprecated_registers[REGISTER_BYTE (regi)];
c906108c
SS
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}
This page took 0.220699 seconds and 4 git commands to generate.