Hi Rabin, I forwarded your post directly to Daisuke Hatayama for review. Thanks, Dave ----- Original Message ----- > From: Rabin Vincent <rabinv@xxxxxxxx> > > This adds basic support for MIPS to the gcore extension. > --- > gcore.mk | 10 +++ > libgcore/gcore_coredump.c | 2 +- > libgcore/gcore_defs.h | 39 ++++++++++-- > libgcore/gcore_mips.c | 159 > ++++++++++++++++++++++++++++++++++++++++++++++ > 4 files changed, 205 insertions(+), 5 deletions(-) > create mode 100644 libgcore/gcore_mips.c > > diff --git a/gcore.mk b/gcore.mk > index c9683d4..ffc9ce7 100644 > --- a/gcore.mk > +++ b/gcore.mk > @@ -42,6 +42,12 @@ ifeq ($(shell arch), aarch64) > ARCH=SUPPORTED > endif > > +ifeq ($(shell arch), mips) > + TARGET=MIPS > + TARGET_CFLAGS= > + ARCH=SUPPORTED > +endif > + > ifeq ($(shell arch), ppc64) > TARGET=PPC64 > TARGET_CFLAGS= > @@ -85,6 +91,10 @@ ifneq (,$(findstring $(TARGET), ARM64)) > GCORE_CFILES += libgcore/gcore_arm64.c > endif > > +ifneq (,$(findstring $(TARGET), MIPS)) > +GCORE_CFILES += libgcore/gcore_mips.c > +endif > + > ifneq (,$(findstring $(TARGET), PPC64)) > GCORE_CFILES += libgcore/gcore_ppc64.c > endif > diff --git a/libgcore/gcore_coredump.c b/libgcore/gcore_coredump.c > index 892ddf9..e91f29a 100644 > --- a/libgcore/gcore_coredump.c > +++ b/libgcore/gcore_coredump.c > @@ -683,7 +683,7 @@ fill_prstatus_note(struct elf_note_info *info, struct > task_context *tc, > struct memelfnote *memnote) > { > struct elf_prstatus *prstatus; > -#if defined(X86) || defined(X86_64) || defined(ARM) || defined(PPC64) > +#if defined(X86) || defined(X86_64) || defined(ARM) || defined(MIPS) || > defined(PPC64) > struct user_regs_struct *regs = (struct user_regs_struct *)memnote->data; > #endif > #ifdef ARM64 > diff --git a/libgcore/gcore_defs.h b/libgcore/gcore_defs.h > index ba1fde2..6fdb943 100644 > --- a/libgcore/gcore_defs.h > +++ b/libgcore/gcore_defs.h > @@ -94,6 +94,26 @@ > #define Elf_Nhdr Elf32_Nhdr > #endif > > +#ifdef MIPS > +#define ELF_EXEC_PAGESIZE 4096 > + > +#define ELF_MACHINE EM_MIPS > +#define ELF_OSABI ELFOSABI_NONE > + > +#define ELF_CLASS ELFCLASS32 > +#define ELF_DATA ELFDATA2LSB > +#define ELF_ARCH EM_MIPS > + > +#define Elf_Half Elf32_Half > +#define Elf_Word Elf32_Word > +#define Elf_Off Elf32_Off > + > +#define Elf_Ehdr Elf32_Ehdr > +#define Elf_Phdr Elf32_Phdr > +#define Elf_Shdr Elf32_Shdr > +#define Elf_Nhdr Elf32_Nhdr > +#endif > + > #ifdef ARM64 > #define ELF_EXEC_PAGESIZE PAGESIZE() > > @@ -290,6 +310,11 @@ extern void gcore_default_regsets_init(void); > #define REGSET_VIEW_MACHINE EM_AARCH64 > #endif > > +#ifdef MIPS > +#define REGSET_VIEW_NAME "mips" > +#define REGSET_VIEW_MACHINE EM_MIPS > +#endif > + > #ifdef PPC64 > #define REGSET_VIEW_NAME "ppc64" > #define REGSET_VIEW_MACHINE EM_PPC64 > @@ -594,6 +619,12 @@ struct user_regs_struct32{ > #endif /* GCORE_ARCH_COMPAT */ > #endif > > +#ifdef MIPS > +struct user_regs_struct { > + unsigned long gregs[45]; > +}; > +#endif > + > #ifdef PPC64 > /* taken from asm/ptrace.h */ > struct user_regs_struct { > @@ -620,13 +651,13 @@ struct user_regs_struct { > }; > #endif > > -#if defined(X86) || defined(X86_64) || defined(ARM) > +#if defined(X86) || defined(X86_64) || defined(ARM) || defined(MIPS) > typedef ulong elf_greg_t; > #define ELF_NGREG (sizeof(struct user_regs_struct) / sizeof(elf_greg_t)) > typedef elf_greg_t elf_gregset_t[ELF_NGREG]; > #endif > > -#if defined(X86) || defined(ARM) > +#if defined(X86) || defined(ARM) || defined(MIPS) > #define PAGE_SIZE 4096 > #endif > #if defined(ARM64) || defined(PPC64) > @@ -783,7 +814,7 @@ struct elf_prstatus > int pr_fpvalid; /* True if math co-processor being used. */ > }; > > -#if defined(X86) || defined(X86_64) || defined(ARM) > +#if defined(X86) || defined(X86_64) || defined(ARM) || defined(MIPS) > typedef unsigned short __kernel_old_uid_t; > typedef unsigned short __kernel_old_gid_t; > #endif > @@ -803,7 +834,7 @@ typedef __kernel_gid_t __kernel_old_gid_t; > typedef __kernel_old_uid_t old_uid_t; > typedef __kernel_old_gid_t old_gid_t; > > -#if defined(X86) || defined(ARM) > +#if defined(X86) || defined(ARM) || defined(MIPS) > typedef unsigned short __kernel_uid_t; > typedef unsigned short __kernel_gid_t; > #endif > diff --git a/libgcore/gcore_mips.c b/libgcore/gcore_mips.c > new file mode 100644 > index 0000000..be67d51 > --- /dev/null > +++ b/libgcore/gcore_mips.c > @@ -0,0 +1,159 @@ > +/* gcore_mips.c -- core analysis suite > + * > + * Copyright (C) 2016 Axis Communications > + * > + * This program is free software; you can redistribute it and/or modify > + * it under the terms of the GNU General Public License as published by > + * the Free Software Foundation; either version 2 of the License, or > + * (at your option) any later version. > + * > + * This program is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > + * GNU General Public License for more details. > + */ > +#if defined(MIPS) > + > +#include "defs.h" > +#include <gcore_defs.h> > +#include <stdint.h> > +#include <elf.h> > +#include <asm/ldt.h> > + > +#define MIPS32_EF_R0 6 > +#define MIPS32_EF_R1 7 > +#define MIPS32_EF_R26 32 > +#define MIPS32_EF_R27 33 > +#define MIPS32_EF_R31 37 > +#define MIPS32_EF_LO 38 > +#define MIPS32_EF_HI 39 > +#define MIPS32_EF_CP0_EPC 40 > +#define MIPS32_EF_CP0_BADVADDR 41 > +#define MIPS32_EF_CP0_STATUS 42 > +#define MIPS32_EF_CP0_CAUSE 43 > + > +static int gpr_get(struct task_context *target, > + const struct user_regset *regset, > + unsigned int size, void *buf) > +{ > + static int once; > + struct user_regs_struct *regs = buf; > + struct mips_pt_regs_main *mains; > + struct mips_pt_regs_cp0 *cp0; > + char pt_regs[SIZE(pt_regs)]; > + int i; > + > + /* > + * All registers are saved in thread_info.regs only on certain types of > + * entries to the kernel (such as abort handling). For other types of > + * entries (such as system calls), only a subset of the registers are > + * saved on entry and the rest are saved on the stack according to the > + * ABI's calling conventions. To always get the full register set we > + * would have to unwind the stack and find where the registers are by > + * using DWARF information. We don't have an implementation for this > + * right now so warn to avoid misleading the user. Only warn since > + * this function is called multiple times even for a single invocation > + * of the gcore command. > + */ > + if (!once) { > + once = 1; > + error(WARNING, "WARNING: Current register values may be inaccurate\n"); > + } > + > + readmem(machdep->get_stacktop(target->task) - 32 - SIZE(pt_regs), > + KVADDR, pt_regs, SIZE(pt_regs), "genregs_get: pt_regs", > + gcore_verbose_error_handle()); > + > + mains = (struct mips_pt_regs_main *) (pt_regs + OFFSET(pt_regs_regs)); > + cp0 = (struct mips_pt_regs_cp0 *) \ > + (pt_regs + OFFSET(pt_regs_cp0_badvaddr)); > + > + BZERO(regs, sizeof(*regs)); > + > + for (i = MIPS32_EF_R1; i <= MIPS32_EF_R31; i++) { > + /* k0/k1 are copied as zero. */ > + if (i == MIPS32_EF_R26 || i == MIPS32_EF_R27) > + continue; > + > + regs->gregs[i] = mains->regs[i - MIPS32_EF_R0]; > + } > + > + regs->gregs[MIPS32_EF_LO] = mains->lo; > + regs->gregs[MIPS32_EF_HI] = mains->hi; > + regs->gregs[MIPS32_EF_CP0_EPC] = cp0->cp0_epc; > + regs->gregs[MIPS32_EF_CP0_BADVADDR] = cp0->cp0_badvaddr; > + regs->gregs[MIPS32_EF_CP0_STATUS] = mains->cp0_status; > + regs->gregs[MIPS32_EF_CP0_CAUSE] = cp0->cp0_cause; > + > + return 0; > +} > + > +enum gcore_regset { > + REGSET_GPR, > +}; > + > +static struct user_regset mips_regsets[] = { > + [REGSET_GPR] = { > + .core_note_type = NT_PRSTATUS, > + .name = "CORE", > + .size = ELF_NGREG * sizeof(unsigned int), > + .get = gpr_get, > + }, > +}; > + > +#ifndef ARRAY_SIZE > +#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) > +#endif > + > +static const struct user_regset_view mips_regset_view = { > + .name = "mips", > + .regsets = mips_regsets, > + .n = ARRAY_SIZE(mips_regsets), > + .e_machine = EM_MIPS, > +}; > + > +const struct user_regset_view * > +task_user_regset_view(void) > +{ > + return &mips_regset_view; > +} > + > +int gcore_is_arch_32bit_emulation(struct task_context *tc) > +{ > + return FALSE; > +} > + > +ulong gcore_arch_get_gate_vma(void) > +{ > + return 0UL; > +} > + > +char *gcore_arch_vma_name(ulong vma) > +{ > + ulong mm, vm_start, vdso; > + > + readmem(vma + OFFSET(vm_area_struct_vm_mm), KVADDR, &mm, sizeof(mm), > + "gcore_arch_vma_name: vma->vm_mm", > + gcore_verbose_error_handle()); > + > + readmem(vma + OFFSET(vm_area_struct_vm_start), KVADDR, &vm_start, > + sizeof(vm_start), "gcore_arch_vma_name: vma->vm_start", > + gcore_verbose_error_handle()); > + > + readmem(mm + GCORE_OFFSET(mm_struct_context) + > + GCORE_OFFSET(mm_context_t_vdso), KVADDR, &vdso, > + sizeof(vdso), "gcore_arch_vma_name: mm->context.vdso", > + gcore_verbose_error_handle()); > + > + if (mm && vm_start == vdso) > + return "[vdso]"; > + > + return NULL; > +} > + > +int gcore_arch_vsyscall_has_vm_alwaysdump_flag(void) > +{ > + return FALSE; > +} > + > +#endif /* defined(MIPS) */ > -- > 2.1.4 > > -- > Crash-utility mailing list > Crash-utility@xxxxxxxxxx > https://www.redhat.com/mailman/listinfo/crash-utility > -- Crash-utility mailing list Crash-utility@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/crash-utility