----- Original Message -----
>
>
> Hello Daisuke,
>
> Attached is a patch that introduces support for the PPC64 architecture.
> The patch was written by Michal Toman ([email protected]). It is based
> upon crash-gcore-command-1.3.0-rc.
>
> The patch supports both big-endian and little-endian formats. However,
> it does require the ELF_DATA fix to elf64_fill_elf_header() that I reported
> yesterday. I have attached a separate patch to fix elf64_fill_elf_header
> and elf32_fill_elf_header().
>
> Please include these two patches in crash-gcore-command-1.3.0.
Hi Daisuke,
Can you please replace the add-ppc64-v5.patch with the attached
add-ppc64-v6.patch?
The change consists of one line that replaces the (non-existent) "PPC64LE" test
with the __BYTE_ORDER test:
+ifndef ELF_DATA
+#ifdef PPC64LE
+#define ELF_DATA ELFDATA2LSB
+#else
+#define ELF_DATA ELFDATA2MSB
+#endif
+#endif
to this:
+#ifndef ELF_DATA
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+#define ELF_DATA ELFDATA2LSB
+#else
+#define ELF_DATA ELFDATA2MSB
+#endif
+#endif
Actually it's highly unlikely that ELF_DATA will *not* be defined, but
just in case there are distributions where the #include file path does
not pick up /usr/include/asm/elf.h, then the change above will resolve it.
Thanks,
Dave
diff -up crash-gcore-command-1.3.0-rc/libgcore/gcore_elf_struct.c.orig crash-gcore-command-1.3.0-rc/libgcore/gcore_elf_struct.c
--- crash-gcore-command-1.3.0-rc/libgcore/gcore_elf_struct.c.orig 2014-10-16 15:38:49.209728831 -0400
+++ crash-gcore-command-1.3.0-rc/libgcore/gcore_elf_struct.c 2014-10-16 15:39:07.689867117 -0400
@@ -44,7 +44,7 @@ elf64_fill_elf_header(struct gcore_elf_s
BCOPY(ELFMAG, e->e_ident, SELFMAG);
e->e_ident[EI_CLASS] = ELFCLASS64;
- e->e_ident[EI_DATA] = ELFDATA2LSB;
+ e->e_ident[EI_DATA] = ELF_DATA;
e->e_ident[EI_VERSION] = EV_CURRENT;
e->e_ident[EI_OSABI] = ei_osabi;
e->e_ehsize = sizeof(Elf64_Ehdr);
@@ -217,7 +217,7 @@ elf32_fill_elf_header(struct gcore_elf_s
BCOPY(ELFMAG, e->e_ident, SELFMAG);
e->e_ident[EI_CLASS] = ELFCLASS32;
- e->e_ident[EI_DATA] = ELFDATA2LSB;
+ e->e_ident[EI_DATA] = ELF_DATA;
e->e_ident[EI_VERSION] = EV_CURRENT;
e->e_ident[EI_OSABI] = ei_osabi;
e->e_ehsize = sizeof(Elf32_Ehdr);
diff -urNp crash-gcore-command-1.3.0-rc/gcore.mk c/gcore.mk
--- crash-gcore-command-1.3.0-rc/gcore.mk 2014-10-14 09:55:38.000000000 +0000
+++ c/gcore.mk 2014-10-17 09:26:39.650043751 +0000
@@ -42,6 +42,18 @@ ifeq ($(shell arch), aarch64)
ARCH=SUPPORTED
endif
+ifeq ($(shell arch), ppc64)
+ TARGET=PPC64
+ TARGET_CFLAGS=
+ ARCH=SUPPORTED
+endif
+
+ifeq ($(shell arch), ppc64le)
+ TARGET=PPC64
+ TARGET_CFLAGS=
+ ARCH=SUPPORTED
+endif
+
ifeq ($(shell /bin/ls /usr/include/crash/defs.h 2>/dev/null), /usr/include/crash/defs.h)
INCDIR=/usr/include/crash
endif
@@ -73,6 +85,10 @@ ifneq (,$(findstring $(TARGET), ARM64))
GCORE_CFILES += libgcore/gcore_arm64.c
endif
+ifneq (,$(findstring $(TARGET), PPC64))
+GCORE_CFILES += libgcore/gcore_ppc64.c
+endif
+
GCORE_OFILES = $(patsubst %.c,%.o,$(GCORE_CFILES))
COMMON_CFLAGS=-Wall -I$(INCDIR) -I./libgcore -fPIC -D$(TARGET) \
diff -urNp crash-gcore-command-1.3.0-rc/libgcore/gcore_coredump.c c/libgcore/gcore_coredump.c
--- crash-gcore-command-1.3.0-rc/libgcore/gcore_coredump.c 2014-10-14 09:55:38.000000000 +0000
+++ c/libgcore/gcore_coredump.c 2014-10-17 09:26:39.650043751 +0000
@@ -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)
+#if defined(X86) || defined(X86_64) || defined(ARM) || defined(PPC64)
struct user_regs_struct *regs = (struct user_regs_struct *)memnote->data;
#endif
#ifdef ARM64
diff -urNp crash-gcore-command-1.3.0-rc/libgcore/gcore_defs.h c/libgcore/gcore_defs.h
--- crash-gcore-command-1.3.0-rc/libgcore/gcore_defs.h 2014-10-14 09:55:38.000000000 +0000
+++ c/libgcore/gcore_defs.h 2014-10-17 09:28:04.610045138 +0000
@@ -114,6 +114,34 @@
#endif
#endif
+#ifdef PPC64
+#define ELF_EXEC_PAGESIZE PAGESIZE()
+
+#define ELF_MACHINE EM_PPC64
+#define ELF_OSABI ELFOSABI_NONE
+
+#define ELF_CLASS ELFCLASS64
+
+#ifndef ELF_DATA
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+#define ELF_DATA ELFDATA2LSB
+#else
+#define ELF_DATA ELFDATA2MSB
+#endif
+#endif
+
+#define ELF_ARCH EM_PPC64
+
+#define Elf_Half Elf64_Half
+#define Elf_Word Elf64_Word
+#define Elf_Off Elf64_Off
+
+#define Elf_Ehdr Elf64_Ehdr
+#define Elf_Phdr Elf64_Phdr
+#define Elf_Shdr Elf64_Shdr
+#define Elf_Nhdr Elf64_Nhdr
+#endif
+
#define PAGE_ALIGN(X) roundup(X, ELF_EXEC_PAGESIZE)
/*
@@ -258,6 +286,11 @@ extern void gcore_default_regsets_init(v
#define REGSET_VIEW_MACHINE EM_AARCH64
#endif
+#ifdef PPC64
+#define REGSET_VIEW_NAME "ppc64"
+#define REGSET_VIEW_MACHINE EM_PPC64
+#endif
+
extern int gcore_arch_get_fp_valid(struct task_context *tc);
/*
@@ -534,6 +567,32 @@ typedef struct user_fpsimd_state elf_fpr
#endif
+#ifdef PPC64
+/* taken from asm/ptrace.h */
+struct user_regs_struct {
+ unsigned long gpr[32];
+ unsigned long nip;
+ unsigned long msr;
+ unsigned long orig_gpr3; /* Used for restarting system calls */
+ unsigned long ctr;
+ unsigned long link;
+ unsigned long xer;
+ unsigned long ccr;
+#ifdef __powerpc64__
+ unsigned long softe; /* Soft enabled/disabled */
+#else
+ unsigned long mq; /* 601 only (not used at present) */
+ /* Used on APUS to hold IPL value. */
+#endif
+ unsigned long trap; /* Reason for being here */
+ /* N.B. for critical exceptions on 4xx, the dar and dsisr
+ fields are overloaded to hold srr0 and srr1. */
+ unsigned long dar; /* Fault registers */
+ unsigned long dsisr; /* on 4xx/Book-E used for ESR */
+ unsigned long result; /* Result of a system call */
+};
+#endif
+
#if defined(X86) || defined(X86_64) || defined(ARM)
typedef ulong elf_greg_t;
#define ELF_NGREG (sizeof(struct user_regs_struct) / sizeof(elf_greg_t))
@@ -543,7 +602,7 @@ typedef elf_greg_t elf_gregset_t[ELF_NGR
#if defined(X86) || defined(ARM)
#define PAGE_SIZE 4096
#endif
-#ifdef ARM64
+#if defined(ARM64) || defined(PPC64)
#define PAGE_SIZE PAGESIZE()
#endif
@@ -702,7 +761,7 @@ typedef unsigned short __kernel_old_uid_
typedef unsigned short __kernel_old_gid_t;
#endif
-#if defined(X86_64) || defined(ARM64)
+#if defined(X86_64) || defined(ARM64) || defined(PPC64)
typedef unsigned int __kernel_uid_t;
typedef unsigned int __kernel_gid_t;
#endif
diff -urNp crash-gcore-command-1.3.0-rc/libgcore/gcore_ppc64.c c/libgcore/gcore_ppc64.c
--- crash-gcore-command-1.3.0-rc/libgcore/gcore_ppc64.c 1970-01-01 00:00:00.000000000 +0000
+++ c/libgcore/gcore_ppc64.c 2014-10-17 09:26:39.650043751 +0000
@@ -0,0 +1,90 @@
+/* gcore_ppc64.c
+ *
+ * Copyright (C) 2014 Red Hat, Inc. All rights reserved
+ *
+ * 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.
+ */
+
+#ifdef PPC64
+
+#include "defs.h"
+#include <gcore_defs.h>
+#include <stdint.h>
+#include <elf.h>
+
+static int gpr_get(struct task_context *target,
+ const struct user_regset *regset,
+ unsigned int size, void *buf)
+{
+ struct user_regs_struct *regs = (struct user_regs_struct *)buf;
+
+ BZERO(regs, sizeof(*regs));
+
+ readmem(machdep->get_stacktop(target->task) - SIZE(pt_regs), KVADDR,
+ regs, SIZE(pt_regs), "genregs_get: pt_regs",
+ gcore_verbose_error_handle());
+
+ return 0;
+}
+
+enum gcore_regset {
+ REGSET_GPR,
+};
+
+static struct user_regset ppc64_regsets[] = {
+ [REGSET_GPR] = {
+ .core_note_type = NT_PRSTATUS,
+ .name = "CORE",
+ .size = ELF_NGREG * sizeof(unsigned int),
+ .get = gpr_get,
+ },
+};
+
+static const struct user_regset_view ppc64_regset_view = {
+ .name = "ppc64",
+ .regsets = ppc64_regsets,
+ .n = 1,
+ .e_machine = EM_PPC64,
+};
+
+const struct user_regset_view *
+task_user_regset_view(void)
+{
+ return &ppc64_regset_view;
+}
+
+int gcore_is_arch_32bit_emulation(struct task_context *tc)
+{
+ return FALSE;
+}
+
+/**
+ * Return an address to gate_vma.
+ */
+ulong gcore_arch_get_gate_vma(void)
+{
+ if (!symbol_exists("gate_vma"))
+ return 0UL;
+
+ return symbol_value("gate_vma");
+}
+
+char *gcore_arch_vma_name(ulong vma)
+{
+ return NULL;
+}
+
+int gcore_arch_vsyscall_has_vm_alwaysdump_flag(void)
+{
+ return FALSE;
+}
+
+#endif
--
Crash-utility mailing list
[email protected]
https://www.redhat.com/mailman/listinfo/crash-utility