Add support form printing out the registers from the dump file. We don't
take the registers directly from the ELF notes but instead use the version
we've saved into the machine_specific structure. If we don't do this,
we'd get misleading output when the number of ELF notes don't match the
number of online CPUs.
E.g. Without this patch:
crash> help -r
help: -r option not supported for this dumpfile
E.g. With this patch:
crash> help -r
...
CPU 3:
R0: 0000000000000000 R1: 0000000000000001 R2: 9800000254f3c400
R3: 0000000000000000 R4: ffffffff8123b6b0 R5: 0000000000000000
R6: 9800000243bcf200 R7: fffffffffffffff8 R8: fffffffffffffffd
R9: 00180000000000ff R10: ffffffff810e29a8 R11: ffffffff80e84190
R12: 000000005400cce0 R13: 0000000000000000 R14: 0000000000000040
R15: 6e69636e79732074 R16: ffffffff81200000 R17: ffffffff81240000
R18: 0000000000000000 R19: ffffffff81430000 R20: 980000024291f938
R21: 0000000000000001 R22: 980000024aef7320 R23: ffffffff81430000
R24: 0000000000000002 R25: ffffffff80878b58 R26: 0000000000000000
R27: 0000000000000000 R28: 980000024291c000 R29: 980000024291f930
R30: 9800000243bcf200 R31: ffffffff802fff00
LO: ffffffff81210000 HI: ffffffff81210000
EPC: ffffffff802fff84 BADVADDR: ffffffff802bbe9c
STATUS: ffffffff81430000 CAUSE: 9800000243bcf200
Signed-off-by: Huacai Chen <chenhuacai(a)loongson.cn>
Signed-off-by: Youling Tang <tangyouling(a)loongson.cn>
---
v1 -> v2:
- Add the use of MIPS64 (MACHINE_TYPE).
diskdump.c | 11 ++++++++--
mips64.c | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
netdump.c | 4 +++-
3 files changed, 82 insertions(+), 3 deletions(-)
diff --git a/diskdump.c b/diskdump.c
index 3726c9d..3853b2b 100644
--- a/diskdump.c
+++ b/diskdump.c
@@ -2486,6 +2486,12 @@ diskdump_display_regs(int cpu, FILE *ofp)
UINT(user_regs + OFFSET(user_regs_struct_eflags))
);
}
+
+ if (machine_type("MIPS"))
+ mips_display_regs_from_elf_notes(cpu, ofp);
+
+ if (machine_type("MIPS64"))
+ mips64_display_regs_from_elf_notes(cpu, ofp);
}
void
@@ -2494,8 +2500,9 @@ dump_registers_for_compressed_kdump(void)
int c;
if (!KDUMP_CMPRS_VALID() || (dd->header->header_version < 4) ||
- !(machine_type("X86") || machine_type("X86_64") ||
- machine_type("ARM64") || machine_type("PPC64")))
+ !(machine_type("X86") || machine_type("X86_64") ||
+ machine_type("ARM64") || machine_type("PPC64") ||
+ machine_type("MIPS") || machine_type("MIPS64")))
error(FATAL, "-r option not supported for this dumpfile\n");
if (machine_type("ARM64") && (kt->cpus !=
dd->num_prstatus_notes))
diff --git a/mips64.c b/mips64.c
index 95f198f..62ed799 100644
--- a/mips64.c
+++ b/mips64.c
@@ -1277,9 +1277,79 @@ mips64_init(int when)
}
}
+/*
+ * 'help -r' command output
+ */
void
mips64_display_regs_from_elf_notes(int cpu, FILE *ofp)
{
+ const struct machine_specific *ms = machdep->machspec;
+ struct mips64_register *regs;
+
+ if (!ms->crash_task_regs) {
+ error(INFO, "registers not collected for cpu %d\n", cpu);
+ return;
+ }
+
+ regs = &ms->crash_task_regs[cpu];
+ if (!regs->regs[MIPS64_EF_R29] && !regs->regs[MIPS64_EF_CP0_EPC]) {
+ error(INFO, "registers not collected for cpu %d\n", cpu);
+ return;
+ }
+
+ fprintf(ofp,
+ " R0: %016lx R1: %016lx R2: %016lx\n"
+ " R3: %016lx R4: %016lx R5: %016lx\n"
+ " R6: %016lx R7: %016lx R8: %016lx\n"
+ " R9: %016lx R10: %016lx R11: %016lx\n"
+ " R12: %016lx R13: %016lx R14: %016lx\n"
+ " R15: %016lx R16: %016lx R17: %016lx\n"
+ " R18: %016lx R19: %016lx R20: %016lx\n"
+ " R21: %016lx R22: %016lx R23: %016lx\n"
+ " R24: %016lx R25: %016lx R26: %016lx\n"
+ " R27: %016lx R28: %016lx R29: %016lx\n"
+ " R30: %016lx R31: %016lx\n"
+ " LO: %016lx HI: %016lx\n"
+ " EPC: %016lx BADVADDR: %016lx\n"
+ " STATUS: %016lx CAUSE: %016lx\n",
+ regs->regs[MIPS64_EF_R0],
+ regs->regs[MIPS64_EF_R0 + 1],
+ regs->regs[MIPS64_EF_R0 + 2],
+ regs->regs[MIPS64_EF_R0 + 3],
+ regs->regs[MIPS64_EF_R0 + 4],
+ regs->regs[MIPS64_EF_R0 + 5],
+ regs->regs[MIPS64_EF_R0 + 6],
+ regs->regs[MIPS64_EF_R0 + 7],
+ regs->regs[MIPS64_EF_R0 + 8],
+ regs->regs[MIPS64_EF_R0 + 9],
+ regs->regs[MIPS64_EF_R0 + 10],
+ regs->regs[MIPS64_EF_R0 + 11],
+ regs->regs[MIPS64_EF_R0 + 12],
+ regs->regs[MIPS64_EF_R0 + 13],
+ regs->regs[MIPS64_EF_R0 + 14],
+ regs->regs[MIPS64_EF_R0 + 15],
+ regs->regs[MIPS64_EF_R0 + 16],
+ regs->regs[MIPS64_EF_R0 + 17],
+ regs->regs[MIPS64_EF_R0 + 18],
+ regs->regs[MIPS64_EF_R0 + 19],
+ regs->regs[MIPS64_EF_R0 + 20],
+ regs->regs[MIPS64_EF_R0 + 21],
+ regs->regs[MIPS64_EF_R0 + 22],
+ regs->regs[MIPS64_EF_R0 + 23],
+ regs->regs[MIPS64_EF_R0 + 24],
+ regs->regs[MIPS64_EF_R0 + 25],
+ regs->regs[MIPS64_EF_R0 + 26],
+ regs->regs[MIPS64_EF_R0 + 27],
+ regs->regs[MIPS64_EF_R0 + 28],
+ regs->regs[MIPS64_EF_R0 + 29],
+ regs->regs[MIPS64_EF_R0 + 30],
+ regs->regs[MIPS64_EF_R0 + 31],
+ regs->regs[MIPS64_EF_LO],
+ regs->regs[MIPS64_EF_HI],
+ regs->regs[MIPS64_EF_CP0_EPC],
+ regs->regs[MIPS64_EF_CP0_BADVADDR],
+ regs->regs[MIPS64_EF_CP0_STATUS],
+ regs->regs[MIPS64_EF_CP0_CAUSE]);
}
#else /* !MIPS64 */
diff --git a/netdump.c b/netdump.c
index d08f3ca..7238c92 100644
--- a/netdump.c
+++ b/netdump.c
@@ -2923,6 +2923,8 @@ display_regs_from_elf_notes(int cpu, FILE *ofp)
UINT(user_regs + sizeof(ulong) * 34));
} else if (machine_type("MIPS")) {
mips_display_regs_from_elf_notes(cpu, ofp);
+ } else if (machine_type("MIPS64")) {
+ mips64_display_regs_from_elf_notes(cpu, ofp);
}
}
@@ -2933,7 +2935,7 @@ dump_registers_for_elf_dumpfiles(void)
if (!(machine_type("X86") || machine_type("X86_64") ||
machine_type("ARM64") || machine_type("PPC64") ||
- machine_type("MIPS")))
+ machine_type("MIPS") || machine_type("MIPS64")))
error(FATAL, "-r option not supported for this dumpfile\n");
if (NETDUMP_DUMPFILE()) {
--
2.1.0