From: Mark W. <ma...@so...> - 2025-02-25 16:52:34
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=32fc9cc751809c90deac9d40f1c755691de6ce12 commit 32fc9cc751809c90deac9d40f1c755691de6ce12 Author: Petr Pavlu <pet...@da...> Date: Tue Apr 11 19:30:42 2023 +0000 riscv64: Add initial support: Valgrind modifications The following people contributed to the initial RISC-V support: Petr Pavlu <pet...@da...> Xeonacid <h.d...@gm...> laokz <la...@fo...> Chelsea E. Manning <me...@xy...> zhaomingxin <zha...@al...> Jojo R <rj...@li...> https://bugs.kde.org/show_bug.cgi?id=493507 Diff: --- .gitignore | 30 ++ Makefile.all.am | 6 + Makefile.am | 1 + Makefile.tool.am | 11 + Makefile.vex.am | 14 +- cachegrind/cg_arch.c | 7 + cachegrind/cg_branchpred.c | 2 +- configure.ac | 28 +- coregrind/Makefile.am | 15 +- coregrind/launcher-linux.c | 23 +- coregrind/m_aspacemgr/aspacemgr-common.c | 11 +- coregrind/m_cache.c | 3 +- coregrind/m_coredump/coredump-elf.c | 70 +++- coregrind/m_debuginfo/d3basics.c | 3 + coregrind/m_debuginfo/debuginfo.c | 36 +- coregrind/m_debuginfo/priv_storage.h | 13 + coregrind/m_debuginfo/readdwarf.c | 42 ++- coregrind/m_debuginfo/readelf.c | 4 +- coregrind/m_debuginfo/storage.c | 5 + coregrind/m_debuglog.c | 28 ++ coregrind/m_gdbserver/target.c | 2 + coregrind/m_gdbserver/valgrind_low.h | 1 + coregrind/m_initimg/initimg-linux.c | 35 +- coregrind/m_libcassert.c | 19 ++ coregrind/m_libcfile.c | 56 ++-- coregrind/m_libcproc.c | 27 +- coregrind/m_machine.c | 60 +++- coregrind/m_main.c | 32 ++ coregrind/m_options.c | 3 +- coregrind/m_redir.c | 15 + coregrind/m_scheduler/scheduler.c | 9 + coregrind/m_signals.c | 67 ++-- coregrind/m_stacktrace.c | 95 ++++++ coregrind/m_syscall.c | 39 +++ coregrind/m_syswrap/priv_syswrap-linux.h | 7 + coregrind/m_syswrap/priv_types_n_macros.h | 2 +- coregrind/m_syswrap/syswrap-generic.c | 4 +- coregrind/m_syswrap/syswrap-linux.c | 32 +- coregrind/m_syswrap/syswrap-main.c | 74 +++++ coregrind/m_trampoline.S | 76 +++++ coregrind/m_translate.c | 4 + coregrind/pub_core_basics.h | 10 +- coregrind/pub_core_debuginfo.h | 4 + coregrind/pub_core_machine.h | 9 + coregrind/pub_core_mallocfree.h | 1 + coregrind/pub_core_syscall.h | 1 + coregrind/pub_core_trampoline.h | 6 + coregrind/pub_core_transtab.h | 3 +- coregrind/pub_core_transtab_asm.h | 11 +- coregrind/vgdb-invoker-ptrace.c | 25 +- docs/Makefile.am | 1 + docs/xml/dist-docs.xml | 10 + drd/drd_bitmap.h | 2 +- drd/drd_load_store.c | 2 + include/Makefile.am | 3 + include/pub_tool_basics.h | 6 +- include/pub_tool_guest.h | 3 + include/pub_tool_machine.h | 6 + include/pub_tool_redir.h | 2 + include/pub_tool_vkiscnums_asm.h | 4 + include/valgrind.h.in | 535 ++++++++++++++++++++++++++++++ include/vki/vki-linux.h | 4 + memcheck/mc_machine.c | 105 ++++++ 63 files changed, 1666 insertions(+), 98 deletions(-) diff --git a/.gitignore b/.gitignore index c5a2b0592c..de2306df78 100644 --- a/.gitignore +++ b/.gitignore @@ -57,6 +57,7 @@ /auxprogs/getoff-mips32-linux /auxprogs/getoff-mips64-linux /auxprogs/getoff-nanomips-linux +/auxprogs/getoff-riscv64-linux /auxprogs/getoff-amd64-solaris /auxprogs/getoff-x86-solaris /auxprogs/getoff-*-freebsd @@ -1132,6 +1133,18 @@ /memcheck/tests/arm64-linux/Makefile.in /memcheck/tests/arm64-linux/scalar +# /memcheck/tests/riscv64-linux/ +/memcheck/tests/riscv64-linux/*.stderr.diff +/memcheck/tests/riscv64-linux/*.stderr.out +/memcheck/tests/riscv64-linux/*.stdout.diff +/memcheck/tests/riscv64-linux/*.stdout.out +/memcheck/tests/riscv64-linux/.deps +/memcheck/tests/riscv64-linux/Makefile +/memcheck/tests/riscv64-linux/Makefile.in +/memcheck/tests/riscv64-linux/context_float +/memcheck/tests/riscv64-linux/context_integer +/memcheck/tests/riscv64-linux/scalar + # /memcheck/tests/common/ /memcheck/tests/common/Makefile /memcheck/tests/common/Makefile.in @@ -2201,6 +2214,23 @@ /none/tests/s390x/vec2 /none/tests/s390x/vec2_float +# /none/tests/riscv64/ +/none/tests/riscv64/*.stderr.diff +/none/tests/riscv64/*.stderr.out +/none/tests/riscv64/*.stdout.diff +/none/tests/riscv64/*.stdout.out +/none/tests/riscv64/.deps +/none/tests/riscv64/Makefile +/none/tests/riscv64/Makefile.in +/none/tests/riscv64/allexec +/none/tests/riscv64/atomic +/none/tests/riscv64/compressed +/none/tests/riscv64/csr +/none/tests/riscv64/float32 +/none/tests/riscv64/float64 +/none/tests/riscv64/integer +/none/tests/riscv64/muldiv + # /none/tests/scripts/ /none/tests/scripts/*.dSYM /none/tests/scripts/*.so diff --git a/Makefile.all.am b/Makefile.all.am index e221198d6c..d4f6b3fb79 100755 --- a/Makefile.all.am +++ b/Makefile.all.am @@ -292,6 +292,11 @@ AM_CFLAGS_PSO_MIPS64_LINUX = @FLAG_M64@ $(AM_CFLAGS_BASE) \ $(AM_CFLAGS_PSO_BASE) AM_CCASFLAGS_MIPS64_LINUX = @FLAG_M64@ -g +AM_FLAG_M3264_RISCV64_LINUX = @FLAG_M64@ +AM_CFLAGS_RISCV64_LINUX = @FLAG_M64@ $(AM_CFLAGS_BASE) +AM_CFLAGS_PSO_RISCV64_LINUX = @FLAG_M64@ $(AM_CFLAGS_BASE) $(AM_CFLAGS_PSO_BASE) +AM_CCASFLAGS_RISCV64_LINUX = @FLAG_M64@ -g + AM_FLAG_M3264_X86_SOLARIS = @FLAG_M32@ AM_CFLAGS_X86_SOLARIS = @FLAG_M32@ @PREFERRED_STACK_BOUNDARY_2@ \ $(AM_CFLAGS_BASE) -fomit-frame-pointer @SOLARIS_UNDEF_LARGESOURCE@ @@ -353,6 +358,7 @@ PRELOAD_LDFLAGS_S390X_LINUX = $(PRELOAD_LDFLAGS_COMMON_LINUX) @FLAG_M64@ PRELOAD_LDFLAGS_MIPS32_LINUX = $(PRELOAD_LDFLAGS_COMMON_LINUX) @FLAG_M32@ PRELOAD_LDFLAGS_NANOMIPS_LINUX = $(PRELOAD_LDFLAGS_COMMON_LINUX) @FLAG_M32@ PRELOAD_LDFLAGS_MIPS64_LINUX = $(PRELOAD_LDFLAGS_COMMON_LINUX) @FLAG_M64@ +PRELOAD_LDFLAGS_RISCV64_LINUX = $(PRELOAD_LDFLAGS_COMMON_LINUX) @FLAG_M64@ PRELOAD_LDFLAGS_X86_SOLARIS = $(PRELOAD_LDFLAGS_COMMON_SOLARIS) @FLAG_M32@ PRELOAD_LDFLAGS_AMD64_SOLARIS = $(PRELOAD_LDFLAGS_COMMON_SOLARIS) @FLAG_M64@ diff --git a/Makefile.am b/Makefile.am index d745e26bf4..db8cfa382c 100644 --- a/Makefile.am +++ b/Makefile.am @@ -118,6 +118,7 @@ EXTRA_DIST = \ README.android_emulator \ README.mips \ README.aarch64 \ + README.riscv64 \ README.solaris \ README.freebsd \ NEWS.old \ diff --git a/Makefile.tool.am b/Makefile.tool.am index c779596e71..7f18d25476 100644 --- a/Makefile.tool.am +++ b/Makefile.tool.am @@ -110,6 +110,9 @@ TOOL_LDFLAGS_MIPS64_LINUX = \ -static -nodefaultlibs -nostartfiles -u __start @FLAG_NO_BUILD_ID@ \ @FLAG_M64@ +TOOL_LDFLAGS_RISCV64_LINUX = \ + $(TOOL_LDFLAGS_COMMON_LINUX) @FLAG_M64@ + TOOL_LDFLAGS_X86_SOLARIS = \ $(TOOL_LDFLAGS_COMMON_SOLARIS) @FLAG_M32@ @@ -181,6 +184,9 @@ LIBREPLACEMALLOC_MIPS32_LINUX = \ LIBREPLACEMALLOC_MIPS64_LINUX = \ $(top_builddir)/coregrind/libreplacemalloc_toolpreload-mips64-linux.a +LIBREPLACEMALLOC_RISCV64_LINUX = \ + $(top_builddir)/coregrind/libreplacemalloc_toolpreload-riscv64-linux.a + LIBREPLACEMALLOC_X86_SOLARIS = \ $(top_builddir)/coregrind/libreplacemalloc_toolpreload-x86-solaris.a @@ -258,6 +264,11 @@ LIBREPLACEMALLOC_LDFLAGS_MIPS64_LINUX = \ $(LIBREPLACEMALLOC_MIPS64_LINUX) \ -Wl,--no-whole-archive +LIBREPLACEMALLOC_LDFLAGS_RISCV64_LINUX = \ + -Wl,--whole-archive \ + $(LIBREPLACEMALLOC_RISCV64_LINUX) \ + -Wl,--no-whole-archive + LIBREPLACEMALLOC_LDFLAGS_X86_SOLARIS = \ -Wl,--whole-archive \ $(LIBREPLACEMALLOC_X86_SOLARIS) \ diff --git a/Makefile.vex.am b/Makefile.vex.am index c1244a69d2..f75e9b4c69 100644 --- a/Makefile.vex.am +++ b/Makefile.vex.am @@ -26,6 +26,7 @@ pkginclude_HEADERS = \ pub/libvex_guest_s390x.h \ pub/libvex_guest_mips32.h \ pub/libvex_guest_mips64.h \ + pub/libvex_guest_riscv64.h \ pub/libvex_s390x_common.h \ pub/libvex_ir.h \ pub/libvex_trc_values.h \ @@ -49,6 +50,7 @@ noinst_HEADERS = \ priv/guest_mips_defs.h \ priv/mips_defs.h \ priv/guest_nanomips_defs.h \ + priv/guest_riscv64_defs.h \ priv/host_generic_regs.h \ priv/host_generic_simd64.h \ priv/host_generic_simd128.h \ @@ -65,7 +67,8 @@ noinst_HEADERS = \ priv/s390_defs.h \ priv/host_mips_defs.h \ priv/host_nanomips_defs.h \ - priv/common_nanomips_defs.h + priv/common_nanomips_defs.h \ + priv/host_riscv64_defs.h BUILT_SOURCES = pub/libvex_guest_offsets.h CLEANFILES = pub/libvex_guest_offsets.h @@ -94,7 +97,8 @@ pub/libvex_guest_offsets.h: auxprogs/genoffsets.c \ pub/libvex_guest_arm64.h \ pub/libvex_guest_s390x.h \ pub/libvex_guest_mips32.h \ - pub/libvex_guest_mips64.h + pub/libvex_guest_mips64.h \ + pub/libvex_guest_riscv64.h rm -f auxprogs/genoffsets.s $(mkdir_p) auxprogs pub $(CC) $(CFLAGS_FOR_GENOFFSETS) \ @@ -152,6 +156,8 @@ LIBVEX_SOURCES_COMMON = \ priv/guest_mips_toIR.c \ priv/guest_nanomips_helpers.c \ priv/guest_nanomips_toIR.c \ + priv/guest_riscv64_helpers.c \ + priv/guest_riscv64_toIR.c \ priv/host_generic_regs.c \ priv/host_generic_simd64.c \ priv/host_generic_simd128.c \ @@ -176,7 +182,9 @@ LIBVEX_SOURCES_COMMON = \ priv/host_mips_defs.c \ priv/host_nanomips_defs.c \ priv/host_mips_isel.c \ - priv/host_nanomips_isel.c + priv/host_nanomips_isel.c \ + priv/host_riscv64_defs.c \ + priv/host_riscv64_isel.c LIBVEXMULTIARCH_SOURCES = priv/multiarch_main_main.c diff --git a/cachegrind/cg_arch.c b/cachegrind/cg_arch.c index 68314c9dbe..be2973405a 100644 --- a/cachegrind/cg_arch.c +++ b/cachegrind/cg_arch.c @@ -484,6 +484,13 @@ configure_caches(cache_t *I1c, cache_t *D1c, cache_t *LLc, *D1c = (cache_t) { 65536, 2, 64 }; *LLc = (cache_t) { 262144, 8, 64 }; +#elif defined(VGA_riscv64) + + // Default cache configuration is SiFive FU740-C000 (HiFive Unmatched) + *I1c = (cache_t) { 32768, 4, 64 }; + *D1c = (cache_t) { 32768, 8, 64 }; + *LLc = (cache_t) { 2097152, 16, 64 }; + #else #error "Unknown arch" diff --git a/cachegrind/cg_branchpred.c b/cachegrind/cg_branchpred.c index 927b7bf21c..f7a261c6fe 100644 --- a/cachegrind/cg_branchpred.c +++ b/cachegrind/cg_branchpred.c @@ -48,7 +48,7 @@ # define N_IADDR_LO_ZERO_BITS 2 #elif defined(VGA_x86) || defined(VGA_amd64) # define N_IADDR_LO_ZERO_BITS 0 -#elif defined(VGA_s390x) || defined(VGA_arm) +#elif defined(VGA_s390x) || defined(VGA_arm) || defined(VGA_riscv64) # define N_IADDR_LO_ZERO_BITS 1 #else # error "Unsupported architecture" diff --git a/configure.ac b/configure.ac index 9dec9f3b00..e6ae0501bd 100755 --- a/configure.ac +++ b/configure.ac @@ -302,6 +302,11 @@ case "${host_cpu}" in ARCH_MAX="nanomips" ;; + riscv64) + AC_MSG_RESULT([ok (${host_cpu})]) + ARCH_MAX="riscv64" + ;; + *) AC_MSG_RESULT([no (${host_cpu})]) AC_MSG_ERROR([Unsupported host architecture. Sorry]) @@ -874,6 +879,17 @@ case "$ARCH_MAX-$VGCONF_OS" in valt_load_address_sec_inner="0xUNSET" AC_MSG_RESULT([ok (${ARCH_MAX}-${VGCONF_OS})]) ;; + riscv64-linux) + VGCONF_ARCH_PRI="riscv64" + VGCONF_ARCH_SEC="" + VGCONF_PLATFORM_PRI_CAPS="RISCV64_LINUX" + VGCONF_PLATFORM_SEC_CAPS="" + valt_load_address_pri_norml="0x58000000" + valt_load_address_pri_inner="0x38000000" + valt_load_address_sec_norml="0xUNSET" + valt_load_address_sec_inner="0xUNSET" + AC_MSG_RESULT([ok (${ARCH_MAX}-${VGCONF_OS})]) + ;; x86-solaris) VGCONF_ARCH_PRI="x86" VGCONF_ARCH_SEC="" @@ -967,6 +983,8 @@ AM_CONDITIONAL(VGCONF_ARCHS_INCLUDE_MIPS64, test x$VGCONF_PLATFORM_PRI_CAPS = xMIPS64_LINUX ) AM_CONDITIONAL(VGCONF_ARCHS_INCLUDE_NANOMIPS, test x$VGCONF_PLATFORM_PRI_CAPS = xNANOMIPS_LINUX ) +AM_CONDITIONAL(VGCONF_ARCHS_INCLUDE_RISCV64, + test x$VGCONF_PLATFORM_PRI_CAPS = xRISCV64_LINUX ) # Set up VGCONF_PLATFORMS_INCLUDE_<platform>. Either one or two of these # become defined. @@ -997,6 +1015,8 @@ AM_CONDITIONAL(VGCONF_PLATFORMS_INCLUDE_MIPS64_LINUX, test x$VGCONF_PLATFORM_PRI_CAPS = xMIPS64_LINUX) AM_CONDITIONAL(VGCONF_PLATFORMS_INCLUDE_NANOMIPS_LINUX, test x$VGCONF_PLATFORM_PRI_CAPS = xNANOMIPS_LINUX) +AM_CONDITIONAL(VGCONF_PLATFORMS_INCLUDE_RISCV64_LINUX, + test x$VGCONF_PLATFORM_PRI_CAPS = xRISCV64_LINUX) AM_CONDITIONAL(VGCONF_PLATFORMS_INCLUDE_X86_FREEBSD, test x$VGCONF_PLATFORM_PRI_CAPS = xX86_FREEBSD \ -o x$VGCONF_PLATFORM_SEC_CAPS = xX86_FREEBSD) @@ -1030,7 +1050,8 @@ AM_CONDITIONAL(VGCONF_OS_IS_LINUX, -o x$VGCONF_PLATFORM_PRI_CAPS = xS390X_LINUX \ -o x$VGCONF_PLATFORM_PRI_CAPS = xMIPS32_LINUX \ -o x$VGCONF_PLATFORM_PRI_CAPS = xMIPS64_LINUX \ - -o x$VGCONF_PLATFORM_PRI_CAPS = xNANOMIPS_LINUX) + -o x$VGCONF_PLATFORM_PRI_CAPS = xNANOMIPS_LINUX \ + -o x$VGCONF_PLATFORM_PRI_CAPS = xRISCV64_LINUX) AM_CONDITIONAL(VGCONF_OS_IS_FREEBSD, test x$VGCONF_PLATFORM_PRI_CAPS = xX86_FREEBSD \ -o x$VGCONF_PLATFORM_PRI_CAPS = xAMD64_FREEBSD \ @@ -5049,7 +5070,8 @@ elif test x$VGCONF_PLATFORM_PRI_CAPS = xAMD64_LINUX \ -o x$VGCONF_PLATFORM_PRI_CAPS = xARM64_LINUX \ -o x$VGCONF_PLATFORM_PRI_CAPS = xARM64_FREEBSD \ -o x$VGCONF_PLATFORM_PRI_CAPS = xMIPS64_LINUX \ - -o x$VGCONF_PLATFORM_PRI_CAPS = xS390X_LINUX ; then + -o x$VGCONF_PLATFORM_PRI_CAPS = xS390X_LINUX \ + -o x$VGCONF_PLATFORM_PRI_CAPS = xRISCV64_LINUX ; then mflag_primary=$FLAG_M64 elif test x$VGCONF_PLATFORM_PRI_CAPS = xX86_DARWIN ; then mflag_primary="$FLAG_M32 -arch i386" @@ -5657,6 +5679,7 @@ AC_CONFIG_FILES([ memcheck/tests/amd64-linux/Makefile memcheck/tests/arm64-linux/Makefile memcheck/tests/x86-linux/Makefile + memcheck/tests/riscv64-linux/Makefile memcheck/tests/amd64-solaris/Makefile memcheck/tests/x86-solaris/Makefile memcheck/tests/amd64-freebsd/Makefile @@ -5702,6 +5725,7 @@ AC_CONFIG_FILES([ none/tests/mips32/Makefile none/tests/mips64/Makefile none/tests/nanomips/Makefile + none/tests/riscv64/Makefile none/tests/linux/Makefile none/tests/darwin/Makefile none/tests/solaris/Makefile diff --git a/coregrind/Makefile.am b/coregrind/Makefile.am index 5491fc6726..700751dea4 100644 --- a/coregrind/Makefile.am +++ b/coregrind/Makefile.am @@ -392,6 +392,7 @@ COREGRIND_SOURCES_COMMON = \ m_dispatch/dispatch-mips32-linux.S \ m_dispatch/dispatch-mips64-linux.S \ m_dispatch/dispatch-nanomips-linux.S \ + m_dispatch/dispatch-riscv64-linux.S \ m_dispatch/dispatch-x86-freebsd.S \ m_dispatch/dispatch-amd64-freebsd.S \ m_dispatch/dispatch-arm64-freebsd.S \ @@ -419,6 +420,7 @@ COREGRIND_SOURCES_COMMON = \ m_gdbserver/valgrind-low-mips32.c \ m_gdbserver/valgrind-low-mips64.c \ m_gdbserver/valgrind-low-nanomips.c \ + m_gdbserver/valgrind-low-riscv64.c \ m_gdbserver/version.c \ m_initimg/initimg-linux.c \ m_initimg/initimg-freebsd.c \ @@ -447,6 +449,7 @@ COREGRIND_SOURCES_COMMON = \ m_sigframe/sigframe-mips32-linux.c \ m_sigframe/sigframe-mips64-linux.c \ m_sigframe/sigframe-nanomips-linux.c \ + m_sigframe/sigframe-riscv64-linux.c \ m_sigframe/sigframe-x86-darwin.c \ m_sigframe/sigframe-amd64-darwin.c \ m_sigframe/sigframe-solaris.c \ @@ -461,6 +464,7 @@ COREGRIND_SOURCES_COMMON = \ m_syswrap/syscall-mips32-linux.S \ m_syswrap/syscall-mips64-linux.S \ m_syswrap/syscall-nanomips-linux.S \ + m_syswrap/syscall-riscv64-linux.S \ m_syswrap/syscall-x86-freebsd.S \ m_syswrap/syscall-amd64-freebsd.S \ m_syswrap/syscall-arm64-freebsd.S \ @@ -488,6 +492,7 @@ COREGRIND_SOURCES_COMMON = \ m_syswrap/syswrap-mips32-linux.c \ m_syswrap/syswrap-mips64-linux.c \ m_syswrap/syswrap-nanomips-linux.c \ + m_syswrap/syswrap-riscv64-linux.c \ m_syswrap/syswrap-x86-darwin.c \ m_syswrap/syswrap-amd64-darwin.c \ m_syswrap/syswrap-xen.c \ @@ -780,7 +785,15 @@ GDBSERVER_XML_FILES = \ m_gdbserver/mips64-linux-valgrind.xml \ m_gdbserver/mips64-fpu-valgrind-s1.xml \ m_gdbserver/mips64-fpu-valgrind-s2.xml \ - m_gdbserver/mips64-fpu.xml + m_gdbserver/mips64-fpu.xml \ + m_gdbserver/riscv64-cpu-valgrind-s1.xml \ + m_gdbserver/riscv64-cpu-valgrind-s2.xml \ + m_gdbserver/riscv64-cpu.xml \ + m_gdbserver/riscv64-linux.xml \ + m_gdbserver/riscv64-linux-valgrind.xml \ + m_gdbserver/riscv64-fpu-valgrind-s1.xml \ + m_gdbserver/riscv64-fpu-valgrind-s2.xml \ + m_gdbserver/riscv64-fpu.xml # so as to make sure these get copied into the install tree vglibdir = $(pkglibexecdir) diff --git a/coregrind/launcher-linux.c b/coregrind/launcher-linux.c index 715fdab818..20e624003a 100644 --- a/coregrind/launcher-linux.c +++ b/coregrind/launcher-linux.c @@ -51,16 +51,18 @@ #include <string.h> #include <unistd.h> +/* Provide own definitions for elf.h constants that might not be yet available + on some older systems. */ #ifndef EM_X86_64 -#define EM_X86_64 62 // elf.h doesn't define this on some older systems +#define EM_X86_64 62 #endif #ifndef EM_AARCH64 -#define EM_AARCH64 183 // ditto +#define EM_AARCH64 183 #endif #ifndef EM_PPC64 -#define EM_PPC64 21 // ditto +#define EM_PPC64 21 #endif #ifndef EM_NANOMIPS @@ -75,6 +77,10 @@ #define E_MIPS_ABI2 0x00000020 #endif +#ifndef EM_RISCV +#define EM_RISCV 243 +#endif + /* Report fatal errors */ __attribute__((noreturn)) static void barf ( const char *format, ... ) @@ -316,6 +322,10 @@ static const char *select_platform(const char *clientname) (header.ehdr64.e_ident[EI_OSABI] == ELFOSABI_SYSV || header.ehdr64.e_ident[EI_OSABI] == ELFOSABI_LINUX)) { platform = "ppc64le-linux"; + } else if (header.ehdr64.e_machine == EM_RISCV && + (header.ehdr64.e_ident[EI_OSABI] == ELFOSABI_SYSV || + header.ehdr64.e_ident[EI_OSABI] == ELFOSABI_LINUX)) { + platform = "riscv64-linux"; } } else if (header.c[EI_DATA] == ELFDATA2MSB) { # if !defined(VGPV_arm_linux_android) \ @@ -404,8 +414,8 @@ int main(int argc, char** argv, char** envp) the executable (eg because it's a shell script). VG_PLATFORM is the default_platform. Its value is defined in coregrind/Makefile.am and typically it is the primary build target. Unless the primary build - target is not built is not built in which case VG_PLATFORM is the - secondary build target. */ + target is not built in which case VG_PLATFORM is the secondary build + target. */ # if defined(VGO_linux) if ((0==strcmp(VG_PLATFORM,"x86-linux")) || (0==strcmp(VG_PLATFORM,"amd64-linux")) || @@ -417,7 +427,8 @@ int main(int argc, char** argv, char** envp) (0==strcmp(VG_PLATFORM,"s390x-linux")) || (0==strcmp(VG_PLATFORM,"mips32-linux")) || (0==strcmp(VG_PLATFORM,"mips64-linux")) || - (0==strcmp(VG_PLATFORM,"nanomips-linux"))) + (0==strcmp(VG_PLATFORM,"nanomips-linux")) || + (0==strcmp(VG_PLATFORM,"riscv64-linux"))) default_platform = VG_PLATFORM; # elif defined(VGO_solaris) if ((0==strcmp(VG_PLATFORM,"x86-solaris")) || diff --git a/coregrind/m_aspacemgr/aspacemgr-common.c b/coregrind/m_aspacemgr/aspacemgr-common.c index 68bc5b40c9..14864d96c3 100644 --- a/coregrind/m_aspacemgr/aspacemgr-common.c +++ b/coregrind/m_aspacemgr/aspacemgr-common.c @@ -157,7 +157,8 @@ SysRes VG_(am_do_mmap_NO_NOTIFY)( Addr start, SizeT length, UInt prot, # elif defined(VGP_amd64_linux) \ || defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux) \ || defined(VGP_s390x_linux) || defined(VGP_mips32_linux) \ - || defined(VGP_mips64_linux) || defined(VGP_arm64_linux) + || defined(VGP_mips64_linux) || defined(VGP_arm64_linux) \ + || defined(VGP_riscv64_linux) res = VG_(do_syscall6)(__NR_mmap, (UWord)start, length, prot, flags, fd, offset); # elif defined(VGP_x86_darwin) @@ -262,8 +263,9 @@ SysRes ML_(am_do_relocate_nooverlap_mapping_NO_NOTIFY)( SysRes ML_(am_open) ( const HChar* pathname, Int flags, Int mode ) { -# if defined(VGP_arm64_linux) || defined(VGP_nanomips_linux) - /* ARM64 wants to use __NR_openat rather than __NR_open. */ +# if defined(VGP_arm64_linux) || defined(VGP_nanomips_linux) \ + || defined(VGP_riscv64_linux) + /* More recent Linux platforms have only __NR_openat and no __NR_open. */ SysRes res = VG_(do_syscall4)(__NR_openat, VKI_AT_FDCWD, (UWord)pathname, flags, mode); # elif defined(VGO_linux) || defined(VGO_darwin) || defined(VGO_freebsd) @@ -291,7 +293,8 @@ void ML_(am_close) ( Int fd ) Int ML_(am_readlink)(const HChar* path, HChar* buf, UInt bufsiz) { SysRes res; -# if defined(VGP_arm64_linux) || defined(VGP_nanomips_linux) +# if defined(VGP_arm64_linux) || defined(VGP_nanomips_linux) \ + || defined(VGP_riscv64_linux) res = VG_(do_syscall4)(__NR_readlinkat, VKI_AT_FDCWD, (UWord)path, (UWord)buf, bufsiz); # elif defined(VGO_linux) || defined(VGO_darwin) || defined(VGO_freebsd) diff --git a/coregrind/m_cache.c b/coregrind/m_cache.c index d12941cd68..4abd26f0b2 100644 --- a/coregrind/m_cache.c +++ b/coregrind/m_cache.c @@ -539,7 +539,8 @@ get_cache_info(VexArchInfo *vai) #elif defined(VGA_arm) || defined(VGA_ppc32) || \ defined(VGA_ppc64be) || defined(VGA_ppc64le) || \ defined(VGA_mips32) || defined(VGA_mips64) || \ - defined(VGA_arm64) || defined(VGA_nanomips) + defined(VGA_arm64) || defined(VGA_nanomips) || \ + defined(VGA_riscv64) static Bool get_cache_info(VexArchInfo *vai) { diff --git a/coregrind/m_coredump/coredump-elf.c b/coregrind/m_coredump/coredump-elf.c index a4632d9e28..b57d26275b 100644 --- a/coregrind/m_coredump/coredump-elf.c +++ b/coregrind/m_coredump/coredump-elf.c @@ -277,7 +277,7 @@ static void fill_prstatus(const ThreadState *tst, prs->pr_sid = VG_(getpgrp)(); #endif -#if defined(VGP_s390x_linux) +#if defined(VGP_s390x_linux) || defined(VGP_riscv64_linux) /* prs->pr_reg has struct type. Need to take address. */ regs = (struct vki_user_regs_struct *)&(prs->pr_reg); #elif defined(VGP_mips32_linux) || defined(VGP_mips64_linux) \ @@ -489,6 +489,39 @@ static void fill_prstatus(const ThreadState *tst, regs[VKI_MIPS32_EF_CP0_STATUS] = arch->vex.guest_CP0_status; regs[VKI_MIPS32_EF_CP0_EPC] = arch->vex.guest_PC; # undef DO +#elif defined(VGP_riscv64_linux) + regs->pc = arch->vex.guest_pc; + regs->ra = arch->vex.guest_x1; + regs->sp = arch->vex.guest_x2; + regs->gp = arch->vex.guest_x3; + regs->tp = arch->vex.guest_x4; + regs->t0 = arch->vex.guest_x5; + regs->t1 = arch->vex.guest_x6; + regs->t2 = arch->vex.guest_x7; + regs->s0 = arch->vex.guest_x8; + regs->s1 = arch->vex.guest_x9; + regs->a0 = arch->vex.guest_x10; + regs->a1 = arch->vex.guest_x11; + regs->a2 = arch->vex.guest_x12; + regs->a3 = arch->vex.guest_x13; + regs->a4 = arch->vex.guest_x14; + regs->a5 = arch->vex.guest_x15; + regs->a6 = arch->vex.guest_x16; + regs->a7 = arch->vex.guest_x17; + regs->s2 = arch->vex.guest_x18; + regs->s3 = arch->vex.guest_x19; + regs->s4 = arch->vex.guest_x20; + regs->s5 = arch->vex.guest_x21; + regs->s6 = arch->vex.guest_x22; + regs->s7 = arch->vex.guest_x23; + regs->s8 = arch->vex.guest_x24; + regs->s9 = arch->vex.guest_x25; + regs->s10 = arch->vex.guest_x26; + regs->s11 = arch->vex.guest_x27; + regs->t3 = arch->vex.guest_x28; + regs->t4 = arch->vex.guest_x29; + regs->t5 = arch->vex.guest_x30; + regs->t6 = arch->vex.guest_x31; #elif defined(VGP_amd64_freebsd) regs->rflags = LibVEX_GuestAMD64_get_rflags( &arch->vex ); regs->rsp = arch->vex.guest_RSP; @@ -691,6 +724,41 @@ static void fill_fpu(const ThreadState *tst, vki_elf_fpregset_t *fpu) # undef DO #elif defined(VGP_nanomips_linux) +#elif defined(VGP_riscv64_linux) + fpu->d.f[0] = arch->vex.guest_f0; + fpu->d.f[1] = arch->vex.guest_f1; + fpu->d.f[2] = arch->vex.guest_f2; + fpu->d.f[3] = arch->vex.guest_f3; + fpu->d.f[4] = arch->vex.guest_f4; + fpu->d.f[5] = arch->vex.guest_f5; + fpu->d.f[6] = arch->vex.guest_f6; + fpu->d.f[7] = arch->vex.guest_f7; + fpu->d.f[8] = arch->vex.guest_f8; + fpu->d.f[9] = arch->vex.guest_f9; + fpu->d.f[10] = arch->vex.guest_f10; + fpu->d.f[11] = arch->vex.guest_f11; + fpu->d.f[12] = arch->vex.guest_f12; + fpu->d.f[13] = arch->vex.guest_f13; + fpu->d.f[14] = arch->vex.guest_f14; + fpu->d.f[15] = arch->vex.guest_f15; + fpu->d.f[16] = arch->vex.guest_f16; + fpu->d.f[17] = arch->vex.guest_f17; + fpu->d.f[18] = arch->vex.guest_f18; + fpu->d.f[19] = arch->vex.guest_f19; + fpu->d.f[20] = arch->vex.guest_f20; + fpu->d.f[21] = arch->vex.guest_f21; + fpu->d.f[22] = arch->vex.guest_f22; + fpu->d.f[23] = arch->vex.guest_f23; + fpu->d.f[24] = arch->vex.guest_f24; + fpu->d.f[25] = arch->vex.guest_f25; + fpu->d.f[26] = arch->vex.guest_f26; + fpu->d.f[27] = arch->vex.guest_f27; + fpu->d.f[28] = arch->vex.guest_f28; + fpu->d.f[29] = arch->vex.guest_f29; + fpu->d.f[30] = arch->vex.guest_f30; + fpu->d.f[31] = arch->vex.guest_f31; + fpu->d.fcsr = arch->vex.guest_fcsr; + #elif defined(VGP_x86_freebsd) #elif defined(VGP_amd64_freebsd) diff --git a/coregrind/m_debuginfo/d3basics.c b/coregrind/m_debuginfo/d3basics.c index 564b832e63..80dec21a65 100644 --- a/coregrind/m_debuginfo/d3basics.c +++ b/coregrind/m_debuginfo/d3basics.c @@ -555,6 +555,9 @@ static Bool get_Dwarf_Reg( /*OUT*/Addr* a, Word regno, const RegSummary* regs ) # elif defined(VGP_arm64_linux) || defined(VGP_arm64_freebsd) if (regno == 31) { *a = regs->sp; return True; } if (regno == 29) { *a = regs->fp; return True; } +# elif defined(VGP_riscv64_linux) + if (regno == 2) { *a = regs->sp; return True; } + if (regno == 8) { *a = regs->fp; return True; } # else # error "Unknown platform" # endif diff --git a/coregrind/m_debuginfo/debuginfo.c b/coregrind/m_debuginfo/debuginfo.c index 11ab473542..97d0f35c05 100644 --- a/coregrind/m_debuginfo/debuginfo.c +++ b/coregrind/m_debuginfo/debuginfo.c @@ -1277,7 +1277,7 @@ ULong VG_(di_notify_mmap)( Addr a, Bool allow_SkFileV, Int use_fd ) is_rx_map = seg->hasR && seg->hasX; is_rw_map = seg->hasR && seg->hasW; # elif defined(VGA_amd64) || defined(VGA_ppc64be) || defined(VGA_ppc64le) \ - || defined(VGA_arm) || defined(VGA_arm64) + || defined(VGA_arm) || defined(VGA_arm64) || defined(VGA_riscv64) is_rx_map = seg->hasR && seg->hasX && !seg->hasW; is_rw_map = seg->hasR && seg->hasW && !seg->hasX; # elif defined(VGP_s390x_linux) @@ -3092,12 +3092,12 @@ UWord evalCfiExpr ( const XArray* exprs, Int ix, case Creg_IA_SP: return eec->uregs->sp; case Creg_IA_BP: return eec->uregs->fp; case Creg_MIPS_RA: return eec->uregs->ra; -# elif defined(VGA_ppc32) || defined(VGA_ppc64be) \ - || defined(VGA_ppc64le) # elif defined(VGP_arm64_linux) || defined(VGP_arm64_freebsd) case Creg_ARM64_SP: return eec->uregs->sp; case Creg_ARM64_X30: return eec->uregs->x30; case Creg_ARM64_X29: return eec->uregs->x29; +# elif defined(VGA_ppc32) || defined(VGA_ppc64be) \ + || defined(VGA_ppc64le) || defined(VGP_riscv64_linux) # else # error "Unsupported arch" # endif @@ -3378,7 +3378,13 @@ static Addr compute_cfa ( const D3UnwindRegs* uregs, case CFIC_ARM64_X29REL: cfa = cfsi_m->cfa_off + uregs->x29; break; - +# elif defined(VGP_riscv64_linux) + case CFIC_IA_SPREL: + cfa = cfsi_m->cfa_off + uregs->sp; + break; + case CFIC_IA_BPREL: + cfa = cfsi_m->cfa_off + uregs->fp; + break; # else # error "Unsupported arch" # endif @@ -3450,6 +3456,15 @@ Addr ML_(get_CFA) ( Addr ip, Addr sp, Addr fp, return compute_cfa(&uregs, min_accessible, max_accessible, ce->di, ce->cfsi_m); } +#elif defined(VGA_riscv64) + { D3UnwindRegs uregs; + uregs.pc = ip; + uregs.sp = sp; + uregs.fp = fp; + uregs.ra = 0; + return compute_cfa(&uregs, + min_accessible, max_accessible, ce->di, ce->cfsi_m); + } # else return 0; /* indicates failure */ @@ -3501,6 +3516,8 @@ void VG_(ppUnwindInfo) (Addr from, Addr to) For arm64, the unwound registers are: X29(FP) X30(LR) SP PC. For s390, the unwound registers are: R11(FP) R14(LR) R15(SP) F0..F7 PC. + + For riscv64, the unwound registers are: X2(SP) X8(FP) PC */ Bool VG_(use_CF_info) ( /*MOD*/D3UnwindRegs* uregsHere, Addr min_accessible, @@ -3526,6 +3543,8 @@ Bool VG_(use_CF_info) ( /*MOD*/D3UnwindRegs* uregsHere, ipHere = uregsHere->pc; # elif defined(VGP_arm64_freebsd) ipHere = uregsHere->pc; +# elif defined(VGP_riscv64_linux) + ipHere = uregsHere->pc; # else # error "Unknown arch" # endif @@ -3671,6 +3690,15 @@ Bool VG_(use_CF_info) ( /*MOD*/D3UnwindRegs* uregsHere, COMPUTE(uregsPrev.sp, uregsHere->sp, cfsi_m->sp_how, cfsi_m->sp_off); COMPUTE(uregsPrev.x30, uregsHere->x30, cfsi_m->x30_how, cfsi_m->x30_off); COMPUTE(uregsPrev.x29, uregsHere->x29, cfsi_m->x29_how, cfsi_m->x29_off); +# elif defined(VGP_riscv64_linux) + /* Compute register values in the caller's frame. Notice that the previous + pc is equal to the previous ra and is calculated as such. The previous ra + is however set to 0 here as this helps to promptly fail cases where an + inner frame uses the CFIR_SAME rule for ra which is bogus. */ + COMPUTE(uregsPrev.pc, uregsHere->ra, cfsi_m->ra_how, cfsi_m->ra_off); + COMPUTE(uregsPrev.sp, uregsHere->sp, cfsi_m->sp_how, cfsi_m->sp_off); + COMPUTE(uregsPrev.fp, uregsHere->fp, cfsi_m->fp_how, cfsi_m->fp_off); + uregsPrev.ra = 0; # else # error "Unknown arch" # endif diff --git a/coregrind/m_debuginfo/priv_storage.h b/coregrind/m_debuginfo/priv_storage.h index 441b379d2e..d8cba81c48 100644 --- a/coregrind/m_debuginfo/priv_storage.h +++ b/coregrind/m_debuginfo/priv_storage.h @@ -355,6 +355,19 @@ typedef } DiCfSI_m; #elif defined(VGA_mips32) || defined(VGA_mips64) || defined(VGA_nanomips) +typedef + struct { + UChar cfa_how; /* a CFIC_ value */ + UChar ra_how; /* a CFIR_ value */ + UChar sp_how; /* a CFIR_ value */ + UChar fp_how; /* a CFIR_ value */ + Int cfa_off; + Int ra_off; + Int sp_off; + Int fp_off; + } + DiCfSI_m; +#elif defined(VGA_riscv64) typedef struct { UChar cfa_how; /* a CFIC_ value */ diff --git a/coregrind/m_debuginfo/readdwarf.c b/coregrind/m_debuginfo/readdwarf.c index 0686e8d078..b08720182e 100644 --- a/coregrind/m_debuginfo/readdwarf.c +++ b/coregrind/m_debuginfo/readdwarf.c @@ -2066,6 +2066,10 @@ void ML_(read_debuginfo_dwarf1) ( # define FP_REG 30 # define SP_REG 29 # define RA_REG_DEFAULT 31 +#elif defined(VGP_riscv64_linux) +# define FP_REG 8 +# define SP_REG 2 +# define RA_REG_DEFAULT 1 #else # error "Unknown platform" #endif @@ -2084,6 +2088,8 @@ void ML_(read_debuginfo_dwarf1) ( # define N_CFI_REGS 128 #elif defined(VGP_s390x_linux) # define N_CFI_REGS 66 +#elif defined(VGP_riscv64_linux) +# define N_CFI_REGS 128 #else # define N_CFI_REGS 20 #endif @@ -2310,6 +2316,10 @@ static void initUnwindContext ( /*OUT*/UnwindContext* ctx ) start out as RR_Same. */ ctx->state[j].reg[29/*FP*/].tag = RR_Same; ctx->state[j].reg[30/*LR*/].tag = RR_Same; +# elif defined(VGA_riscv64) + /* Registers fp and ra start out implicitly as RR_Same. */ + ctx->state[j].reg[FP_REG].tag = RR_Same; + ctx->state[j].reg[RA_REG_DEFAULT].tag = RR_Same; # endif } } @@ -2392,7 +2402,8 @@ static Bool summarise_context(/*OUT*/Addr* base, if (ctxs->cfa_is_regoff && ctxs->cfa_reg == SP_REG) { si_m->cfa_off = ctxs->cfa_off; # if defined(VGA_x86) || defined(VGA_amd64) || defined(VGA_s390x) \ - || defined(VGA_mips32) || defined(VGA_nanomips) || defined(VGA_mips64) + || defined(VGA_mips32) || defined(VGA_nanomips) \ + || defined(VGA_mips64) || defined(VGA_riscv64) si_m->cfa_how = CFIC_IA_SPREL; # elif defined(VGA_arm) si_m->cfa_how = CFIC_ARM_R13REL; @@ -2406,7 +2417,8 @@ static Bool summarise_context(/*OUT*/Addr* base, if (ctxs->cfa_is_regoff && ctxs->cfa_reg == FP_REG) { si_m->cfa_off = ctxs->cfa_off; # if defined(VGA_x86) || defined(VGA_amd64) || defined(VGA_s390x) \ - || defined(VGA_mips32) || defined(VGA_nanomips) || defined(VGA_mips64) + || defined(VGA_mips32) || defined(VGA_nanomips) \ + || defined(VGA_mips64) || defined(VGA_riscv64) si_m->cfa_how = CFIC_IA_BPREL; # elif defined(VGA_arm) si_m->cfa_how = CFIC_ARM_R12REL; @@ -2786,6 +2798,30 @@ static Bool summarise_context(/*OUT*/Addr* base, # elif defined(VGA_ppc32) || defined(VGA_ppc64be) || defined(VGA_ppc64le) /* These don't use CFI based unwinding (is that really true?) */ +# elif defined(VGA_riscv64) + + /* --- entire tail of this fn specialised for riscv64 --- */ + + SUMMARISE_HOW(si_m->ra_how, si_m->ra_off, ctxs->reg[ctx->ra_reg]); + SUMMARISE_HOW(si_m->fp_how, si_m->fp_off, ctxs->reg[FP_REG]); + + /* on riscv64, it seems the old sp value before the call is always + the same as the CFA. Therefore ... */ + si_m->sp_how = CFIR_CFAREL; + si_m->sp_off = 0; + + /* bogus looking range? Note, we require that the difference is + representable in 32 bits. */ + if (loc_start >= ctx->loc) + { why = 4; goto failed; } + if (ctx->loc - loc_start > 10000000 /* let's say */) + { why = 5; goto failed; } + + *base = loc_start + ctx->initloc; + *len = (UInt)(ctx->loc - loc_start); + + return True; + # else # error "Unknown arch" # endif @@ -2884,7 +2920,7 @@ static Int copy_convert_CfiExpr_tree ( XArray* dstxa, if (dwreg == srcuc->ra_reg) return ML_(CfiExpr_CfiReg)( dstxa, Creg_ARM64_X30 ); # elif defined(VGA_ppc32) || defined(VGA_ppc64be) \ - || defined(VGA_ppc64le) + || defined(VGA_ppc64le) || defined(VGA_riscv64) # else # error "Unknown arch" # endif diff --git a/coregrind/m_debuginfo/readelf.c b/coregrind/m_debuginfo/readelf.c index 77ed4798b0..1dadbc72c5 100644 --- a/coregrind/m_debuginfo/readelf.c +++ b/coregrind/m_debuginfo/readelf.c @@ -1786,7 +1786,8 @@ static HChar* readlink_path (const HChar *path) while (tries > 0) { SysRes res; -#if defined(VGP_arm64_linux) || defined(VGP_nanomips_linux) +#if defined(VGP_arm64_linux) || defined(VGP_nanomips_linux) \ + || defined(VGP_riscv64_linux) res = VG_(do_syscall4)(__NR_readlinkat, VKI_AT_FDCWD, (UWord)path, (UWord)buf, bufsiz); #elif defined(VGO_linux) || defined(VGO_darwin) || defined(VGO_freebsd) @@ -2711,6 +2712,7 @@ Bool ML_(read_elf_object) ( struct _DebugInfo* di ) || defined(VGP_arm_linux) || defined (VGP_s390x_linux) \ || defined(VGP_mips32_linux) || defined(VGP_mips64_linux) \ || defined(VGP_arm64_linux) || defined(VGP_nanomips_linux) \ + || defined(VGP_riscv64_linux) \ || defined(VGP_x86_solaris) || defined(VGP_amd64_solaris) \ || defined(VGP_x86_freebsd) || defined(VGP_amd64_freebsd) \ || defined(VGP_arm64_freebsd) diff --git a/coregrind/m_debuginfo/storage.c b/coregrind/m_debuginfo/storage.c index ef6a400510..12ad681304 100644 --- a/coregrind/m_debuginfo/storage.c +++ b/coregrind/m_debuginfo/storage.c @@ -260,6 +260,11 @@ void ML_(ppDiCfSI) ( const XArray* /* of CfiExpr */ exprs, SHOW_HOW(si_m->x30_how, si_m->x30_off); VG_(printf)(" X29="); SHOW_HOW(si_m->x29_how, si_m->x29_off); +# elif defined(VGA_riscv64) + VG_(printf)(" SP="); + SHOW_HOW(si_m->sp_how, si_m->sp_off); + VG_(printf)(" FP="); + SHOW_HOW(si_m->fp_how, si_m->fp_off); # else # error "Unknown arch" # endif diff --git a/coregrind/m_debuglog.c b/coregrind/m_debuglog.c index cad95bcbe2..225e5a0854 100644 --- a/coregrind/m_debuglog.c +++ b/coregrind/m_debuglog.c @@ -637,6 +637,34 @@ static UInt local_sys_getpid ( void ) return a0; } +#elif defined(VGP_riscv64_linux) + +static UInt local_sys_write_stderr ( const HChar* buf, Int n ) +{ + register RegWord a0 asm("a0") = 2; /* stderr */ + register RegWord a1 asm("a1") = (RegWord)buf; + register RegWord a2 asm("a2") = n; + register RegWord a7 asm("a7") = __NR_write; + __asm__ volatile ( + "ecall\n" + : "+r" (a0) + : "r" (a1), "r" (a2), "r" (a7) + ); + return a0 >= 0 ? (UInt)a0 : -1; +} + +static UInt local_sys_getpid ( void ) +{ + register RegWord a0 asm("a0"); + register RegWord a7 asm("a7") = __NR_getpid; + __asm__ volatile ( + "ecall\n" + : "=r" (a0) + : "r" (a7) + ); + return (UInt)a0; +} + #elif defined(VGP_x86_solaris) static UInt local_sys_write_stderr ( const HChar* buf, Int n ) { diff --git a/coregrind/m_gdbserver/target.c b/coregrind/m_gdbserver/target.c index f9f32f4aa5..4238c608cb 100644 --- a/coregrind/m_gdbserver/target.c +++ b/coregrind/m_gdbserver/target.c @@ -867,6 +867,8 @@ void valgrind_initialize_target(void) mips64_init_architecture(&the_low_target); #elif defined(VGA_nanomips) nanomips_init_architecture(&the_low_target); +#elif defined(VGA_riscv64) + riscv64_init_architecture(&the_low_target); #else #error "architecture missing in target.c valgrind_initialize_target" #endif diff --git a/coregrind/m_gdbserver/valgrind_low.h b/coregrind/m_gdbserver/valgrind_low.h index d8ae3c9086..ef4e190897 100644 --- a/coregrind/m_gdbserver/valgrind_low.h +++ b/coregrind/m_gdbserver/valgrind_low.h @@ -109,5 +109,6 @@ extern void s390x_init_architecture (struct valgrind_target_ops *target); extern void mips32_init_architecture (struct valgrind_target_ops *target); extern void mips64_init_architecture (struct valgrind_target_ops *target); extern void nanomips_init_architecture (struct valgrind_target_ops *target); +extern void riscv64_init_architecture (struct valgrind_target_ops *target); #endif diff --git a/coregrind/m_initimg/initimg-linux.c b/coregrind/m_initimg/initimg-linux.c index feec1e5f11..483b7a3ddd 100644 --- a/coregrind/m_initimg/initimg-linux.c +++ b/coregrind/m_initimg/initimg-linux.c @@ -910,9 +910,13 @@ Addr setup_client_stack( void* init_sp, && !defined(VGP_ppc64le_linux) \ && !defined(VGP_mips32_linux) && !defined(VGP_mips64_linux) \ && !defined(VGP_nanomips_linux) \ - && !defined(VGP_s390x_linux) + && !defined(VGP_s390x_linux) \ + && !defined(VGP_riscv64_linux) case AT_SYSINFO_EHDR: { /* Trash this, because we don't reproduce it */ + /* riscv64-linux: Keep the VDSO mapping on this platform present. + It contains __vdso_rt_sigreturn() which the kernel sets the ra + register to point to on a signal delivery. */ const NSegment* ehdrseg = VG_(am_find_nsegment)((Addr)auxv->u.a_ptr); vg_assert(ehdrseg); VG_(am_munmap_valgrind)(ehdrseg->start, ehdrseg->end - ehdrseg->start); @@ -1341,6 +1345,35 @@ void VG_(ii_finalise_image)( IIFinaliseImageInfo iifii ) arch->vex.guest_PC = iifii.initial_client_IP; arch->vex.guest_r31 = iifii.initial_client_SP; +# elif defined(VGP_riscv64_linux) + vg_assert(0 == sizeof(VexGuestRISCV64State) % LibVEX_GUEST_STATE_ALIGN); + + /* Zero out the initial state. */ + LibVEX_GuestRISCV64_initialise(&arch->vex); + + /* Mark all registers as undefined ... */ + VG_(memset)(&arch->vex_shadow1, 0xFF, sizeof(VexGuestRISCV64State)); + VG_(memset)(&arch->vex_shadow2, 0x00, sizeof(VexGuestRISCV64State)); + /* ... except x2 (sp), pc and fcsr. */ + arch->vex_shadow1.guest_x2 = 0; + arch->vex_shadow1.guest_pc = 0; + arch->vex_shadow1.guest_fcsr = 0; + + /* Put essential stuff into the new state. */ + arch->vex.guest_x2 = iifii.initial_client_SP; + arch->vex.guest_pc = iifii.initial_client_IP; + /* Initialize fcsr in the same way as done by the Linux kernel: + accrued exception flags cleared; round to nearest, ties to even. */ + arch->vex.guest_fcsr = 0; + + /* Tell the tool about the registers we just wrote. */ + VG_TRACK(post_reg_write, Vg_CoreStartup, /*tid*/1, VG_O_STACK_PTR, 8); + VG_TRACK(post_reg_write, Vg_CoreStartup, /*tid*/1, VG_O_INSTR_PTR, 8); + VG_TRACK(post_reg_write, Vg_CoreStartup, /*tid*/1, + offsetof(VexGuestRISCV64State, guest_fcsr), 4); + +#define PRECISE_GUEST_REG_DEFINEDNESS_AT_STARTUP 1 + # else # error Unknown platform # endif diff --git a/coregrind/m_libcassert.c b/coregrind/m_libcassert.c index 257c26bc63..c6380d4e0b 100644 --- a/coregrind/m_libcassert.c +++ b/coregrind/m_libcassert.c @@ -264,6 +264,25 @@ (srP)->misc.MIPS32.r31 = (UInt)ra; \ (srP)->misc.MIPS32.r28 = (UInt)gp; \ } +#elif defined(VGP_riscv64_linux) +# define GET_STARTREGS(srP) \ + { ULong pc, sp, fp, ra; \ + __asm__ __volatile__( \ + "jal %0, 0f;" \ + "0:\n" \ + "mv %1, sp;" \ + "mv %2, fp;" \ + "mv %3, ra;" \ + : "=r" (pc), \ + "=r" (sp), \ + "=r" (fp), \ + "=r" (ra) \ + ); \ + (srP)->r_pc = pc; \ + (srP)->r_sp = sp; \ + (srP)->misc.RISCV64.r_fp = fp; \ + (srP)->misc.RISCV64.r_ra = ra; \ + } #else # error Unknown platform #endif diff --git a/coregrind/m_libcfile.c b/coregrind/m_libcfile.c index fb93b4867c..e132e76597 100644 --- a/coregrind/m_libcfile.c +++ b/coregrind/m_libcfile.c @@ -264,8 +264,9 @@ Bool VG_(resolve_filemode) ( Int fd, Int * result ) SysRes VG_(mknod) ( const HChar* pathname, Int mode, UWord dev ) { -# if defined(VGP_arm64_linux) || defined(VGP_nanomips_linux) - /* ARM64 wants to use __NR_mknodat rather than __NR_mknod. */ +# if defined(VGP_arm64_linux) || defined(VGP_nanomips_linux) \ + || defined(VGP_riscv64_linux) + /* More recent Linux platforms have only __NR_mknodat and no __NR_mknod. */ SysRes res = VG_(do_syscall4)(__NR_mknodat, VKI_AT_FDCWD, (UWord)pathname, mode, dev); # elif defined(VGO_linux) || defined(VGO_darwin) @@ -290,8 +291,9 @@ SysRes VG_(mknod) ( const HChar* pathname, Int mode, UWord dev ) SysRes VG_(open) ( const HChar* pathname, Int flags, Int mode ) { -# if defined(VGP_arm64_linux) || defined(VGP_nanomips_linux) - /* ARM64 wants to use __NR_openat rather than __NR_open. */ +# if defined(VGP_arm64_linux) || defined(VGP_nanomips_linux) \ + || defined(VGP_riscv64_linux) + /* More recent Linux platforms have only __NR_openat and no __NR_open. */ SysRes res = VG_(do_syscall4)(__NR_openat, VKI_AT_FDCWD, (UWord)pathname, flags, mode); # elif defined(VGO_linux) || defined(VGO_freebsd) @@ -384,7 +386,8 @@ Int VG_(pipe) ( Int fd[2] ) } else { return -1; } -# elif defined(VGP_arm64_linux) || defined(VGP_nanomips_linux) +# elif defined(VGP_arm64_linux) || defined(VGP_nanomips_linux) \ + || defined(VGP_riscv64_linux) SysRes res = VG_(do_syscall2)(__NR_pipe2, (UWord)fd, 0); return sr_isError(res) ? -1 : 0; # elif defined(VGO_linux) @@ -731,7 +734,8 @@ SysRes VG_(dup) ( Int oldfd ) SysRes VG_(dup2) ( Int oldfd, Int newfd ) { -# if defined(VGP_arm64_linux) || defined(VGP_nanomips_linux) +# if defined(VGP_arm64_linux) || defined(VGP_nanomips_linux) \ + || defined(VGP_riscv64_linux) /* We only have dup3, that means we have to mimic dup2. The only real difference is when oldfd == newfd. dup3 always returns an error, but dup2 returns only an @@ -777,7 +781,7 @@ Int VG_(rename) ( const HChar* old_name, const HChar* new_name ) # if defined(VGO_solaris) || defined(VGP_arm64_linux) SysRes res = VG_(do_syscall4)(__NR_renameat, VKI_AT_FDCWD, (UWord)old_name, VKI_AT_FDCWD, (UWord)new_name); -# elif defined(VGP_nanomips_linux) +# elif defined(VGP_nanomips_linux) || defined(VGP_riscv64_linux) SysRes res = VG_(do_syscall5)(__NR_renameat2, VKI_AT_FDCWD, (UWord)old_name, VKI_AT_FDCWD, (UWord)new_name, 0); @@ -791,7 +795,8 @@ Int VG_(rename) ( const HChar* old_name, const HChar* new_name ) Int VG_(unlink) ( const HChar* file_name ) { -# if defined(VGP_arm64_linux) || defined(VGP_nanomips_linux) +# if defined(VGP_arm64_linux) || defined(VGP_nanomips_linux) \ + || defined(VGP_riscv64_linux) SysRes res = VG_(do_syscall2)(__NR_unlinkat, VKI_AT_FDCWD, (UWord)file_name); # elif defined(VGO_linux) || defined(VGO_darwin) || defined(VGO_freebsd) @@ -870,8 +875,9 @@ const HChar *VG_(get_startup_wd) ( void ) SysRes VG_(poll) (struct vki_pollfd *fds, Int nfds, Int timeout) { SysRes res; -# if defined(VGP_arm64_linux) || defined(VGP_nanomips_linux) - /* ARM64 wants to use __NR_ppoll rather than __NR_poll. */ +# if defined(VGP_arm64_linux) || defined(VGP_nanomips_linux) \ + || defined(VGP_riscv64_linux) + /* More recent Linux platforms have only __NR_ppoll and no __NR_poll. */ struct vki_timespec timeout_ts; if (timeout >= 0) { timeout_ts.tv_sec = timeout / 1000; @@ -915,7 +921,8 @@ SSizeT VG_(readlink) (const HChar* path, HChar* buf, SizeT bufsiz) { SysRes res; /* res = readlink( path, buf, bufsiz ); */ -# if defined(VGP_arm64_linux) || defined(VGP_nanomips_linux) +# if defined(VGP_arm64_linux) || defined(VGP_nanomips_linux) \ + || defined(VGP_riscv64_linux) res = VG_(do_syscall4)(__NR_readlinkat, VKI_AT_FDCWD, (UWord)path, (UWord)buf, bufsiz); # elif defined(VGO_linux) || defined(VGO_darwin) || defined(VGO_freebsd) @@ -994,7 +1001,8 @@ Int VG_(access) ( const HChar* path, Bool irusr, Bool iwusr, Bool ixusr ) UWord w = (irusr ? VKI_R_OK : 0) | (iwusr ? VKI_W_OK : 0) | (ixusr ? VKI_X_OK : 0); -# if defined(VGP_arm64_linux) || defined(VGP_nanomips_linux) +# if defined(VGP_arm64_linux) || defined(VGP_nanomips_linux) \ + || defined(VGP_riscv64_linux) SysRes res = VG_(do_syscall3)(__NR_faccessat, VKI_AT_FDCWD, (UWord)path, w); # elif defined(VGO_linux) || defined(VGO_darwin) || defined(VGO_freebsd) SysRes res = VG_(do_syscall2)(__NR_access, (UWord)path, w); @@ -1140,7 +1148,8 @@ SysRes VG_(pread) ( Int fd, void* buf, Int count, OffT offset ) return res; # elif defined(VGP_amd64_linux) || defined(VGP_s390x_linux) \ || defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux) \ - || defined(VGP_mips64_linux) || defined(VGP_arm64_linux) + || defined(VGP_mips64_linux) || defined(VGP_arm64_linux) \ + || defined(VGP_riscv64_linux) res = VG_(do_syscall4)(__NR_pread64, fd, (UWord)buf, count, offset); return res; # elif defined(VGP_amd64_freebsd) || defined(VGP_arm64_freebsd) @@ -1405,7 +1414,8 @@ Int VG_(socket) ( Int domain, Int type, Int protocol ) # elif defined(VGP_amd64_linux) || defined(VGP_arm_linux) \ || defined(VGP_mips32_linux) || defined(VGP_mips64_linux) \ - || defined(VGP_arm64_linux) || defined(VGP_nanomips_linux) || defined(VGO_freebsd) + || defined(VGP_arm64_linux) || defined(VGP_nanomips_linux) \ + || defined(VGP_riscv64_linux) || defined(VGO_freebsd) SysRes res; res = VG_(do_syscall3)(__NR_socket, domain, type, protocol ); return sr_isError(res) ? -1 : sr_Res(res); @@ -1460,7 +1470,8 @@ Int my_connect ( Int sockfd, struct vki_sockaddr_in* serv_addr, Int addrlen ) # elif defined(VGP_amd64_linux) || defined(VGP_arm_linux) \ || defined(VGP_mips32_linux) || defined(VGP_mips64_linux) \ - || defined(VGP_arm64_linux) || defined(VGP_nanomips_linux) || defined(VGO_freebsd) + || defined(VGP_arm64_linux) || defined(VGP_nanomips_linux) \ + || defined(VGP_riscv64_linux) || defined(VGO_freebsd) SysRes res; res = VG_(do_syscall3)(__NR_connect, sockfd, (UWord)serv_addr, addrlen); return sr_isError(res) ? -1 : sr_Res(res); @@ -1507,7 +1518,8 @@ Int VG_(write_socket)( Int sd, const void *msg, Int count ) # elif defined(VGP_amd64_linux) || defined(VGP_arm_linux) \ || defined(VGP_mips32_linux) || defined(VGP_mips64_linux) \ - || defined(VGP_arm64_linux) || defined(VGP_nanomips_linux) || defined(VGO_freebsd) + || defined(VGP_arm64_linux) || defined(VGP_nanomips_linux) \ + || defined(VGP_riscv64_linux) || defined(VGO_freebsd) SysRes res; res = VG_(do_syscall6)(__NR_sendto, sd, (UWord)msg, count, VKI_MSG_NOSIGNAL, 0,0); @@ -1544,8 +1556,8 @@ Int VG_(getsockname) ( Int sd, struct vki_sockaddr *name, Int *namelen) # elif defined(VGP_amd64_linux) || defined(VGP_arm_linux) \ || defined(VGP_mips64_linux) || defined(VGP_arm64_linux) \ - || defined(VGP_nanomips_linux) || defined(VGO_freebsd) \ - || defined(VGP_mips64_linux) || defined(VGP_arm64_linux) + || defined(VGP_nanomips_linux) || defined(VGP_riscv64_linux) \ + || defined(VGO_freebsd) SysRes res; res = VG_(do_syscall3)( __NR_getsockname, (UWord)sd, (UWord)name, (UWord)namelen ); @@ -1584,7 +1596,8 @@ Int VG_(getpeername) ( Int sd, struct vki_sockaddr *name, Int *namelen) # elif defined(VGP_amd64_linux) || defined(VGP_arm_linux) \ || defined(VGP_mips64_linux) || defined(VGP_arm64_linux) \ - || defined(VGP_nanomips_linux) || defined(VGO_freebsd) + || defined(VGP_nanomips_linux) || defined(VGP_riscv64_linux) \ + || defined(VGO_freebsd) SysRes res; res = VG_(do_syscall3)( __NR_getpeername, (UWord)sd, (UWord)name, (UWord)namelen ); @@ -1626,7 +1639,7 @@ Int VG_(getsockopt) ( Int sd, Int level, Int optname, void *optval, # elif defined(VGP_amd64_linux) || defined(VGP_arm_linux) \ || defined(VGP_mips32_linux) || defined(VGP_mips64_linux) \ || defined(VGP_arm64_linux) || defined(VGP_nanomips_linux) \ - || defined(VGO_freebsd) + || defined(VGP_riscv64_linux) || defined(VGO_freebsd) SysRes res; res = VG_(do_syscall5)( __NR_getsockopt, (UWord)sd, (UWord)level, (UWord)optname, @@ -1670,7 +1683,8 @@ Int VG_(setsockopt) ( Int sd, Int level, Int optname, void *optval, # elif defined(VGP_amd64_linux) || defined(VGP_arm_linux) \ || defined(VGP_mips32_linux) || defined(VGP_mips64_linux) \ - || defined(VGP_arm64_linux) || defined(VGP_nanomips_linux) + || defined(VGP_arm64_linux) || defined(VGP_nanomips_linux) \ + || defined(VGP_riscv64_linux) SysRes res; res = VG_(do_syscall5)( __NR_setsockopt, (UWord)sd, (UWord)level, (UWord)optname, diff --git a/coregrind/m_libcproc.c b/coregrind/m_libcproc.c index 280ab1cff2..c70f229e5d 100644 --- a/coregrind/m_libcproc.c +++ b/coregrind/m_libcproc.c @@ -698,7 +698,8 @@ Int VG_(gettid)(void) * the /proc/self link is pointing... */ -# if defined(VGP_arm64_linux) || defined(VGP_nanomips_linux) +# if defined(VGP_arm64_linux) || defined(VGP_nanomips_linux) \ + || defined(VGP_riscv64_linux) res = VG_(do_syscall4)(__NR_readlinkat, VKI_AT_FDCWD, (UWord)"/proc/self", (UWord)pid, sizeof(pid)); @@ -753,7 +754,8 @@ Int VG_(getpid) ( void ) Int VG_(getpgrp) ( void ) { /* ASSUMES SYSCALL ALWAYS SUCCEEDS */ -# if defined(VGP_arm64_linux) || defined(VGP_nanomips_linux) +# if defined(VGP_arm64_linux) || defined(VGP_nanomips_linux) \ + || defined(VGP_riscv64_linux) return sr_Res( VG_(do_syscall1)(__NR_getpgid, 0) ); # elif defined(VGO_linux) || defined(VGO_darwin) || defined(VGO_freebsd) return sr_Res( VG_(do_syscall0)(__NR_getpgrp) ); @@ -850,7 +852,7 @@ Int VG_(getgroups)( Int size, UInt* list ) || defined(VGO_darwin) || defined(VGP_s390x_linux) \ || defined(VGP_mips32_linux) || defined(VGP_arm64_linux) \ || defined(VGO_solaris) || defined(VGP_nanomips_linux) \ - || defined(VGO_freebsd) + || defined(VGP_riscv64_linux) || defined(VGO_freebsd) SysRes sres; sres = VG_(do_syscall2)(__NR_getgroups, size, (Addr)list); if (sr_isError(sres)) @@ -951,7 +953,8 @@ Int VG_(fork) ( void ) fds[0] = fds[1] = -1; } -# if defined(VGP_arm64_linux) || defined(VGP_nanomips_linux) +# if defined(VGP_arm64_linux) || defined(VGP_nanomips_linux) \ + || defined(VGP_riscv64_linux) SysRes res; res = VG_(do_syscall5)(__NR_clone, VKI_SIGCHLD, (UWord)NULL, (UWord)NULL, (UWord)NULL, (UWord)NULL); @@ -1426,10 +1429,22 @@ void VG_(invalidate_icache) ( void *ptr, SizeT nbytes ) (UWord) nbytes, (UWord) 3); vg_assert( !sr_isError(sres) ); -# elif defined(VGA_nanomips) - +# elif defined(VGA_nanomips) __builtin___clear_cache(ptr, (char*)ptr + nbytes); +# elif defined(VGP_riscv64_linux) + /* Make data stores to the area visible to all RISC-V harts. */ + __asm__ __volatile__("fence w,r"); + + /* Ask the kernel to execute fence.i on all harts to guarantee that an + instruction fetch on each hart will see any previous data stores visible + to the same hart. */ + Addr startaddr = (Addr)ptr; + Addr endaddr = startaddr + nbytes; + SysRes sres = VG_(do_syscall3)(__NR_riscv_flush_icache, startaddr, endaddr, + 0 /*flags*/); + vg_assert(!sr_isError(sres)); + # endif } diff --git a/coregrind/m_machine.c b/coregrind/m_machine.c index 234efb312d..dec4f2373e 100644 --- a/coregrind/m_machine.c +++ b/coregrind/m_machine.c @@ -152,6 +152,11 @@ void VG_(get_UnwindStartRegs) ( /*OUT*/UnwindStartRegs* regs, = VG_(threads)[tid].arch.vex.guest_r31; regs->misc.MIPS64.r28 = VG_(threads)[tid].arch.vex.guest_r28; +# elif defined(VGA_riscv64) + regs->r_pc = VG_(threads)[tid].arch.vex.guest_pc; + regs->r_sp = VG_(threads)[tid].arch.vex.guest_x2; + regs->misc.RISCV64.r_fp = VG_(threads)[tid].arch.vex.guest_x8; + regs->misc.RISCV64.r_ra = VG_(threads)[tid].arch.vex.guest_x1; # else # error "Unknown arch" # endif @@ -369,6 +374,39 @@ static void apply_to_GPs_of_tid(ThreadId tid, void (*f)(ThreadId, (*f)(tid, "x28", vex->guest_X28); (*f)(tid, "x29", vex->guest_X29); (*f)(tid, "x30", vex->guest_X30); +#elif defined(VGA_riscv64) + (*f)(tid, "x0" , vex->guest_x0 ); + (*f)(tid, "x1" , vex->guest_x1 ); + (*f)(tid, "x2" , vex->guest_x2 ); + (*f)(tid, "x3" , vex->guest_x3 ); + (*f)(tid, "x4" , vex->guest_x4 ); + (*f)(tid, "x5" , vex->guest_x5 ); + (*f)(tid, "x6" , vex->guest_x6 ); + (*f)(tid, "x7" , vex->guest_x7 ); + (*f)(tid, "x8" , vex->guest_x8 ); + (*f)(tid, "x9" , vex->guest_x9 ); + (*f)(tid, "x10", vex->guest_x10); + (*f)(tid, "x11", vex->guest_x11); + (*f)(tid, "x12", vex->guest_x12); + (*f)(tid, "x13", vex->guest_x13); + (*f)(tid, "x14", vex->guest_x14); + (*f)(tid, "x15", vex->guest_x15); + (*f)(tid, "x16", vex->guest_x16); + (*f)(tid, "x17", vex->guest_x17); + (*f)(tid, "x18", vex->guest_x18); + (*f)(tid, "x19", vex->guest_x19); + (*f)(tid, "x20", vex->guest_x20); + (*f)(tid, "x21", vex->guest_x21); + (*f)(tid, "x22", vex->guest_x22); + (*f)(tid, "x23", vex->guest_x23); + (*f)(tid, "x24", vex->guest_x24); + (*f)(tid, "x25", vex->guest_x25); + (*f)(tid, "x26", vex->guest_x26); + (*f)(tid, "x27", vex->guest_x27); + (*f)(tid, "x28", vex->guest_x28); + (*f)(tid, "x29", vex->guest_x29); + (*f)(tid, "x30", vex->guest_x30); + (*f)(tid, "x31", vex->guest_x31); #else # error Unknown arch #endif @@ -2241,6 +2279,22 @@ Bool VG_(machine_get_hwcaps)( void ) return True; } + +#elif defined(VGA_riscv64) + { + va = VexArchRISCV64; + vai.endness = VexEndnessLE; + + /* Hardware baseline is RV64GC. */ + vai.hwcaps = 0; + + VG_(debugLog)(1, "machine", "hwcaps = 0x%x\n", vai.hwcaps); + + VG_(machine_get_cache_info)(&vai); + + return True; + } + #else # error "Unknown arch" #endif @@ -2381,6 +2435,10 @@ Int VG_(machine_get_size_of_largest_guest_register) ( void ) # elif defined(VGA_mips64) return 8; +# elif defined(VGA_riscv64) + /* 64-bit integer and floating-point registers, no vector set. */ + return 8; + # else # error "Unknown arch" # endif @@ -2397,7 +2455,7 @@ void* VG_(fnptr_to_fnentry)( void* f ) || defined(VGP_s390x_linux) || defined(VGP_mips32_linux) \ || defined(VGP_mips64_linux) || defined(VGP_arm64_linux) \ || defined(VGP_x86_solaris) || defined(VGP_amd64_solaris) \ - || defined(VGP_nanomips_linux) + || defined(VGP_nanomips_linux) || defined(VGP_riscv64_linux) return f; # elif defined(VGP_ppc64be_linux) /* ppc64-linux uses the AIX scheme, in which f is a pointer to a diff --git a/coregrind/m_main.c b/coregrind/m_main.c index 3f07e57a91..877e6b0b68 100644 --- a/coregrind/m_main.c +++ b/coregrind/m_main.c @@ -2554,6 +2554,11 @@ static void final_tidyup(ThreadId tid) VG_TRACK(post_reg_write, Vg_CoreClientReq, tid, offsetof(VexGuestPPC64State, guest_GPR3), sizeof(VG_(threads)[tid].arch.vex.guest_GPR3)); +# elif defined(VGA_riscv64) + VG_(threads)[tid].arch.vex.guest_x10 = to_run; + VG_TRACK(post_reg_write, Vg_CoreClientReq, tid, + offsetof(VexGuestRISCV64State, guest_x10), + sizeof(VG_(threads)[tid].arch.vex.guest_x10)); # elif defined(VGA_s390x) VG_(threads)[tid].arch.vex.guest_r2 = to_run; VG_TRACK(post_reg_write, Vg_CoreClientReq, tid, @@ -3087,6 +3092,33 @@ asm( ".set pop \n\t" ".previous \n\t" ); +#elif defined(VGP_riscv64_linux) +asm("\n" + "\t.text\n" + "\t.type _start,@function\n" + "\t.global _start\n" + "_start:\n" + /* establish the global pointer in gp */ + ".option push\n" + ".option norelax\n" + "\tla gp, __global_pointer$\n" + ".option pop\n" + /* set up the new stack in t0 */ + "\tla t0, vgPlain_interim_stack\n" + "\tli t1, "VG_STRINGIFY(VG_STACK_GUARD_SZB)"\n" + "\tadd t0, t0, t1\n" + "\tli t1, "VG_STRINGIFY(VG_DEFAULT_STACK_ACTIVE_SZB)"\n" + "\tadd t0, t0, t1\n" + "\tli t1, 0xFFFFFF00\n" + "\tand t0, t0, t1\n" + /* install it, and collect the original one */ + "\tmv a0, sp\n" + "\tmv sp, t0\n" + /* call _start_in_C_linux, passing it the startup sp */ + "\tj _start_in_C_linux\n" + "\tunimp\n" + ".previous\n" +); #els... [truncated message content] |