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