Included VSX registers in powerpc core dumps
Summary: Included VSX registers in powerpc core dumps (both kernel and gcore) Submitted by: Luis Pires Differential Revision: https://reviews.freebsd.org/D15512
This commit is contained in:
parent
15825d5b78
commit
5167f178ab
@ -52,6 +52,7 @@
|
||||
|
||||
#include <machine/altivec.h>
|
||||
#include <machine/cpu.h>
|
||||
#include <machine/fpu.h>
|
||||
#include <machine/elf.h>
|
||||
#include <machine/reg.h>
|
||||
#include <machine/md_var.h>
|
||||
@ -171,19 +172,44 @@ elf32_dump_thread(struct thread *td, void *dst, size_t *off)
|
||||
{
|
||||
size_t len;
|
||||
struct pcb *pcb;
|
||||
uint64_t vshr[32];
|
||||
uint64_t *vsr_dw1;
|
||||
int vsr_idx;
|
||||
|
||||
len = 0;
|
||||
pcb = td->td_pcb;
|
||||
|
||||
if (pcb->pcb_flags & PCB_VEC) {
|
||||
save_vec_nodrop(td);
|
||||
if (dst != NULL) {
|
||||
len += elf32_populate_note(NT_PPC_VMX,
|
||||
&pcb->pcb_vec, dst,
|
||||
&pcb->pcb_vec, (char *)dst + len,
|
||||
sizeof(pcb->pcb_vec), NULL);
|
||||
} else
|
||||
len += elf32_populate_note(NT_PPC_VMX, NULL, NULL,
|
||||
sizeof(pcb->pcb_vec), NULL);
|
||||
}
|
||||
|
||||
if (pcb->pcb_flags & PCB_VSX) {
|
||||
save_fpu_nodrop(td);
|
||||
if (dst != NULL) {
|
||||
/*
|
||||
* Doubleword 0 of VSR0-VSR31 overlap with FPR0-FPR31 and
|
||||
* VSR32-VSR63 overlap with VR0-VR31, so we only copy
|
||||
* the non-overlapping data, which is doubleword 1 of VSR0-VSR31.
|
||||
*/
|
||||
for (vsr_idx = 0; vsr_idx < nitems(vshr); vsr_idx++) {
|
||||
vsr_dw1 = (uint64_t *)&pcb->pcb_fpu.fpr[vsr_idx].vsr[2];
|
||||
vshr[vsr_idx] = *vsr_dw1;
|
||||
}
|
||||
len += elf32_populate_note(NT_PPC_VSX,
|
||||
vshr, (char *)dst + len,
|
||||
sizeof(vshr), NULL);
|
||||
} else
|
||||
len += elf32_populate_note(NT_PPC_VSX, NULL, NULL,
|
||||
sizeof(vshr), NULL);
|
||||
}
|
||||
|
||||
*off = len;
|
||||
}
|
||||
|
||||
|
@ -48,6 +48,7 @@
|
||||
|
||||
#include <machine/altivec.h>
|
||||
#include <machine/cpu.h>
|
||||
#include <machine/fpu.h>
|
||||
#include <machine/elf.h>
|
||||
#include <machine/md_var.h>
|
||||
|
||||
@ -234,19 +235,44 @@ elf64_dump_thread(struct thread *td, void *dst, size_t *off)
|
||||
{
|
||||
size_t len;
|
||||
struct pcb *pcb;
|
||||
uint64_t vshr[32];
|
||||
uint64_t *vsr_dw1;
|
||||
int vsr_idx;
|
||||
|
||||
len = 0;
|
||||
pcb = td->td_pcb;
|
||||
|
||||
if (pcb->pcb_flags & PCB_VEC) {
|
||||
save_vec_nodrop(td);
|
||||
if (dst != NULL) {
|
||||
len += elf64_populate_note(NT_PPC_VMX,
|
||||
&pcb->pcb_vec, dst,
|
||||
&pcb->pcb_vec, (char *)dst + len,
|
||||
sizeof(pcb->pcb_vec), NULL);
|
||||
} else
|
||||
len += elf64_populate_note(NT_PPC_VMX, NULL, NULL,
|
||||
sizeof(pcb->pcb_vec), NULL);
|
||||
}
|
||||
|
||||
if (pcb->pcb_flags & PCB_VSX) {
|
||||
save_fpu_nodrop(td);
|
||||
if (dst != NULL) {
|
||||
/*
|
||||
* Doubleword 0 of VSR0-VSR31 overlap with FPR0-FPR31 and
|
||||
* VSR32-VSR63 overlap with VR0-VR31, so we only copy
|
||||
* the non-overlapping data, which is doubleword 1 of VSR0-VSR31.
|
||||
*/
|
||||
for (vsr_idx = 0; vsr_idx < nitems(vshr); vsr_idx++) {
|
||||
vsr_dw1 = (uint64_t *)&pcb->pcb_fpu.fpr[vsr_idx].vsr[2];
|
||||
vshr[vsr_idx] = *vsr_dw1;
|
||||
}
|
||||
len += elf64_populate_note(NT_PPC_VSX,
|
||||
vshr, (char *)dst + len,
|
||||
sizeof(vshr), NULL);
|
||||
} else
|
||||
len += elf64_populate_note(NT_PPC_VSX, NULL, NULL,
|
||||
sizeof(vshr), NULL);
|
||||
}
|
||||
|
||||
*off = len;
|
||||
}
|
||||
|
||||
|
@ -774,6 +774,7 @@ typedef struct {
|
||||
#define NT_PROCSTAT_AUXV 16 /* Procstat auxv data. */
|
||||
#define NT_PTLWPINFO 17 /* Thread ptrace miscellaneous info. */
|
||||
#define NT_PPC_VMX 0x100 /* PowerPC Altivec/VMX registers */
|
||||
#define NT_PPC_VSX 0x102 /* PowerPC VSX registers */
|
||||
#define NT_X86_XSTATE 0x202 /* x86 XSAVE extended state. */
|
||||
#define NT_ARM_VFP 0x400 /* ARM VFP registers */
|
||||
|
||||
|
@ -119,6 +119,7 @@ static void *elf_note_x86_xstate(void *, size_t *);
|
||||
#endif
|
||||
#if defined(__powerpc__)
|
||||
static void *elf_note_powerpc_vmx(void *, size_t *);
|
||||
static void *elf_note_powerpc_vsx(void *, size_t *);
|
||||
#endif
|
||||
static void *elf_note_procstat_auxv(void *, size_t *);
|
||||
static void *elf_note_procstat_files(void *, size_t *);
|
||||
@ -381,6 +382,7 @@ elf_putnotes(pid_t pid, struct sbuf *sb, size_t *sizep)
|
||||
#endif
|
||||
#if defined(__powerpc__)
|
||||
elf_putnote(NT_PPC_VMX, elf_note_powerpc_vmx, tids + i, sb);
|
||||
elf_putnote(NT_PPC_VSX, elf_note_powerpc_vsx, tids + i, sb);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -803,6 +805,30 @@ elf_note_powerpc_vmx(void *arg, size_t *sizep)
|
||||
*sizep = sizeof(*vmx);
|
||||
return (vmx);
|
||||
}
|
||||
|
||||
static void *
|
||||
elf_note_powerpc_vsx(void *arg, size_t *sizep)
|
||||
{
|
||||
lwpid_t tid;
|
||||
char *vshr_data;
|
||||
static bool has_vsx = true;
|
||||
uint64_t vshr[32];
|
||||
|
||||
tid = *(lwpid_t *)arg;
|
||||
if (has_vsx) {
|
||||
if (ptrace(PT_GETVSRREGS, tid, (void *)vshr,
|
||||
sizeof(vshr)) != 0)
|
||||
has_vsx = false;
|
||||
}
|
||||
if (!has_vsx) {
|
||||
*sizep = 0;
|
||||
return (NULL);
|
||||
}
|
||||
vshr_data = calloc(1, sizeof(vshr));
|
||||
memcpy(vshr_data, vshr, sizeof(vshr));
|
||||
*sizep = sizeof(vshr);
|
||||
return (vshr_data);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void *
|
||||
|
Loading…
x
Reference in New Issue
Block a user