diff --git a/.crash-gcore-command.metadata b/.crash-gcore-command.metadata index ebba7a9..abdc1e6 100644 --- a/.crash-gcore-command.metadata +++ b/.crash-gcore-command.metadata @@ -1 +1 @@ -9f1a889ad7b3f01c88866dac44cabddd7d35f99c SOURCES/crash-gcore-command-1.3.1.tar.gz +9c542d8503824e5f16d00c47bfdb38a7481ed752 SOURCES/crash-gcore-command-1.5.1.tar.gz diff --git a/.gitignore b/.gitignore index 0f92527..569004f 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -SOURCES/crash-gcore-command-1.3.1.tar.gz +SOURCES/crash-gcore-command-1.5.1.tar.gz diff --git a/SOURCES/arm64_thread_struct_fpsimd_state.patch b/SOURCES/arm64_thread_struct_fpsimd_state.patch deleted file mode 100644 index ad819a9..0000000 --- a/SOURCES/arm64_thread_struct_fpsimd_state.patch +++ /dev/null @@ -1,15 +0,0 @@ - ---- crash-gcore-command-1.3.1/gcore.c.orig -+++ crash-gcore-command-1.3.1/gcore.c -@@ -501,6 +501,10 @@ static void gcore_offset_table_init(void - GCORE_MEMBER_OFFSET_INIT(vfp_hard_struct_fpscr, "vfp_hard_struct", "fpscr"); - GCORE_MEMBER_OFFSET_INIT(thread_struct_fpsimd_state, "thread_struct", "fpsimd_state"); - GCORE_MEMBER_OFFSET_INIT(thread_struct_tp_value, "thread_struct", "tp_value"); -+ if (GCORE_INVALID_MEMBER(thread_struct_fpsimd_state)) { -+ GCORE_ANON_MEMBER_OFFSET_INIT(thread_struct_fpsimd_state, "thread_struct", "uw.fpsimd_state"); -+ GCORE_ANON_MEMBER_OFFSET_INIT(thread_struct_tp_value, "thread_struct", "uw.tp_value"); -+ } - } - - static void gcore_size_table_init(void) - diff --git a/SOURCES/pid_link.patch b/SOURCES/pid_link.patch deleted file mode 100644 index 2993cca..0000000 --- a/SOURCES/pid_link.patch +++ /dev/null @@ -1,162 +0,0 @@ - -From: Masayoshi Mizuma - -On 4.19 and newer kernel, gcore command fails as following: - -=========================================================== - gcore: invalid structure size: pid_link - FILE: libgcore/gcore_coredump_table.c LINE: 423 FUNCTION: pid_alive() - - [./crash] error trace: 7f4a7a6762b8 => 7f4a7a676e0f => 53b391 => 53b316 - - 53b316: SIZE_verify.part.31+70 - 53b391: SIZE_verify+49 - - gcore: invalid structure size: pid_link - FILE: libgcore/gcore_coredump_table.c LINE: 423 FUNCTION: pid_alive() - - Failed. -=========================================================== - -That is because struct pid_link is removed and struct pid array is added to -struct signal_struct by commit 2c4704756cab ("pids: Move the pgrp and session -pid pointers from task_struct to signal_struct"). - -Get the pointer of struct pid from task_struct->thread_pid or -signal_struct->pids[] to fix the failure. - -Signed-off-by: Masayoshi Mizuma ---- - gcore.c | 4 +++ - libgcore/gcore_coredump_table.c | 48 +++++++++++++++++++++++++++------ - libgcore/gcore_defs.h | 2 ++ - 3 files changed, 46 insertions(+), 8 deletions(-) - - ---- a/gcore.c -+++ b/gcore.c -@@ -505,6 +505,10 @@ static void gcore_offset_table_init(void - GCORE_ANON_MEMBER_OFFSET_INIT(thread_struct_fpsimd_state, "thread_struct", "uw.fpsimd_state"); - GCORE_ANON_MEMBER_OFFSET_INIT(thread_struct_tp_value, "thread_struct", "uw.tp_value"); - } -+ if (MEMBER_EXISTS("task_struct", "thread_pid")) -+ GCORE_MEMBER_OFFSET_INIT(task_struct_thread_pid, "task_struct", "thread_pid"); -+ if (MEMBER_EXISTS("signal_struct", "pids")) -+ GCORE_MEMBER_OFFSET_INIT(signal_struct_pids, "signal_struct", "pids"); - } - - static void gcore_size_table_init(void) - -diff --git a/libgcore/gcore_coredump_table.c b/libgcore/gcore_coredump_table.c -index a073591..4cf9c38 100644 ---- a/libgcore/gcore_coredump_table.c -+++ b/libgcore/gcore_coredump_table.c -@@ -224,7 +224,7 @@ __task_pid_nr_ns(ulong task, enum pid_type type) - sizeof(ns), "__task_pid_nr_ns: ns", gcore_verbose_error_handle()); - - if (pid_alive(task)) { -- ulong pids_type_pid; -+ ulong pids_type_pid, signal; - - if (type != PIDTYPE_PID) - readmem(task + MEMBER_OFFSET("task_struct", -@@ -233,10 +233,34 @@ __task_pid_nr_ns(ulong task, enum pid_type type) - "__task_pid_nr_ns: group_leader", - gcore_verbose_error_handle()); - -- readmem(task + OFFSET(task_struct_pids) + type * SIZE(pid_link) -- + OFFSET(pid_link_pid), KVADDR, &pids_type_pid, -- sizeof(pids_type_pid), -- "__task_pid_nr_ns: pids_type_pid", gcore_verbose_error_handle()); -+ if (VALID_MEMBER(task_struct_pids)) -+ readmem(task + OFFSET(task_struct_pids) + -+ type * SIZE(pid_link) + OFFSET(pid_link_pid), -+ KVADDR, &pids_type_pid, -+ sizeof(pids_type_pid), -+ "__task_pid_nr_ns: pids_type_pid", -+ gcore_verbose_error_handle()); -+ else -+ if (type == PIDTYPE_PID) -+ readmem(task + GCORE_OFFSET(task_struct_thread_pid), -+ KVADDR, &pids_type_pid, -+ sizeof(pids_type_pid), -+ "__task_pid_nr_ns: pids_type_pid", -+ gcore_verbose_error_handle()); -+ else { -+ readmem(task + OFFSET(task_struct_signal), -+ KVADDR, &signal, -+ sizeof(signal), -+ "__task_pid_nr_ns: signal", -+ gcore_verbose_error_handle()); -+ -+ readmem(signal + GCORE_OFFSET(signal_struct_pids) + -+ type * sizeof(void *), -+ KVADDR, &pids_type_pid, -+ sizeof(pids_type_pid), -+ "__task_pid_nr_ns: pids_type_pid", -+ gcore_verbose_error_handle()); -+ } - - nr = pid_nr_ns(pids_type_pid, ns); - } -@@ -420,9 +444,17 @@ pid_alive(ulong task) - { - pid_t pid; - -- readmem(task + OFFSET(task_struct_pids) + PIDTYPE_PID * SIZE(pid_link) -- + OFFSET(pid_link_pid), KVADDR, &pid, sizeof(pid), "pid_alive", -- gcore_verbose_error_handle()); -+ if (VALID_MEMBER(task_struct_pids)) -+ readmem(task + OFFSET(task_struct_pids) + -+ PIDTYPE_PID * SIZE(pid_link) + OFFSET(pid_link_pid), -+ KVADDR, &pid, sizeof(pid), -+ "pid_alive", -+ gcore_verbose_error_handle()); -+ else -+ readmem(task + GCORE_OFFSET(task_struct_thread_pid), -+ KVADDR, &pid, sizeof(pid), -+ "task_struct.thread_pid", -+ gcore_verbose_error_handle()); - - return !!pid; - } -diff --git a/libgcore/gcore_defs.h b/libgcore/gcore_defs.h -index 18c4c2c..3c839f9 100644 ---- a/libgcore/gcore_defs.h -+++ b/libgcore/gcore_defs.h -@@ -1077,6 +1077,7 @@ struct gcore_offset_table - long sched_entity_sum_exec_runtime; - long signal_struct_cutime; - long signal_struct_pgrp; -+ long signal_struct_pids; - long signal_struct_session; - long signal_struct_stime; - long signal_struct_sum_sched_runtime; -@@ -1090,6 +1091,7 @@ struct gcore_offset_table - long task_struct_static_prio; - long task_struct_uid; - long task_struct_used_math; -+ long task_struct_thread_pid; - long thread_info_status; - long thread_info_fpstate; - long thread_info_vfpstate; --- -2.18.1 - - ---- a/gcore.mk -+++ b/gcore.mk -@@ -12,9 +12,9 @@ - # GNU General Public License for more details. - # - --VERSION=1.5.0 --DATE=30 Nov 2018 --PERIOD=2010, 2011, 2012, 2013, 2014, 2016, 2017, 2018 -+VERSION=1.5.1 -+DATE=25 Jun 2019 -+PERIOD=2010, 2011, 2012, 2013, 2014, 2016, 2017, 2018, 2019 - - ARCH=UNSUPPORTED - - diff --git a/SOURCES/upstream_1.5.0_equiv.patch b/SOURCES/upstream_1.5.0_equiv.patch deleted file mode 100644 index 118d23b..0000000 --- a/SOURCES/upstream_1.5.0_equiv.patch +++ /dev/null @@ -1,751 +0,0 @@ ---- crash-gcore-command-1.3.1/libgcore/gcore_x86.c.orig -+++ crash-gcore-command-1.3.1/libgcore/gcore_x86.c -@@ -20,10 +20,14 @@ - #include - #include - -+#undef MIN -+#define MIN(X,Y) (((X) < (Y)) ? (X) : (Y)) -+ - struct gcore_x86_table - { - #ifdef X86_64 - ulong (*get_old_rsp)(int cpu); -+ ulong (*user_stack_pointer)(struct task_context *tc); - #endif - ulong (*get_thread_struct_fpu)(struct task_context *tc); - ulong (*get_thread_struct_fpu_size)(void); -@@ -42,9 +46,14 @@ static ulong gcore_x86_64_get_old_rsp(in - static ulong gcore_x86_64_get_per_cpu__old_rsp(int cpu); - static ulong gcore_x86_64_get_cpu_pda_oldrsp(int cpu); - static ulong gcore_x86_64_get_cpu__pda_oldrsp(int cpu); -+ -+static ulong gcore_x86_64_user_stack_pointer_userrsp(struct task_context *tc); -+static ulong gcore_x86_64_user_stack_pointer_pt_regs(struct task_context *tc); - #endif - - static ulong -+gcore_x86_get_thread_struct_fpu_fpregs_state(struct task_context *tc); -+static ulong - gcore_x86_get_thread_struct_fpu_thread_xstate(struct task_context *tc); - static ulong gcore_x86_get_thread_struct_fpu_thread_xstate_size(void); - static ulong -@@ -78,6 +87,7 @@ static int is_special_ia32_syscall_v26(i - - static int tsk_used_math_v0(ulong task); - static int tsk_used_math_v11(ulong task); -+static int tsk_used_math_v4_14(ulong task); - - #ifdef X86_64 - static void gcore_x86_64_regset_xstate_init(void); -@@ -352,18 +362,15 @@ static int xfpregs_get(struct task_conte - unsigned int size, - void *buf) - { -- struct i387_fxsave_struct *fxsave = (struct i387_fxsave_struct *)buf; - union thread_xstate xstate; - - readmem(gxt->get_thread_struct_fpu(target), KVADDR, &xstate, -- gxt->get_thread_struct_fpu_size(), -+ sizeof(xstate), - "xfpregs_get: xstate", gcore_verbose_error_handle()); -- memcpy(buf, &xstate.fsave, sizeof(xstate.fsave)); -+ memcpy(buf, &xstate.fsave, MIN(size, sizeof(xstate.fsave))); - - init_fpu(target->task); - -- *fxsave = xstate.fxsave; -- - return 0; - } - -@@ -485,7 +492,7 @@ convert_from_fxsr(struct user_i387_ia32_ - int i; - - readmem(gxt->get_thread_struct_fpu(target), KVADDR, &xstate, -- gxt->get_thread_struct_fpu_size(), "convert_from_fxsr: xstate", -+ sizeof(xstate), "convert_from_fxsr: xstate", - gcore_verbose_error_handle()); - - to = (struct _fpreg *) &env->st_space[0]; -@@ -549,9 +556,9 @@ static int fpregs_get(struct task_contex - - if (!cpu_has_fxsr()) { - readmem(gxt->get_thread_struct_fpu(target), KVADDR, &xstate, -- gxt->get_thread_struct_fpu_size(), -+ sizeof(xstate), - "fpregs_get: xstate", gcore_verbose_error_handle()); -- memcpy(buf, &xstate.fsave, sizeof(xstate.fsave)); -+ memcpy(buf, &xstate.fsave, MIN(size, sizeof(xstate.fsave))); - return 0; - } - -@@ -562,6 +569,14 @@ static int fpregs_get(struct task_contex - return 0; - } - -+static ulong gcore_x86_get_thread_struct_fpu_fpregs_state(struct task_context *tc) -+{ -+ return tc->task + -+ OFFSET(task_struct_thread) + -+ GCORE_OFFSET(thread_struct_fpu) + -+ GCORE_OFFSET(fpu_state); -+} -+ - static ulong gcore_x86_get_thread_struct_fpu_thread_xstate(struct task_context *tc) - { - ulong state; -@@ -1010,6 +1025,26 @@ static int tsk_used_math_v11(ulong task) - return !!(flags & PF_USED_MATH); - } - -+static int tsk_used_math_v4_14(ulong task) -+{ -+ unsigned char initialized; -+ -+ if (!cpu_has_fxsr()) -+ return 0; -+ -+ readmem(task + -+ OFFSET(task_struct_thread) + -+ GCORE_OFFSET(thread_struct_fpu) + -+ MEMBER_OFFSET("fpu", "initialized"), -+ KVADDR, -+ &initialized, -+ sizeof(initialized), -+ "tsk_used_math_v4_14: initialized", -+ gcore_verbose_error_handle()); -+ -+ return !!initialized; -+} -+ - static inline int - user_mode(const struct user_regs_struct *regs) - { -@@ -1331,6 +1366,23 @@ static inline void restore_rest(ulong ta - } - - /** -+ * gcore_x86_64_get_old_rsp_zero() - get rsp at per-cpu area -+ * -+ * @cpu target CPU's CPU id -+ * -+ * Given a CPU id, returns a RSP value saved at per-cpu area for the -+ * CPU whose id is the given CPU id. -+ * -+ * This is a method of get_old_rsp() returning always 0 for when no -+ * appropriate method is found. -+ */ -+static ulong gcore_x86_64_get_old_rsp_zero(int cpu) -+{ -+ error(WARNING, "failed to detect location of sp register, forcing 0.\n"); -+ return 0UL; -+} -+ -+/** - * gcore_x86_64_get_old_rsp() - get rsp at per-cpu area - * - * @cpu target CPU's CPU id -@@ -1421,6 +1473,50 @@ static ulong gcore_x86_64_get_cpu__pda_o - return oldrsp; - } - -+static ulong gcore_x86_64_user_stack_pointer_userrsp(struct task_context *tc) -+{ -+ ulong usersp; -+ -+ /* -+ * rsp is saved in per-CPU old_rsp, which is saved in -+ * thread->usersp at each context switch. -+ */ -+ if (is_task_active(tc->task)) -+ return gxt->get_old_rsp(tc->processor); -+ -+ readmem(tc->task + OFFSET(task_struct_thread) + -+ GCORE_OFFSET(thread_struct_usersp), KVADDR, &usersp, -+ sizeof(usersp), -+ "gcore_x86_64_user_stack_pointer_userrsp: usersp", -+ gcore_verbose_error_handle()); -+ -+ return usersp; -+} -+ -+static ulong gcore_x86_64_user_stack_pointer_pt_regs(struct task_context *tc) -+{ -+ char *pt_regs_buf; -+ ulong sp0, sp; -+ struct machine_specific *ms = machdep->machspec; -+ -+ pt_regs_buf = GETBUF(SIZE(pt_regs)); -+ -+ readmem(tc->task + OFFSET(task_struct_thread) + -+ GCORE_OFFSET(thread_struct_sp0), KVADDR, &sp0, -+ sizeof(sp0), -+ "gcore_x86_64_user_stack_pointer_pt_regs: sp0", -+ gcore_verbose_error_handle()); -+ -+ readmem(sp0 - SIZE(pt_regs), KVADDR, pt_regs_buf, SIZE(pt_regs), -+ "gcore_x86_64_user_stack_pointer_pt_regs: pt_regs", -+ gcore_verbose_error_handle()); -+ -+ sp = ULONG(pt_regs_buf + ms->pto.rsp); -+ -+ FREEBUF(pt_regs_buf); -+ return sp; -+} -+ - static int - gcore_find_regs_from_bt_output(FILE *output, char *buf, size_t bufsize) - { -@@ -1648,18 +1744,8 @@ restore_regs_syscall_context(struct task - { - const int nr_syscall = (int)regs->orig_ax; - -- /* -- * rsp is saved in per-CPU old_rsp, which is saved in -- * thread->usersp at each context switch. -- */ -- if (is_task_active(target->task)) { -- regs->sp = gxt->get_old_rsp(target->processor); -- } else { -- readmem(target->task + OFFSET(task_struct_thread) + -- GCORE_OFFSET(thread_struct_usersp), KVADDR, ®s->sp, -- sizeof(regs->sp), -- "genregs_get: usersp", gcore_verbose_error_handle()); -- } -+ if (gxt->user_stack_pointer) -+ regs->sp = gxt->user_stack_pointer(target); - - /* - * entire registers are saved for special system calls. -@@ -1788,6 +1874,15 @@ static int genregs_get(struct task_conte - "system call instruction used could not be found\n"); - case GCORE_KERNEL_ENTRY_IRQ: - case GCORE_KERNEL_ENTRY_INT80: -+ /* -+ * The commit ff467594f2a4be01a0fa5e9ffc223fa930d232dd -+ * in the linux kernel begins saving all registers -+ * including callee-saved registers on the bottom of -+ * the kernel stack even on the IRQ entry. I'm very -+ * happy. -+ */ -+ if (THIS_KERNEL_VERSION < LINUX(4,2,0)) -+ restore_rest(target->task, regs, &active_regs); - restore_rest(target->task, regs, &active_regs); - restore_segment_registers(target->task, regs); - break; -@@ -1834,14 +1929,31 @@ static void gcore_x86_table_register_get - - else if (symbol_exists("_cpu_pda")) - gxt->get_old_rsp = gcore_x86_64_get_cpu__pda_oldrsp; -+ -+ else -+ gxt->get_old_rsp = gcore_x86_64_get_old_rsp_zero; -+} -+ -+static void gcore_x86_table_register_user_stack_pointer(void) -+{ -+ if (MEMBER_EXISTS("thread_struct", "usersp") || -+ MEMBER_EXISTS("thread_struct", "userrsp")) -+ gxt->user_stack_pointer = gcore_x86_64_user_stack_pointer_userrsp; -+ -+ else if (MEMBER_EXISTS("thread_struct", "sp0")) -+ gxt->user_stack_pointer = gcore_x86_64_user_stack_pointer_pt_regs; - } - #endif - - static void gcore_x86_table_register_get_thread_struct_fpu(void) - { - if (MEMBER_EXISTS("thread_struct", "fpu")) { -- gxt->get_thread_struct_fpu = -- gcore_x86_get_thread_struct_fpu_thread_xstate; -+ if (MEMBER_OFFSET("fpu", "state") == 8) -+ gxt->get_thread_struct_fpu = -+ gcore_x86_get_thread_struct_fpu_thread_xstate; -+ else -+ gxt->get_thread_struct_fpu = -+ gcore_x86_get_thread_struct_fpu_fpregs_state; - gxt->get_thread_struct_fpu_size = - gcore_x86_get_thread_struct_fpu_thread_xstate_size; - } else if (MEMBER_EXISTS("thread_struct", "xstate")) { -@@ -1900,7 +2012,9 @@ static void gcore_x86_table_register_is_ - */ - static void gcore_x86_table_register_tsk_used_math(void) - { -- if (GCORE_VALID_MEMBER(task_struct_used_math)) -+ if (MEMBER_EXISTS("fpu", "initialized")) -+ gxt->tsk_used_math = tsk_used_math_v4_14; -+ else if (GCORE_VALID_MEMBER(task_struct_used_math)) - gxt->tsk_used_math = tsk_used_math_v0; - else - gxt->tsk_used_math = tsk_used_math_v11; -@@ -1911,6 +2025,7 @@ static void gcore_x86_table_register_tsk - void gcore_x86_table_init(void) - { - gcore_x86_table_register_get_old_rsp(); -+ gcore_x86_table_register_user_stack_pointer(); - gcore_x86_table_register_get_thread_struct_fpu(); - gcore_x86_table_register_is_special_syscall(); - gcore_x86_table_register_is_special_ia32_syscall(); -@@ -2248,6 +2363,20 @@ ulong gcore_arch_get_gate_vma(void) - if (gcore_is_arch_32bit_emulation(CURRENT_CONTEXT())) - return 0UL; - -+ if (symbol_exists("vsyscall_mode")) { -+ enum { ENUMERATE, NONE } vsyscall_mode; -+ -+ readmem(symbol_value("vsyscall_mode"), -+ KVADDR, -+ &vsyscall_mode, -+ sizeof(vsyscall_mode), -+ "gcore_arch_get_gate_vma: vsyscall_mode", -+ gcore_verbose_error_handle()); -+ -+ if (vsyscall_mode == NONE) -+ return 0UL; -+ } -+ - return symbol_value("gate_vma"); - #else - return 0UL; ---- crash-gcore-command-1.3.1/libgcore/gcore_coredump.c.orig -+++ crash-gcore-command-1.3.1/libgcore/gcore_coredump.c -@@ -683,7 +683,7 @@ fill_prstatus_note(struct elf_note_info - 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 ---- crash-gcore-command-1.3.1/libgcore/gcore_dumpfilter.c.orig -+++ crash-gcore-command-1.3.1/libgcore/gcore_dumpfilter.c -@@ -18,10 +18,61 @@ - - static ulong dumpfilter = GCORE_DUMPFILTER_DEFAULT; - -+static int special_mapping_name(ulong vma) -+{ -+ ulong vm_private_data, name_p; -+ -+ readmem(vma + GCORE_OFFSET(vm_area_struct_vm_private_data), -+ KVADDR, -+ &vm_private_data, -+ sizeof(vm_private_data), -+ "always_dump_vma: vma->vm_private_data", -+ gcore_verbose_error_handle()); -+ -+ readmem(vm_private_data + -+ GCORE_OFFSET(vm_special_mapping_name), -+ KVADDR, -+ &name_p, -+ sizeof(name_p), -+ "always_dump_vma: ((struct vm_special_mapping *)vma->vm_private_data)->name", -+ gcore_verbose_error_handle()); -+ -+ return name_p ? TRUE : FALSE; -+} -+ - static int always_dump_vma(ulong vma) - { - if (vma == gcore_arch_get_gate_vma()) - return TRUE; -+ -+ if (GCORE_VALID_MEMBER(vm_special_mapping_name)) { -+ ulong vm_ops, name; -+ -+ readmem(vma + GCORE_OFFSET(vm_area_struct_vm_ops), -+ KVADDR, -+ &vm_ops, -+ sizeof(vm_ops), -+ "always_dump_vma: vma->vm_ops", -+ gcore_verbose_error_handle()); -+ -+ if (!vm_ops) -+ goto out; -+ -+ readmem(vm_ops + GCORE_OFFSET(vm_operations_struct_name), -+ KVADDR, -+ &name, -+ sizeof(name), -+ "always_dump_vma: vma->vm_ops->name", -+ gcore_verbose_error_handle()); -+ -+ if (!name) -+ goto out; -+ -+ if (name == symbol_value("special_mapping_name")) -+ return special_mapping_name(vma); -+ } -+out: -+ - if (gcore_arch_vma_name(vma)) - return TRUE; - return FALSE; ---- crash-gcore-command-1.3.1/libgcore/gcore_defs.h.orig -+++ crash-gcore-command-1.3.1/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(v - #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 - 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 -@@ -1070,6 +1101,7 @@ struct gcore_offset_table - long thread_struct_gs; - long thread_struct_gsindex; - long thread_struct_i387; -+ long thread_struct_sp0; - long thread_struct_tls_array; - long thread_struct_usersp; - long thread_struct_xstate; -@@ -1082,6 +1114,10 @@ struct gcore_offset_table - long vfp_hard_struct_fpregs; - long vfp_hard_struct_fpscr; - long vm_area_struct_anon_vma; -+ long vm_area_struct_vm_ops; -+ long vm_area_struct_vm_private_data; -+ long vm_operations_struct_name; -+ long vm_special_mapping_name; - long x8664_pda_oldrsp; - }; - ---- crash-gcore-command-1.3.1/libgcore/gcore_mips.c.orig -+++ crash-gcore-command-1.3.1/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 -+#include -+#include -+#include -+ -+#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) */ ---- crash-gcore-command-1.3.1/gcore.c.orig -+++ crash-gcore-command-1.3.1/gcore.c -@@ -463,10 +463,16 @@ static void gcore_offset_table_init(void - GCORE_MEMBER_OFFSET_INIT(thread_info_vfpstate, "thread_info", "vfpstate"); - GCORE_MEMBER_OFFSET_INIT(thread_struct_ds, "thread_struct", "ds"); - GCORE_MEMBER_OFFSET_INIT(thread_struct_es, "thread_struct", "es"); -- GCORE_MEMBER_OFFSET_INIT(thread_struct_fs, "thread_struct", "fs"); -+ if (MEMBER_EXISTS("thread_struct", "fs")) -+ GCORE_MEMBER_OFFSET_INIT(thread_struct_fs, "thread_struct", "fs"); -+ else -+ GCORE_MEMBER_OFFSET_INIT(thread_struct_fs, "thread_struct", "fsbase"); - GCORE_MEMBER_OFFSET_INIT(thread_struct_fsindex, "thread_struct", "fsindex"); - GCORE_MEMBER_OFFSET_INIT(thread_struct_fpu, "thread_struct", "fpu"); -- GCORE_MEMBER_OFFSET_INIT(thread_struct_gs, "thread_struct", "gs"); -+ if (MEMBER_EXISTS("thread_struct", "gs")) -+ GCORE_MEMBER_OFFSET_INIT(thread_struct_gs, "thread_struct", "gs"); -+ else -+ GCORE_MEMBER_OFFSET_INIT(thread_struct_gs, "thread_struct", "gsbase"); - GCORE_MEMBER_OFFSET_INIT(thread_struct_gsindex, "thread_struct", "gsindex"); - GCORE_MEMBER_OFFSET_INIT(thread_struct_i387, "thread_struct", "i387"); - GCORE_MEMBER_OFFSET_INIT(thread_struct_tls_array, "thread_struct", "tls_array"); -@@ -474,6 +480,7 @@ static void gcore_offset_table_init(void - GCORE_MEMBER_OFFSET_INIT(thread_struct_usersp, "thread_struct", "usersp"); - else if (MEMBER_EXISTS("thread_struct", "userrsp")) - GCORE_MEMBER_OFFSET_INIT(thread_struct_usersp, "thread_struct", "userrsp"); -+ GCORE_MEMBER_OFFSET_INIT(thread_struct_sp0, "thread_struct", "sp0"); - if (MEMBER_EXISTS("thread_struct", "xstate")) - GCORE_MEMBER_OFFSET_INIT(thread_struct_xstate, "thread_struct", "xstate"); - else if (MEMBER_EXISTS("thread_struct", "i387")) -@@ -482,6 +489,10 @@ static void gcore_offset_table_init(void - GCORE_MEMBER_OFFSET_INIT(thread_struct_io_bitmap_ptr, "thread_struct", "io_bitmap_ptr"); - GCORE_MEMBER_OFFSET_INIT(user_regset_n, "user_regset", "n"); - GCORE_MEMBER_OFFSET_INIT(vm_area_struct_anon_vma, "vm_area_struct", "anon_vma"); -+ GCORE_MEMBER_OFFSET_INIT(vm_area_struct_vm_ops, "vm_area_struct", "vm_ops"); -+ GCORE_MEMBER_OFFSET_INIT(vm_area_struct_vm_private_data, "vm_area_struct", "vm_private_data"); -+ GCORE_MEMBER_OFFSET_INIT(vm_operations_struct_name, "vm_operations_struct", "name"); -+ GCORE_MEMBER_OFFSET_INIT(vm_special_mapping_name, "vm_special_mapping", "name"); - - if (symbol_exists("_cpu_pda")) - GCORE_MEMBER_OFFSET_INIT(x8664_pda_oldrsp, "x8664_pda", "oldrsp"); -@@ -499,9 +510,15 @@ static void gcore_size_table_init(void) - GCORE_MEMBER_SIZE_INIT(mm_struct_saved_auxv, "mm_struct", "saved_auxv"); - GCORE_MEMBER_SIZE_INIT(thread_struct_ds, "thread_struct", "ds"); - GCORE_MEMBER_SIZE_INIT(thread_struct_es, "thread_struct", "es"); -- GCORE_MEMBER_SIZE_INIT(thread_struct_fs, "thread_struct", "fs"); -+ if (MEMBER_EXISTS("thread_struct", "fs")) -+ GCORE_MEMBER_SIZE_INIT(thread_struct_fs, "thread_struct", "fs"); -+ else -+ GCORE_MEMBER_SIZE_INIT(thread_struct_fs, "thread_struct", "fsbase"); - GCORE_MEMBER_SIZE_INIT(thread_struct_fsindex, "thread_struct", "fsindex"); -- GCORE_MEMBER_SIZE_INIT(thread_struct_gs, "thread_struct", "gs"); -+ if (MEMBER_EXISTS("thread_struct", "gs")) -+ GCORE_MEMBER_SIZE_INIT(thread_struct_gs, "thread_struct", "gs"); -+ else -+ GCORE_MEMBER_SIZE_INIT(thread_struct_gs, "thread_struct", "gsbase"); - GCORE_MEMBER_SIZE_INIT(thread_struct_gsindex, "thread_struct", "gsindex"); - GCORE_MEMBER_SIZE_INIT(thread_struct_tls_array, "thread_struct", "tls_array"); - GCORE_STRUCT_SIZE_INIT(thread_xstate, "thread_xstate"); ---- crash-gcore-command-1.3.1/gcore.mk.orig -+++ crash-gcore-command-1.3.1/gcore.mk -@@ -12,9 +12,9 @@ - # GNU General Public License for more details. - # - --VERSION=1.3.1 --DATE=6 Nov 2014 --PERIOD=2010, 2011, 2012, 2013, 2014 -+VERSION=1.5.0 -+DATE=30 Nov 2018 -+PERIOD=2010, 2011, 2012, 2013, 2014, 2016, 2017, 2018 - - ARCH=UNSUPPORTED - -@@ -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/SPECS/crash-gcore-command.spec b/SPECS/crash-gcore-command.spec index de50a3f..0fc0872 100644 --- a/SPECS/crash-gcore-command.spec +++ b/SPECS/crash-gcore-command.spec @@ -3,12 +3,12 @@ # Summary: Gcore extension module for the crash utility Name: crash-gcore-command -Version: 1.3.1 -Release: 4%{?dist} +Version: 1.5.1 +Release: 1%{?dist} License: GPLv2 Group: Development/Debuggers -Source: %{name}-%{version}.tar.gz -URL: http://people.redhat.com/anderson/extensions/%{name}-%{version}.tar.gz +Source: https://github.com/crash-utility/crash-extensions/blob/master/%{name}-%{version}.tar.gz +URL: https://crash-utility.github.io/extensions.html # Vendor: FUJITSU LIMITED # Packager: HATAYAMA Daisuke ExclusiveOS: Linux @@ -17,9 +17,6 @@ Buildroot: %{_tmppath}/%{name}-root BuildRequires: crash-devel >= 5.1.5, zlib-devel lzo-devel snappy-devel Requires: crash >= 5.1.5 Patch0: rhel8_build.patch -Patch1: upstream_1.5.0_equiv.patch -Patch2: arm64_thread_struct_fpsimd_state.patch -Patch3: pid_link.patch %description Command for creating a core dump file of a user-space task that was @@ -28,9 +25,6 @@ running in a kernel dumpfile. %prep %setup -q -n %{name}-%{version} %patch0 -p1 -b rhel8_build.patch -%patch1 -p1 -b upstream_1.5.0_equiv.patch -%patch2 -p1 -b arm64_thread_struct_fpsimd_state.patch -%patch3 -p1 -b pid_link.patch %build make -f gcore.mk @@ -50,6 +44,10 @@ rm -Rf $RPM_BUILD_ROOT %doc COPYING %changelog +* Wed Jul 8 2020 Bhupesh Sharma - 1.5.1-1 +- Rebase crash-gcore-command to github upstream version crash-gcore-command-1.5.1 + Resolves: rhbz#1851747 + * Tue Jun 25 2019 Dave Anderson - 1.3.1-4 - Fix "invalid structure size: pid_link" Resolves: rhbz#1722726