Rabin,
Sorry for my very delayed response.
Thanks for your patch set.
I'll include the patch set in the next version and release it soon.
By the way, please note that I can develop x86 codes only.
I cannot test the MIPS codes at all and this is the same policy as for other
architectures.
If you want to keep quality of the MIPS codes good,
please test and fix the MIPS codes at each release and send the corresponding patch set to
me.
-----Original Message-----
From: crash-utility-bounces(a)redhat.com
[mailto:crash-utility-bounces@redhat.com] On Behalf Of Dave Anderson
Sent: Tuesday, December 27, 2016 10:35 PM
To: Discussion list for crash utility usage, maintenance and development
<crash-utility(a)redhat.com>
Cc: Rabin Vincent <rabinv(a)axis.com>
Subject: Re: [Crash-utility] [PATCH] gcore: Add MIPS support
Hi Rabin,
I forwarded your post directly to Daisuke Hatayama for review.
Thanks,
Dave
----- Original Message -----
> From: Rabin Vincent <rabinv(a)axis.com>
>
> 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(a)redhat.com
>
https://www.redhat.com/mailman/listinfo/crash-utility
>
--
Crash-utility mailing list
Crash-utility(a)redhat.com
https://www.redhat.com/mailman/listinfo/crash-utility