diff --git a/linux-user/mips64/elfload.c b/linux-user/mips64/elfload.c index 9081ae8111..e4d84a7bd6 100644 --- a/linux-user/mips64/elfload.c +++ b/linux-user/mips64/elfload.c @@ -15,16 +15,31 @@ */ void elf_core_copy_regs(target_elf_gregset_t *r, const CPUMIPSState *env) { - /* R0 is always 0; r->reserved is zero-initialised by the caller */ + /* + * linux-user/elfload.c allocates target_elf_prstatus using the + * definition from mips64/target_elf.h, where target_elf_gregset_t + * has target_ulong reserved[45] (8 bytes each = 360 bytes total). + * + * But in this compilation unit, "#include target_elf.h" resolved to + * mips/target_elf.h (wrong directory), so our local target_elf_gregset_t + * has abi_ulong reserved[45] which is only 4 bytes each for mipsn32. + * Using r->reserved[i] would write to the wrong offsets for mipsn32. + * + * Cast to target_ulong * to always write 8-byte entries at the correct + * positions, matching the layout that elfload.c allocated. + */ + target_ulong *regs = (target_ulong *)r; + + /* R0 is always 0; buffer is zero-initialised by the caller */ for (int i = 1; i < 32; i++) { - r->reserved[i] = tswap64(env->active_tc.gpr[i]); + regs[i] = tswap64(env->active_tc.gpr[i]); } - r->reserved[26] = 0; /* k0 */ - r->reserved[27] = 0; /* k1 */ - r->reserved[32] = tswap64(env->active_tc.LO[0]); - r->reserved[33] = tswap64(env->active_tc.HI[0]); - r->reserved[34] = tswap64(env->active_tc.PC); - r->reserved[35] = tswap64(env->CP0_BadVAddr); - r->reserved[36] = tswap64(env->CP0_Status); - r->reserved[37] = tswap64(env->CP0_Cause); + regs[26] = 0; /* k0 */ + regs[27] = 0; /* k1 */ + regs[32] = tswap64(env->active_tc.LO[0]); + regs[33] = tswap64(env->active_tc.HI[0]); + regs[34] = tswap64(env->active_tc.PC); + regs[35] = tswap64(env->CP0_BadVAddr); + regs[36] = tswap64(env->CP0_Status); + regs[37] = tswap64(env->CP0_Cause); }