1130812Smarcel/* Low level Alpha interface, for GDB when running native. 2130812Smarcel Copyright 1993, 1995, 1996, 1998, 1999, 2000, 2001, 2003 3130812Smarcel Free Software Foundation, Inc. 4130812Smarcel 5130812Smarcel This file is part of GDB. 6130812Smarcel 7130812Smarcel This program is free software; you can redistribute it and/or modify 8130812Smarcel it under the terms of the GNU General Public License as published by 9130812Smarcel the Free Software Foundation; either version 2 of the License, or 10130812Smarcel (at your option) any later version. 11130812Smarcel 12130812Smarcel This program is distributed in the hope that it will be useful, 13130812Smarcel but WITHOUT ANY WARRANTY; without even the implied warranty of 14130812Smarcel MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15130812Smarcel GNU General Public License for more details. 16130812Smarcel 17130812Smarcel You should have received a copy of the GNU General Public License 18130812Smarcel along with this program; if not, write to the Free Software 19130812Smarcel Foundation, Inc., 59 Temple Place - Suite 330, 20130812Smarcel Boston, MA 02111-1307, USA. */ 21130812Smarcel 22130812Smarcel#include "defs.h" 23130812Smarcel#include "gdb_string.h" 24130812Smarcel#include "inferior.h" 25130812Smarcel#include "gdbcore.h" 26130812Smarcel#include "target.h" 27130812Smarcel#include "regcache.h" 28130812Smarcel 29130812Smarcel#include "alpha-tdep.h" 30130812Smarcel 31130812Smarcel#include <sys/ptrace.h> 32130812Smarcel#ifdef __linux__ 33130812Smarcel#include <asm/reg.h> 34130812Smarcel#include <alpha/ptrace.h> 35130812Smarcel#else 36130812Smarcel#include <alpha/coreregs.h> 37130812Smarcel#endif 38130812Smarcel#include <sys/user.h> 39130812Smarcel 40130812Smarcel/* Prototypes for local functions. */ 41130812Smarcel 42130812Smarcelstatic void fetch_osf_core_registers (char *, unsigned, int, CORE_ADDR); 43130812Smarcelstatic void fetch_elf_core_registers (char *, unsigned, int, CORE_ADDR); 44130812Smarcel 45130812Smarcel/* Extract the register values out of the core file and store 46130812Smarcel them where `read_register' will find them. 47130812Smarcel 48130812Smarcel CORE_REG_SECT points to the register values themselves, read into memory. 49130812Smarcel CORE_REG_SIZE is the size of that area. 50130812Smarcel WHICH says which set of registers we are handling (0 = int, 2 = float 51130812Smarcel on machines where they are discontiguous). 52130812Smarcel REG_ADDR is the offset from u.u_ar0 to the register values relative to 53130812Smarcel core_reg_sect. This is used with old-fashioned core files to 54130812Smarcel locate the registers in a large upage-plus-stack ".reg" section. 55130812Smarcel Original upage address X is at location core_reg_sect+x+reg_addr. 56130812Smarcel */ 57130812Smarcel 58130812Smarcelstatic void 59130812Smarcelfetch_osf_core_registers (char *core_reg_sect, unsigned core_reg_size, 60130812Smarcel int which, CORE_ADDR reg_addr) 61130812Smarcel{ 62130812Smarcel int regno; 63130812Smarcel int addr; 64130812Smarcel int bad_reg = -1; 65130812Smarcel 66130812Smarcel /* Table to map a gdb regnum to an index in the core register 67130812Smarcel section. The floating point register values are garbage in 68130812Smarcel OSF/1.2 core files. OSF5 uses different names for the register 69130812Smarcel enum list, need to handle two cases. The actual values are the 70130812Smarcel same. */ 71130812Smarcel static int const core_reg_mapping[ALPHA_NUM_REGS] = 72130812Smarcel { 73130812Smarcel#ifdef NCF_REGS 74130812Smarcel#define EFL NCF_REGS 75130812Smarcel CF_V0, CF_T0, CF_T1, CF_T2, CF_T3, CF_T4, CF_T5, CF_T6, 76130812Smarcel CF_T7, CF_S0, CF_S1, CF_S2, CF_S3, CF_S4, CF_S5, CF_S6, 77130812Smarcel CF_A0, CF_A1, CF_A2, CF_A3, CF_A4, CF_A5, CF_T8, CF_T9, 78130812Smarcel CF_T10, CF_T11, CF_RA, CF_T12, CF_AT, CF_GP, CF_SP, -1, 79130812Smarcel EFL + 0, EFL + 1, EFL + 2, EFL + 3, EFL + 4, EFL + 5, EFL + 6, EFL + 7, 80130812Smarcel EFL + 8, EFL + 9, EFL + 10, EFL + 11, EFL + 12, EFL + 13, EFL + 14, EFL + 15, 81130812Smarcel EFL + 16, EFL + 17, EFL + 18, EFL + 19, EFL + 20, EFL + 21, EFL + 22, EFL + 23, 82130812Smarcel EFL + 24, EFL + 25, EFL + 26, EFL + 27, EFL + 28, EFL + 29, EFL + 30, EFL + 31, 83130812Smarcel CF_PC, -1 84130812Smarcel#else 85130812Smarcel#define EFL (EF_SIZE / 8) 86130812Smarcel EF_V0, EF_T0, EF_T1, EF_T2, EF_T3, EF_T4, EF_T5, EF_T6, 87130812Smarcel EF_T7, EF_S0, EF_S1, EF_S2, EF_S3, EF_S4, EF_S5, EF_S6, 88130812Smarcel EF_A0, EF_A1, EF_A2, EF_A3, EF_A4, EF_A5, EF_T8, EF_T9, 89130812Smarcel EF_T10, EF_T11, EF_RA, EF_T12, EF_AT, EF_GP, EF_SP, -1, 90130812Smarcel EFL + 0, EFL + 1, EFL + 2, EFL + 3, EFL + 4, EFL + 5, EFL + 6, EFL + 7, 91130812Smarcel EFL + 8, EFL + 9, EFL + 10, EFL + 11, EFL + 12, EFL + 13, EFL + 14, EFL + 15, 92130812Smarcel EFL + 16, EFL + 17, EFL + 18, EFL + 19, EFL + 20, EFL + 21, EFL + 22, EFL + 23, 93130812Smarcel EFL + 24, EFL + 25, EFL + 26, EFL + 27, EFL + 28, EFL + 29, EFL + 30, EFL + 31, 94130812Smarcel EF_PC, -1 95130812Smarcel#endif 96130812Smarcel }; 97130812Smarcel 98130812Smarcel for (regno = 0; regno < ALPHA_NUM_REGS; regno++) 99130812Smarcel { 100130812Smarcel if (CANNOT_FETCH_REGISTER (regno)) 101130812Smarcel { 102130812Smarcel supply_register (regno, NULL); 103130812Smarcel continue; 104130812Smarcel } 105130812Smarcel addr = 8 * core_reg_mapping[regno]; 106130812Smarcel if (addr < 0 || addr >= core_reg_size) 107130812Smarcel { 108130812Smarcel /* ??? UNIQUE is a new addition. Don't generate an error. */ 109130812Smarcel if (regno == ALPHA_UNIQUE_REGNUM) 110130812Smarcel { 111130812Smarcel supply_register (regno, NULL); 112130812Smarcel continue; 113130812Smarcel } 114130812Smarcel if (bad_reg < 0) 115130812Smarcel bad_reg = regno; 116130812Smarcel } 117130812Smarcel else 118130812Smarcel { 119130812Smarcel supply_register (regno, core_reg_sect + addr); 120130812Smarcel } 121130812Smarcel } 122130812Smarcel if (bad_reg >= 0) 123130812Smarcel { 124130812Smarcel error ("Register %s not found in core file.", REGISTER_NAME (bad_reg)); 125130812Smarcel } 126130812Smarcel} 127130812Smarcel 128130812Smarcelstatic void 129130812Smarcelfetch_elf_core_registers (char *core_reg_sect, unsigned core_reg_size, 130130812Smarcel int which, CORE_ADDR reg_addr) 131130812Smarcel{ 132130812Smarcel if (core_reg_size < 32 * 8) 133130812Smarcel { 134130812Smarcel error ("Core file register section too small (%u bytes).", core_reg_size); 135130812Smarcel return; 136130812Smarcel } 137130812Smarcel 138130812Smarcel switch (which) 139130812Smarcel { 140130812Smarcel case 0: /* integer registers */ 141130812Smarcel /* PC is in slot 32; UNIQUE is in slot 33, if present. */ 142130812Smarcel alpha_supply_int_regs (-1, core_reg_sect, core_reg_sect + 31*8, 143130812Smarcel (core_reg_size >= 33 * 8 144130812Smarcel ? core_reg_sect + 32*8 : NULL)); 145130812Smarcel break; 146130812Smarcel 147130812Smarcel case 2: /* floating-point registers */ 148130812Smarcel /* FPCR is in slot 32. */ 149130812Smarcel alpha_supply_fp_regs (-1, core_reg_sect, core_reg_sect + 31*8); 150130812Smarcel break; 151130812Smarcel 152130812Smarcel default: 153130812Smarcel break; 154130812Smarcel } 155130812Smarcel} 156130812Smarcel 157130812Smarcel 158130812Smarcel/* Map gdb internal register number to a ptrace ``address''. 159130812Smarcel These ``addresses'' are defined in <sys/ptrace.h>, with 160130812Smarcel the exception of ALPHA_UNIQUE_PTRACE_ADDR. */ 161130812Smarcel 162130812Smarcel#ifndef ALPHA_UNIQUE_PTRACE_ADDR 163130812Smarcel#define ALPHA_UNIQUE_PTRACE_ADDR 0 164130812Smarcel#endif 165130812Smarcel 166130812SmarcelCORE_ADDR 167130812Smarcelregister_addr (int regno, CORE_ADDR blockend) 168130812Smarcel{ 169130812Smarcel if (regno == PC_REGNUM) 170130812Smarcel return PC; 171130812Smarcel if (regno == ALPHA_UNIQUE_REGNUM) 172130812Smarcel return ALPHA_UNIQUE_PTRACE_ADDR; 173130812Smarcel if (regno < FP0_REGNUM) 174130812Smarcel return GPR_BASE + regno; 175130812Smarcel else 176130812Smarcel return FPR_BASE + regno - FP0_REGNUM; 177130812Smarcel} 178130812Smarcel 179130812Smarcelint 180130812Smarcelkernel_u_size (void) 181130812Smarcel{ 182130812Smarcel return (sizeof (struct user)); 183130812Smarcel} 184130812Smarcel 185130812Smarcel#if defined(USE_PROC_FS) || defined(HAVE_GREGSET_T) 186130812Smarcel#include <sys/procfs.h> 187130812Smarcel 188130812Smarcel/* Prototypes for supply_gregset etc. */ 189130812Smarcel#include "gregset.h" 190130812Smarcel 191130812Smarcel/* Locate the UNIQUE value within the gregset_t. */ 192130812Smarcel#ifndef ALPHA_REGSET_UNIQUE 193130812Smarcel#define ALPHA_REGSET_UNIQUE(ptr) NULL 194130812Smarcel#endif 195130812Smarcel 196130812Smarcel/* 197130812Smarcel * See the comment in m68k-tdep.c regarding the utility of these functions. 198130812Smarcel */ 199130812Smarcel 200130812Smarcelvoid 201130812Smarcelsupply_gregset (gdb_gregset_t *gregsetp) 202130812Smarcel{ 203130812Smarcel long *regp = ALPHA_REGSET_BASE (gregsetp); 204130812Smarcel void *unique = ALPHA_REGSET_UNIQUE (gregsetp); 205130812Smarcel 206130812Smarcel /* PC is in slot 32. */ 207130812Smarcel alpha_supply_int_regs (-1, regp, regp + 31, unique); 208130812Smarcel} 209130812Smarcel 210130812Smarcelvoid 211130812Smarcelfill_gregset (gdb_gregset_t *gregsetp, int regno) 212130812Smarcel{ 213130812Smarcel long *regp = ALPHA_REGSET_BASE (gregsetp); 214130812Smarcel void *unique = ALPHA_REGSET_UNIQUE (gregsetp); 215130812Smarcel 216130812Smarcel /* PC is in slot 32. */ 217130812Smarcel alpha_fill_int_regs (regno, regp, regp + 31, unique); 218130812Smarcel} 219130812Smarcel 220130812Smarcel/* 221130812Smarcel * Now we do the same thing for floating-point registers. 222130812Smarcel * Again, see the comments in m68k-tdep.c. 223130812Smarcel */ 224130812Smarcel 225130812Smarcelvoid 226130812Smarcelsupply_fpregset (gdb_fpregset_t *fpregsetp) 227130812Smarcel{ 228130812Smarcel long *regp = ALPHA_REGSET_BASE (fpregsetp); 229130812Smarcel 230130812Smarcel /* FPCR is in slot 32. */ 231130812Smarcel alpha_supply_fp_regs (-1, regp, regp + 31); 232130812Smarcel} 233130812Smarcel 234130812Smarcelvoid 235130812Smarcelfill_fpregset (gdb_fpregset_t *fpregsetp, int regno) 236130812Smarcel{ 237130812Smarcel long *regp = ALPHA_REGSET_BASE (fpregsetp); 238130812Smarcel 239130812Smarcel /* FPCR is in slot 32. */ 240130812Smarcel alpha_fill_fp_regs (regno, regp, regp + 31); 241130812Smarcel} 242130812Smarcel#endif 243130812Smarcel 244130812Smarcel 245130812Smarcel/* Register that we are able to handle alpha core file formats. */ 246130812Smarcel 247130812Smarcelstatic struct core_fns alpha_osf_core_fns = 248130812Smarcel{ 249130812Smarcel /* This really is bfd_target_unknown_flavour. */ 250130812Smarcel 251130812Smarcel bfd_target_unknown_flavour, /* core_flavour */ 252130812Smarcel default_check_format, /* check_format */ 253130812Smarcel default_core_sniffer, /* core_sniffer */ 254130812Smarcel fetch_osf_core_registers, /* core_read_registers */ 255130812Smarcel NULL /* next */ 256130812Smarcel}; 257130812Smarcel 258130812Smarcelstatic struct core_fns alpha_elf_core_fns = 259130812Smarcel{ 260130812Smarcel bfd_target_elf_flavour, /* core_flavour */ 261130812Smarcel default_check_format, /* check_format */ 262130812Smarcel default_core_sniffer, /* core_sniffer */ 263130812Smarcel fetch_elf_core_registers, /* core_read_registers */ 264130812Smarcel NULL /* next */ 265130812Smarcel}; 266130812Smarcel 267130812Smarcelvoid 268130812Smarcel_initialize_core_alpha (void) 269130812Smarcel{ 270130812Smarcel add_core_fns (&alpha_osf_core_fns); 271130812Smarcel add_core_fns (&alpha_elf_core_fns); 272130812Smarcel} 273