Skip to content

Commit

Permalink
target-arm: dump-guest-memory: add vfp notes for arm
Browse files Browse the repository at this point in the history
gdb won't actually dump these with 'info all-registers' since
it first tries to confirm that it should by checking the VFP
hwcap in the .auxv note. Well, we don't generate an .auxv note.

Signed-off-by: Andrew Jones <drjones@redhat.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 1452542185-10914-9-git-send-email-drjones@redhat.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
  • Loading branch information
Andrew Jones authored and pm215 committed Jan 15, 2016
1 parent 7d68e47 commit ade0d0c
Showing 1 changed file with 46 additions and 3 deletions.
49 changes: 46 additions & 3 deletions target-arm/arch_dump.c
Expand Up @@ -183,15 +183,28 @@ struct arm_elf_prstatus {

QEMU_BUILD_BUG_ON(sizeof(struct arm_elf_prstatus) != 148);

/* struct user_vfp from arch/arm/include/asm/user.h */
struct arm_user_vfp_state {
uint64_t vregs[32];
uint32_t fpscr;
} QEMU_PACKED;

QEMU_BUILD_BUG_ON(sizeof(struct arm_user_vfp_state) != 260);

struct arm_note {
Elf32_Nhdr hdr;
char name[8]; /* align_up(sizeof("CORE"), 4) */
struct arm_elf_prstatus prstatus;
char name[8]; /* align_up(sizeof("LINUX"), 4) */
union {
struct arm_elf_prstatus prstatus;
struct arm_user_vfp_state vfp;
};
} QEMU_PACKED;

#define ARM_NOTE_HEADER_SIZE offsetof(struct arm_note, prstatus)
#define ARM_PRSTATUS_NOTE_SIZE \
(ARM_NOTE_HEADER_SIZE + sizeof(struct arm_elf_prstatus))
#define ARM_VFP_NOTE_SIZE \
(ARM_NOTE_HEADER_SIZE + sizeof(struct arm_user_vfp_state))

static void arm_note_init(struct arm_note *note, DumpState *s,
const char *name, Elf32_Word namesz,
Expand All @@ -206,17 +219,40 @@ static void arm_note_init(struct arm_note *note, DumpState *s,
memcpy(note->name, name, namesz);
}

static int arm_write_elf32_vfp(WriteCoreDumpFunction f, CPUARMState *env,
int cpuid, DumpState *s)
{
struct arm_note note;
int ret, i;

arm_note_init(&note, s, "LINUX", 6, NT_ARM_VFP, sizeof(note.vfp));

for (i = 0; i < 32; ++i) {
note.vfp.vregs[i] = cpu_to_dump64(s, float64_val(env->vfp.regs[i]));
}

note.vfp.fpscr = cpu_to_dump32(s, vfp_get_fpscr(env));

ret = f(&note, ARM_VFP_NOTE_SIZE, s);
if (ret < 0) {
return -1;
}

return 0;
}

int arm_cpu_write_elf32_note(WriteCoreDumpFunction f, CPUState *cs,
int cpuid, void *opaque)
{
struct arm_note note;
CPUARMState *env = &ARM_CPU(cs)->env;
DumpState *s = opaque;
int ret, i;
int ret, i, fpvalid = !!arm_feature(env, ARM_FEATURE_VFP);

arm_note_init(&note, s, "CORE", 5, NT_PRSTATUS, sizeof(note.prstatus));

note.prstatus.pr_pid = cpu_to_dump32(s, cpuid);
note.prstatus.pr_fpvalid = cpu_to_dump32(s, fpvalid);

for (i = 0; i < 16; ++i) {
note.prstatus.pr_reg.regs[i] = cpu_to_dump32(s, env->regs[i]);
Expand All @@ -226,6 +262,8 @@ int arm_cpu_write_elf32_note(WriteCoreDumpFunction f, CPUState *cs,
ret = f(&note, ARM_PRSTATUS_NOTE_SIZE, s);
if (ret < 0) {
return -1;
} else if (fpvalid) {
return arm_write_elf32_vfp(f, env, cpuid, s);
}

return 0;
Expand Down Expand Up @@ -280,13 +318,18 @@ int cpu_get_dump_info(ArchDumpInfo *info,

ssize_t cpu_get_note_size(int class, int machine, int nr_cpus)
{
ARMCPU *cpu = ARM_CPU(first_cpu);
CPUARMState *env = &cpu->env;
size_t note_size;

if (class == ELFCLASS64) {
note_size = AARCH64_PRSTATUS_NOTE_SIZE;
note_size += AARCH64_PRFPREG_NOTE_SIZE;
} else {
note_size = ARM_PRSTATUS_NOTE_SIZE;
if (arm_feature(env, ARM_FEATURE_VFP)) {
note_size += ARM_VFP_NOTE_SIZE;
}
}

return note_size * nr_cpus;
Expand Down

0 comments on commit ade0d0c

Please sign in to comment.