]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/alpha-nat.c
Copyright updates for 2007.
[thirdparty/binutils-gdb.git] / gdb / alpha-nat.c
CommitLineData
c906108c 1/* Low level Alpha interface, for GDB when running native.
6aba47ca 2 Copyright (C) 1993, 1995, 1996, 1998, 1999, 2000, 2001, 2003, 2007
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
197e01b6
EZ
19 Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 Boston, MA 02110-1301, 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 61{
52f0bd74
AC
62 int regno;
63 int addr;
c906108c
SS
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. */
98a8e1e5 71 static int const 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,
515921d7 83 CF_PC, -1, -1
f1e3ec29 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,
515921d7 94 EF_PC, -1, -1
f1e3ec29 95#endif
c906108c 96 };
c906108c 97
98a8e1e5 98 for (regno = 0; regno < ALPHA_NUM_REGS; regno++)
c906108c
SS
99 {
100 if (CANNOT_FETCH_REGISTER (regno))
101 {
23a6d369 102 regcache_raw_supply (current_regcache, regno, NULL);
c906108c
SS
103 continue;
104 }
105 addr = 8 * core_reg_mapping[regno];
106 if (addr < 0 || addr >= core_reg_size)
107 {
98a8e1e5
RH
108 /* ??? UNIQUE is a new addition. Don't generate an error. */
109 if (regno == ALPHA_UNIQUE_REGNUM)
110 {
23a6d369 111 regcache_raw_supply (current_regcache, regno, NULL);
98a8e1e5
RH
112 continue;
113 }
c906108c
SS
114 if (bad_reg < 0)
115 bad_reg = regno;
116 }
117 else
118 {
23a6d369 119 regcache_raw_supply (current_regcache, regno, core_reg_sect + addr);
c906108c
SS
120 }
121 }
122 if (bad_reg >= 0)
123 {
edefbb7c 124 error (_("Register %s not found in core file."), REGISTER_NAME (bad_reg));
c906108c
SS
125 }
126}
127
128static void
fba45db2
KB
129fetch_elf_core_registers (char *core_reg_sect, unsigned core_reg_size,
130 int which, CORE_ADDR reg_addr)
c906108c 131{
c5aa993b 132 if (core_reg_size < 32 * 8)
c906108c 133 {
edefbb7c 134 error (_("Core file register section too small (%u bytes)."), core_reg_size);
c906108c
SS
135 return;
136 }
137
98a8e1e5 138 switch (which)
c906108c 139 {
98a8e1e5
RH
140 case 0: /* integer registers */
141 /* PC is in slot 32; UNIQUE is in slot 33, if present. */
142 alpha_supply_int_regs (-1, core_reg_sect, core_reg_sect + 31*8,
143 (core_reg_size >= 33 * 8
144 ? core_reg_sect + 32*8 : NULL));
145 break;
146
147 case 2: /* floating-point registers */
148 /* FPCR is in slot 32. */
149 alpha_supply_fp_regs (-1, core_reg_sect, core_reg_sect + 31*8);
150 break;
151
152 default:
153 break;
c906108c
SS
154 }
155}
156
157
158/* Map gdb internal register number to a ptrace ``address''.
87d1b352
RH
159 These ``addresses'' are defined in <sys/ptrace.h>, with
160 the exception of ALPHA_UNIQUE_PTRACE_ADDR. */
c906108c 161
87d1b352
RH
162#ifndef ALPHA_UNIQUE_PTRACE_ADDR
163#define ALPHA_UNIQUE_PTRACE_ADDR 0
164#endif
c906108c
SS
165
166CORE_ADDR
fba45db2 167register_addr (int regno, CORE_ADDR blockend)
c906108c 168{
87d1b352
RH
169 if (regno == PC_REGNUM)
170 return PC;
171 if (regno == ALPHA_UNIQUE_REGNUM)
172 return ALPHA_UNIQUE_PTRACE_ADDR;
173 if (regno < FP0_REGNUM)
174 return GPR_BASE + regno;
175 else
176 return FPR_BASE + regno - FP0_REGNUM;
c906108c
SS
177}
178
179int
fba45db2 180kernel_u_size (void)
c906108c
SS
181{
182 return (sizeof (struct user));
183}
184
185#if defined(USE_PROC_FS) || defined(HAVE_GREGSET_T)
186#include <sys/procfs.h>
187
c60c0f5f
MS
188/* Prototypes for supply_gregset etc. */
189#include "gregset.h"
190
98a8e1e5
RH
191/* Locate the UNIQUE value within the gregset_t. */
192#ifndef ALPHA_REGSET_UNIQUE
193#define ALPHA_REGSET_UNIQUE(ptr) NULL
194#endif
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 202{
52f0bd74 203 long *regp = ALPHA_REGSET_BASE (gregsetp);
98a8e1e5 204 void *unique = ALPHA_REGSET_UNIQUE (gregsetp);
c906108c 205
98a8e1e5
RH
206 /* PC is in slot 32. */
207 alpha_supply_int_regs (-1, regp, regp + 31, unique);
c906108c
SS
208}
209
210void
ce589877 211fill_gregset (gdb_gregset_t *gregsetp, int regno)
c906108c 212{
52f0bd74 213 long *regp = ALPHA_REGSET_BASE (gregsetp);
98a8e1e5 214 void *unique = ALPHA_REGSET_UNIQUE (gregsetp);
c906108c 215
98a8e1e5
RH
216 /* PC is in slot 32. */
217 alpha_fill_int_regs (regno, regp, regp + 31, unique);
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 227{
52f0bd74 228 long *regp = ALPHA_REGSET_BASE (fpregsetp);
c906108c 229
98a8e1e5
RH
230 /* FPCR is in slot 32. */
231 alpha_supply_fp_regs (-1, regp, regp + 31);
c906108c
SS
232}
233
234void
ce589877 235fill_fpregset (gdb_fpregset_t *fpregsetp, int regno)
c906108c 236{
52f0bd74 237 long *regp = ALPHA_REGSET_BASE (fpregsetp);
c906108c 238
98a8e1e5
RH
239 /* FPCR is in slot 32. */
240 alpha_fill_fp_regs (regno, regp, regp + 31);
c906108c
SS
241}
242#endif
c906108c 243\f
c5aa993b 244
c906108c
SS
245/* Register that we are able to handle alpha core file formats. */
246
247static struct core_fns alpha_osf_core_fns =
248{
249 /* This really is bfd_target_unknown_flavour. */
250
2acceee2
JM
251 bfd_target_unknown_flavour, /* core_flavour */
252 default_check_format, /* check_format */
253 default_core_sniffer, /* core_sniffer */
254 fetch_osf_core_registers, /* core_read_registers */
255 NULL /* next */
c906108c
SS
256};
257
258static struct core_fns alpha_elf_core_fns =
259{
2acceee2
JM
260 bfd_target_elf_flavour, /* core_flavour */
261 default_check_format, /* check_format */
262 default_core_sniffer, /* core_sniffer */
263 fetch_elf_core_registers, /* core_read_registers */
264 NULL /* next */
c906108c
SS
265};
266
267void
fba45db2 268_initialize_core_alpha (void)
c906108c 269{
00e32a35
AC
270 deprecated_add_core_fns (&alpha_osf_core_fns);
271 deprecated_add_core_fns (&alpha_elf_core_fns);
c906108c 272}