diff options
Diffstat (limited to 'linux-user/mips/elfload.c')
| -rw-r--r-- | linux-user/mips/elfload.c | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/linux-user/mips/elfload.c b/linux-user/mips/elfload.c index c353ccc1ad..6e884911af 100644 --- a/linux-user/mips/elfload.c +++ b/linux-user/mips/elfload.c @@ -4,6 +4,7 @@ #include "qemu.h" #include "loader.h" #include "elf.h" +#include "target_elf.h" const char *get_elf_cpu_model(uint32_t eflags) @@ -122,3 +123,48 @@ const char *get_elf_base_platform(CPUState *cs) } #undef MATCH_PLATFORM_INSN + +#ifdef TARGET_ABI_MIPSN32 +#define tswapreg(ptr) tswap64(ptr) +#else +#define tswapreg(ptr) tswapal(ptr) +#endif + +/* See linux kernel: arch/mips/include/asm/reg.h. */ +enum { +#ifdef TARGET_MIPS64 + TARGET_EF_R0 = 0, +#else + TARGET_EF_R0 = 6, +#endif + TARGET_EF_R26 = TARGET_EF_R0 + 26, + TARGET_EF_R27 = TARGET_EF_R0 + 27, + TARGET_EF_LO = TARGET_EF_R0 + 32, + TARGET_EF_HI = TARGET_EF_R0 + 33, + TARGET_EF_CP0_EPC = TARGET_EF_R0 + 34, + TARGET_EF_CP0_BADVADDR = TARGET_EF_R0 + 35, + TARGET_EF_CP0_STATUS = TARGET_EF_R0 + 36, + TARGET_EF_CP0_CAUSE = TARGET_EF_R0 + 37 +}; + +/* See linux kernel: arch/mips/kernel/process.c:elf_dump_regs. */ +void elf_core_copy_regs(target_elf_gregset_t *r, const CPUMIPSState *env) +{ + int i; + + for (i = 0; i <= TARGET_EF_R0; i++) { + r->regs[i] = 0; + } + for (i = 1; i < ARRAY_SIZE(env->active_tc.gpr); i++) { + r->regs[TARGET_EF_R0 + i] = tswapreg(env->active_tc.gpr[i]); + } + + r->regs[TARGET_EF_R26] = 0; + r->regs[TARGET_EF_R27] = 0; + r->regs[TARGET_EF_LO] = tswapreg(env->active_tc.LO[0]); + r->regs[TARGET_EF_HI] = tswapreg(env->active_tc.HI[0]); + r->regs[TARGET_EF_CP0_EPC] = tswapreg(env->active_tc.PC); + r->regs[TARGET_EF_CP0_BADVADDR] = tswapreg(env->CP0_BadVAddr); + r->regs[TARGET_EF_CP0_STATUS] = tswapreg(env->CP0_Status); + r->regs[TARGET_EF_CP0_CAUSE] = tswapreg(env->CP0_Cause); +} |