Hello Daisuke, Attached is a patch that introduces support for the PPC64 architecture. The patch was written by Michal Toman (mtoman@xxxxxxxxxx). 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. 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 +#ifdef PPC64LE +#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 Crash-utility@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/crash-utility