| 1 | /* PPC GNU/Linux native support. |
| 2 | |
| 3 | Copyright 1988, 1989, 1991, 1992, 1994, 1996, 2000, 2001, 2002, |
| 4 | 2003 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 2 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, write to the Free Software |
| 20 | Foundation, Inc., 59 Temple Place - Suite 330, |
| 21 | Boston, MA 02111-1307, USA. */ |
| 22 | |
| 23 | #include "defs.h" |
| 24 | #include "gdb_string.h" |
| 25 | #include "frame.h" |
| 26 | #include "inferior.h" |
| 27 | #include "gdbcore.h" |
| 28 | #include "regcache.h" |
| 29 | |
| 30 | #include <sys/types.h> |
| 31 | #include <sys/param.h> |
| 32 | #include <signal.h> |
| 33 | #include <sys/user.h> |
| 34 | #include <sys/ioctl.h> |
| 35 | #include "gdb_wait.h" |
| 36 | #include <fcntl.h> |
| 37 | #include <sys/procfs.h> |
| 38 | #include <sys/ptrace.h> |
| 39 | |
| 40 | /* Prototypes for supply_gregset etc. */ |
| 41 | #include "gregset.h" |
| 42 | #include "ppc-tdep.h" |
| 43 | |
| 44 | #ifndef PT_READ_U |
| 45 | #define PT_READ_U PTRACE_PEEKUSR |
| 46 | #endif |
| 47 | #ifndef PT_WRITE_U |
| 48 | #define PT_WRITE_U PTRACE_POKEUSR |
| 49 | #endif |
| 50 | |
| 51 | /* Default the type of the ptrace transfer to int. */ |
| 52 | #ifndef PTRACE_XFER_TYPE |
| 53 | #define PTRACE_XFER_TYPE int |
| 54 | #endif |
| 55 | |
| 56 | /* Glibc's headers don't define PTRACE_GETVRREGS so we cannot use a |
| 57 | configure time check. Some older glibc's (for instance 2.2.1) |
| 58 | don't have a specific powerpc version of ptrace.h, and fall back on |
| 59 | a generic one. In such cases, sys/ptrace.h defines |
| 60 | PTRACE_GETFPXREGS and PTRACE_SETFPXREGS to the same numbers that |
| 61 | ppc kernel's asm/ptrace.h defines PTRACE_GETVRREGS and |
| 62 | PTRACE_SETVRREGS to be. This also makes a configury check pretty |
| 63 | much useless. */ |
| 64 | |
| 65 | /* These definitions should really come from the glibc header files, |
| 66 | but Glibc doesn't know about the vrregs yet. */ |
| 67 | #ifndef PTRACE_GETVRREGS |
| 68 | #define PTRACE_GETVRREGS 18 |
| 69 | #define PTRACE_SETVRREGS 19 |
| 70 | #endif |
| 71 | |
| 72 | /* This oddity is because the Linux kernel defines elf_vrregset_t as |
| 73 | an array of 33 16 bytes long elements. I.e. it leaves out vrsave. |
| 74 | However the PTRACE_GETVRREGS and PTRACE_SETVRREGS requests return |
| 75 | the vrsave as an extra 4 bytes at the end. I opted for creating a |
| 76 | flat array of chars, so that it is easier to manipulate for gdb. |
| 77 | |
| 78 | There are 32 vector registers 16 bytes longs, plus a VSCR register |
| 79 | which is only 4 bytes long, but is fetched as a 16 bytes |
| 80 | quantity. Up to here we have the elf_vrregset_t structure. |
| 81 | Appended to this there is space for the VRSAVE register: 4 bytes. |
| 82 | Even though this vrsave register is not included in the regset |
| 83 | typedef, it is handled by the ptrace requests. |
| 84 | |
| 85 | Note that GNU/Linux doesn't support little endian PPC hardware, |
| 86 | therefore the offset at which the real value of the VSCR register |
| 87 | is located will be always 12 bytes. |
| 88 | |
| 89 | The layout is like this (where x is the actual value of the vscr reg): */ |
| 90 | |
| 91 | /* *INDENT-OFF* */ |
| 92 | /* |
| 93 | |.|.|.|.|.....|.|.|.|.||.|.|.|x||.| |
| 94 | <-------> <-------><-------><-> |
| 95 | VR0 VR31 VSCR VRSAVE |
| 96 | */ |
| 97 | /* *INDENT-ON* */ |
| 98 | |
| 99 | #define SIZEOF_VRREGS 33*16+4 |
| 100 | |
| 101 | typedef char gdb_vrregset_t[SIZEOF_VRREGS]; |
| 102 | |
| 103 | /* For runtime check of ptrace support for VRREGS. */ |
| 104 | int have_ptrace_getvrregs = 1; |
| 105 | |
| 106 | int |
| 107 | kernel_u_size (void) |
| 108 | { |
| 109 | return (sizeof (struct user)); |
| 110 | } |
| 111 | |
| 112 | /* *INDENT-OFF* */ |
| 113 | /* registers layout, as presented by the ptrace interface: |
| 114 | PT_R0, PT_R1, PT_R2, PT_R3, PT_R4, PT_R5, PT_R6, PT_R7, |
| 115 | PT_R8, PT_R9, PT_R10, PT_R11, PT_R12, PT_R13, PT_R14, PT_R15, |
| 116 | PT_R16, PT_R17, PT_R18, PT_R19, PT_R20, PT_R21, PT_R22, PT_R23, |
| 117 | PT_R24, PT_R25, PT_R26, PT_R27, PT_R28, PT_R29, PT_R30, PT_R31, |
| 118 | PT_FPR0, PT_FPR0 + 2, PT_FPR0 + 4, PT_FPR0 + 6, PT_FPR0 + 8, PT_FPR0 + 10, PT_FPR0 + 12, PT_FPR0 + 14, |
| 119 | PT_FPR0 + 16, PT_FPR0 + 18, PT_FPR0 + 20, PT_FPR0 + 22, PT_FPR0 + 24, PT_FPR0 + 26, PT_FPR0 + 28, PT_FPR0 + 30, |
| 120 | PT_FPR0 + 32, PT_FPR0 + 34, PT_FPR0 + 36, PT_FPR0 + 38, PT_FPR0 + 40, PT_FPR0 + 42, PT_FPR0 + 44, PT_FPR0 + 46, |
| 121 | PT_FPR0 + 48, PT_FPR0 + 50, PT_FPR0 + 52, PT_FPR0 + 54, PT_FPR0 + 56, PT_FPR0 + 58, PT_FPR0 + 60, PT_FPR0 + 62, |
| 122 | PT_NIP, PT_MSR, PT_CCR, PT_LNK, PT_CTR, PT_XER, PT_MQ */ |
| 123 | /* *INDENT_ON * */ |
| 124 | |
| 125 | static int |
| 126 | ppc_register_u_addr (int regno) |
| 127 | { |
| 128 | int u_addr = -1; |
| 129 | struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); |
| 130 | /* NOTE: cagney/2003-11-25: This is the word size used by the ptrace |
| 131 | interface, and not the wordsize of the program's ABI. */ |
| 132 | int wordsize = sizeof (PTRACE_XFER_TYPE); |
| 133 | |
| 134 | /* General purpose registers occupy 1 slot each in the buffer */ |
| 135 | if (regno >= tdep->ppc_gp0_regnum && regno <= tdep->ppc_gplast_regnum ) |
| 136 | u_addr = ((PT_R0 + regno) * wordsize); |
| 137 | |
| 138 | /* Floating point regs: eight bytes each in both 32- and 64-bit |
| 139 | ptrace interfaces. Thus, two slots each in 32-bit interface, one |
| 140 | slot each in 64-bit interface. */ |
| 141 | if (regno >= FP0_REGNUM && regno <= FPLAST_REGNUM) |
| 142 | u_addr = (PT_FPR0 * wordsize) + ((regno - FP0_REGNUM) * 8); |
| 143 | |
| 144 | /* UISA special purpose registers: 1 slot each */ |
| 145 | if (regno == PC_REGNUM) |
| 146 | u_addr = PT_NIP * wordsize; |
| 147 | if (regno == tdep->ppc_lr_regnum) |
| 148 | u_addr = PT_LNK * wordsize; |
| 149 | if (regno == tdep->ppc_cr_regnum) |
| 150 | u_addr = PT_CCR * wordsize; |
| 151 | if (regno == tdep->ppc_xer_regnum) |
| 152 | u_addr = PT_XER * wordsize; |
| 153 | if (regno == tdep->ppc_ctr_regnum) |
| 154 | u_addr = PT_CTR * wordsize; |
| 155 | #ifdef PT_MQ |
| 156 | if (regno == tdep->ppc_mq_regnum) |
| 157 | u_addr = PT_MQ * wordsize; |
| 158 | #endif |
| 159 | if (regno == tdep->ppc_ps_regnum) |
| 160 | u_addr = PT_MSR * wordsize; |
| 161 | if (regno == tdep->ppc_fpscr_regnum) |
| 162 | u_addr = PT_FPSCR * wordsize; |
| 163 | |
| 164 | return u_addr; |
| 165 | } |
| 166 | |
| 167 | static int |
| 168 | ppc_ptrace_cannot_fetch_store_register (int regno) |
| 169 | { |
| 170 | return (ppc_register_u_addr (regno) == -1); |
| 171 | } |
| 172 | |
| 173 | /* The Linux kernel ptrace interface for AltiVec registers uses the |
| 174 | registers set mechanism, as opposed to the interface for all the |
| 175 | other registers, that stores/fetches each register individually. */ |
| 176 | static void |
| 177 | fetch_altivec_register (int tid, int regno) |
| 178 | { |
| 179 | int ret; |
| 180 | int offset = 0; |
| 181 | gdb_vrregset_t regs; |
| 182 | struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); |
| 183 | int vrregsize = DEPRECATED_REGISTER_RAW_SIZE (tdep->ppc_vr0_regnum); |
| 184 | |
| 185 | ret = ptrace (PTRACE_GETVRREGS, tid, 0, ®s); |
| 186 | if (ret < 0) |
| 187 | { |
| 188 | if (errno == EIO) |
| 189 | { |
| 190 | have_ptrace_getvrregs = 0; |
| 191 | return; |
| 192 | } |
| 193 | perror_with_name ("Unable to fetch AltiVec register"); |
| 194 | } |
| 195 | |
| 196 | /* VSCR is fetched as a 16 bytes quantity, but it is really 4 bytes |
| 197 | long on the hardware. We deal only with the lower 4 bytes of the |
| 198 | vector. VRSAVE is at the end of the array in a 4 bytes slot, so |
| 199 | there is no need to define an offset for it. */ |
| 200 | if (regno == (tdep->ppc_vrsave_regnum - 1)) |
| 201 | offset = vrregsize - DEPRECATED_REGISTER_RAW_SIZE (tdep->ppc_vrsave_regnum); |
| 202 | |
| 203 | supply_register (regno, |
| 204 | regs + (regno - tdep->ppc_vr0_regnum) * vrregsize + offset); |
| 205 | } |
| 206 | |
| 207 | static void |
| 208 | fetch_register (int tid, int regno) |
| 209 | { |
| 210 | /* This isn't really an address. But ptrace thinks of it as one. */ |
| 211 | char mess[128]; /* For messages */ |
| 212 | int i; |
| 213 | unsigned int offset; /* Offset of registers within the u area. */ |
| 214 | char buf[MAX_REGISTER_SIZE]; |
| 215 | CORE_ADDR regaddr = ppc_register_u_addr (regno); |
| 216 | |
| 217 | if (altivec_register_p (regno)) |
| 218 | { |
| 219 | /* If this is the first time through, or if it is not the first |
| 220 | time through, and we have comfirmed that there is kernel |
| 221 | support for such a ptrace request, then go and fetch the |
| 222 | register. */ |
| 223 | if (have_ptrace_getvrregs) |
| 224 | { |
| 225 | fetch_altivec_register (tid, regno); |
| 226 | return; |
| 227 | } |
| 228 | /* If we have discovered that there is no ptrace support for |
| 229 | AltiVec registers, fall through and return zeroes, because |
| 230 | regaddr will be -1 in this case. */ |
| 231 | } |
| 232 | |
| 233 | if (regaddr == -1) |
| 234 | { |
| 235 | memset (buf, '\0', DEPRECATED_REGISTER_RAW_SIZE (regno)); /* Supply zeroes */ |
| 236 | supply_register (regno, buf); |
| 237 | return; |
| 238 | } |
| 239 | |
| 240 | /* Read the raw register using PTRACE_XFER_TYPE sized chunks. On a |
| 241 | 32-bit platform, 64-bit floating-point registers will require two |
| 242 | transfers. */ |
| 243 | for (i = 0; i < DEPRECATED_REGISTER_RAW_SIZE (regno); i += sizeof (PTRACE_XFER_TYPE)) |
| 244 | { |
| 245 | errno = 0; |
| 246 | *(PTRACE_XFER_TYPE *) & buf[i] = ptrace (PT_READ_U, tid, |
| 247 | (PTRACE_ARG3_TYPE) regaddr, 0); |
| 248 | regaddr += sizeof (PTRACE_XFER_TYPE); |
| 249 | if (errno != 0) |
| 250 | { |
| 251 | sprintf (mess, "reading register %s (#%d)", |
| 252 | REGISTER_NAME (regno), regno); |
| 253 | perror_with_name (mess); |
| 254 | } |
| 255 | } |
| 256 | |
| 257 | /* Now supply the register. Be careful to map between ptrace's and |
| 258 | the current_regcache's idea of the current wordsize. */ |
| 259 | if ((regno >= FP0_REGNUM && regno < FP0_REGNUM +32) |
| 260 | || gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_LITTLE) |
| 261 | /* FPs are always 64 bits. Little endian values are always found |
| 262 | at the left-hand end of the register. */ |
| 263 | regcache_raw_supply (current_regcache, regno, buf); |
| 264 | else |
| 265 | /* Big endian register, need to fetch the right-hand end. */ |
| 266 | regcache_raw_supply (current_regcache, regno, |
| 267 | (buf + sizeof (PTRACE_XFER_TYPE) |
| 268 | - register_size (current_gdbarch, regno))); |
| 269 | } |
| 270 | |
| 271 | static void |
| 272 | supply_vrregset (gdb_vrregset_t *vrregsetp) |
| 273 | { |
| 274 | int i; |
| 275 | struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); |
| 276 | int num_of_vrregs = tdep->ppc_vrsave_regnum - tdep->ppc_vr0_regnum + 1; |
| 277 | int vrregsize = DEPRECATED_REGISTER_RAW_SIZE (tdep->ppc_vr0_regnum); |
| 278 | int offset = vrregsize - DEPRECATED_REGISTER_RAW_SIZE (tdep->ppc_vrsave_regnum); |
| 279 | |
| 280 | for (i = 0; i < num_of_vrregs; i++) |
| 281 | { |
| 282 | /* The last 2 registers of this set are only 32 bit long, not |
| 283 | 128. However an offset is necessary only for VSCR because it |
| 284 | occupies a whole vector, while VRSAVE occupies a full 4 bytes |
| 285 | slot. */ |
| 286 | if (i == (num_of_vrregs - 2)) |
| 287 | supply_register (tdep->ppc_vr0_regnum + i, |
| 288 | *vrregsetp + i * vrregsize + offset); |
| 289 | else |
| 290 | supply_register (tdep->ppc_vr0_regnum + i, *vrregsetp + i * vrregsize); |
| 291 | } |
| 292 | } |
| 293 | |
| 294 | static void |
| 295 | fetch_altivec_registers (int tid) |
| 296 | { |
| 297 | int ret; |
| 298 | gdb_vrregset_t regs; |
| 299 | |
| 300 | ret = ptrace (PTRACE_GETVRREGS, tid, 0, ®s); |
| 301 | if (ret < 0) |
| 302 | { |
| 303 | if (errno == EIO) |
| 304 | { |
| 305 | have_ptrace_getvrregs = 0; |
| 306 | return; |
| 307 | } |
| 308 | perror_with_name ("Unable to fetch AltiVec registers"); |
| 309 | } |
| 310 | supply_vrregset (®s); |
| 311 | } |
| 312 | |
| 313 | static void |
| 314 | fetch_ppc_registers (int tid) |
| 315 | { |
| 316 | int i; |
| 317 | struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); |
| 318 | |
| 319 | for (i = 0; i <= tdep->ppc_fpscr_regnum; i++) |
| 320 | fetch_register (tid, i); |
| 321 | if (tdep->ppc_mq_regnum != -1) |
| 322 | fetch_register (tid, tdep->ppc_mq_regnum); |
| 323 | if (have_ptrace_getvrregs) |
| 324 | if (tdep->ppc_vr0_regnum != -1 && tdep->ppc_vrsave_regnum != -1) |
| 325 | fetch_altivec_registers (tid); |
| 326 | } |
| 327 | |
| 328 | /* Fetch registers from the child process. Fetch all registers if |
| 329 | regno == -1, otherwise fetch all general registers or all floating |
| 330 | point registers depending upon the value of regno. */ |
| 331 | void |
| 332 | fetch_inferior_registers (int regno) |
| 333 | { |
| 334 | /* Overload thread id onto process id */ |
| 335 | int tid = TIDGET (inferior_ptid); |
| 336 | |
| 337 | /* No thread id, just use process id */ |
| 338 | if (tid == 0) |
| 339 | tid = PIDGET (inferior_ptid); |
| 340 | |
| 341 | if (regno == -1) |
| 342 | fetch_ppc_registers (tid); |
| 343 | else |
| 344 | fetch_register (tid, regno); |
| 345 | } |
| 346 | |
| 347 | /* Store one register. */ |
| 348 | static void |
| 349 | store_altivec_register (int tid, int regno) |
| 350 | { |
| 351 | int ret; |
| 352 | int offset = 0; |
| 353 | gdb_vrregset_t regs; |
| 354 | struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); |
| 355 | int vrregsize = DEPRECATED_REGISTER_RAW_SIZE (tdep->ppc_vr0_regnum); |
| 356 | |
| 357 | ret = ptrace (PTRACE_GETVRREGS, tid, 0, ®s); |
| 358 | if (ret < 0) |
| 359 | { |
| 360 | if (errno == EIO) |
| 361 | { |
| 362 | have_ptrace_getvrregs = 0; |
| 363 | return; |
| 364 | } |
| 365 | perror_with_name ("Unable to fetch AltiVec register"); |
| 366 | } |
| 367 | |
| 368 | /* VSCR is fetched as a 16 bytes quantity, but it is really 4 bytes |
| 369 | long on the hardware. */ |
| 370 | if (regno == (tdep->ppc_vrsave_regnum - 1)) |
| 371 | offset = vrregsize - DEPRECATED_REGISTER_RAW_SIZE (tdep->ppc_vrsave_regnum); |
| 372 | |
| 373 | regcache_collect (regno, |
| 374 | regs + (regno - tdep->ppc_vr0_regnum) * vrregsize + offset); |
| 375 | |
| 376 | ret = ptrace (PTRACE_SETVRREGS, tid, 0, ®s); |
| 377 | if (ret < 0) |
| 378 | perror_with_name ("Unable to store AltiVec register"); |
| 379 | } |
| 380 | |
| 381 | static void |
| 382 | store_register (int tid, int regno) |
| 383 | { |
| 384 | /* This isn't really an address. But ptrace thinks of it as one. */ |
| 385 | CORE_ADDR regaddr = ppc_register_u_addr (regno); |
| 386 | char mess[128]; /* For messages */ |
| 387 | int i; |
| 388 | unsigned int offset; /* Offset of registers within the u area. */ |
| 389 | char buf[MAX_REGISTER_SIZE]; |
| 390 | |
| 391 | if (altivec_register_p (regno)) |
| 392 | { |
| 393 | store_altivec_register (tid, regno); |
| 394 | return; |
| 395 | } |
| 396 | |
| 397 | if (regaddr == -1) |
| 398 | return; |
| 399 | |
| 400 | /* First collect the register value from the regcache. Be careful |
| 401 | to to convert the regcache's wordsize into ptrace's wordsize. */ |
| 402 | memset (buf, 0, sizeof buf); |
| 403 | if ((regno >= FP0_REGNUM && regno < FP0_REGNUM + 32) |
| 404 | || TARGET_BYTE_ORDER == BFD_ENDIAN_LITTLE) |
| 405 | /* Floats are always 64-bit. Little endian registers are always |
| 406 | at the left-hand end of the register cache. */ |
| 407 | regcache_raw_collect (current_regcache, regno, buf); |
| 408 | else |
| 409 | /* Big-endian registers belong at the right-hand end of the |
| 410 | buffer. */ |
| 411 | regcache_raw_collect (current_regcache, regno, |
| 412 | (buf + sizeof (PTRACE_XFER_TYPE) |
| 413 | - register_size (current_gdbarch, regno))); |
| 414 | |
| 415 | for (i = 0; i < DEPRECATED_REGISTER_RAW_SIZE (regno); i += sizeof (PTRACE_XFER_TYPE)) |
| 416 | { |
| 417 | errno = 0; |
| 418 | ptrace (PT_WRITE_U, tid, (PTRACE_ARG3_TYPE) regaddr, |
| 419 | *(PTRACE_XFER_TYPE *) & buf[i]); |
| 420 | regaddr += sizeof (PTRACE_XFER_TYPE); |
| 421 | |
| 422 | if (errno == EIO |
| 423 | && regno == gdbarch_tdep (current_gdbarch)->ppc_fpscr_regnum) |
| 424 | { |
| 425 | /* Some older kernel versions don't allow fpscr to be written. */ |
| 426 | continue; |
| 427 | } |
| 428 | |
| 429 | if (errno != 0) |
| 430 | { |
| 431 | sprintf (mess, "writing register %s (#%d)", |
| 432 | REGISTER_NAME (regno), regno); |
| 433 | perror_with_name (mess); |
| 434 | } |
| 435 | } |
| 436 | } |
| 437 | |
| 438 | static void |
| 439 | fill_vrregset (gdb_vrregset_t *vrregsetp) |
| 440 | { |
| 441 | int i; |
| 442 | struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); |
| 443 | int num_of_vrregs = tdep->ppc_vrsave_regnum - tdep->ppc_vr0_regnum + 1; |
| 444 | int vrregsize = DEPRECATED_REGISTER_RAW_SIZE (tdep->ppc_vr0_regnum); |
| 445 | int offset = vrregsize - DEPRECATED_REGISTER_RAW_SIZE (tdep->ppc_vrsave_regnum); |
| 446 | |
| 447 | for (i = 0; i < num_of_vrregs; i++) |
| 448 | { |
| 449 | /* The last 2 registers of this set are only 32 bit long, not |
| 450 | 128, but only VSCR is fetched as a 16 bytes quantity. */ |
| 451 | if (i == (num_of_vrregs - 2)) |
| 452 | regcache_collect (tdep->ppc_vr0_regnum + i, |
| 453 | *vrregsetp + i * vrregsize + offset); |
| 454 | else |
| 455 | regcache_collect (tdep->ppc_vr0_regnum + i, *vrregsetp + i * vrregsize); |
| 456 | } |
| 457 | } |
| 458 | |
| 459 | static void |
| 460 | store_altivec_registers (int tid) |
| 461 | { |
| 462 | int ret; |
| 463 | gdb_vrregset_t regs; |
| 464 | |
| 465 | ret = ptrace (PTRACE_GETVRREGS, tid, 0, ®s); |
| 466 | if (ret < 0) |
| 467 | { |
| 468 | if (errno == EIO) |
| 469 | { |
| 470 | have_ptrace_getvrregs = 0; |
| 471 | return; |
| 472 | } |
| 473 | perror_with_name ("Couldn't get AltiVec registers"); |
| 474 | } |
| 475 | |
| 476 | fill_vrregset (®s); |
| 477 | |
| 478 | if (ptrace (PTRACE_SETVRREGS, tid, 0, ®s) < 0) |
| 479 | perror_with_name ("Couldn't write AltiVec registers"); |
| 480 | } |
| 481 | |
| 482 | static void |
| 483 | store_ppc_registers (int tid) |
| 484 | { |
| 485 | int i; |
| 486 | struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); |
| 487 | |
| 488 | for (i = 0; i <= tdep->ppc_fpscr_regnum; i++) |
| 489 | store_register (tid, i); |
| 490 | if (tdep->ppc_mq_regnum != -1) |
| 491 | store_register (tid, tdep->ppc_mq_regnum); |
| 492 | if (have_ptrace_getvrregs) |
| 493 | if (tdep->ppc_vr0_regnum != -1 && tdep->ppc_vrsave_regnum != -1) |
| 494 | store_altivec_registers (tid); |
| 495 | } |
| 496 | |
| 497 | void |
| 498 | store_inferior_registers (int regno) |
| 499 | { |
| 500 | /* Overload thread id onto process id */ |
| 501 | int tid = TIDGET (inferior_ptid); |
| 502 | |
| 503 | /* No thread id, just use process id */ |
| 504 | if (tid == 0) |
| 505 | tid = PIDGET (inferior_ptid); |
| 506 | |
| 507 | if (regno >= 0) |
| 508 | store_register (tid, regno); |
| 509 | else |
| 510 | store_ppc_registers (tid); |
| 511 | } |
| 512 | |
| 513 | void |
| 514 | supply_gregset (gdb_gregset_t *gregsetp) |
| 515 | { |
| 516 | ppc_linux_supply_gregset ((char *) gregsetp); |
| 517 | } |
| 518 | |
| 519 | void |
| 520 | fill_gregset (gdb_gregset_t *gregsetp, int regno) |
| 521 | { |
| 522 | int regi; |
| 523 | elf_greg_t *regp = (elf_greg_t *) gregsetp; |
| 524 | struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); |
| 525 | |
| 526 | for (regi = 0; regi < 32; regi++) |
| 527 | { |
| 528 | if ((regno == -1) || regno == regi) |
| 529 | regcache_collect (regi, regp + PT_R0 + regi); |
| 530 | } |
| 531 | |
| 532 | if ((regno == -1) || regno == PC_REGNUM) |
| 533 | regcache_collect (PC_REGNUM, regp + PT_NIP); |
| 534 | if ((regno == -1) || regno == tdep->ppc_lr_regnum) |
| 535 | regcache_collect (tdep->ppc_lr_regnum, regp + PT_LNK); |
| 536 | if ((regno == -1) || regno == tdep->ppc_cr_regnum) |
| 537 | regcache_collect (tdep->ppc_cr_regnum, regp + PT_CCR); |
| 538 | if ((regno == -1) || regno == tdep->ppc_xer_regnum) |
| 539 | regcache_collect (tdep->ppc_xer_regnum, regp + PT_XER); |
| 540 | if ((regno == -1) || regno == tdep->ppc_ctr_regnum) |
| 541 | regcache_collect (tdep->ppc_ctr_regnum, regp + PT_CTR); |
| 542 | #ifdef PT_MQ |
| 543 | if (((regno == -1) || regno == tdep->ppc_mq_regnum) |
| 544 | && (tdep->ppc_mq_regnum != -1)) |
| 545 | regcache_collect (tdep->ppc_mq_regnum, regp + PT_MQ); |
| 546 | #endif |
| 547 | if ((regno == -1) || regno == tdep->ppc_ps_regnum) |
| 548 | regcache_collect (tdep->ppc_ps_regnum, regp + PT_MSR); |
| 549 | } |
| 550 | |
| 551 | void |
| 552 | supply_fpregset (gdb_fpregset_t * fpregsetp) |
| 553 | { |
| 554 | ppc_linux_supply_fpregset ((char *) fpregsetp); |
| 555 | } |
| 556 | |
| 557 | /* Given a pointer to a floating point register set in /proc format |
| 558 | (fpregset_t *), update the register specified by REGNO from gdb's |
| 559 | idea of the current floating point register set. If REGNO is -1, |
| 560 | update them all. */ |
| 561 | void |
| 562 | fill_fpregset (gdb_fpregset_t *fpregsetp, int regno) |
| 563 | { |
| 564 | int regi; |
| 565 | struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); |
| 566 | |
| 567 | for (regi = 0; regi < 32; regi++) |
| 568 | { |
| 569 | if ((regno == -1) || (regno == FP0_REGNUM + regi)) |
| 570 | regcache_collect (FP0_REGNUM + regi, (char *) (*fpregsetp + regi)); |
| 571 | } |
| 572 | if ((regno == -1) || regno == tdep->ppc_fpscr_regnum) |
| 573 | regcache_collect (tdep->ppc_fpscr_regnum, (char *) (*fpregsetp + regi)); |
| 574 | } |