static void fetch_ppc_registers (int tid) { int i; struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); for (i = 0; i < ppc_num_gprs; i++) fetch_register (tid, tdep->ppc_gp0_regnum + i); if (tdep->ppc_fp0_regnum >= 0) for (i = 0; i < ppc_num_fprs; i++) fetch_register (tid, tdep->ppc_fp0_regnum + i); fetch_register (tid, PC_REGNUM); if (tdep->ppc_ps_regnum != -1) fetch_register (tid, tdep->ppc_ps_regnum); if (tdep->ppc_cr_regnum != -1) fetch_register (tid, tdep->ppc_cr_regnum); if (tdep->ppc_lr_regnum != -1) fetch_register (tid, tdep->ppc_lr_regnum); if (tdep->ppc_ctr_regnum != -1) fetch_register (tid, tdep->ppc_ctr_regnum); if (tdep->ppc_xer_regnum != -1) fetch_register (tid, tdep->ppc_xer_regnum); if (tdep->ppc_mq_regnum != -1) fetch_register (tid, tdep->ppc_mq_regnum); if (tdep->ppc_fpscr_regnum != -1) fetch_register (tid, tdep->ppc_fpscr_regnum); if (have_ptrace_getvrregs) if (tdep->ppc_vr0_regnum != -1 && tdep->ppc_vrsave_regnum != -1) fetch_altivec_registers (tid); if (tdep->ppc_ev0_upper_regnum >= 0) fetch_spe_register (tid, -1); }
static void fetch_ppc_registers (struct regcache *regcache, int tid) { int i; struct gdbarch *gdbarch = get_regcache_arch (regcache); struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); for (i = 0; i < ppc_num_gprs; i++) fetch_register (regcache, tid, tdep->ppc_gp0_regnum + i); if (tdep->ppc_fp0_regnum >= 0) for (i = 0; i < ppc_num_fprs; i++) fetch_register (regcache, tid, tdep->ppc_fp0_regnum + i); fetch_register (regcache, tid, gdbarch_pc_regnum (gdbarch)); if (tdep->ppc_ps_regnum != -1) fetch_register (regcache, tid, tdep->ppc_ps_regnum); if (tdep->ppc_cr_regnum != -1) fetch_register (regcache, tid, tdep->ppc_cr_regnum); if (tdep->ppc_lr_regnum != -1) fetch_register (regcache, tid, tdep->ppc_lr_regnum); if (tdep->ppc_ctr_regnum != -1) fetch_register (regcache, tid, tdep->ppc_ctr_regnum); if (tdep->ppc_xer_regnum != -1) fetch_register (regcache, tid, tdep->ppc_xer_regnum); if (tdep->ppc_mq_regnum != -1) fetch_register (regcache, tid, tdep->ppc_mq_regnum); if (ppc_linux_trap_reg_p (gdbarch)) { fetch_register (regcache, tid, PPC_ORIG_R3_REGNUM); fetch_register (regcache, tid, PPC_TRAP_REGNUM); } if (tdep->ppc_fpscr_regnum != -1) fetch_register (regcache, tid, tdep->ppc_fpscr_regnum); if (have_ptrace_getvrregs) if (tdep->ppc_vr0_regnum != -1 && tdep->ppc_vrsave_regnum != -1) fetch_altivec_registers (regcache, tid); if (have_ptrace_getsetvsxregs) if (tdep->ppc_vsr0_upper_regnum != -1) fetch_vsx_registers (regcache, tid); if (tdep->ppc_ev0_upper_regnum >= 0) fetch_spe_register (regcache, tid, -1); }
static void fetch_register (int tid, int regno) { struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); /* This isn't really an address. But ptrace thinks of it as one. */ CORE_ADDR regaddr = ppc_register_u_addr (regno); int bytes_transferred; unsigned int offset; /* Offset of registers within the u area. */ char buf[MAX_REGISTER_SIZE]; if (altivec_register_p (regno)) { /* If this is the first time through, or if it is not the first time through, and we have comfirmed that there is kernel support for such a ptrace request, then go and fetch the register. */ if (have_ptrace_getvrregs) { fetch_altivec_register (tid, regno); return; } /* If we have discovered that there is no ptrace support for AltiVec registers, fall through and return zeroes, because regaddr will be -1 in this case. */ } else if (spe_register_p (regno)) { fetch_spe_register (tid, regno); return; } if (regaddr == -1) { memset (buf, '\0', register_size (current_gdbarch, regno)); /* Supply zeroes */ regcache_raw_supply (current_regcache, regno, buf); return; } /* Read the raw register using sizeof(long) sized chunks. On a 32-bit platform, 64-bit floating-point registers will require two transfers. */ for (bytes_transferred = 0; bytes_transferred < register_size (current_gdbarch, regno); bytes_transferred += sizeof (long)) { errno = 0; *(long *) &buf[bytes_transferred] = ptrace (PTRACE_PEEKUSER, tid, (PTRACE_TYPE_ARG3) regaddr, 0); regaddr += sizeof (long); if (errno != 0) { char message[128]; sprintf (message, "reading register %s (#%d)", REGISTER_NAME (regno), regno); perror_with_name (message); } } /* Now supply the register. Keep in mind that the regcache's idea of the register's size may not be a multiple of sizeof (long). */ if (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_LITTLE) { /* Little-endian values are always found at the left end of the bytes transferred. */ regcache_raw_supply (current_regcache, regno, buf); } else if (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG) { /* Big-endian values are found at the right end of the bytes transferred. */ size_t padding = (bytes_transferred - register_size (current_gdbarch, regno)); regcache_raw_supply (current_regcache, regno, buf + padding); } else internal_error (__FILE__, __LINE__, _("fetch_register: unexpected byte order: %d"), gdbarch_byte_order (current_gdbarch)); }