* configure.in (AC_PREREQ): autoconf 2.5 or higher.
[deliverable/binutils-gdb.git] / gdb / alpha-nat.c
CommitLineData
cef4c2e7 1/* Low level Alpha interface, for GDB when running native.
7531f36e 2 Copyright 1993, 1995, 1996 Free Software Foundation, Inc.
cef4c2e7
PS
3
4This file is part of GDB.
5
6This program is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2 of the License, or
9(at your option) any later version.
10
11This program is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with this program; if not, write to the Free Software
6c9638b4 18Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
cef4c2e7
PS
19
20#include "defs.h"
21#include "inferior.h"
22#include "gdbcore.h"
23#include "target.h"
24#include <sys/ptrace.h>
9391c997
FF
25#ifdef __linux__
26# include <asm/reg.h>
27# include <alpha/ptrace.h>
28#else
29# include <machine/reg.h>
30#endif
7531f36e 31#include <sys/user.h>
cef4c2e7
PS
32
33/* Size of elements in jmpbuf */
34
35#define JB_ELEMENT_SIZE 8
36
37/* The definition for JB_PC in machine/reg.h is wrong.
38 And we can't get at the correct definition in setjmp.h as it is
39 not always available (eg. if _POSIX_SOURCE is defined which is the
40 default). As the defintion is unlikely to change (see comment
41 in <setjmp.h>, define the correct value here. */
42
43#undef JB_PC
44#define JB_PC 2
45
46/* Figure out where the longjmp will land.
47 We expect the first arg to be a pointer to the jmp_buf structure from which
48 we extract the pc (JB_PC) that we will land at. The pc is copied into PC.
49 This routine returns true on success. */
50
51int
52get_longjmp_target (pc)
53 CORE_ADDR *pc;
54{
55 CORE_ADDR jb_addr;
56 char raw_buffer[MAX_REGISTER_RAW_SIZE];
57
58 jb_addr = read_register(A0_REGNUM);
59
60 if (target_read_memory(jb_addr + JB_PC * JB_ELEMENT_SIZE, raw_buffer,
61 sizeof(CORE_ADDR)))
62 return 0;
63
64 *pc = extract_address (raw_buffer, sizeof(CORE_ADDR));
65 return 1;
66}
67
68/* Extract the register values out of the core file and store
69 them where `read_register' will find them.
70
71 CORE_REG_SECT points to the register values themselves, read into memory.
72 CORE_REG_SIZE is the size of that area.
73 WHICH says which set of registers we are handling (0 = int, 2 = float
74 on machines where they are discontiguous).
75 REG_ADDR is the offset from u.u_ar0 to the register values relative to
76 core_reg_sect. This is used with old-fashioned core files to
77 locate the registers in a large upage-plus-stack ".reg" section.
78 Original upage address X is at location core_reg_sect+x+reg_addr.
79 */
80
a1df8e78 81static void
cef4c2e7
PS
82fetch_core_registers (core_reg_sect, core_reg_size, which, reg_addr)
83 char *core_reg_sect;
84 unsigned core_reg_size;
85 int which;
86 unsigned reg_addr;
87{
88 register int regno;
89 register int addr;
90 int bad_reg = -1;
91
92 /* Table to map a gdb regnum to an index in the core register section.
93 The floating point register values are garbage in OSF/1.2 core files. */
94 static int core_reg_mapping[NUM_REGS] =
95 {
96#define EFL (EF_SIZE / 8)
97 EF_V0, EF_T0, EF_T1, EF_T2, EF_T3, EF_T4, EF_T5, EF_T6,
98 EF_T7, EF_S0, EF_S1, EF_S2, EF_S3, EF_S4, EF_S5, EF_S6,
99 EF_A0, EF_A1, EF_A2, EF_A3, EF_A4, EF_A5, EF_T8, EF_T9,
100 EF_T10, EF_T11, EF_RA, EF_T12, EF_AT, EF_GP, EF_SP, -1,
101 EFL+0, EFL+1, EFL+2, EFL+3, EFL+4, EFL+5, EFL+6, EFL+7,
102 EFL+8, EFL+9, EFL+10, EFL+11, EFL+12, EFL+13, EFL+14, EFL+15,
103 EFL+16, EFL+17, EFL+18, EFL+19, EFL+20, EFL+21, EFL+22, EFL+23,
104 EFL+24, EFL+25, EFL+26, EFL+27, EFL+28, EFL+29, EFL+30, EFL+31,
105 EF_PC, -1
106 };
107 static char zerobuf[MAX_REGISTER_RAW_SIZE] = {0};
108
109 for (regno = 0; regno < NUM_REGS; regno++)
110 {
111 if (CANNOT_FETCH_REGISTER (regno))
112 {
113 supply_register (regno, zerobuf);
114 continue;
115 }
116 addr = 8 * core_reg_mapping[regno];
117 if (addr < 0 || addr >= core_reg_size)
118 {
119 if (bad_reg < 0)
120 bad_reg = regno;
121 }
122 else
123 {
124 supply_register (regno, core_reg_sect + addr);
125 }
126 }
127 if (bad_reg >= 0)
128 {
129 error ("Register %s not found in core file.", reg_names[bad_reg]);
130 }
131}
132
133/* Map gdb internal register number to a ptrace ``address''.
134 These ``addresses'' are defined in <sys/ptrace.h> */
135
136#define REGISTER_PTRACE_ADDR(regno) \
137 (regno < FP0_REGNUM ? GPR_BASE + (regno) \
138 : regno == PC_REGNUM ? PC \
139 : regno >= FP0_REGNUM ? FPR_BASE + ((regno) - FP0_REGNUM) \
140 : 0)
141
142/* Return the ptrace ``address'' of register REGNO. */
143
144unsigned int
145register_addr (regno, blockend)
146 int regno;
147 int blockend;
148{
149 return REGISTER_PTRACE_ADDR (regno);
150}
2592eef8 151
7531f36e
FF
152int
153kernel_u_size ()
154{
155 return (sizeof (struct user));
156}
157
2592eef8
PS
158#ifdef USE_PROC_FS
159#include <sys/procfs.h>
160
161/*
162 * See the comment in m68k-tdep.c regarding the utility of these functions.
163 */
164
165void
166supply_gregset (gregsetp)
167 gregset_t *gregsetp;
168{
169 register int regi;
170 register long *regp = gregsetp->regs;
3f403f6a 171 static char zerobuf[MAX_REGISTER_RAW_SIZE] = {0};
2592eef8
PS
172
173 for (regi = 0; regi < 31; regi++)
174 supply_register (regi, (char *)(regp + regi));
175
176 supply_register (PC_REGNUM, (char *)(regp + 31));
3f403f6a
PS
177
178 /* Fill inaccessible registers with zero. */
179 supply_register (ZERO_REGNUM, zerobuf);
180 supply_register (FP_REGNUM, zerobuf);
2592eef8
PS
181}
182
183void
184fill_gregset (gregsetp, regno)
185 gregset_t *gregsetp;
186 int regno;
187{
188 int regi;
189 register long *regp = gregsetp->regs;
190
191 for (regi = 0; regi < 31; regi++)
192 if ((regno == -1) || (regno == regi))
193 *(regp + regi) = *(long *) &registers[REGISTER_BYTE (regi)];
194
195 if ((regno == -1) || (regno == PC_REGNUM))
196 *(regp + 31) = *(long *) &registers[REGISTER_BYTE (PC_REGNUM)];
197}
198
199/*
200 * Now we do the same thing for floating-point registers.
201 * Again, see the comments in m68k-tdep.c.
202 */
203
204void
205supply_fpregset (fpregsetp)
206 fpregset_t *fpregsetp;
207{
208 register int regi;
209 register long *regp = fpregsetp->regs;
210
211 for (regi = 0; regi < 32; regi++)
212 supply_register (regi + FP0_REGNUM, (char *)(regp + regi));
213}
214
215void
216fill_fpregset (fpregsetp, regno)
217 fpregset_t *fpregsetp;
218 int regno;
219{
220 int regi;
221 register long *regp = fpregsetp->regs;
222
223 for (regi = FP0_REGNUM; regi < FP0_REGNUM + 32; regi++)
224 {
225 if ((regno == -1) || (regno == regi))
226 {
227 *(regp + regi - FP0_REGNUM) =
228 *(long *) &registers[REGISTER_BYTE (regi)];
229 }
230 }
231}
232#endif
a1df8e78
FF
233
234\f
235/* Register that we are able to handle alpha core file formats. */
236
237static struct core_fns alpha_core_fns =
238{
239 bfd_target_aout_flavour,
240 fetch_core_registers,
241 NULL
242};
243
244void
245_initialize_core_alpha ()
246{
247 add_core_fns (&alpha_core_fns);
248}
This page took 0.127552 seconds and 4 git commands to generate.