GDB (API)
|
00001 /* Low level Alpha interface, for GDB when running native. 00002 Copyright (C) 1993-2013 Free Software Foundation, Inc. 00003 00004 This file is part of GDB. 00005 00006 This program is free software; you can redistribute it and/or modify 00007 it under the terms of the GNU General Public License as published by 00008 the Free Software Foundation; either version 3 of the License, or 00009 (at your option) any later version. 00010 00011 This program is distributed in the hope that it will be useful, 00012 but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 GNU General Public License for more details. 00015 00016 You should have received a copy of the GNU General Public License 00017 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 00018 00019 #include "defs.h" 00020 #include "gdb_string.h" 00021 #include "inferior.h" 00022 #include "gdbcore.h" 00023 #include "target.h" 00024 #include "procfs.h" 00025 #include "regcache.h" 00026 00027 #include "alpha-tdep.h" 00028 00029 #include <sys/ptrace.h> 00030 #include <alpha/coreregs.h> 00031 #include <sys/user.h> 00032 00033 00034 /* Extract the register values out of the core file and store 00035 them into REGCACHE. 00036 00037 CORE_REG_SECT points to the register values themselves, read into memory. 00038 CORE_REG_SIZE is the size of that area. 00039 WHICH says which set of registers we are handling (0 = int, 2 = float 00040 on machines where they are discontiguous). 00041 REG_ADDR is the offset from u.u_ar0 to the register values relative to 00042 core_reg_sect. This is used with old-fashioned core files to 00043 locate the registers in a large upage-plus-stack ".reg" section. 00044 Original upage address X is at location core_reg_sect+x+reg_addr. */ 00045 00046 static void 00047 fetch_osf_core_registers (struct regcache *regcache, 00048 char *core_reg_sect, unsigned core_reg_size, 00049 int which, CORE_ADDR reg_addr) 00050 { 00051 struct gdbarch *gdbarch = get_regcache_arch (regcache); 00052 int regno; 00053 int addr; 00054 int bad_reg = -1; 00055 00056 /* Table to map a gdb regnum to an index in the core register 00057 section. The floating point register values are garbage in 00058 OSF/1.2 core files. OSF5 uses different names for the register 00059 enum list, need to handle two cases. The actual values are the 00060 same. */ 00061 static int const core_reg_mapping[ALPHA_NUM_REGS] = 00062 { 00063 #ifdef NCF_REGS 00064 #define EFL NCF_REGS 00065 CF_V0, CF_T0, CF_T1, CF_T2, CF_T3, CF_T4, CF_T5, CF_T6, 00066 CF_T7, CF_S0, CF_S1, CF_S2, CF_S3, CF_S4, CF_S5, CF_S6, 00067 CF_A0, CF_A1, CF_A2, CF_A3, CF_A4, CF_A5, CF_T8, CF_T9, 00068 CF_T10, CF_T11, CF_RA, CF_T12, CF_AT, CF_GP, CF_SP, -1, 00069 EFL + 0, EFL + 1, EFL + 2, EFL + 3, 00070 EFL + 4, EFL + 5, EFL + 6, EFL + 7, 00071 EFL + 8, EFL + 9, EFL + 10, EFL + 11, 00072 EFL + 12, EFL + 13, EFL + 14, EFL + 15, 00073 EFL + 16, EFL + 17, EFL + 18, EFL + 19, 00074 EFL + 20, EFL + 21, EFL + 22, EFL + 23, 00075 EFL + 24, EFL + 25, EFL + 26, EFL + 27, 00076 EFL + 28, EFL + 29, EFL + 30, EFL + 31, 00077 CF_PC, -1, -1 00078 #else 00079 #define EFL (EF_SIZE / 8) 00080 EF_V0, EF_T0, EF_T1, EF_T2, EF_T3, EF_T4, EF_T5, EF_T6, 00081 EF_T7, EF_S0, EF_S1, EF_S2, EF_S3, EF_S4, EF_S5, EF_S6, 00082 EF_A0, EF_A1, EF_A2, EF_A3, EF_A4, EF_A5, EF_T8, EF_T9, 00083 EF_T10, EF_T11, EF_RA, EF_T12, EF_AT, EF_GP, EF_SP, -1, 00084 EFL + 0, EFL + 1, EFL + 2, EFL + 3, 00085 EFL + 4, EFL + 5, EFL + 6, EFL + 7, 00086 EFL + 8, EFL + 9, EFL + 10, EFL + 11, 00087 EFL + 12, EFL + 13, EFL + 14, EFL + 15, 00088 EFL + 16, EFL + 17, EFL + 18, EFL + 19, 00089 EFL + 20, EFL + 21, EFL + 22, EFL + 23, 00090 EFL + 24, EFL + 25, EFL + 26, EFL + 27, 00091 EFL + 28, EFL + 29, EFL + 30, EFL + 31, 00092 EF_PC, -1, -1 00093 #endif 00094 }; 00095 00096 for (regno = 0; regno < ALPHA_NUM_REGS; regno++) 00097 { 00098 if (gdbarch_cannot_fetch_register (gdbarch, regno)) 00099 { 00100 regcache_raw_supply (regcache, regno, NULL); 00101 continue; 00102 } 00103 00104 if (regno == ALPHA_ZERO_REGNUM) 00105 { 00106 const gdb_byte zero[8] = { 0 }; 00107 00108 regcache_raw_supply (regcache, regno, zero); 00109 continue; 00110 } 00111 00112 addr = 8 * core_reg_mapping[regno]; 00113 if (addr < 0 || addr >= core_reg_size) 00114 { 00115 /* ??? UNIQUE is a new addition. Don't generate an error. */ 00116 if (regno == ALPHA_UNIQUE_REGNUM) 00117 { 00118 regcache_raw_supply (regcache, regno, NULL); 00119 continue; 00120 } 00121 if (bad_reg < 0) 00122 bad_reg = regno; 00123 } 00124 else 00125 { 00126 regcache_raw_supply (regcache, regno, core_reg_sect + addr); 00127 } 00128 } 00129 if (bad_reg >= 0) 00130 { 00131 error (_("Register %s not found in core file."), 00132 gdbarch_register_name (gdbarch, bad_reg)); 00133 } 00134 } 00135 00136 00137 #include <sys/procfs.h> 00138 /* Prototypes for supply_gregset etc. */ 00139 #include "gregset.h" 00140 00141 /* See the comment in m68k-tdep.c regarding the utility of these 00142 functions. */ 00143 00144 void 00145 supply_gregset (struct regcache *regcache, const gdb_gregset_t *gregsetp) 00146 { 00147 const long *regp = gregsetp->regs; 00148 00149 /* PC is in slot 32. */ 00150 alpha_supply_int_regs (regcache, -1, regp, regp + 31, NULL); 00151 } 00152 00153 void 00154 fill_gregset (const struct regcache *regcache, 00155 gdb_gregset_t *gregsetp, int regno) 00156 { 00157 long *regp = gregsetp->regs; 00158 00159 /* PC is in slot 32. */ 00160 alpha_fill_int_regs (regcache, regno, regp, regp + 31, NULL); 00161 } 00162 00163 /* Now we do the same thing for floating-point registers. 00164 Again, see the comments in m68k-tdep.c. */ 00165 00166 void 00167 supply_fpregset (struct regcache *regcache, const gdb_fpregset_t *fpregsetp) 00168 { 00169 const long *regp = fpregsetp->regs; 00170 00171 /* FPCR is in slot 32. */ 00172 alpha_supply_fp_regs (regcache, -1, regp, regp + 31); 00173 } 00174 00175 void 00176 fill_fpregset (const struct regcache *regcache, 00177 gdb_fpregset_t *fpregsetp, int regno) 00178 { 00179 long *regp = fpregsetp->regs; 00180 00181 /* FPCR is in slot 32. */ 00182 alpha_fill_fp_regs (regcache, regno, regp, regp + 31); 00183 } 00184 00185 00186 /* Register that we are able to handle alpha core file formats. */ 00187 00188 static struct core_fns alpha_osf_core_fns = 00189 { 00190 /* This really is bfd_target_unknown_flavour. */ 00191 00192 bfd_target_unknown_flavour, /* core_flavour */ 00193 default_check_format, /* check_format */ 00194 default_core_sniffer, /* core_sniffer */ 00195 fetch_osf_core_registers, /* core_read_registers */ 00196 NULL /* next */ 00197 }; 00198 00199 /* Provide a prototype to silence -Wmissing-prototypes. */ 00200 extern initialize_file_ftype _initialize_alpha_nat; 00201 00202 void 00203 _initialize_alpha_nat (void) 00204 { 00205 struct target_ops *t; 00206 00207 t = procfs_target (); 00208 add_target (t); 00209 00210 deprecated_add_core_fns (&alpha_osf_core_fns); 00211 }