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