1 /* Functions specific to running GDB native on HPPA running GNU/Linux. 2 3 Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 4 Free Software Foundation, Inc. 5 6 This file is part of GDB. 7 8 This program is free software; you can redistribute it and/or modify 9 it under the terms of the GNU General Public License as published by 10 the Free Software Foundation; either version 3 of the License, or 11 (at your option) any later version. 12 13 This program is distributed in the hope that it will be useful, 14 but WITHOUT ANY WARRANTY; without even the implied warranty of 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 GNU General Public License for more details. 17 18 You should have received a copy of the GNU General Public License 19 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 20 21 #include "defs.h" 22 #include "gdbcore.h" 23 #include "regcache.h" 24 #include "gdb_string.h" 25 #include "inferior.h" 26 #include "target.h" 27 #include "linux-nat.h" 28 29 #include <sys/procfs.h> 30 #include <sys/ptrace.h> 31 #include <linux/version.h> 32 33 #include <asm/ptrace.h> 34 #include "hppa-linux-offsets.h" 35 36 #include "hppa-tdep.h" 37 38 /* Prototypes for supply_gregset etc. */ 39 #include "gregset.h" 40 41 /* These must match the order of the register names. 42 43 Some sort of lookup table is needed because the offsets associated 44 with the registers are all over the board. */ 45 46 static const int u_offsets[] = 47 { 48 /* general registers */ 49 -1, 50 PT_GR1, 51 PT_GR2, 52 PT_GR3, 53 PT_GR4, 54 PT_GR5, 55 PT_GR6, 56 PT_GR7, 57 PT_GR8, 58 PT_GR9, 59 PT_GR10, 60 PT_GR11, 61 PT_GR12, 62 PT_GR13, 63 PT_GR14, 64 PT_GR15, 65 PT_GR16, 66 PT_GR17, 67 PT_GR18, 68 PT_GR19, 69 PT_GR20, 70 PT_GR21, 71 PT_GR22, 72 PT_GR23, 73 PT_GR24, 74 PT_GR25, 75 PT_GR26, 76 PT_GR27, 77 PT_GR28, 78 PT_GR29, 79 PT_GR30, 80 PT_GR31, 81 82 PT_SAR, 83 PT_IAOQ0, 84 PT_IASQ0, 85 PT_IAOQ1, 86 PT_IASQ1, 87 -1, /* eiem */ 88 PT_IIR, 89 PT_ISR, 90 PT_IOR, 91 PT_PSW, 92 -1, /* goto */ 93 94 PT_SR4, 95 PT_SR0, 96 PT_SR1, 97 PT_SR2, 98 PT_SR3, 99 PT_SR5, 100 PT_SR6, 101 PT_SR7, 102 103 -1, /* cr0 */ 104 -1, /* pid0 */ 105 -1, /* pid1 */ 106 -1, /* ccr */ 107 -1, /* pid2 */ 108 -1, /* pid3 */ 109 -1, /* cr24 */ 110 -1, /* cr25 */ 111 -1, /* cr26 */ 112 PT_CR27, 113 -1, /* cr28 */ 114 -1, /* cr29 */ 115 -1, /* cr30 */ 116 117 /* Floating point regs. */ 118 PT_FR0, PT_FR0 + 4, 119 PT_FR1, PT_FR1 + 4, 120 PT_FR2, PT_FR2 + 4, 121 PT_FR3, PT_FR3 + 4, 122 PT_FR4, PT_FR4 + 4, 123 PT_FR5, PT_FR5 + 4, 124 PT_FR6, PT_FR6 + 4, 125 PT_FR7, PT_FR7 + 4, 126 PT_FR8, PT_FR8 + 4, 127 PT_FR9, PT_FR9 + 4, 128 PT_FR10, PT_FR10 + 4, 129 PT_FR11, PT_FR11 + 4, 130 PT_FR12, PT_FR12 + 4, 131 PT_FR13, PT_FR13 + 4, 132 PT_FR14, PT_FR14 + 4, 133 PT_FR15, PT_FR15 + 4, 134 PT_FR16, PT_FR16 + 4, 135 PT_FR17, PT_FR17 + 4, 136 PT_FR18, PT_FR18 + 4, 137 PT_FR19, PT_FR19 + 4, 138 PT_FR20, PT_FR20 + 4, 139 PT_FR21, PT_FR21 + 4, 140 PT_FR22, PT_FR22 + 4, 141 PT_FR23, PT_FR23 + 4, 142 PT_FR24, PT_FR24 + 4, 143 PT_FR25, PT_FR25 + 4, 144 PT_FR26, PT_FR26 + 4, 145 PT_FR27, PT_FR27 + 4, 146 PT_FR28, PT_FR28 + 4, 147 PT_FR29, PT_FR29 + 4, 148 PT_FR30, PT_FR30 + 4, 149 PT_FR31, PT_FR31 + 4, 150 }; 151 152 static CORE_ADDR 153 hppa_linux_register_addr (int regno, CORE_ADDR blockend) 154 { 155 CORE_ADDR addr; 156 157 if ((unsigned) regno >= ARRAY_SIZE (u_offsets)) 158 error (_("Invalid register number %d."), regno); 159 160 if (u_offsets[regno] == -1) 161 addr = 0; 162 else 163 { 164 addr = (CORE_ADDR) u_offsets[regno]; 165 } 166 167 return addr; 168 } 169 170 /* 171 * Registers saved in a coredump: 172 * gr0..gr31 173 * sr0..sr7 174 * iaoq0..iaoq1 175 * iasq0..iasq1 176 * sar, iir, isr, ior, ipsw 177 * cr0, cr24..cr31 178 * cr8,9,12,13 179 * cr10, cr15 180 */ 181 #define GR_REGNUM(_n) (HPPA_R0_REGNUM+_n) 182 #define TR_REGNUM(_n) (HPPA_TR0_REGNUM+_n) 183 static const int greg_map[] = 184 { 185 GR_REGNUM(0), GR_REGNUM(1), GR_REGNUM(2), GR_REGNUM(3), 186 GR_REGNUM(4), GR_REGNUM(5), GR_REGNUM(6), GR_REGNUM(7), 187 GR_REGNUM(8), GR_REGNUM(9), GR_REGNUM(10), GR_REGNUM(11), 188 GR_REGNUM(12), GR_REGNUM(13), GR_REGNUM(14), GR_REGNUM(15), 189 GR_REGNUM(16), GR_REGNUM(17), GR_REGNUM(18), GR_REGNUM(19), 190 GR_REGNUM(20), GR_REGNUM(21), GR_REGNUM(22), GR_REGNUM(23), 191 GR_REGNUM(24), GR_REGNUM(25), GR_REGNUM(26), GR_REGNUM(27), 192 GR_REGNUM(28), GR_REGNUM(29), GR_REGNUM(30), GR_REGNUM(31), 193 194 HPPA_SR4_REGNUM+1, HPPA_SR4_REGNUM+2, HPPA_SR4_REGNUM+3, HPPA_SR4_REGNUM+4, 195 HPPA_SR4_REGNUM, HPPA_SR4_REGNUM+5, HPPA_SR4_REGNUM+6, HPPA_SR4_REGNUM+7, 196 197 HPPA_PCOQ_HEAD_REGNUM, HPPA_PCOQ_TAIL_REGNUM, 198 HPPA_PCSQ_HEAD_REGNUM, HPPA_PCSQ_TAIL_REGNUM, 199 200 HPPA_SAR_REGNUM, HPPA_IIR_REGNUM, HPPA_ISR_REGNUM, HPPA_IOR_REGNUM, 201 HPPA_IPSW_REGNUM, HPPA_RCR_REGNUM, 202 203 TR_REGNUM(0), TR_REGNUM(1), TR_REGNUM(2), TR_REGNUM(3), 204 TR_REGNUM(4), TR_REGNUM(5), TR_REGNUM(6), TR_REGNUM(7), 205 206 HPPA_PID0_REGNUM, HPPA_PID1_REGNUM, HPPA_PID2_REGNUM, HPPA_PID3_REGNUM, 207 HPPA_CCR_REGNUM, HPPA_EIEM_REGNUM, 208 }; 209 210 211 212 /* Fetch one register. */ 213 214 static void 215 fetch_register (struct regcache *regcache, int regno) 216 { 217 struct gdbarch *gdbarch = get_regcache_arch (regcache); 218 int tid; 219 int val; 220 221 if (gdbarch_cannot_fetch_register (gdbarch, regno)) 222 { 223 regcache_raw_supply (regcache, regno, NULL); 224 return; 225 } 226 227 /* GNU/Linux LWP ID's are process ID's. */ 228 tid = TIDGET (inferior_ptid); 229 if (tid == 0) 230 tid = PIDGET (inferior_ptid); /* Not a threaded program. */ 231 232 errno = 0; 233 val = ptrace (PTRACE_PEEKUSER, tid, hppa_linux_register_addr (regno, 0), 0); 234 if (errno != 0) 235 error (_("Couldn't read register %s (#%d): %s."), 236 gdbarch_register_name (gdbarch, regno), 237 regno, safe_strerror (errno)); 238 239 regcache_raw_supply (regcache, regno, &val); 240 } 241 242 /* Store one register. */ 243 244 static void 245 store_register (const struct regcache *regcache, int regno) 246 { 247 struct gdbarch *gdbarch = get_regcache_arch (regcache); 248 int tid; 249 int val; 250 251 if (gdbarch_cannot_store_register (gdbarch, regno)) 252 return; 253 254 /* GNU/Linux LWP ID's are process ID's. */ 255 tid = TIDGET (inferior_ptid); 256 if (tid == 0) 257 tid = PIDGET (inferior_ptid); /* Not a threaded program. */ 258 259 errno = 0; 260 regcache_raw_collect (regcache, regno, &val); 261 ptrace (PTRACE_POKEUSER, tid, hppa_linux_register_addr (regno, 0), val); 262 if (errno != 0) 263 error (_("Couldn't write register %s (#%d): %s."), 264 gdbarch_register_name (gdbarch, regno), 265 regno, safe_strerror (errno)); 266 } 267 268 /* Fetch registers from the child process. Fetch all registers if 269 regno == -1, otherwise fetch all general registers or all floating 270 point registers depending upon the value of regno. */ 271 272 static void 273 hppa_linux_fetch_inferior_registers (struct target_ops *ops, 274 struct regcache *regcache, int regno) 275 { 276 if (-1 == regno) 277 { 278 for (regno = 0; 279 regno < gdbarch_num_regs (get_regcache_arch (regcache)); 280 regno++) 281 fetch_register (regcache, regno); 282 } 283 else 284 { 285 fetch_register (regcache, regno); 286 } 287 } 288 289 /* Store registers back into the inferior. Store all registers if 290 regno == -1, otherwise store all general registers or all floating 291 point registers depending upon the value of regno. */ 292 293 static void 294 hppa_linux_store_inferior_registers (struct target_ops *ops, 295 struct regcache *regcache, int regno) 296 { 297 if (-1 == regno) 298 { 299 for (regno = 0; 300 regno < gdbarch_num_regs (get_regcache_arch (regcache)); 301 regno++) 302 store_register (regcache, regno); 303 } 304 else 305 { 306 store_register (regcache, regno); 307 } 308 } 309 310 /* Fill GDB's register array with the general-purpose register values 311 in *gregsetp. */ 312 313 void 314 supply_gregset (struct regcache *regcache, const gdb_gregset_t *gregsetp) 315 { 316 int i; 317 const greg_t *regp = (const elf_greg_t *) gregsetp; 318 319 for (i = 0; i < sizeof (greg_map) / sizeof (greg_map[0]); i++, regp++) 320 { 321 int regno = greg_map[i]; 322 regcache_raw_supply (regcache, regno, regp); 323 } 324 } 325 326 /* Fill register regno (if it is a general-purpose register) in 327 *gregsetp with the appropriate value from GDB's register array. 328 If regno is -1, do this for all registers. */ 329 330 void 331 fill_gregset (const struct regcache *regcache, 332 gdb_gregset_t *gregsetp, int regno) 333 { 334 int i; 335 336 for (i = 0; i < sizeof (greg_map) / sizeof (greg_map[0]); i++) 337 { 338 int mregno = greg_map[i]; 339 340 if (regno == -1 || regno == mregno) 341 { 342 regcache_raw_collect(regcache, mregno, &(*gregsetp)[i]); 343 } 344 } 345 } 346 347 /* Given a pointer to a floating point register set in /proc format 348 (fpregset_t *), unpack the register contents and supply them as gdb's 349 idea of the current floating point register values. */ 350 351 void 352 supply_fpregset (struct regcache *regcache, const gdb_fpregset_t *fpregsetp) 353 { 354 int regi; 355 const char *from; 356 357 for (regi = 0; regi <= 31; regi++) 358 { 359 from = (const char *) &((*fpregsetp)[regi]); 360 regcache_raw_supply (regcache, 2*regi + HPPA_FP0_REGNUM, from); 361 regcache_raw_supply (regcache, 2*regi + HPPA_FP0_REGNUM + 1, from + 4); 362 } 363 } 364 365 /* Given a pointer to a floating point register set in /proc format 366 (fpregset_t *), update the register specified by REGNO from gdb's idea 367 of the current floating point register set. If REGNO is -1, update 368 them all. */ 369 370 void 371 fill_fpregset (const struct regcache *regcache, 372 gdb_fpregset_t *fpregsetp, int regno) 373 { 374 int i; 375 376 for (i = HPPA_FP0_REGNUM; i < HPPA_FP0_REGNUM + 32 * 2; i++) 377 { 378 /* Gross. fpregset_t is double, registers[x] has single 379 precision reg. */ 380 char *to = (char *) &((*fpregsetp)[(i - HPPA_FP0_REGNUM) / 2]); 381 if ((i - HPPA_FP0_REGNUM) & 1) 382 to += 4; 383 regcache_raw_collect (regcache, i, to); 384 } 385 } 386 387 void _initialize_hppa_linux_nat (void); 388 389 void 390 _initialize_hppa_linux_nat (void) 391 { 392 struct target_ops *t; 393 394 /* Fill in the generic GNU/Linux methods. */ 395 t = linux_target (); 396 397 /* Add our register access methods. */ 398 t->to_fetch_registers = hppa_linux_fetch_inferior_registers; 399 t->to_store_registers = hppa_linux_store_inferior_registers; 400 401 /* Register the target. */ 402 linux_nat_add_target (t); 403 } 404