Mainly added some environment configurations, macro definitions, specific architecture structures and some function declarations supported by the RISCV64 architecture. With this patch we can get crash command, $ make target=RISCV64 -j16 Signed-off-by: Xianting Tian <xianting.tian@xxxxxxxxxxxxxxxxx> --- Makefile | 7 ++- README | 2 +- configure.c | 33 ++++++++++- defs.h | 136 +++++++++++++++++++++++++++++++++++++++++++- diskdump.c | 24 +++++++- help.c | 2 +- lkcd_vmdump_v2_v3.h | 2 +- netdump.c | 11 +++- ramdump.c | 2 + riscv64.c | 45 +++++++++++++++ symbols.c | 10 ++++ 11 files changed, 264 insertions(+), 10 deletions(-) create mode 100644 riscv64.c diff --git a/Makefile b/Makefile index e520b12..e2e1c4a 100644 --- a/Makefile +++ b/Makefile @@ -64,7 +64,7 @@ CFILES=main.c tools.c global_data.c memory.c filesys.c help.c task.c \ kernel.c test.c gdb_interface.c configure.c net.c dev.c bpf.c \ printk.c \ alpha.c x86.c ppc.c ia64.c s390.c s390x.c s390dbf.c ppc64.c x86_64.c \ - arm.c arm64.c mips.c mips64.c sparc64.c \ + arm.c arm64.c mips.c mips64.c riscv64.c sparc64.c \ extensions.c remote.c va_server.c va_server_v1.c symbols.c cmdline.c \ lkcd_common.c lkcd_v1.c lkcd_v2_v3.c lkcd_v5.c lkcd_v7.c lkcd_v8.c\ lkcd_fix_mem.c s390_dump.c lkcd_x86_trace.c \ @@ -84,7 +84,7 @@ OBJECT_FILES=main.o tools.o global_data.o memory.o filesys.o help.o task.o \ build_data.o kernel.o test.o gdb_interface.o net.o dev.o bpf.o \ printk.o \ alpha.o x86.o ppc.o ia64.o s390.o s390x.o s390dbf.o ppc64.o x86_64.o \ - arm.o arm64.o mips.o mips64.o sparc64.o \ + arm.o arm64.o mips.o mips64.o riscv64.o sparc64.o \ extensions.o remote.o va_server.o va_server_v1.o symbols.o cmdline.o \ lkcd_common.o lkcd_v1.o lkcd_v2_v3.o lkcd_v5.o lkcd_v7.o lkcd_v8.o \ lkcd_fix_mem.o s390_dump.o netdump.o diskdump.o makedumpfile.o xendump.o \ @@ -438,6 +438,9 @@ mips.o: ${GENERIC_HFILES} ${REDHAT_HFILES} mips.c mips64.o: ${GENERIC_HFILES} ${REDHAT_HFILES} mips64.c ${CC} -c ${CRASH_CFLAGS} mips64.c ${WARNING_OPTIONS} ${WARNING_ERROR} +riscv64.o: ${GENERIC_HFILES} ${REDHAT_HFILES} riscv64.c + ${CC} -c ${CRASH_CFLAGS} riscv64.c ${WARNING_OPTIONS} ${WARNING_ERROR} + sparc64.o: ${GENERIC_HFILES} ${REDHAT_HFILES} sparc64.c ${CC} -c ${CRASH_CFLAGS} sparc64.c ${WARNING_OPTIONS} ${WARNING_ERROR} diff --git a/README b/README index 5abbce1..5ac5b60 100644 --- a/README +++ b/README @@ -37,7 +37,7 @@ These are the current prerequisites: o At this point, x86, ia64, x86_64, ppc64, ppc, arm, arm64, alpha, mips, - mips64, s390 and s390x-based kernels are supported. Other architectures + mips64, riscv64, s390 and s390x-based kernels are supported. Other architectures may be addressed in the future. o One size fits all -- the utility can be run on any Linux kernel version diff --git a/configure.c b/configure.c index 5188851..6a36b49 100644 --- a/configure.c +++ b/configure.c @@ -107,6 +107,7 @@ void add_extra_lib(char *); #undef MIPS #undef SPARC64 #undef MIPS64 +#undef RISCV64 #define UNKNOWN 0 #define X86 1 @@ -122,6 +123,7 @@ void add_extra_lib(char *); #define MIPS 11 #define SPARC64 12 #define MIPS64 13 +#define RISCV64 14 #define TARGET_X86 "TARGET=X86" #define TARGET_ALPHA "TARGET=ALPHA" @@ -136,6 +138,7 @@ void add_extra_lib(char *); #define TARGET_MIPS "TARGET=MIPS" #define TARGET_MIPS64 "TARGET=MIPS64" #define TARGET_SPARC64 "TARGET=SPARC64" +#define TARGET_RISCV64 "TARGET=RISCV64" #define TARGET_CFLAGS_X86 "TARGET_CFLAGS=-D_FILE_OFFSET_BITS=64" #define TARGET_CFLAGS_ALPHA "TARGET_CFLAGS=" @@ -158,6 +161,7 @@ void add_extra_lib(char *); #define TARGET_CFLAGS_MIPS_ON_X86_64 "TARGET_CFLAGS=-m32 -D_FILE_OFFSET_BITS=64" #define TARGET_CFLAGS_MIPS64 "TARGET_CFLAGS=" #define TARGET_CFLAGS_SPARC64 "TARGET_CFLAGS=" +#define TARGET_CFLAGS_RISCV64 "TARGET_CFLAGS=" #define GDB_TARGET_DEFAULT "GDB_CONF_FLAGS=" #define GDB_TARGET_ARM_ON_X86 "GDB_CONF_FLAGS=--target=arm-elf-linux" @@ -404,6 +408,9 @@ get_current_configuration(struct supported_gdb_version *sp) #ifdef __sparc_v9__ target_data.target = SPARC64; #endif +#ifdef __riscv64__ + target_data.target = RISCV64; +#endif set_initial_target(sp); @@ -457,6 +464,12 @@ get_current_configuration(struct supported_gdb_version *sp) if ((target_data.initial_gdb_target != UNKNOWN) && (target_data.host != target_data.initial_gdb_target)) arch_mismatch(sp); + } else if ((target_data.target == X86_64) && + (name_to_target((char *)target_data.target_as_param) == RISCV64)) { + /* + * Build an RISCV64 crash binary on an X86_64 host. + */ + target_data.target = RISCV64; } else { fprintf(stderr, "\ntarget=%s is not supported on the %s host architecture\n\n", @@ -497,6 +510,10 @@ get_current_configuration(struct supported_gdb_version *sp) (target_data.target != MIPS64)) arch_mismatch(sp); + if ((target_data.initial_gdb_target == RISCV64) && + (target_data.target != RISCV64)) + arch_mismatch(sp); + if ((target_data.initial_gdb_target == X86) && (target_data.target != X86)) { if (target_data.target == X86_64) @@ -660,6 +677,9 @@ show_configuration(void) case SPARC64: printf("TARGET: SPARC64\n"); break; + case RISCV64: + printf("TARGET: RISCV64\n"); + break; } if (strlen(target_data.program)) { @@ -777,6 +797,10 @@ build_configure(struct supported_gdb_version *sp) target = TARGET_SPARC64; target_CFLAGS = TARGET_CFLAGS_SPARC64; break; + case RISCV64: + target = TARGET_RISCV64; + target_CFLAGS = TARGET_CFLAGS_RISCV64; + break; } ldflags = get_extra_flags("LDFLAGS.extra", NULL); @@ -1374,7 +1398,7 @@ make_spec_file(struct supported_gdb_version *sp) printf("Vendor: Red Hat, Inc.\n"); printf("Packager: Dave Anderson <anderson@xxxxxxxxxx>\n"); printf("ExclusiveOS: Linux\n"); - printf("ExclusiveArch: %%{ix86} alpha ia64 ppc ppc64 ppc64pseries ppc64iseries x86_64 s390 s390x arm aarch64 ppc64le mips mipsel mips64el sparc64\n"); + printf("ExclusiveArch: %%{ix86} alpha ia64 ppc ppc64 ppc64pseries ppc64iseries x86_64 s390 s390x arm aarch64 ppc64le mips mipsel mips64el sparc64 riscv64\n"); printf("Buildroot: %%{_tmppath}/%%{name}-root\n"); printf("BuildRequires: ncurses-devel zlib-devel bison\n"); printf("Requires: binutils\n"); @@ -1613,6 +1637,8 @@ set_initial_target(struct supported_gdb_version *sp) target_data.initial_gdb_target = MIPS; else if (strncmp(buf, "SPARC64", strlen("SPARC64")) == 0) target_data.initial_gdb_target = SPARC64; + else if (strncmp(buf, "RISCV64", strlen("RISCV64")) == 0) + target_data.initial_gdb_target = RISCV64; } char * @@ -1633,6 +1659,7 @@ target_to_name(int target) case MIPS: return("MIPS"); case MIPS64: return("MIPS64"); case SPARC64: return("SPARC64"); + case RISCV64: return("RISCV64"); } return "UNKNOWN"; @@ -1697,6 +1724,10 @@ name_to_target(char *name) return MIPS64; else if (strncmp(name, "sparc64", strlen("sparc64")) == 0) return SPARC64; + else if (strncmp(name, "RISCV64", strlen("RISCV64")) == 0) + return RISCV64; + else if (strncmp(name, "riscv64", strlen("riscv64")) == 0) + return RISCV64; return UNKNOWN; } diff --git a/defs.h b/defs.h index a6735d0..428e874 100644 --- a/defs.h +++ b/defs.h @@ -76,7 +76,7 @@ #if !defined(X86) && !defined(X86_64) && !defined(ALPHA) && !defined(PPC) && \ !defined(IA64) && !defined(PPC64) && !defined(S390) && !defined(S390X) && \ !defined(ARM) && !defined(ARM64) && !defined(MIPS) && !defined(MIPS64) && \ - !defined(SPARC64) + !defined(RISCV64) && !defined(SPARC64) #ifdef __alpha__ #define ALPHA #endif @@ -118,6 +118,9 @@ #ifdef __sparc_v9__ #define SPARC64 #endif +#ifdef __riscv64__ +#define RISCV64 +#endif #endif #ifdef X86 @@ -159,6 +162,9 @@ #ifdef SPARC64 #define NR_CPUS (4096) #endif +#ifdef RISCV64 +#define NR_CPUS (256) +#endif #define NR_DEVICE_DUMPS (64) @@ -3470,6 +3476,43 @@ struct arm64_stackframe { #define _MAX_PHYSMEM_BITS 48 #endif /* MIPS64 */ +#ifdef RISCV64 +#define _64BIT_ +#define MACHINE_TYPE "RISCV64" + +#define PAGEBASE(X) (((ulong)(X)) & (ulong)machdep->pagemask) + +#define PTOV(X) ((unsigned long)(X)+(machdep->kvbase)) +#define VTOP(X) ((unsigned long)(X)-(machdep->kvbase)) + +#define IS_VMALLOC_ADDR(X) (vt->vmalloc_start && (ulong)(X) >= vt->vmalloc_start) + +#define MODULES_VADDR (machdep->machspec->modules_vaddr) +#define MODULES_END (machdep->machspec->modules_end) +#define VMALLOC_START (machdep->machspec->vmalloc_start_addr) +#define VMALLOC_END (machdep->machspec->vmalloc_end) + +/* from arch/riscv/include/asm/pgtable.h */ +#define __SWP_TYPE_SHIFT 6 +#define __SWP_TYPE_BITS 5 +#define __SWP_TYPE_MASK ((1UL << __SWP_TYPE_BITS) - 1) +#define __SWP_OFFSET_SHIFT (__SWP_TYPE_BITS + __SWP_TYPE_SHIFT) + +#define MAX_SWAPFILES_CHECK() \ + BUILD_BUG_ON(MAX_SWAPFILES_SHIFT > __SWP_TYPE_BITS) + +#define SWP_TYPE(entry) (((entry) >> __SWP_TYPE_SHIFT) & __SWP_TYPE_MASK) +#define SWP_OFFSET(entry) ((entry) >> __SWP_OFFSET_SHIFT) +#define __swp_type(entry) SWP_TYPE(entry) +#define __swp_offset(entry) SWP_OFFSET(entry) + +#define TIF_SIGPENDING (THIS_KERNEL_VERSION >= LINUX(2,6,23) ? 1 : 2) + +/* from arch/riscv/include/asm/sparsemem.h */ +#define _SECTION_SIZE_BITS 27 +#define _MAX_PHYSMEM_BITS 56 +#endif /* RISCV64 */ + #ifdef X86 #define _32BIT_ #define MACHINE_TYPE "X86" @@ -4518,6 +4561,10 @@ struct machine_specific { #define MAX_HEXADDR_STRLEN (16) #define UVADDR_PRLEN (16) #endif +#ifdef RISCV64 +#define MAX_HEXADDR_STRLEN (16) +#define UVADDR_PRLEN (16) +#endif #define BADADDR ((ulong)(-1)) #define BADVAL ((ulong)(-1)) @@ -5112,6 +5159,9 @@ void dump_build_data(void); #ifdef MIPS64 #define machdep_init(X) mips64_init(X) #endif +#ifdef RISCV64 +#define machdep_init(X) riscv64_init(X) +#endif #ifdef SPARC64 #define machdep_init(X) sparc64_init(X) #endif @@ -5592,6 +5642,9 @@ void display_help_screen(char *); #ifdef SPARC64 #define dump_machdep_table(X) sparc64_dump_machdep_table(X) #endif +#ifdef RISCV64 +#define dump_machdep_table(X) riscv64_dump_machdep_table(X) +#endif extern char *help_pointer[]; extern char *help_alias[]; extern char *help_ascii[]; @@ -6653,6 +6706,87 @@ struct machine_specific { #endif /* MIPS64 */ +/* + * riscv64.c + */ +void riscv64_display_regs_from_elf_notes(int, FILE *); + +#ifdef RISCV64 +void riscv64_init(int); +void riscv64_dump_machdep_table(ulong); + +#define display_idt_table() \ + error(FATAL, "-d option is not applicable to RISCV64 architecture\n") + +/* from arch/riscv/include/asm/ptrace.h */ +struct riscv64_register { + ulong regs[35]; +}; + +struct riscv64_pt_regs { + ulong badvaddr; + ulong cause; + ulong epc; +}; + +struct riscv64_unwind_frame { + unsigned long pc; + unsigned long ra; + unsigned long sp; +}; + +#define KSYMS_START (0x1) + +struct machine_specific { + ulong phys_base; + ulong vmalloc_start_addr; + ulong modules_vaddr; + ulong modules_end; + + ulong _page_present; + ulong _page_read; + ulong _page_write; + ulong _page_exec; + ulong _page_user; + ulong _page_global; + ulong _page_accessed; + ulong _page_dirty; + ulong _page_soft; + ulong _page_sec; + ulong _page_share; + ulong _page_buf; + ulong _page_cache; + ulong _page_so; + ulong _page_special; + ulong _page_table; + ulong _page_prot_none; + + ulong _pfn_shift; + + struct riscv64_register *crash_task_regs; +}; +/* from arch/riscv/include/asm/pgtable-bits.h */ +#define _PAGE_PRESENT (machdep->machspec->_page_present) +#define _PAGE_READ (machdep->machspec->_page_read) +#define _PAGE_WRITE (machdep->machspec->_page_write) +#define _PAGE_EXEC (machdep->machspec->_page_exec) +#define _PAGE_USER (machdep->machspec->_page_user) +#define _PAGE_GLOBAL (machdep->machspec->_page_global) +#define _PAGE_ACCESSED (machdep->machspec->_page_accessed) +#define _PAGE_DIRTY (machdep->machspec->_page_dirty) +#define _PAGE_SOFT (machdep->machspec->_page_soft) +#define _PAGE_SEC (machdep->machspec->_page_sec) +#define _PAGE_SHARE (machdep->machspec->_page_share) +#define _PAGE_BUF (machdep->machspec->_page_buf) +#define _PAGE_CACHE (machdep->machspec->_page_cache) +#define _PAGE_SO (machdep->machspec->_page_so) +#define _PAGE_SPECIAL _PAGE_SOFT +#define _PAGE_TABLE _PAGE_PRESENT +#define _PAGE_PROT_NONE _PAGE_READ +#define _PAGE_PFN_SHIFT 10 + +#endif /* RISCV64 */ + /* * sparc64.c */ diff --git a/diskdump.c b/diskdump.c index 2c1f9be..fb08ac2 100644 --- a/diskdump.c +++ b/diskdump.c @@ -622,6 +622,9 @@ restart: else if (STRNEQ(header->utsname.machine, "aarch64") && machine_type_mismatch(file, "ARM64", NULL, 0)) goto err; + else if (STRNEQ(header->utsname.machine, "riscv64") && + machine_type_mismatch(file, "RISCV64", NULL, 0)) + goto err; if (header->block_size != block_size) { block_size = header->block_size; @@ -780,6 +783,8 @@ restart: dd->machine_type = EM_AARCH64; else if (machine_type("SPARC64")) dd->machine_type = EM_SPARCV9; + else if (machine_type("RISCV64")) + dd->machine_type = EM_RISCV; else { error(INFO, "%s: unsupported machine type: %s\n", DISKDUMP_VALID() ? "diskdump" : "compressed kdump", @@ -1526,6 +1531,12 @@ get_diskdump_regs_mips(struct bt_info *bt, ulong *eip, ulong *esp) machdep->get_stack_frame(bt, eip, esp); } +static void +get_diskdump_regs_riscv64(struct bt_info *bt, ulong *eip, ulong *esp) +{ + machdep->get_stack_frame(bt, eip, esp); +} + static void get_diskdump_regs_sparc64(struct bt_info *bt, ulong *eip, ulong *esp) { @@ -1605,6 +1616,10 @@ get_diskdump_regs(struct bt_info *bt, ulong *eip, ulong *esp) get_diskdump_regs_sparc64(bt, eip, esp); break; + case EM_RISCV: + get_diskdump_regs_riscv64(bt, eip, esp); + break; + default: error(FATAL, "%s: unsupported machine type: %s\n", DISKDUMP_VALID() ? "diskdump" : "compressed kdump", @@ -1751,7 +1766,8 @@ dump_note_offsets(FILE *fp) qemu = FALSE; if (machine_type("X86_64") || machine_type("S390X") || machine_type("ARM64") || machine_type("PPC64") || - machine_type("SPARC64") || machine_type("MIPS64")) { + machine_type("SPARC64") || machine_type("MIPS64") || + machine_type("RISCV64")) { note64 = (void *)dd->notes_buf + tot; len = sizeof(Elf64_Nhdr); if (STRNEQ((char *)note64 + len, "QEMU")) @@ -2548,6 +2564,9 @@ diskdump_display_regs(int cpu, FILE *ofp) if (machine_type("MIPS64")) mips64_display_regs_from_elf_notes(cpu, ofp); + + if (machine_type("RISCV64")) + riscv64_display_regs_from_elf_notes(cpu, ofp); } void @@ -2558,7 +2577,8 @@ dump_registers_for_compressed_kdump(void) if (!KDUMP_CMPRS_VALID() || (dd->header->header_version < 4) || !(machine_type("X86") || machine_type("X86_64") || machine_type("ARM64") || machine_type("PPC64") || - machine_type("MIPS") || machine_type("MIPS64"))) + machine_type("MIPS") || machine_type("MIPS64") || + machine_type("RISCV64"))) error(FATAL, "-r option not supported for this dumpfile\n"); if (machine_type("ARM64") && (kt->cpus != dd->num_prstatus_notes)) diff --git a/help.c b/help.c index 51a0fe3..e4c39ed 100644 --- a/help.c +++ b/help.c @@ -9481,7 +9481,7 @@ char *README[] = { " These are the current prerequisites: ", "", " o At this point, x86, ia64, x86_64, ppc64, ppc, arm, arm64, alpha, mips,", -" mips64, s390 and s390x-based kernels are supported. Other architectures", +" mips64, riscv64, s390 and s390x-based kernels are supported. Other architectures", " may be addressed in the future.", "", " o One size fits all -- the utility can be run on any Linux kernel version", diff --git a/lkcd_vmdump_v2_v3.h b/lkcd_vmdump_v2_v3.h index 984c2c2..7fa70b9 100644 --- a/lkcd_vmdump_v2_v3.h +++ b/lkcd_vmdump_v2_v3.h @@ -37,7 +37,7 @@ #if defined(ARM) || defined(X86) || defined(PPC) || defined(S390) || \ defined(S390X) || defined(ARM64) || defined(MIPS) || \ - defined(MIPS64) || defined(SPARC64) + defined(MIPS64) || defined(SPARC64) || defined(RISCV64) /* * Kernel header file for Linux crash dumps. diff --git a/netdump.c b/netdump.c index ff273b4..45b9ddd 100644 --- a/netdump.c +++ b/netdump.c @@ -300,6 +300,12 @@ is_netdump(char *file, ulong source_query) goto bailout; break; + case EM_RISCV: + if (machine_type_mismatch(file, "RISCV64", NULL, + source_query)) + goto bailout; + break; + default: if (machine_type_mismatch(file, "(unknown)", NULL, source_query)) @@ -2925,6 +2931,8 @@ display_regs_from_elf_notes(int cpu, FILE *ofp) mips_display_regs_from_elf_notes(cpu, ofp); } else if (machine_type("MIPS64")) { mips64_display_regs_from_elf_notes(cpu, ofp); + } else if (machine_type("RISCV64")) { + riscv64_display_regs_from_elf_notes(cpu, ofp); } } @@ -2935,7 +2943,8 @@ dump_registers_for_elf_dumpfiles(void) if (!(machine_type("X86") || machine_type("X86_64") || machine_type("ARM64") || machine_type("PPC64") || - machine_type("MIPS") || machine_type("MIPS64"))) + machine_type("MIPS") || machine_type("MIPS64") || + machine_type("RISCV64"))) error(FATAL, "-r option not supported for this dumpfile\n"); if (NETDUMP_DUMPFILE()) { diff --git a/ramdump.c b/ramdump.c index a206fcb..d2bd7ff 100644 --- a/ramdump.c +++ b/ramdump.c @@ -188,6 +188,8 @@ char *ramdump_to_elf(void) e_machine = EM_MIPS; else if (machine_type("X86_64")) e_machine = EM_X86_64; + else if (machine_type("RISCV64")) + e_machine = EM_RISCV; else error(FATAL, "ramdump: unsupported machine type: %s\n", MACHINE_TYPE); diff --git a/riscv64.c b/riscv64.c new file mode 100644 index 0000000..a4cd5c8 --- /dev/null +++ b/riscv64.c @@ -0,0 +1,45 @@ +/* riscv64.c - core analysis suite + * + * Copyright (C) 2022 Alibaba Group Holding Limited. + * + * 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 <elf.h> +#include "defs.h" + +void +riscv64_dump_machdep_table(ulong arg) +{ +} + +void +riscv64_init(int when) +{ +} + +void +riscv64_display_regs_from_elf_notes(int cpu, FILE *ofp) +{ +} + +#else /* !RISCV64 */ + +#include "defs.h" + +void +riscv64_display_regs_from_elf_notes(int cpu, FILE *ofp) +{ + return; +} + +#endif /* !RISCV64 */ diff --git a/symbols.c b/symbols.c index ba5e274..0ba2b00 100644 --- a/symbols.c +++ b/symbols.c @@ -3743,6 +3743,11 @@ is_kernel(char *file) goto bailout; break; + case EM_RISCV: + if (machine_type_mismatch(file, "RISCV64", NULL, 0)) + goto bailout; + break; + default: if (machine_type_mismatch(file, "(unknown)", NULL, 0)) goto bailout; @@ -4002,6 +4007,11 @@ is_shared_object(char *file) if (machine_type("MIPS64")) return TRUE; break; + + case EM_RISCV: + if (machine_type("RISCV64")) + return TRUE; + break; } if (CRASHDEBUG(1)) -- 2.17.1 -- Crash-utility mailing list Crash-utility@xxxxxxxxxx https://listman.redhat.com/mailman/listinfo/crash-utility Contribution Guidelines: https://github.com/crash-utility/crash/wiki