1 /* Low level Alpha interface, for GDB when running native. 2 Copyright 1993, 1995, 1996, 1998, 1999, 2000, 2001, 2003 3 Free Software Foundation, Inc. 4 5 This file is part of GDB. 6 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. 11 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. 16 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. */ 21 22 #include "defs.h" 23 #include "gdb_string.h" 24 #include "inferior.h" 25 #include "gdbcore.h" 26 #include "target.h" 27 #include "regcache.h" 28 29 #include "alpha-tdep.h" 30 31 #include <sys/ptrace.h> 32 #ifdef __linux__ 33 #include <asm/reg.h> 34 #include <alpha/ptrace.h> 35 #else 36 #include <alpha/coreregs.h> 37 #endif 38 #include <sys/user.h> 39 40 /* Prototypes for local functions. */ 41 42 static void fetch_osf_core_registers (char *, unsigned, int, CORE_ADDR); 43 static void fetch_elf_core_registers (char *, unsigned, int, CORE_ADDR); 44 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 51 on machines where they are discontiguous). 52 REG_ADDR is the offset from u.u_ar0 to the register values relative to 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. 56 */ 57 58 static void 59 fetch_osf_core_registers (char *core_reg_sect, unsigned core_reg_size, 60 int which, CORE_ADDR reg_addr) 61 { 62 int regno; 63 int addr; 64 int bad_reg = -1; 65 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. */ 71 static int const core_reg_mapping[ALPHA_NUM_REGS] = 72 { 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 85 #define EFL (EF_SIZE / 8) 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 95 #endif 96 }; 97 98 for (regno = 0; regno < ALPHA_NUM_REGS; regno++) 99 { 100 if (CANNOT_FETCH_REGISTER (regno)) 101 { 102 regcache_raw_supply (current_regcache, regno, NULL); 103 continue; 104 } 105 addr = 8 * core_reg_mapping[regno]; 106 if (addr < 0 || addr >= core_reg_size) 107 { 108 /* ??? UNIQUE is a new addition. Don't generate an error. */ 109 if (regno == ALPHA_UNIQUE_REGNUM) 110 { 111 regcache_raw_supply (current_regcache, regno, NULL); 112 continue; 113 } 114 if (bad_reg < 0) 115 bad_reg = regno; 116 } 117 else 118 { 119 regcache_raw_supply (current_regcache, regno, core_reg_sect + addr); 120 } 121 } 122 if (bad_reg >= 0) 123 { 124 error ("Register %s not found in core file.", REGISTER_NAME (bad_reg)); 125 } 126 } 127 128 static void 129 fetch_elf_core_registers (char *core_reg_sect, unsigned core_reg_size, 130 int which, CORE_ADDR reg_addr) 131 { 132 if (core_reg_size < 32 * 8) 133 { 134 error ("Core file register section too small (%u bytes).", core_reg_size); 135 return; 136 } 137 138 switch (which) 139 { 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; 154 } 155 } 156 157 158 /* Map gdb internal register number to a ptrace ``address''. 159 These ``addresses'' are defined in <sys/ptrace.h>, with 160 the exception of ALPHA_UNIQUE_PTRACE_ADDR. */ 161 162 #ifndef ALPHA_UNIQUE_PTRACE_ADDR 163 #define ALPHA_UNIQUE_PTRACE_ADDR 0 164 #endif 165 166 CORE_ADDR 167 register_addr (int regno, CORE_ADDR blockend) 168 { 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; 177 } 178 179 int 180 kernel_u_size (void) 181 { 182 return (sizeof (struct user)); 183 } 184 185 #if defined(USE_PROC_FS) || defined(HAVE_GREGSET_T) 186 #include <sys/procfs.h> 187 188 /* Prototypes for supply_gregset etc. */ 189 #include "gregset.h" 190 191 /* Locate the UNIQUE value within the gregset_t. */ 192 #ifndef ALPHA_REGSET_UNIQUE 193 #define ALPHA_REGSET_UNIQUE(ptr) NULL 194 #endif 195 196 /* 197 * See the comment in m68k-tdep.c regarding the utility of these functions. 198 */ 199 200 void 201 supply_gregset (gdb_gregset_t *gregsetp) 202 { 203 long *regp = ALPHA_REGSET_BASE (gregsetp); 204 void *unique = ALPHA_REGSET_UNIQUE (gregsetp); 205 206 /* PC is in slot 32. */ 207 alpha_supply_int_regs (-1, regp, regp + 31, unique); 208 } 209 210 void 211 fill_gregset (gdb_gregset_t *gregsetp, int regno) 212 { 213 long *regp = ALPHA_REGSET_BASE (gregsetp); 214 void *unique = ALPHA_REGSET_UNIQUE (gregsetp); 215 216 /* PC is in slot 32. */ 217 alpha_fill_int_regs (regno, regp, regp + 31, unique); 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 225 void 226 supply_fpregset (gdb_fpregset_t *fpregsetp) 227 { 228 long *regp = ALPHA_REGSET_BASE (fpregsetp); 229 230 /* FPCR is in slot 32. */ 231 alpha_supply_fp_regs (-1, regp, regp + 31); 232 } 233 234 void 235 fill_fpregset (gdb_fpregset_t *fpregsetp, int regno) 236 { 237 long *regp = ALPHA_REGSET_BASE (fpregsetp); 238 239 /* FPCR is in slot 32. */ 240 alpha_fill_fp_regs (regno, regp, regp + 31); 241 } 242 #endif 243 244 245 /* Register that we are able to handle alpha core file formats. */ 246 247 static struct core_fns alpha_osf_core_fns = 248 { 249 /* This really is bfd_target_unknown_flavour. */ 250 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 */ 256 }; 257 258 static struct core_fns alpha_elf_core_fns = 259 { 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 */ 265 }; 266 267 void 268 _initialize_core_alpha (void) 269 { 270 deprecated_add_core_fns (&alpha_osf_core_fns); 271 deprecated_add_core_fns (&alpha_elf_core_fns); 272 } 273