static UserPpc64VrstateEntry *copy_altivec_regs(__vector128 *vrregs) { UserPpc64VrstateEntry *vse; uint64_t *p64; uint32_t *p32; int i; vse = xmalloc(sizeof(*vse)); if (!vse) return NULL; user_ppc64_vrstate_entry__init(vse); /* protocol buffer store only 64bit entries and we need 128bit */ vse->n_vrregs = (NVRREG-1) * 2; vse->vrregs = xmalloc(vse->n_vrregs * sizeof(vse->vrregs[0])); if (!vse->vrregs) { xfree(vse); return NULL; } /* Vectors are 2*64bits entries */ for (i = 0; i < (NVRREG-1); i++) { p64 = (uint64_t*) &vrregs[i]; vse->vrregs[i*2] = p64[0]; vse->vrregs[i*2 + 1] = p64[1]; } p32 = (uint32_t*) &vrregs[NVRREG-1]; vse->vrsave = *p32; return vse; }
static int get_altivec_regs(pid_t pid, CoreEntry *core) { /* The kernel returns : * 32 Vector registers (128bit) * VSCR (32bit) stored in a 128bit entry (odd) * VRSAVE (32bit) store at the end. * * Kernel setup_sigcontext's comment mentions: * "Userland shall check AT_HWCAP to know whether it can rely on the * v_regs pointer or not" */ unsigned char vrregs[33 * 16 + 4]; UserPpc64VrstateEntry *vse; uint64_t *p64; uint32_t *p32; int i; if (ptrace(PTRACE_GETVRREGS, pid, 0, (void*)&vrregs) < 0) { /* PTRACE_GETVRREGS returns EIO if Altivec is not supported. * This should not happen if msr_vec is set. */ if (errno != EIO) { pr_perror("Couldn't get Altivec registers"); return -1; } pr_debug("Altivec not supported\n"); return 0; } pr_debug("Dumping Altivec registers\n"); vse = xmalloc(sizeof(*vse)); if (!vse) return -1; user_ppc64_vrstate_entry__init(vse); vse->n_vrregs = 33 * 2; /* protocol buffer store 64bit entries */ vse->vrregs = xmalloc(vse->n_vrregs * sizeof(vse->vrregs[0])); if (!vse->vrregs) { xfree(vse); return -1; } /* Vectors are 2*64bits entries */ for (i = 0; i < 33; i++) { p64 = (uint64_t*) &vrregs[i * 2 * sizeof(uint64_t)]; vse->vrregs[i*2] = p64[0]; vse->vrregs[i*2 + 1] = p64[1]; } p32 = (uint32_t*) &vrregs[33 * 2 * sizeof(uint64_t)]; vse->vrsave = *p32; core->ti_ppc64->vrstate = vse; /* * Force the MSR_VEC bit of the restored MSR otherwise the kernel * will not restore them from the signal frame. */ core->ti_ppc64->gpregs->msr |= MSR_VEC; return 0; }