From 21b7d6492cf0a77a74c09a370c206df623930c43 Mon Sep 17 00:00:00 2001 From: wangjunqiang Date: Fri, 16 Sep 2022 10:37:54 +0800 Subject: [PATCH] add riscv64 support --- src/gcore.mk | 10 ++++ src/libgcore/gcore_coredump.c | 2 +- src/libgcore/gcore_defs.h | 47 ++++++++++++++++-- src/libgcore/gcore_riscv64.c | 91 +++++++++++++++++++++++++++++++++++ 4 files changed, 145 insertions(+), 5 deletions(-) create mode 100644 src/libgcore/gcore_riscv64.c diff --git a/src/gcore.mk b/src/gcore.mk index 4af292b..e986871 100644 --- a/src/gcore.mk +++ b/src/gcore.mk @@ -60,6 +60,12 @@ ifeq ($(shell arch), ppc64le) ARCH=SUPPORTED endif +ifeq ($(shell arch), riscv64) + TARGET=RISCV64 + 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 @@ -99,6 +105,10 @@ ifneq (,$(findstring $(TARGET), PPC64)) GCORE_CFILES += libgcore/gcore_ppc64.c endif +ifneq (,$(findstring $(TARGET), RISCV64)) +GCORE_CFILES += libgcore/gcore_riscv64.c +endif + GCORE_OFILES = $(patsubst %.c,%.o,$(GCORE_CFILES)) COMMON_CFLAGS=-Wall -I$(INCDIR) -I./libgcore -fPIC -D$(TARGET) \ diff --git a/src/libgcore/gcore_coredump.c b/src/libgcore/gcore_coredump.c index 3d0c0fc..e9ba91a 100644 --- a/src/libgcore/gcore_coredump.c +++ b/src/libgcore/gcore_coredump.c @@ -752,7 +752,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(MIPS) || defined(PPC64) +#if defined(X86) || defined(X86_64) || defined(ARM) || defined(MIPS) || defined(PPC64) || defined(RISCV64) struct user_regs_struct *regs = (struct user_regs_struct *)memnote->data; #endif #ifdef ARM64 diff --git a/src/libgcore/gcore_defs.h b/src/libgcore/gcore_defs.h index df87851..32d6553 100644 --- a/src/libgcore/gcore_defs.h +++ b/src/libgcore/gcore_defs.h @@ -166,6 +166,34 @@ #define Elf_Nhdr Elf64_Nhdr #endif +#ifdef RISCV64 +#define ELF_EXEC_PAGESIZE PAGESIZE() + +#define ELF_MACHINE EM_RISCV +#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_RISCV + +#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 + #ifndef NT_FILE #define NT_FILE 0x46494c45 #endif @@ -329,6 +357,11 @@ extern void gcore_default_regsets_init(void); #define REGSET_VIEW_MACHINE EM_PPC64 #endif +#ifdef RISCV64 +#define REGSET_VIEW_NAME "riscv64" +#define REGSET_VIEW_MACHINE EM_RISCV +#endif + extern int gcore_arch_get_fp_valid(struct task_context *tc); /* @@ -669,7 +702,13 @@ struct user_regs_struct { }; #endif -#if defined(X86) || defined(X86_64) || defined(ARM) || defined(MIPS) +#ifdef RISCV64 +struct user_regs_struct { + unsigned long gregs[32]; +}; +#endif + +#if defined(X86) || defined(X86_64) || defined(ARM) || defined(MIPS) || defined(RISCV64) 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]; @@ -678,7 +717,7 @@ typedef elf_greg_t elf_gregset_t[ELF_NGREG]; #if defined(X86) || defined(ARM) || defined(MIPS) #define PAGE_SIZE 4096 #endif -#if defined(ARM64) || defined(PPC64) +#if defined(ARM64) || defined(PPC64) || defined(RISCV64) #define PAGE_SIZE PAGESIZE() #endif @@ -837,12 +876,12 @@ typedef unsigned short __kernel_old_uid_t; typedef unsigned short __kernel_old_gid_t; #endif -#if defined(X86_64) || defined(ARM64) || defined(PPC64) +#if defined(X86_64) || defined(ARM64) || defined(PPC64) || defined(RISCV64) typedef unsigned int __kernel_uid_t; typedef unsigned int __kernel_gid_t; #endif -#ifdef ARM64 +#if defined(ARM64) || defined(RISCV64) #ifndef __kernel_old_uid_t typedef __kernel_uid_t __kernel_old_uid_t; typedef __kernel_gid_t __kernel_old_gid_t; diff --git a/src/libgcore/gcore_riscv64.c b/src/libgcore/gcore_riscv64.c new file mode 100644 index 0000000..7578cdf --- /dev/null +++ b/src/libgcore/gcore_riscv64.c @@ -0,0 +1,91 @@ +/* gcore_riscv64.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 RISCV64 + +#include "defs.h" +#include +#include +#include + +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), "gpr_get: pt_regs", + gcore_verbose_error_handle()); + + return 0; +} + +enum gcore_regset { + REGSET_GPR, +}; + +static struct user_regset riscv64_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 riscv64_regset_view = { + .name = "riscv64", + .regsets = riscv64_regsets, + .n = 1, + .e_machine = EM_RISCV, +}; + +const struct user_regset_view * +task_user_regset_view(void) +{ + return &riscv64_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 -- 2.25.1