]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
riscv64: Add initial support: new port-specific Valgrind files
authorPetr Pavlu <petr.pavlu@dagobah.cz>
Tue, 11 Apr 2023 19:30:42 +0000 (19:30 +0000)
committerMark Wielaard <mark@klomp.org>
Tue, 25 Feb 2025 16:02:45 +0000 (17:02 +0100)
The following people contributed to the initial RISC-V support:
Petr Pavlu <petr.pavlu@dagobah.cz>
Xeonacid <h.dwwwwww@gmail.com>
laokz <laokz@foxmail.com>
Chelsea E. Manning <me@xychelsea.is>
zhaomingxin <zhaomingxin.zmx@alibaba-inc.com>
Jojo R <rjiejie@linux.alibaba.com>

Some integration fixes were added by Mark Wielaard <mark@klomp.org>
- Remove POST handler from sys_close
- Define VKI_O_DIRECT in vki-riscv64-linux.h
- Wrap riscv64-linux mlock2
- Add POST handler for sys_readlinkat

https://bugs.kde.org/show_bug.cgi?id=493507

18 files changed:
README.riscv64 [new file with mode: 0644]
coregrind/m_dispatch/dispatch-riscv64-linux.S [new file with mode: 0644]
coregrind/m_gdbserver/riscv64-cpu-valgrind-s1.xml [new file with mode: 0644]
coregrind/m_gdbserver/riscv64-cpu-valgrind-s2.xml [new file with mode: 0644]
coregrind/m_gdbserver/riscv64-cpu.xml [new file with mode: 0644]
coregrind/m_gdbserver/riscv64-fpu-valgrind-s1.xml [new file with mode: 0644]
coregrind/m_gdbserver/riscv64-fpu-valgrind-s2.xml [new file with mode: 0644]
coregrind/m_gdbserver/riscv64-fpu.xml [new file with mode: 0644]
coregrind/m_gdbserver/riscv64-linux-valgrind.xml [new file with mode: 0644]
coregrind/m_gdbserver/riscv64-linux.xml [new file with mode: 0644]
coregrind/m_gdbserver/valgrind-low-riscv64.c [new file with mode: 0644]
coregrind/m_sigframe/sigframe-riscv64-linux.c [new file with mode: 0644]
coregrind/m_syswrap/syscall-riscv64-linux.S [new file with mode: 0644]
coregrind/m_syswrap/syswrap-riscv64-linux.c [new file with mode: 0644]
docs/internals/qemu-riscv64-linux-HOWTO.txt [new file with mode: 0644]
include/vki/vki-posixtypes-riscv64-linux.h [new file with mode: 0644]
include/vki/vki-riscv64-linux.h [new file with mode: 0644]
include/vki/vki-scnums-riscv64-linux.h [new file with mode: 0644]

diff --git a/README.riscv64 b/README.riscv64
new file mode 100644 (file)
index 0000000..04f2bc9
--- /dev/null
@@ -0,0 +1,45 @@
+
+Status
+~~~~~~
+
+The RISC-V port targets the 64-bit RISC-V architecture and the Linux operating
+system. The port has been tested to work on real hardware and under QEMU.
+
+The following ISA base and extensions are currently supported:
+
+| Name         | Description                       | #Instrs | Notes    |
+| ------------ | --------------------------------- | ------- | -------- |
+| RV64I        | Base instruction set              |   52/52 |          |
+| RV64M        | Integer multiplication & division |   12/13 | (1)      |
+| RV64A        | Atomic                            |   22/22 | (2)      |
+| RV64F        | Single-precision floating-point   |   30/30 | (3)      |
+| RV64D        | Double-precision floating-point   |   32/32 |          |
+| RV64Zicsr    | Control & status register         |     2/6 | (4), (5) |
+| RV64Zifencei | Instruction-fetch fence           |     0/1 | (6)      |
+| RV64C        | Compressed                        |   37/37 |          |
+
+Notes:
+(1) MULHSU is not recognized.
+(2) LR and SC use the VEX "fallback" method which suffers from the ABA problem.
+(3) Operations do not check if the input operands are correctly NaN-boxed.
+(4) CSRRC, CSRRWI, CSRRSI and CSRRCI are not recognized.
+(5) Only registers fflags, frm and fcsr are accepted.
+(6) FENCE.I is not recognized.
+
+
+Implementation tidying-up/TODO notes
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+* Implement a proper "non-fallback" method for LR and SC instructions.
+* Add a check for correct NaN-boxing of 32-bit floating-point operands.
+* Optimize instruction selection, in particular make more use of <instr>i
+  variants.
+* Optimize handling of floating-point exceptions. Avoid helpers and calculate
+  exception flags using the same instruction which produced an actual result.
+* Review register usage by the codegen.
+* Avoid re-use of Intel-constants CFIC_IA_SPREL and CFIC_IA_BPREL. Generalize
+  them for all architectures or introduce same CFIC_RISCV64_ variants.
+* Get rid of the typedef of vki_modify_ldt_t in include/vki/vki-riscv64-linux.h.
+* Review if setup_client_stack() should expose AT_SYSINFO_EHDR to clients.
+* Make sure that the final exit sequence in run_a_thread_NORETURN() is not racy
+  in regards to accessing the thread state.
diff --git a/coregrind/m_dispatch/dispatch-riscv64-linux.S b/coregrind/m_dispatch/dispatch-riscv64-linux.S
new file mode 100644 (file)
index 0000000..c4941e4
--- /dev/null
@@ -0,0 +1,298 @@
+
+/*--------------------------------------------------------------------*/
+/*--- The core dispatch loop, for jumping to a code address.       ---*/
+/*---                                     dispatch-riscv64-linux.S ---*/
+/*--------------------------------------------------------------------*/
+
+/*
+  This file is part of Valgrind, a dynamic binary instrumentation
+  framework.
+
+  Copyright (C) 2020-2023 Petr Pavlu
+      petr.pavlu@dagobah.cz
+
+  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.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+
+  The GNU General Public License is contained in the file COPYING.
+*/
+
+#include "pub_core_basics_asm.h"
+
+#if defined(VGP_riscv64_linux)
+
+#include "pub_core_dispatch_asm.h"
+#include "pub_core_transtab_asm.h"
+#include "libvex_guest_offsets.h"
+
+
+/*------------------------------------------------------------*/
+/*---                                                      ---*/
+/*--- The dispatch loop.  VG_(disp_run_translations) is    ---*/
+/*--- used to run all translations,                        ---*/
+/*--- including no-redir ones.                             ---*/
+/*---                                                      ---*/
+/*------------------------------------------------------------*/
+
+/*----------------------------------------------------*/
+/*--- Entry and preamble (set everything up)       ---*/
+/*----------------------------------------------------*/
+
+/* signature:
+void VG_(disp_run_translations)( UWord* two_words,
+                                 void*  guest_state,
+                                 Addr   host_addr );
+*/
+.text
+.global VG_(disp_run_translations)
+VG_(disp_run_translations):
+       /* a0 holds two_words
+          a1 holds guest_state
+          a2 holds host_addr
+       */
+       /* Push the callee-saved registers. Note this sequence maintains
+          16-alignment of sp. Also save a0 since it will be needed in the
+          postamble. */
+       addi sp, sp, -112
+       sd ra, 104(sp)
+       sd s0, 96(sp)
+       sd s1, 88(sp)
+       sd s2, 80(sp)
+       sd s3, 72(sp)
+       sd s4, 64(sp)
+       sd s5, 56(sp)
+       sd s6, 48(sp)
+       sd s7, 40(sp)
+       sd s8, 32(sp)
+       sd s9, 24(sp)
+       sd s10, 16(sp)
+       sd s11, 8(sp)
+       sd a0, 0(sp)
+
+       /* Set up the guest state pointer. */
+       li t0, 2048
+       add s0, a1, t0
+
+       /* and jump into the code cache. Chained translations in the code cache
+          run, until for whatever reason, they can't continue. When that
+          happens, the translation in question will jump (or call) to one of
+          the continuation points VG_(cp_...) below. */
+       jr a2
+       /* NOTREACHED */
+
+/*----------------------------------------------------*/
+/*--- Postamble and exit.                          ---*/
+/*----------------------------------------------------*/
+
+postamble:
+       /* At this point, t0 and t1 contain two words to be returned to the
+          caller. t0 holds a TRC value, and t1 optionally may hold another
+          word (for CHAIN_ME exits, the address of the place to patch.) */
+
+       /* Restore int regs, including importantly a0 (two_words). */
+       ld ra, 104(sp)
+       ld s0, 96(sp)
+       ld s1, 88(sp)
+       ld s2, 80(sp)
+       ld s3, 72(sp)
+       ld s4, 64(sp)
+       ld s5, 56(sp)
+       ld s6, 48(sp)
+       ld s7, 40(sp)
+       ld s8, 32(sp)
+       ld s9, 24(sp)
+       ld s10, 16(sp)
+       ld s11, 8(sp)
+       ld a0, 0(sp)
+       addi sp, sp, 112
+
+       /* Stash return values. */
+       sd t0, 0(a0)
+       sd t1, 8(a0)
+       ret
+
+/*----------------------------------------------------*/
+/*--- Continuation points                          ---*/
+/*----------------------------------------------------*/
+
+/* ------ Chain me to slow entry point ------ */
+.global VG_(disp_cp_chain_me_to_slowEP)
+VG_(disp_cp_chain_me_to_slowEP):
+       /* We got called. The return address indicates where the patching needs
+          to happen. Collect the return address and, exit back to C land,
+          handing the caller the pair (Chain_me_F, RA). */
+       li t0, VG_TRC_CHAIN_ME_TO_SLOW_EP
+       mv t1, ra
+       /* 4 = lui t0, disp_cp_chain_me_to_slowEP[47:28]'
+          4 = addiw t0, t0, disp_cp_chain_me_to_slowEP[27:16]'
+          2 = c.slli t0, 12
+          4 = addi t0, t0, disp_cp_chain_me_to_slowEP[15:4]'
+          2 = c.slli t0, 4
+          2 = c.addi t0, disp_cp_chain_me_to_slowEP[3:0]'
+          2 = c.jalr 0(t0)
+       */
+       addi t1, t1, -(4+4+2+4+2+2+2)
+       j postamble
+
+/* ------ Chain me to fast entry point ------ */
+.global VG_(disp_cp_chain_me_to_fastEP)
+VG_(disp_cp_chain_me_to_fastEP):
+       /* We got called. The return address indicates where the patching needs
+          to happen. Collect the return address and, exit back to C land,
+          handing the caller the pair (Chain_me_F, RA). */
+       li t0, VG_TRC_CHAIN_ME_TO_FAST_EP
+       mv t1, ra
+       /* 4 = lui t0, disp_cp_chain_me_to_fastEP[47:28]'
+          4 = addiw t0, t0, disp_cp_chain_me_to_fastEP[27:16]'
+          2 = c.slli t0, 12
+          4 = addi t0, t0, disp_cp_chain_me_to_fastEP[15:4]'
+          2 = c.slli t0, 4
+          2 = c.addi t0, disp_cp_chain_me_to_fastEP[3:0]'
+          2 = c.jalr 0(t0)
+       */
+       addi t1, t1, -(4+4+2+4+2+2+2)
+       j postamble
+
+/* ------ Indirect but boring jump ------ */
+.global VG_(disp_cp_xindir)
+VG_(disp_cp_xindir):
+       /* Where are we going? */
+       ld t0, OFFSET_riscv64_pc-2048(s0)
+
+       /* Stats only. */
+       lw t1, VG_(stats__n_xIndirs_32)
+       addi t1, t1, 1
+       sw t1, VG_(stats__n_xIndirs_32), t2
+
+       /* LIVE: s0 (guest state ptr), t0 (guest address to go to).
+          We use 6 temporaries:
+            t6 (to point at the relevant FastCacheSet),
+            t1, t2, t3 (scratch, for swapping entries within a set)
+            t4, t5 (other scratch) */
+
+       /* Try a fast lookup in the translation cache. This is pretty much
+          a handcoded version of VG_(lookupInFastCache). */
+
+       /* Compute t6 = VG_TT_FAST_HASH(guest). */
+       srli t6, t0, 1                       /* g2 = guest >> 1 */
+       srli t4, t6, VG_TT_FAST_BITS         /* g2 >> VG_TT_FAST_BITS */
+       xor t6, t4, t6                       /* (g2 >> VG_TT_FAST_BITS) ^ g2 */
+       li t4, VG_TT_FAST_MASK               /* VG_TT_FAST_MASK */
+       and t6, t6, t4                       /* setNo */
+
+       /* Compute t6 = &VG_(tt_fast)[t6]. */
+       la t4, VG_(tt_fast)                  /* &VG_(tt_fast)[0] */
+       slli t6, t6, VG_FAST_CACHE_SET_BITS
+       add t6, t4, t6                       /* &VG_(tt_fast)[setNo] */
+
+       /* LIVE: s0 (guest state ptr), t0 (guest addr), t6 (cache set). */
+       /* Try way 0. */
+       ld t4, FCS_g0(t6)                    /* t4 = .guest0 */
+       bne t4, t0, 1f                       /* cmp against .guest0 */
+       /* Hit at way 0. */
+       /* Go to .host0. */
+       ld t5, FCS_h0(t6)                    /* t5 = .host0 */
+       jr t5
+       /*NOTREACHED*/
+
+1:     /* Try way 1. */
+       ld t4, FCS_g1(t6)
+       bne t4, t0, 2f                       /* cmp against .guest1 */
+       /* Hit at way 1; swap upwards. */
+       ld t1, FCS_g0(t6)                    /* t1 = old .guest0 */
+       ld t2, FCS_h0(t6)                    /* t2 = old .host0 */
+       ld t3, FCS_h1(t6)                    /* t3 = old .host1 */
+       sd t0, FCS_g0(t6)                    /* new .guest0 = guest */
+       sd t3, FCS_h0(t6)                    /* new .host0 = old .host1 */
+       sd t1, FCS_g1(t6)                    /* new .guest1 = old .guest0 */
+       sd t2, FCS_h1(t6)                    /* new .host1 = old .host0 */
+       /* Stats only. */
+       lw t4, VG_(stats__n_xIndir_hits1_32)
+       addi t4, t4, 1
+       sw t4, VG_(stats__n_xIndir_hits1_32), t5
+       /* Go to old .host1 a.k.a. new .host0. */
+       jr t3
+       /*NOTREACHED*/
+
+2:     /* Try way 2. */
+       ld t4, FCS_g2(t6)
+       bne t4, t0, 3f                       /* cmp against .guest2 */
+       /* Hit at way 2; swap upwards. */
+       ld t1, FCS_g1(t6)
+       ld t2, FCS_h1(t6)
+       ld t3, FCS_h2(t6)
+       sd t0, FCS_g1(t6)
+       sd t3, FCS_h1(t6)
+       sd t1, FCS_g2(t6)
+       sd t2, FCS_h2(t6)
+       /* Stats only. */
+       lw t4, VG_(stats__n_xIndir_hits2_32)
+       addi t4, t4, 1
+       sw t4, VG_(stats__n_xIndir_hits2_32), t5
+       /* Go to old .host2 a.k.a. new .host1. */
+       jr t3
+       /*NOTREACHED*/
+
+3:     /* Try way 3. */
+       ld t4, FCS_g3(t6)
+       bne t4, t0, 4f                       /* cmp against .guest3 */
+       /* Hit at way 3; swap upwards. */
+       ld t1, FCS_g2(t6)
+       ld t2, FCS_h2(t6)
+       ld t3, FCS_h3(t6)
+       sd t0, FCS_g2(t6)
+       sd t3, FCS_h2(t6)
+       sd t1, FCS_g3(t6)
+       sd t2, FCS_h3(t6)
+       /* Stats only. */
+       lw t4, VG_(stats__n_xIndir_hits3_32)
+       addi t4, t4, 1
+       sw t4, VG_(stats__n_xIndir_hits3_32), t5
+       /* Go to old .host3 a.k.a. new .host2. */
+       jr t3
+       /*NOTREACHED*/
+
+4:     /* Fast lookup failed. */
+       lw t4, VG_(stats__n_xIndir_misses_32)
+       addi t4, t4, 1
+       sw t4, VG_(stats__n_xIndir_misses_32), t5
+
+       li t0, VG_TRC_INNER_FASTMISS
+       li t1, 0
+       j postamble
+
+/* ------ Assisted jump ------ */
+.global VG_(disp_cp_xassisted)
+VG_(disp_cp_xassisted):
+       /* s0 contains the TRC. */
+       mv t0, s0
+       li t1, 0
+       j postamble
+
+/* ------ Event check failed ------ */
+.global VG_(disp_cp_evcheck_fail)
+VG_(disp_cp_evcheck_fail):
+       li t0, VG_TRC_INNER_COUNTERZERO
+       li t1, 0
+       j postamble
+
+.size VG_(disp_run_translations), .-VG_(disp_run_translations)
+
+#endif // defined(VGP_riscv64_linux)
+
+/* Let the linker know we don't need an executable stack */
+MARK_STACK_NO_EXEC
+
+/*--------------------------------------------------------------------*/
+/*--- end                                 dispatch-riscv64-linux.S ---*/
+/*--------------------------------------------------------------------*/
diff --git a/coregrind/m_gdbserver/riscv64-cpu-valgrind-s1.xml b/coregrind/m_gdbserver/riscv64-cpu-valgrind-s1.xml
new file mode 100644 (file)
index 0000000..22c7dd0
--- /dev/null
@@ -0,0 +1,43 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2018-2022 Free Software Foundation, Inc.
+
+     Copying and distribution of this file, with or without modification,
+     are permitted in any medium without royalty provided the copyright
+     notice and this notice are preserved.  -->
+
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<feature name="org.gnu.gdb.riscv.cpu.valgrind.s1">
+  <reg name="zeros1" bitsize="64" type="int" regnum="69"/>
+  <reg name="ras1" bitsize="64" type="int"/>
+  <reg name="sps1" bitsize="64" type="int"/>
+  <reg name="gps1" bitsize="64" type="int"/>
+  <reg name="tps1" bitsize="64" type="int"/>
+  <reg name="t0s1" bitsize="64" type="int"/>
+  <reg name="t1s1" bitsize="64" type="int"/>
+  <reg name="t2s1" bitsize="64" type="int"/>
+  <reg name="fps1" bitsize="64" type="int"/>
+  <reg name="s1s1" bitsize="64" type="int"/>
+  <reg name="a0s1" bitsize="64" type="int"/>
+  <reg name="a1s1" bitsize="64" type="int"/>
+  <reg name="a2s1" bitsize="64" type="int"/>
+  <reg name="a3s1" bitsize="64" type="int"/>
+  <reg name="a4s1" bitsize="64" type="int"/>
+  <reg name="a5s1" bitsize="64" type="int"/>
+  <reg name="a6s1" bitsize="64" type="int"/>
+  <reg name="a7s1" bitsize="64" type="int"/>
+  <reg name="s2s1" bitsize="64" type="int"/>
+  <reg name="s3s1" bitsize="64" type="int"/>
+  <reg name="s4s1" bitsize="64" type="int"/>
+  <reg name="s5s1" bitsize="64" type="int"/>
+  <reg name="s6s1" bitsize="64" type="int"/>
+  <reg name="s7s1" bitsize="64" type="int"/>
+  <reg name="s8s1" bitsize="64" type="int"/>
+  <reg name="s9s1" bitsize="64" type="int"/>
+  <reg name="s10s1" bitsize="64" type="int"/>
+  <reg name="s11s1" bitsize="64" type="int"/>
+  <reg name="t3s1" bitsize="64" type="int"/>
+  <reg name="t4s1" bitsize="64" type="int"/>
+  <reg name="t5s1" bitsize="64" type="int"/>
+  <reg name="t6s1" bitsize="64" type="int"/>
+  <reg name="pcs1" bitsize="64" type="int"/>
+</feature>
diff --git a/coregrind/m_gdbserver/riscv64-cpu-valgrind-s2.xml b/coregrind/m_gdbserver/riscv64-cpu-valgrind-s2.xml
new file mode 100644 (file)
index 0000000..095a992
--- /dev/null
@@ -0,0 +1,43 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2018-2022 Free Software Foundation, Inc.
+
+     Copying and distribution of this file, with or without modification,
+     are permitted in any medium without royalty provided the copyright
+     notice and this notice are preserved.  -->
+
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<feature name="org.gnu.gdb.riscv.cpu.valgrind.s2">
+  <reg name="zeros2" bitsize="64" type="int" regnum="138"/>
+  <reg name="ras2" bitsize="64" type="int"/>
+  <reg name="sps2" bitsize="64" type="int"/>
+  <reg name="gps2" bitsize="64" type="int"/>
+  <reg name="tps2" bitsize="64" type="int"/>
+  <reg name="t0s2" bitsize="64" type="int"/>
+  <reg name="t1s2" bitsize="64" type="int"/>
+  <reg name="t2s2" bitsize="64" type="int"/>
+  <reg name="fps2" bitsize="64" type="int"/>
+  <reg name="s1s2" bitsize="64" type="int"/>
+  <reg name="a0s2" bitsize="64" type="int"/>
+  <reg name="a1s2" bitsize="64" type="int"/>
+  <reg name="a2s2" bitsize="64" type="int"/>
+  <reg name="a3s2" bitsize="64" type="int"/>
+  <reg name="a4s2" bitsize="64" type="int"/>
+  <reg name="a5s2" bitsize="64" type="int"/>
+  <reg name="a6s2" bitsize="64" type="int"/>
+  <reg name="a7s2" bitsize="64" type="int"/>
+  <reg name="s2s2" bitsize="64" type="int"/>
+  <reg name="s3s2" bitsize="64" type="int"/>
+  <reg name="s4s2" bitsize="64" type="int"/>
+  <reg name="s5s2" bitsize="64" type="int"/>
+  <reg name="s6s2" bitsize="64" type="int"/>
+  <reg name="s7s2" bitsize="64" type="int"/>
+  <reg name="s8s2" bitsize="64" type="int"/>
+  <reg name="s9s2" bitsize="64" type="int"/>
+  <reg name="s10s2" bitsize="64" type="int"/>
+  <reg name="s11s2" bitsize="64" type="int"/>
+  <reg name="t3s2" bitsize="64" type="int"/>
+  <reg name="t4s2" bitsize="64" type="int"/>
+  <reg name="t5s2" bitsize="64" type="int"/>
+  <reg name="t6s2" bitsize="64" type="int"/>
+  <reg name="pcs2" bitsize="64" type="int"/>
+</feature>
diff --git a/coregrind/m_gdbserver/riscv64-cpu.xml b/coregrind/m_gdbserver/riscv64-cpu.xml
new file mode 100644 (file)
index 0000000..2d31a6e
--- /dev/null
@@ -0,0 +1,47 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2018-2022 Free Software Foundation, Inc.
+
+     Copying and distribution of this file, with or without modification,
+     are permitted in any medium without royalty provided the copyright
+     notice and this notice are preserved.  -->
+
+<!-- Register numbers are hard-coded in order to maintain backward
+     compatibility with older versions of tools that didn't use xml
+     register descriptions.  -->
+
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<feature name="org.gnu.gdb.riscv.cpu">
+  <reg name="zero" bitsize="64" type="int" regnum="0"/>
+  <reg name="ra" bitsize="64" type="code_ptr"/>
+  <reg name="sp" bitsize="64" type="data_ptr"/>
+  <reg name="gp" bitsize="64" type="data_ptr"/>
+  <reg name="tp" bitsize="64" type="data_ptr"/>
+  <reg name="t0" bitsize="64" type="int"/>
+  <reg name="t1" bitsize="64" type="int"/>
+  <reg name="t2" bitsize="64" type="int"/>
+  <reg name="fp" bitsize="64" type="data_ptr"/>
+  <reg name="s1" bitsize="64" type="int"/>
+  <reg name="a0" bitsize="64" type="int"/>
+  <reg name="a1" bitsize="64" type="int"/>
+  <reg name="a2" bitsize="64" type="int"/>
+  <reg name="a3" bitsize="64" type="int"/>
+  <reg name="a4" bitsize="64" type="int"/>
+  <reg name="a5" bitsize="64" type="int"/>
+  <reg name="a6" bitsize="64" type="int"/>
+  <reg name="a7" bitsize="64" type="int"/>
+  <reg name="s2" bitsize="64" type="int"/>
+  <reg name="s3" bitsize="64" type="int"/>
+  <reg name="s4" bitsize="64" type="int"/>
+  <reg name="s5" bitsize="64" type="int"/>
+  <reg name="s6" bitsize="64" type="int"/>
+  <reg name="s7" bitsize="64" type="int"/>
+  <reg name="s8" bitsize="64" type="int"/>
+  <reg name="s9" bitsize="64" type="int"/>
+  <reg name="s10" bitsize="64" type="int"/>
+  <reg name="s11" bitsize="64" type="int"/>
+  <reg name="t3" bitsize="64" type="int"/>
+  <reg name="t4" bitsize="64" type="int"/>
+  <reg name="t5" bitsize="64" type="int"/>
+  <reg name="t6" bitsize="64" type="int"/>
+  <reg name="pc" bitsize="64" type="code_ptr"/>
+</feature>
diff --git a/coregrind/m_gdbserver/riscv64-fpu-valgrind-s1.xml b/coregrind/m_gdbserver/riscv64-fpu-valgrind-s1.xml
new file mode 100644 (file)
index 0000000..263a3ff
--- /dev/null
@@ -0,0 +1,47 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2018-2022 Free Software Foundation, Inc.
+
+     Copying and distribution of this file, with or without modification,
+     are permitted in any medium without royalty provided the copyright
+     notice and this notice are preserved.  -->
+
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<feature name="org.gnu.gdb.riscv.fpu.valgrind.s1">
+
+  <reg name="ft0s1" bitsize="64" type="int" regnum="102"/>
+  <reg name="ft1s1" bitsize="64" type="int"/>
+  <reg name="ft2s1" bitsize="64" type="int"/>
+  <reg name="ft3s1" bitsize="64" type="int"/>
+  <reg name="ft4s1" bitsize="64" type="int"/>
+  <reg name="ft5s1" bitsize="64" type="int"/>
+  <reg name="ft6s1" bitsize="64" type="int"/>
+  <reg name="ft7s1" bitsize="64" type="int"/>
+  <reg name="fs0s1" bitsize="64" type="int"/>
+  <reg name="fs1s1" bitsize="64" type="int"/>
+  <reg name="fa0s1" bitsize="64" type="int"/>
+  <reg name="fa1s1" bitsize="64" type="int"/>
+  <reg name="fa2s1" bitsize="64" type="int"/>
+  <reg name="fa3s1" bitsize="64" type="int"/>
+  <reg name="fa4s1" bitsize="64" type="int"/>
+  <reg name="fa5s1" bitsize="64" type="int"/>
+  <reg name="fa6s1" bitsize="64" type="int"/>
+  <reg name="fa7s1" bitsize="64" type="int"/>
+  <reg name="fs2s1" bitsize="64" type="int"/>
+  <reg name="fs3s1" bitsize="64" type="int"/>
+  <reg name="fs4s1" bitsize="64" type="int"/>
+  <reg name="fs5s1" bitsize="64" type="int"/>
+  <reg name="fs6s1" bitsize="64" type="int"/>
+  <reg name="fs7s1" bitsize="64" type="int"/>
+  <reg name="fs8s1" bitsize="64" type="int"/>
+  <reg name="fs9s1" bitsize="64" type="int"/>
+  <reg name="fs10s1" bitsize="64" type="int"/>
+  <reg name="fs11s1" bitsize="64" type="int"/>
+  <reg name="ft8s1" bitsize="64" type="int"/>
+  <reg name="ft9s1" bitsize="64" type="int"/>
+  <reg name="ft10s1" bitsize="64" type="int"/>
+  <reg name="ft11s1" bitsize="64" type="int"/>
+
+  <reg name="fflagss1" bitsize="32" type="int" regnum="135"/>
+  <reg name="frms1" bitsize="32" type="int"/>
+  <reg name="fcsrs1" bitsize="32" type="int"/>
+</feature>
diff --git a/coregrind/m_gdbserver/riscv64-fpu-valgrind-s2.xml b/coregrind/m_gdbserver/riscv64-fpu-valgrind-s2.xml
new file mode 100644 (file)
index 0000000..1992c03
--- /dev/null
@@ -0,0 +1,47 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2018-2022 Free Software Foundation, Inc.
+
+     Copying and distribution of this file, with or without modification,
+     are permitted in any medium without royalty provided the copyright
+     notice and this notice are preserved.  -->
+
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<feature name="org.gnu.gdb.riscv.fpu.valgrind.s2">
+
+  <reg name="ft0s2" bitsize="64" type="int" regnum="171"/>
+  <reg name="ft1s2" bitsize="64" type="int"/>
+  <reg name="ft2s2" bitsize="64" type="int"/>
+  <reg name="ft3s2" bitsize="64" type="int"/>
+  <reg name="ft4s2" bitsize="64" type="int"/>
+  <reg name="ft5s2" bitsize="64" type="int"/>
+  <reg name="ft6s2" bitsize="64" type="int"/>
+  <reg name="ft7s2" bitsize="64" type="int"/>
+  <reg name="fs0s2" bitsize="64" type="int"/>
+  <reg name="fs1s2" bitsize="64" type="int"/>
+  <reg name="fa0s2" bitsize="64" type="int"/>
+  <reg name="fa1s2" bitsize="64" type="int"/>
+  <reg name="fa2s2" bitsize="64" type="int"/>
+  <reg name="fa3s2" bitsize="64" type="int"/>
+  <reg name="fa4s2" bitsize="64" type="int"/>
+  <reg name="fa5s2" bitsize="64" type="int"/>
+  <reg name="fa6s2" bitsize="64" type="int"/>
+  <reg name="fa7s2" bitsize="64" type="int"/>
+  <reg name="fs2s2" bitsize="64" type="int"/>
+  <reg name="fs3s2" bitsize="64" type="int"/>
+  <reg name="fs4s2" bitsize="64" type="int"/>
+  <reg name="fs5s2" bitsize="64" type="int"/>
+  <reg name="fs6s2" bitsize="64" type="int"/>
+  <reg name="fs7s2" bitsize="64" type="int"/>
+  <reg name="fs8s2" bitsize="64" type="int"/>
+  <reg name="fs9s2" bitsize="64" type="int"/>
+  <reg name="fs10s2" bitsize="64" type="int"/>
+  <reg name="fs11s2" bitsize="64" type="int"/>
+  <reg name="ft8s2" bitsize="64" type="int"/>
+  <reg name="ft9s2" bitsize="64" type="int"/>
+  <reg name="ft10s2" bitsize="64" type="int"/>
+  <reg name="ft11s2" bitsize="64" type="int"/>
+
+  <reg name="fflagss2" bitsize="32" type="int" regnum="204"/>
+  <reg name="frms2" bitsize="32" type="int"/>
+  <reg name="fcsrs2" bitsize="32" type="int"/>
+</feature>
diff --git a/coregrind/m_gdbserver/riscv64-fpu.xml b/coregrind/m_gdbserver/riscv64-fpu.xml
new file mode 100644 (file)
index 0000000..ff42b4a
--- /dev/null
@@ -0,0 +1,56 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2018-2022 Free Software Foundation, Inc.
+
+     Copying and distribution of this file, with or without modification,
+     are permitted in any medium without royalty provided the copyright
+     notice and this notice are preserved.  -->
+
+<!-- Register numbers are hard-coded in order to maintain backward
+     compatibility with older versions of tools that didn't use xml
+     register descriptions.  -->
+
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<feature name="org.gnu.gdb.riscv.fpu">
+
+  <union id="riscv_double">
+    <field name="float" type="ieee_single"/>
+    <field name="double" type="ieee_double"/>
+  </union>
+
+  <reg name="ft0" bitsize="64" type="riscv_double" regnum="33"/>
+  <reg name="ft1" bitsize="64" type="riscv_double"/>
+  <reg name="ft2" bitsize="64" type="riscv_double"/>
+  <reg name="ft3" bitsize="64" type="riscv_double"/>
+  <reg name="ft4" bitsize="64" type="riscv_double"/>
+  <reg name="ft5" bitsize="64" type="riscv_double"/>
+  <reg name="ft6" bitsize="64" type="riscv_double"/>
+  <reg name="ft7" bitsize="64" type="riscv_double"/>
+  <reg name="fs0" bitsize="64" type="riscv_double"/>
+  <reg name="fs1" bitsize="64" type="riscv_double"/>
+  <reg name="fa0" bitsize="64" type="riscv_double"/>
+  <reg name="fa1" bitsize="64" type="riscv_double"/>
+  <reg name="fa2" bitsize="64" type="riscv_double"/>
+  <reg name="fa3" bitsize="64" type="riscv_double"/>
+  <reg name="fa4" bitsize="64" type="riscv_double"/>
+  <reg name="fa5" bitsize="64" type="riscv_double"/>
+  <reg name="fa6" bitsize="64" type="riscv_double"/>
+  <reg name="fa7" bitsize="64" type="riscv_double"/>
+  <reg name="fs2" bitsize="64" type="riscv_double"/>
+  <reg name="fs3" bitsize="64" type="riscv_double"/>
+  <reg name="fs4" bitsize="64" type="riscv_double"/>
+  <reg name="fs5" bitsize="64" type="riscv_double"/>
+  <reg name="fs6" bitsize="64" type="riscv_double"/>
+  <reg name="fs7" bitsize="64" type="riscv_double"/>
+  <reg name="fs8" bitsize="64" type="riscv_double"/>
+  <reg name="fs9" bitsize="64" type="riscv_double"/>
+  <reg name="fs10" bitsize="64" type="riscv_double"/>
+  <reg name="fs11" bitsize="64" type="riscv_double"/>
+  <reg name="ft8" bitsize="64" type="riscv_double"/>
+  <reg name="ft9" bitsize="64" type="riscv_double"/>
+  <reg name="ft10" bitsize="64" type="riscv_double"/>
+  <reg name="ft11" bitsize="64" type="riscv_double"/>
+
+  <reg name="fflags" bitsize="32" type="int" regnum="66"/>
+  <reg name="frm" bitsize="32" type="int" regnum="67"/>
+  <reg name="fcsr" bitsize="32" type="int" regnum="68"/>
+</feature>
diff --git a/coregrind/m_gdbserver/riscv64-linux-valgrind.xml b/coregrind/m_gdbserver/riscv64-linux-valgrind.xml
new file mode 100644 (file)
index 0000000..0227f2e
--- /dev/null
@@ -0,0 +1,21 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2018-2022 Free Software Foundation, Inc.
+
+     Copying and distribution of this file, with or without modification,
+     are permitted in any medium without royalty provided the copyright
+     notice and this notice are preserved.  -->
+
+<!DOCTYPE target SYSTEM "gdb-target.dtd">
+<target>
+  <architecture>riscv</architecture>
+  <xi:include href="riscv64-cpu.xml"/>
+  <xi:include href="riscv64-fpu.xml"/>
+  <xi:include href="riscv64-cpu-valgrind-s1.xml"/>
+  <xi:include href="riscv64-fpu-valgrind-s1.xml"/>
+  <xi:include href="riscv64-cpu-valgrind-s2.xml"/>
+  <xi:include href="riscv64-fpu-valgrind-s2.xml"/>
+
+  <feature name="org.gnu.gdb.riscv.linux">
+    <reg name="restart" bitsize="64" group="system"/>
+  </feature>
+</target>
\ No newline at end of file
diff --git a/coregrind/m_gdbserver/riscv64-linux.xml b/coregrind/m_gdbserver/riscv64-linux.xml
new file mode 100644 (file)
index 0000000..7c86312
--- /dev/null
@@ -0,0 +1,17 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2018-2022 Free Software Foundation, Inc.
+
+     Copying and distribution of this file, with or without modification,
+     are permitted in any medium without royalty provided the copyright
+     notice and this notice are preserved.  -->
+
+<!DOCTYPE target SYSTEM "gdb-target.dtd">
+<target>
+  <architecture>riscv</architecture>
+  <xi:include href="riscv64-cpu.xml"/>
+  <xi:include href="riscv64-fpu.xml"/>
+
+  <feature name="org.gnu.gdb.riscv.linux">
+    <reg name="restart" bitsize="64" group="system"/>
+  </feature>
+</target>
\ No newline at end of file
diff --git a/coregrind/m_gdbserver/valgrind-low-riscv64.c b/coregrind/m_gdbserver/valgrind-low-riscv64.c
new file mode 100644 (file)
index 0000000..75088fc
--- /dev/null
@@ -0,0 +1,287 @@
+/* Low level interface to valgrind, for the remote server for GDB integrated
+   in valgrind.
+   Copyright (C) 2022
+   Free Software Foundation, Inc.
+
+   This file is part of VALGRIND.
+   It has been inspired from a file from gdbserver in gdb 6.6.
+
+   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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.  */
+
+#include "server.h"
+#include "target.h"
+#include "regdef.h"
+#include "regcache.h"
+
+#include "pub_core_machine.h"
+#include "pub_core_threadstate.h"
+#include "pub_core_transtab.h"
+#include "pub_core_gdbserver.h"
+#include "pub_core_debuginfo.h"
+
+#include "valgrind_low.h"
+
+#include "libvex_guest_riscv64.h"
+
+/* from GDB gdb/features/riscv/64bit-{cpu,fpu}.c */
+static struct reg regs[] = {
+  { "zero", 0, 64 },
+  { "ra", 64, 64 },
+  { "sp", 128, 64 },
+  { "gp", 192, 64 },
+  { "tp", 256, 64 },
+  { "t0", 320, 64 },
+  { "t1", 384, 64 },
+  { "t2", 448, 64 },
+  { "fp", 512, 64 },
+  { "s1", 576, 64 },
+  { "a0", 640, 64 },
+  { "a1", 704, 64 },
+  { "a2", 768, 64 },
+  { "a3", 832, 64 },
+  { "a4", 896, 64 },
+  { "a5", 960, 64 },
+  { "a6", 1024, 64 },
+  { "a7", 1088, 64 },
+  { "s2", 1152, 64 },
+  { "s3", 1216, 64 },
+  { "s4", 1280, 64 },
+  { "s5", 1344, 64 },
+  { "s6", 1408, 64 },
+  { "s7", 1472, 64 },
+  { "s8", 1536, 64 },
+  { "s9", 1600, 64 },
+  { "s10", 1664, 64 },
+  { "s11", 1728, 64 },
+  { "t3", 1792, 64 },
+  { "t4", 1856, 64 },
+  { "t5", 1920, 64 },
+  { "t6", 1984, 64 },
+  { "pc", 2048, 64 },
+
+  { "ft0", 2112, 64 },
+  { "ft1", 2176, 64 },
+  { "ft2", 2240, 64 },
+  { "ft3", 2304, 64 },
+  { "ft4", 2368, 64 },
+  { "ft5", 2432, 64 },
+  { "ft6", 2496, 64 },
+  { "ft7", 2560, 64 },
+  { "fs0", 2624, 64 },
+  { "fs1", 2688, 64 },
+  { "fa0", 2752, 64 },
+  { "fa1", 2816, 64 },
+  { "fa2", 2880, 64 },
+  { "fa3", 2944, 64 },
+  { "fa4", 3008, 64 },
+  { "fa5", 3072, 64 },
+  { "fa6", 3136, 64 },
+  { "fa7", 3200, 64 },
+  { "fs2", 3264, 64 },
+  { "fs3", 3328, 64 },
+  { "fs4", 3392, 64 },
+  { "fs5", 3456, 64 },
+  { "fs6", 3520, 64 },
+  { "fs7", 3584, 64 },
+  { "fs8", 3648, 64 },
+  { "fs9", 3712, 64 },
+  { "fs10", 3776, 64 },
+  { "fs11", 3840, 64 },
+  { "ft8", 3904, 64 },
+  { "ft9", 3968, 64 },
+  { "ft10", 4032, 64 },
+  { "ft11", 4096, 64 },
+  { "", 4160, 0 },  /* regnums have a hole here */
+  { "fflags", 4160, 32 },
+  { "frm", 4192, 32 },
+  { "fcsr", 4224, 32 },
+};
+
+/* from GDB gdbserver/linux-riscv-low.cc */
+static const char *expedite_regs[] = { "sp", "pc", 0 };
+
+#define num_regs (sizeof (regs) / sizeof (regs[0]))
+
+static
+CORE_ADDR get_pc (void)
+{
+   unsigned long pc;
+
+   collect_register_by_name ("pc", &pc);
+
+   dlog(1, "stop pc is %p\n", (void *) pc);
+   return pc;
+}
+
+static
+void set_pc (CORE_ADDR newpc)
+{
+   supply_register_by_name ("pc", &newpc);
+}
+
+/* store registers in the guest state (gdbserver_to_valgrind)
+   or fetch register from the guest state (valgrind_to_gdbserver). */
+static
+void transfer_register (ThreadId tid, int abs_regno, void * buf,
+                        transfer_direction dir, int size, Bool *mod)
+{
+   ThreadState* tst = VG_(get_ThreadState)(tid);
+   int set = abs_regno / num_regs;
+   int regno = abs_regno % num_regs;
+   *mod = False;
+   UInt v, *p;
+
+   VexGuestRISCV64State* riscv = (VexGuestRISCV64State*) get_arch (set, tst);
+
+   switch (regno) {
+   // numbers here have to match the order of regs above
+   // Attention: gdb order does not match valgrind order.
+   case 0:  VG_(transfer) (&riscv->guest_x0,   buf, dir, size, mod); break;
+   case 1:  VG_(transfer) (&riscv->guest_x1,   buf, dir, size, mod); break;
+   case 2:  VG_(transfer) (&riscv->guest_x2,   buf, dir, size, mod); break;
+   case 3:  VG_(transfer) (&riscv->guest_x3,   buf, dir, size, mod); break;
+   case 4:  VG_(transfer) (&riscv->guest_x4,   buf, dir, size, mod); break;
+   case 5:  VG_(transfer) (&riscv->guest_x5,   buf, dir, size, mod); break;
+   case 6:  VG_(transfer) (&riscv->guest_x6,   buf, dir, size, mod); break;
+   case 7:  VG_(transfer) (&riscv->guest_x7,   buf, dir, size, mod); break;
+   case 8:  VG_(transfer) (&riscv->guest_x8,   buf, dir, size, mod); break;
+   case 9:  VG_(transfer) (&riscv->guest_x9,   buf, dir, size, mod); break;
+   case 10: VG_(transfer) (&riscv->guest_x10,  buf, dir, size, mod); break;
+   case 11: VG_(transfer) (&riscv->guest_x11,  buf, dir, size, mod); break;
+   case 12: VG_(transfer) (&riscv->guest_x12,  buf, dir, size, mod); break;
+   case 13: VG_(transfer) (&riscv->guest_x13,  buf, dir, size, mod); break;
+   case 14: VG_(transfer) (&riscv->guest_x14,  buf, dir, size, mod); break;
+   case 15: VG_(transfer) (&riscv->guest_x15,  buf, dir, size, mod); break;
+   case 16: VG_(transfer) (&riscv->guest_x16,  buf, dir, size, mod); break;
+   case 17: VG_(transfer) (&riscv->guest_x17,  buf, dir, size, mod); break;
+   case 18: VG_(transfer) (&riscv->guest_x18,  buf, dir, size, mod); break;
+   case 19: VG_(transfer) (&riscv->guest_x19,  buf, dir, size, mod); break;
+   case 20: VG_(transfer) (&riscv->guest_x20,  buf, dir, size, mod); break;
+   case 21: VG_(transfer) (&riscv->guest_x21,  buf, dir, size, mod); break;
+   case 22: VG_(transfer) (&riscv->guest_x22,  buf, dir, size, mod); break;
+   case 23: VG_(transfer) (&riscv->guest_x23,  buf, dir, size, mod); break;
+   case 24: VG_(transfer) (&riscv->guest_x24,  buf, dir, size, mod); break;
+   case 25: VG_(transfer) (&riscv->guest_x25,  buf, dir, size, mod); break;
+   case 26: VG_(transfer) (&riscv->guest_x26,  buf, dir, size, mod); break;
+   case 27: VG_(transfer) (&riscv->guest_x27,  buf, dir, size, mod); break;
+   case 28: VG_(transfer) (&riscv->guest_x28,  buf, dir, size, mod); break;
+   case 29: VG_(transfer) (&riscv->guest_x29,  buf, dir, size, mod); break;
+   case 30: VG_(transfer) (&riscv->guest_x30,  buf, dir, size, mod); break;
+   case 31: VG_(transfer) (&riscv->guest_x31,  buf, dir, size, mod); break;
+   case 32: VG_(transfer) (&riscv->guest_pc,   buf, dir, size, mod); break;
+
+   case 33: VG_(transfer) (&riscv->guest_f0,   buf, dir, size, mod); break;
+   case 34: VG_(transfer) (&riscv->guest_f1,   buf, dir, size, mod); break;
+   case 35: VG_(transfer) (&riscv->guest_f2,   buf, dir, size, mod); break;
+   case 36: VG_(transfer) (&riscv->guest_f3,   buf, dir, size, mod); break;
+   case 37: VG_(transfer) (&riscv->guest_f4,   buf, dir, size, mod); break;
+   case 38: VG_(transfer) (&riscv->guest_f5,   buf, dir, size, mod); break;
+   case 39: VG_(transfer) (&riscv->guest_f6,   buf, dir, size, mod); break;
+   case 40: VG_(transfer) (&riscv->guest_f7,   buf, dir, size, mod); break;
+   case 41: VG_(transfer) (&riscv->guest_f8,   buf, dir, size, mod); break;
+   case 42: VG_(transfer) (&riscv->guest_f9,   buf, dir, size, mod); break;
+   case 43: VG_(transfer) (&riscv->guest_f10,  buf, dir, size, mod); break;
+   case 44: VG_(transfer) (&riscv->guest_f11,  buf, dir, size, mod); break;
+   case 45: VG_(transfer) (&riscv->guest_f12,  buf, dir, size, mod); break;
+   case 46: VG_(transfer) (&riscv->guest_f13,  buf, dir, size, mod); break;
+   case 47: VG_(transfer) (&riscv->guest_f14,  buf, dir, size, mod); break;
+   case 48: VG_(transfer) (&riscv->guest_f15,  buf, dir, size, mod); break;
+   case 49: VG_(transfer) (&riscv->guest_f16,  buf, dir, size, mod); break;
+   case 50: VG_(transfer) (&riscv->guest_f17,  buf, dir, size, mod); break;
+   case 51: VG_(transfer) (&riscv->guest_f18,  buf, dir, size, mod); break;
+   case 52: VG_(transfer) (&riscv->guest_f19,  buf, dir, size, mod); break;
+   case 53: VG_(transfer) (&riscv->guest_f20,  buf, dir, size, mod); break;
+   case 54: VG_(transfer) (&riscv->guest_f21,  buf, dir, size, mod); break;
+   case 55: VG_(transfer) (&riscv->guest_f22,  buf, dir, size, mod); break;
+   case 56: VG_(transfer) (&riscv->guest_f23,  buf, dir, size, mod); break;
+   case 57: VG_(transfer) (&riscv->guest_f24,  buf, dir, size, mod); break;
+   case 58: VG_(transfer) (&riscv->guest_f25,  buf, dir, size, mod); break;
+   case 59: VG_(transfer) (&riscv->guest_f26,  buf, dir, size, mod); break;
+   case 60: VG_(transfer) (&riscv->guest_f27,  buf, dir, size, mod); break;
+   case 61: VG_(transfer) (&riscv->guest_f28,  buf, dir, size, mod); break;
+   case 62: VG_(transfer) (&riscv->guest_f29,  buf, dir, size, mod); break;
+   case 63: VG_(transfer) (&riscv->guest_f30,  buf, dir, size, mod); break;
+   case 64: VG_(transfer) (&riscv->guest_f31,  buf, dir, size, mod); break;
+
+   case 65: break;
+
+   case 66: /* fflags = fcsr & 0x1F */
+        p = &riscv->guest_fcsr;
+        if (dir == valgrind_to_gdbserver)
+            v = *p & 0x1F;
+        VG_(transfer) (&v, buf, dir, size, mod);
+        if (dir == gdbserver_to_valgrind)
+            *p = (*p & ~0x1F) | v;
+        break;
+
+   case 67: /* frm = (fcsr & 0xE0) >> 5 */
+        p = &riscv->guest_fcsr;
+        if (dir == valgrind_to_gdbserver)
+            v = (*p & 0xE0) >> 5;
+        VG_(transfer) (&v, buf, dir, size, mod);
+        if (dir == gdbserver_to_valgrind)
+            *p = (*p & ~0xE0) | (v << 5);
+        break;
+
+   case 68: VG_(transfer) (&riscv->guest_fcsr, buf, dir, size, mod); break;
+   default: vg_assert(0);
+   }
+}
+
+static
+const char* target_xml (Bool shadow_mode)
+{
+   if (shadow_mode) {
+      return "riscv64-linux-valgrind.xml";
+   } else {
+      return "riscv64-linux.xml";
+   }
+}
+
+static CORE_ADDR** target_get_dtv (ThreadState *tst)
+{
+   VexGuestRISCV64State* riscv = (VexGuestRISCV64State*)&tst->arch.vex;
+
+   /* RISC-V uses Variant I as described by the ELF TLS specification,
+      with tp containing the address one past the end of the TCB.
+
+      from GLIBC sysdeps/riscv/nptl/tls.h, tp is just after tcbhead_t
+        typedef struct {
+            dtv_t *dtv;
+            void *private;
+        } tcbhead_t;
+   */
+   return (CORE_ADDR**)(void *)(riscv->guest_x4 - 2 * sizeof(void *));
+}
+
+static struct valgrind_target_ops low_target = {
+   num_regs,
+   2, //SP
+   regs,
+   transfer_register,
+   get_pc,
+   set_pc,
+   "riscv64",
+   target_xml,
+   target_get_dtv
+};
+
+void riscv64_init_architecture (struct valgrind_target_ops *target)
+{
+   *target = low_target;
+   set_register_cache (regs, num_regs);
+   gdbserver_expedite_regs = expedite_regs;
+}
diff --git a/coregrind/m_sigframe/sigframe-riscv64-linux.c b/coregrind/m_sigframe/sigframe-riscv64-linux.c
new file mode 100644 (file)
index 0000000..8ef0540
--- /dev/null
@@ -0,0 +1,422 @@
+
+/*--------------------------------------------------------------------*/
+/*--- Create/destroy signal delivery frames.                       ---*/
+/*---                                     sigframe-riscv64-linux.c ---*/
+/*--------------------------------------------------------------------*/
+
+/*
+   This file is part of Valgrind, a dynamic binary instrumentation
+   framework.
+
+   Copyright (C) 2020-2023 Petr Pavlu
+      petr.pavlu@dagobah.cz
+
+   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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, see <http://www.gnu.org/licenses/>.
+
+   The GNU General Public License is contained in the file COPYING.
+*/
+
+#if defined(VGP_riscv64_linux)
+
+#include "libvex_guest_offsets.h"
+#include "priv_sigframe.h"
+#include "pub_core_aspacemgr.h"
+#include "pub_core_basics.h"
+#include "pub_core_libcassert.h"
+#include "pub_core_libcbase.h"
+#include "pub_core_libcprint.h"
+#include "pub_core_machine.h"
+#include "pub_core_options.h"
+#include "pub_core_sigframe.h"
+#include "pub_core_signals.h"
+#include "pub_core_threadstate.h"
+#include "pub_core_tooliface.h"
+#include "pub_core_trampoline.h"
+#include "pub_core_vki.h"
+
+/*------------------------------------------------------------*/
+/*--- Signal frame layout                                  ---*/
+/*------------------------------------------------------------*/
+
+/* Valgrind-specific parts of the signal frame. */
+struct vg_sigframe {
+   /* Sanity check word. */
+   UInt magicPI;
+
+   /* Safely-saved version of sigNo. */
+   Int sigNo_private;
+
+   /* Sanity check word. */
+   UInt magicE;
+};
+
+/* Complete signal frame. */
+struct rt_sigframe {
+   struct vki_siginfo  info;
+   struct vki_ucontext uc;
+   struct vg_sigframe  vg;
+};
+
+/*------------------------------------------------------------*/
+/*--- Creating a signal frame                              ---*/
+/*------------------------------------------------------------*/
+
+static void synth_ucontext(ThreadState*         tst,
+                           const vki_siginfo_t* si,
+                           const vki_sigset_t*  set,
+                           struct vki_ucontext* uc)
+{
+   VG_(memset)(uc, 0, sizeof(*uc));
+
+   /* Prepare common data. */
+   uc->uc_flags = 0;
+   VG_TRACK(post_mem_write, Vg_CoreSignal, tst->tid, (Addr)&uc->uc_flags,
+            sizeof(uc->uc_flags));
+   uc->uc_link = 0;
+   VG_TRACK(post_mem_write, Vg_CoreSignal, tst->tid, (Addr)&uc->uc_link,
+            sizeof(uc->uc_link));
+   uc->uc_sigmask = *set;
+   VG_TRACK(post_mem_write, Vg_CoreSignal, tst->tid, (Addr)&uc->uc_sigmask,
+            sizeof(uc->uc_sigmask));
+   uc->uc_stack = tst->altstack;
+   VG_TRACK(post_mem_write, Vg_CoreSignal, tst->tid, (Addr)&uc->uc_stack,
+            sizeof(uc->uc_stack));
+
+   struct vki_sigcontext* sc = &uc->uc_mcontext;
+
+   /* Save integer registers. */
+#define IREG_TO_CTX(ureg, vreg)                                                \
+   sc->sc_regs.ureg = tst->arch.vex.guest_##vreg;                              \
+   VG_TRACK(copy_reg_to_mem, Vg_CoreSignal, tst->tid, OFFSET_riscv64_##vreg,   \
+            (Addr)&sc->sc_regs.ureg, sizeof(UWord));
+   IREG_TO_CTX(pc, pc);
+   IREG_TO_CTX(ra, x1);
+   IREG_TO_CTX(sp, x2);
+   IREG_TO_CTX(gp, x3);
+   IREG_TO_CTX(tp, x4);
+   IREG_TO_CTX(t0, x5);
+   IREG_TO_CTX(t1, x6);
+   IREG_TO_CTX(t2, x7);
+   IREG_TO_CTX(s0, x8);
+   IREG_TO_CTX(s1, x9);
+   IREG_TO_CTX(a0, x10);
+   IREG_TO_CTX(a1, x11);
+   IREG_TO_CTX(a2, x12);
+   IREG_TO_CTX(a3, x13);
+   IREG_TO_CTX(a4, x14);
+   IREG_TO_CTX(a5, x15);
+   IREG_TO_CTX(a6, x16);
+   IREG_TO_CTX(a7, x17);
+   IREG_TO_CTX(s2, x18);
+   IREG_TO_CTX(s3, x19);
+   IREG_TO_CTX(s4, x20);
+   IREG_TO_CTX(s5, x21);
+   IREG_TO_CTX(s6, x22);
+   IREG_TO_CTX(s7, x23);
+   IREG_TO_CTX(s8, x24);
+   IREG_TO_CTX(s9, x25);
+   IREG_TO_CTX(s10, x26);
+   IREG_TO_CTX(s11, x27);
+   IREG_TO_CTX(t3, x28);
+   IREG_TO_CTX(t4, x29);
+   IREG_TO_CTX(t5, x30);
+   IREG_TO_CTX(t6, x31);
+#undef IREG_TO_CTX
+
+   /* Save floating point registers. */
+#define FREG_TO_CTX(ureg, vreg, type)                                          \
+   sc->sc_fpregs.d.ureg = tst->arch.vex.guest_##vreg;                          \
+   VG_TRACK(copy_reg_to_mem, Vg_CoreSignal, tst->tid, OFFSET_riscv64_##vreg,   \
+            (Addr)&sc->sc_fpregs.d.ureg, sizeof(type));
+   FREG_TO_CTX(f[0], f0, UWord);
+   FREG_TO_CTX(f[1], f1, UWord);
+   FREG_TO_CTX(f[2], f2, UWord);
+   FREG_TO_CTX(f[3], f3, UWord);
+   FREG_TO_CTX(f[4], f4, UWord);
+   FREG_TO_CTX(f[5], f5, UWord);
+   FREG_TO_CTX(f[6], f6, UWord);
+   FREG_TO_CTX(f[7], f7, UWord);
+   FREG_TO_CTX(f[8], f8, UWord);
+   FREG_TO_CTX(f[9], f9, UWord);
+   FREG_TO_CTX(f[10], f10, UWord);
+   FREG_TO_CTX(f[11], f11, UWord);
+   FREG_TO_CTX(f[12], f12, UWord);
+   FREG_TO_CTX(f[13], f13, UWord);
+   FREG_TO_CTX(f[14], f14, UWord);
+   FREG_TO_CTX(f[15], f15, UWord);
+   FREG_TO_CTX(f[16], f16, UWord);
+   FREG_TO_CTX(f[17], f17, UWord);
+   FREG_TO_CTX(f[18], f18, UWord);
+   FREG_TO_CTX(f[19], f19, UWord);
+   FREG_TO_CTX(f[20], f20, UWord);
+   FREG_TO_CTX(f[21], f21, UWord);
+   FREG_TO_CTX(f[22], f22, UWord);
+   FREG_TO_CTX(f[23], f23, UWord);
+   FREG_TO_CTX(f[24], f24, UWord);
+   FREG_TO_CTX(f[25], f25, UWord);
+   FREG_TO_CTX(f[26], f26, UWord);
+   FREG_TO_CTX(f[27], f27, UWord);
+   FREG_TO_CTX(f[28], f28, UWord);
+   FREG_TO_CTX(f[29], f29, UWord);
+   FREG_TO_CTX(f[30], f30, UWord);
+   FREG_TO_CTX(f[31], f31, UWord);
+   FREG_TO_CTX(fcsr, fcsr, UInt);
+#undef FREG_TO_CTX
+}
+
+/* Build the Valgrind-specific part of a signal frame. */
+static void build_vg_sigframe(struct vg_sigframe* frame, Int sigNo)
+{
+   frame->magicPI       = 0x31415927;
+   frame->sigNo_private = sigNo;
+   frame->magicE        = 0x27182818;
+}
+
+static Addr build_rt_sigframe(ThreadState*         tst,
+                              Addr                 sp_top_of_frame,
+                              const vki_siginfo_t* siginfo,
+                              UInt                 flags,
+                              const vki_sigset_t*  mask)
+{
+   SizeT size = sizeof(struct rt_sigframe);
+   Addr  sp   = VG_ROUNDDN(sp_top_of_frame - size, 16);
+
+   if (!ML_(sf_maybe_extend_stack)(tst, sp, size, flags))
+      return sp_top_of_frame;
+
+   /* Tell the tools that the sigframe is to be written. */
+   VG_TRACK(pre_mem_write, Vg_CoreSignal, tst->tid, "signal handler frame", sp,
+            sizeof(struct rt_sigframe));
+
+   struct rt_sigframe* frame = (struct rt_sigframe*)sp;
+
+   /* Fill in the siginfo. */
+   frame->info = *siginfo;
+
+   /* SIGILL defines addr to be the faulting address. */
+   Int sigNo = siginfo->si_signo;
+   if (sigNo == VKI_SIGILL && siginfo->si_code > 0)
+      frame->info._sifields._sigfault._addr = (void*)VG_(get_IP)(tst->tid);
+
+   VG_TRACK(post_mem_write, Vg_CoreSignal, tst->tid, (Addr)&frame->info,
+            sizeof(frame->info));
+
+   /* Fill in the ucontext. */
+   synth_ucontext(tst, siginfo, mask, &frame->uc);
+
+   /* Fill in the Valgrind-specific part. */
+   build_vg_sigframe(&frame->vg, sigNo);
+
+   return sp;
+}
+
+void VG_(sigframe_create)(ThreadId                   tid,
+                          Bool                       on_altstack,
+                          Addr                       rsp_top_of_frame,
+                          const vki_siginfo_t*       siginfo,
+                          const struct vki_ucontext* siguc,
+                          void*                      handler,
+                          UInt                       flags,
+                          const vki_sigset_t*        mask,
+                          void*                      restorer)
+{
+   /* The restorer functionality (SA_RESTORER) is not used on riscv64-linux. */
+   vg_assert(restorer == NULL);
+
+   ThreadState* tst = VG_(get_ThreadState)(tid);
+
+   /* Build the signal frame on the stack. */
+   Addr sp = build_rt_sigframe(tst, rsp_top_of_frame, siginfo, flags, mask);
+   struct rt_sigframe* frame = (struct rt_sigframe*)sp;
+
+   /* Configure guest registers for the signal delivery. */
+   VG_(set_SP)(tid, sp);
+   VG_TRACK(post_reg_write, Vg_CoreSignal, tid, VG_O_STACK_PTR, sizeof(UWord));
+
+   tst->arch.vex.guest_x10 = siginfo->si_signo;
+   VG_TRACK(post_reg_write, Vg_CoreSignal, tst->tid, OFFSET_riscv64_x10,
+            sizeof(UWord));
+   tst->arch.vex.guest_x11 = (Addr)&frame->info;
+   VG_TRACK(post_reg_write, Vg_CoreSignal, tst->tid, OFFSET_riscv64_x11,
+            sizeof(UWord));
+   tst->arch.vex.guest_x12 = (Addr)&frame->uc;
+   VG_TRACK(post_reg_write, Vg_CoreSignal, tst->tid, OFFSET_riscv64_x12,
+            sizeof(UWord));
+
+   tst->arch.vex.guest_x1 = (Addr)&VG_(riscv64_linux_SUBST_FOR_rt_sigreturn);
+   VG_TRACK(post_reg_write, Vg_CoreSignal, tst->tid, OFFSET_riscv64_x1,
+            sizeof(UWord));
+
+   /* Set up the program counter. Note that it is not necessary to inform the
+      tools about this write because pc is always defined. */
+   VG_(set_IP)(tid, (Addr)handler);
+
+   if (VG_(clo_trace_signals))
+      VG_(message)(Vg_DebugMsg,
+                   "sigframe_create (thread %u): next pc=%#lx, next sp=%#lx\n",
+                   tid, (Addr)handler, sp);
+}
+
+/*------------------------------------------------------------*/
+/*--- Destroying a signal frame                            ---*/
+/*------------------------------------------------------------*/
+
+/* Restore the Valgrind-specific part of a signal frame. The returned value
+   indicates whether the frame is valid. If not then nothing is restored and the
+   client is set to take a segfault. */
+static Bool
+restore_vg_sigframe(ThreadState* tst, struct vg_sigframe* frame, Int* sigNo)
+{
+   if (frame->magicPI != 0x31415927 || frame->magicE != 0x27182818) {
+      VG_(message)(
+         Vg_UserMsg,
+         "Thread %u return signal frame corrupted. Killing process.\n",
+         tst->tid);
+      VG_(set_default_handler)(VKI_SIGSEGV);
+      VG_(synth_fault)(tst->tid);
+      *sigNo = VKI_SIGSEGV;
+      return False;
+   }
+   *sigNo = frame->sigNo_private;
+   return True;
+}
+
+static void restore_ucontext(ThreadState* tst, struct vki_ucontext* uc)
+{
+   /* Restore common data. */
+   VG_TRACK(pre_mem_read, Vg_CoreSignal, tst->tid, "signal frame mask",
+            (Addr)&uc->uc_sigmask, sizeof(uc->uc_sigmask));
+   tst->sig_mask     = uc->uc_sigmask;
+   tst->tmp_sig_mask = tst->sig_mask;
+
+   struct vki_sigcontext* sc = &uc->uc_mcontext;
+
+   /* Restore integer registers. */
+#define IREG_FROM_CTX(ureg, vreg)                                              \
+   tst->arch.vex.guest_##vreg = sc->sc_regs.ureg;                              \
+   VG_TRACK(copy_mem_to_reg, Vg_CoreSignal, tst->tid, (Addr)&sc->sc_regs.ureg, \
+            OFFSET_riscv64_##vreg, sizeof(UWord));
+   IREG_FROM_CTX(pc, pc);
+   IREG_FROM_CTX(ra, x1);
+   IREG_FROM_CTX(sp, x2);
+   IREG_FROM_CTX(gp, x3);
+   IREG_FROM_CTX(tp, x4);
+   IREG_FROM_CTX(t0, x5);
+   IREG_FROM_CTX(t1, x6);
+   IREG_FROM_CTX(t2, x7);
+   IREG_FROM_CTX(s0, x8);
+   IREG_FROM_CTX(s1, x9);
+   IREG_FROM_CTX(a0, x10);
+   IREG_FROM_CTX(a1, x11);
+   IREG_FROM_CTX(a2, x12);
+   IREG_FROM_CTX(a3, x13);
+   IREG_FROM_CTX(a4, x14);
+   IREG_FROM_CTX(a5, x15);
+   IREG_FROM_CTX(a6, x16);
+   IREG_FROM_CTX(a7, x17);
+   IREG_FROM_CTX(s2, x18);
+   IREG_FROM_CTX(s3, x19);
+   IREG_FROM_CTX(s4, x20);
+   IREG_FROM_CTX(s5, x21);
+   IREG_FROM_CTX(s6, x22);
+   IREG_FROM_CTX(s7, x23);
+   IREG_FROM_CTX(s8, x24);
+   IREG_FROM_CTX(s9, x25);
+   IREG_FROM_CTX(s10, x26);
+   IREG_FROM_CTX(s11, x27);
+   IREG_FROM_CTX(t3, x28);
+   IREG_FROM_CTX(t4, x29);
+   IREG_FROM_CTX(t5, x30);
+   IREG_FROM_CTX(t6, x31);
+#undef IREG_FROM_CTX
+
+   /* Restore floating point registers. */
+#define FREG_FROM_CTX(ureg, vreg, type)                                        \
+   tst->arch.vex.guest_##vreg = sc->sc_fpregs.d.ureg;                          \
+   VG_TRACK(copy_mem_to_reg, Vg_CoreSignal, tst->tid,                          \
+            (Addr)&sc->sc_fpregs.d.ureg, OFFSET_riscv64_##vreg, sizeof(type));
+   FREG_FROM_CTX(f[0], f0, UWord);
+   FREG_FROM_CTX(f[1], f1, UWord);
+   FREG_FROM_CTX(f[2], f2, UWord);
+   FREG_FROM_CTX(f[3], f3, UWord);
+   FREG_FROM_CTX(f[4], f4, UWord);
+   FREG_FROM_CTX(f[5], f5, UWord);
+   FREG_FROM_CTX(f[6], f6, UWord);
+   FREG_FROM_CTX(f[7], f7, UWord);
+   FREG_FROM_CTX(f[8], f8, UWord);
+   FREG_FROM_CTX(f[9], f9, UWord);
+   FREG_FROM_CTX(f[10], f10, UWord);
+   FREG_FROM_CTX(f[11], f11, UWord);
+   FREG_FROM_CTX(f[12], f12, UWord);
+   FREG_FROM_CTX(f[13], f13, UWord);
+   FREG_FROM_CTX(f[14], f14, UWord);
+   FREG_FROM_CTX(f[15], f15, UWord);
+   FREG_FROM_CTX(f[16], f16, UWord);
+   FREG_FROM_CTX(f[17], f17, UWord);
+   FREG_FROM_CTX(f[18], f18, UWord);
+   FREG_FROM_CTX(f[19], f19, UWord);
+   FREG_FROM_CTX(f[20], f20, UWord);
+   FREG_FROM_CTX(f[21], f21, UWord);
+   FREG_FROM_CTX(f[22], f22, UWord);
+   FREG_FROM_CTX(f[23], f23, UWord);
+   FREG_FROM_CTX(f[24], f24, UWord);
+   FREG_FROM_CTX(f[25], f25, UWord);
+   FREG_FROM_CTX(f[26], f26, UWord);
+   FREG_FROM_CTX(f[27], f27, UWord);
+   FREG_FROM_CTX(f[28], f28, UWord);
+   FREG_FROM_CTX(f[29], f29, UWord);
+   FREG_FROM_CTX(f[30], f30, UWord);
+   FREG_FROM_CTX(f[31], f31, UWord);
+   FREG_FROM_CTX(fcsr, fcsr, UInt);
+#undef FREG_FROM_CTX
+}
+
+static void
+restore_rt_sigframe(ThreadState* tst, struct rt_sigframe* frame, Int* sigNo)
+{
+   if (restore_vg_sigframe(tst, &frame->vg, sigNo))
+      restore_ucontext(tst, &frame->uc);
+}
+
+void VG_(sigframe_destroy)(ThreadId tid, Bool isRT)
+{
+   /* Non-rt sigreturn does not exist on riscv64-linux. */
+   vg_assert(isRT);
+
+   ThreadState* tst = VG_(get_ThreadState)(tid);
+
+   /* Correctly reestablish the frame base address. */
+   Addr sp = VG_(get_SP)(tid);
+
+   /* Restore a state from the signal frame. */
+   Int sigNo;
+   restore_rt_sigframe(tst, (struct rt_sigframe*)sp, &sigNo);
+
+   VG_TRACK(die_mem_stack_signal, sp - VG_STACK_REDZONE_SZB,
+            sizeof(struct rt_sigframe) + VG_STACK_REDZONE_SZB);
+
+   /* Returning from a signal handler. */
+   if (VG_(clo_trace_signals))
+      VG_(message)(Vg_DebugMsg, "sigframe_return (thread %u): pc=%#lx\n", tid,
+                   VG_(get_IP)(tid));
+
+   /* Tell the tools. */
+   VG_TRACK(post_deliver_signal, tid, sigNo);
+}
+
+#endif // defined(VGP_riscv64_linux)
+
+/*--------------------------------------------------------------------*/
+/*--- end                                 sigframe-riscv64-linux.c ---*/
+/*--------------------------------------------------------------------*/
diff --git a/coregrind/m_syswrap/syscall-riscv64-linux.S b/coregrind/m_syswrap/syscall-riscv64-linux.S
new file mode 100644 (file)
index 0000000..cf976ce
--- /dev/null
@@ -0,0 +1,198 @@
+
+/*--------------------------------------------------------------------*/
+/*--- Support for doing system calls.      syscall-riscv64-linux.S ---*/
+/*--------------------------------------------------------------------*/
+
+/*
+  This file is part of Valgrind, a dynamic binary instrumentation
+  framework.
+
+  Copyright (C) 2020-2023 Petr Pavlu
+      petr.pavlu@dagobah.cz
+
+  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.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+
+  The GNU General Public License is contained in the file COPYING.
+*/
+
+#include "pub_core_basics_asm.h"
+
+#if defined(VGP_riscv64_linux)
+
+#include "pub_core_vkiscnums_asm.h"
+#include "libvex_guest_offsets.h"
+
+
+/*----------------------------------------------------------------*/
+/*
+        Perform a syscall for the client.  This will run a syscall
+        with the client's specific per-thread signal mask.
+
+        The structure of this function is such that, if the syscall is
+        interrupted by a signal, we can determine exactly what
+        execution state we were in with respect to the execution of
+        the syscall by examining the value of pc in the signal
+        handler.  This means that we can always do the appropriate
+        thing to precisely emulate the kernel's signal/syscall
+        interactions.
+
+        The syscall number is taken from the argument, even though it
+        should also be in guest_state->guest_x17.  The syscall result
+        is written back to guest_state->guest_x10 on completion.
+
+        Returns 0 if the syscall was successfully called (even if the
+        syscall itself failed), or a nonzero error code in the lowest
+        8 bits if one of the sigprocmasks failed (there's no way to
+        determine which one failed).  And there's no obvious way to
+        recover from that either, but nevertheless we want to know.
+
+        VG_(fixup_guest_state_after_syscall_interrupted) does the
+        thread state fixup in the case where we were interrupted by a
+        signal.
+
+        Prototype:
+
+   UWord ML_(do_syscall_for_client_WRK)(
+              Int syscallno,                 // a0
+              void* guest_state,             // a1
+              const vki_sigset_t *sysmask,   // a2
+              const vki_sigset_t *postmask,  // a3
+              Int nsigwords)                 // a4
+*/
+/* from vki-riscv64-linux.h */
+#define VKI_SIG_SETMASK 2
+
+.globl ML_(do_syscall_for_client_WRK)
+ML_(do_syscall_for_client_WRK):
+
+   /* Stash callee-saves and our args on the stack */
+   addi sp, sp, -144
+   sd ra, 136(sp)
+   sd s0, 128(sp)
+   sd s1, 120(sp)
+   sd s2, 112(sp)
+   sd s3, 104(sp)
+   sd s4, 96(sp)
+   sd s5, 88(sp)
+   sd s6, 80(sp)
+   sd s7, 72(sp)
+   sd s8, 64(sp)
+   sd s9, 56(sp)
+   sd s10, 48(sp)
+   sd s11, 40(sp)
+   sd a0, 32(sp)
+   sd a1, 24(sp)
+   sd a2, 16(sp)
+   sd a3, 8(sp)
+   sd a4, 0(sp)
+
+1:
+
+   li a7, __NR_rt_sigprocmask
+   li a0, VKI_SIG_SETMASK
+   mv a1, a2 /* sysmask */
+   mv a2, a3 /* postmask */
+   mv a3, a4 /* nsigwords */
+   ecall
+
+
+   ld a5, 24(sp) /* saved a1 == guest_state */
+
+   ld a7, 32(sp) /* saved a0 == syscall# */
+   ld a0, OFFSET_riscv64_x10(a5)
+   ld a1, OFFSET_riscv64_x11(a5)
+   ld a2, OFFSET_riscv64_x12(a5)
+   ld a3, OFFSET_riscv64_x13(a5)
+   ld a4, OFFSET_riscv64_x14(a5)
+   ld a5, OFFSET_riscv64_x15(a5)
+
+2: ecall
+3:
+   ld a5, 24(sp) /* saved a1 == guest_state */
+   sd a0, OFFSET_riscv64_x10(a5)
+
+4:
+   li a7, __NR_rt_sigprocmask
+   li a0, VKI_SIG_SETMASK
+   ld a1, 8(sp) /* saved a3 == postmask */
+   li a2, 0
+   ld a3, 0(sp) /* saved a4 == nsigwords */
+   ecall
+
+   bltz x0, 7f
+
+5: /* Success: return zero */
+   li a0, 0
+   ld ra, 136(sp)
+   ld s0, 128(sp)
+   ld s1, 120(sp)
+   ld s2, 112(sp)
+   ld s3, 104(sp)
+   ld s4, 96(sp)
+   ld s5, 88(sp)
+   ld s6, 80(sp)
+   ld s7, 72(sp)
+   ld s8, 64(sp)
+   ld s9, 56(sp)
+   ld s10, 48(sp)
+   ld s11, 40(sp)
+   addi sp, sp, 144
+   ret
+
+7: /* Failure: return 0x8000 | error code */
+   li a1, 0x8000
+   or a0, a0, a1
+   ld ra, 136(sp)
+   ld s0, 128(sp)
+   ld s1, 120(sp)
+   ld s2, 112(sp)
+   ld s3, 104(sp)
+   ld s4, 96(sp)
+   ld s5, 88(sp)
+   ld s6, 80(sp)
+   ld s7, 72(sp)
+   ld s8, 64(sp)
+   ld s9, 56(sp)
+   ld s10, 48(sp)
+   ld s11, 40(sp)
+   addi sp, sp, 144
+   ret
+
+
+
+.section .rodata
+/* export the ranges so that
+   VG_(fixup_guest_state_after_syscall_interrupted) can do the
+   right thing */
+
+.align 3
+.globl ML_(blksys_setup)
+.globl ML_(blksys_restart)
+.globl ML_(blksys_complete)
+.globl ML_(blksys_committed)
+.globl ML_(blksys_finished)
+ML_(blksys_setup):      .quad 1b
+ML_(blksys_restart):    .quad 2b
+ML_(blksys_complete):   .quad 3b
+ML_(blksys_committed):  .quad 4b
+ML_(blksys_finished):   .quad 5b
+
+#endif // defined(VGP_riscv64_linux)
+
+/* Let the linker know we don't need an executable stack */
+MARK_STACK_NO_EXEC
+
+/*--------------------------------------------------------------------*/
+/*--- end                                                          ---*/
+/*--------------------------------------------------------------------*/
diff --git a/coregrind/m_syswrap/syswrap-riscv64-linux.c b/coregrind/m_syswrap/syswrap-riscv64-linux.c
new file mode 100644 (file)
index 0000000..68c53b0
--- /dev/null
@@ -0,0 +1,608 @@
+
+/*--------------------------------------------------------------------*/
+/*--- Platform-specific syscalls stuff.  syswrap-riscv64-linux.c -----*/
+/*--------------------------------------------------------------------*/
+
+/*
+   This file is part of Valgrind, a dynamic binary instrumentation
+   framework.
+
+   Copyright (C) 2020-2023 Petr Pavlu
+      petr.pavlu@dagobah.cz
+
+   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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, see <http://www.gnu.org/licenses/>.
+
+   The GNU General Public License is contained in the file COPYING.
+*/
+
+#if defined(VGP_riscv64_linux)
+
+#include "pub_core_basics.h"
+#include "pub_core_libcassert.h"
+#include "pub_core_libcprint.h"
+#include "pub_core_options.h"
+#include "pub_core_sigframe.h"
+#include "pub_core_stacktrace.h"
+#include "pub_core_syscall.h"
+#include "pub_core_syswrap.h"
+#include "pub_core_threadstate.h"
+#include "pub_core_tooliface.h"
+#include "pub_core_transtab.h"
+#include "pub_core_vki.h"
+#include "pub_core_vkiscnums.h"
+
+#include "priv_syswrap-generic.h"
+#include "priv_syswrap-linux.h"
+#include "priv_types_n_macros.h"
+
+/* ---------------------------------------------------------------------
+   clone() handling
+   ------------------------------------------------------------------ */
+
+/* Call f(arg1), but first switch stacks, using 'stack' as the new stack, and
+   use 'retaddr' as f's return-to address. Also, clear all the integer registers
+   before entering f.*/
+__attribute__((noreturn)) void ML_(call_on_new_stack_0_1)(Addr stack,
+                                                          Addr retaddr,
+                                                          void (*f)(Word),
+                                                          Word arg1);
+/* a0 = stack
+   a1 = retaddr
+   a2 = f
+   a3 = arg1 */
+asm(".text\n"
+    ".globl vgModuleLocal_call_on_new_stack_0_1\n"
+    "vgModuleLocal_call_on_new_stack_0_1:\n"
+    "mv sp, a0\n" /* Set the stack pointer. */
+    "mv ra, a1\n" /* Set the return address. */
+    "mv a0, a3\n" /* Set the first argument. */
+    "li t0, 0\n"  /* Clear our GPRs. */
+    "li t1, 0\n"
+    "li t2, 0\n"
+    "li s0, 0\n"
+    "li s1, 0\n"
+    /* Don't zero out a0, already set to the first argument. */
+    "li a1, 0\n"
+    /* Don't zero out a2, holds the target function f(). */
+    "li a3, 0\n"
+    "li a4, 0\n"
+    "li a5, 0\n"
+    "li a6, 0\n"
+    "li a7, 0\n"
+    "li s2, 0\n"
+    "li s3, 0\n"
+    "li s4, 0\n"
+    "li s5, 0\n"
+    "li s6, 0\n"
+    "li s7, 0\n"
+    "li s8, 0\n"
+    "li s9, 0\n"
+    "li s10, 0\n"
+    "li s11, 0\n"
+    "li t3, 0\n"
+    "li t4, 0\n"
+    "li t5, 0\n"
+    "li t6, 0\n"
+    "jr a2\n"
+    ".previous\n");
+
+/* Perform a clone system call. Clone is strange because it has fork()-like
+   return-twice semantics, so it needs special handling here.
+
+   Upon entry, we have:
+
+      Word (*fn)(void*)   in a0
+      void*  child_stack  in a1
+      int    flags        in a2
+      void*  arg          in a3
+      pid_t* child_tid    in a4
+      pid_t* parent_tid   in a5
+      void*  tls_ptr      in a6
+
+   System call requires:
+
+      int    $__NR_clone  in a7
+      int    flags        in a0
+      void*  child_stack  in a1
+      pid_t* parent_tid   in a2
+      void*  tls_ptr      in a3
+      pid_t* child_tid    in a4
+
+   Returns a Long encoded in the linux-riscv64 way, not a SysRes.
+*/
+#define __NR_CLONE VG_STRINGIFY(__NR_clone)
+#define __NR_EXIT  VG_STRINGIFY(__NR_exit)
+
+/* See priv_syswrap-linux.h for arg profile. */
+asm(".text\n"
+    ".globl do_syscall_clone_riscv64_linux\n"
+    "do_syscall_clone_riscv64_linux:\n"
+    /* Set up the child stack, temporarily preserving fn and arg. */
+    "addi a1, a1, -16\n" /* Make space on the stack. */
+    "sd a3, 8(a1)\n"     /* Save arg. */
+    "sd a0, 0(a1)\n"     /* Save fn. */
+
+    /* Setup the syscall. */
+    "li a7, " __NR_CLONE "\n" /* Load the syscall number. */
+    "mv a0, a2\n"             /* Load syscall arg1: flags. */
+    "mv a1, a1\n"             /* Load syscall arg2: child_stack. */
+    "mv a2, a5\n"             /* Load syscall arg3: parent_tid. */
+    "mv a3, a6\n"             /* Load syscall arg4: tls_ptr. */
+    "mv a4, a4\n"             /* Load syscall arg5: child_tid. */
+
+    "ecall\n" /* clone() */
+
+    "bnez a0, 1f\n" /* Child if retval == 0. */
+
+    /* CHILD - call the thread function. */
+    "ld a1, 0(sp)\n" /* Pop fn. */
+    "ld a0, 8(sp)\n" /* Pop fn arg1: arg. */
+    "addi sp, sp, 16\n"
+    "jalr a1\n" /* Call fn. */
+
+    /* Exit with result. */
+    "mv a0, a0\n" /* arg1: return value from fn. */
+    "li a7, " __NR_EXIT "\n"
+
+    "ecall\n"
+
+    /* Exit returned?! */
+    "unimp\n"
+
+    "1:\n" /* PARENT or ERROR. a0 holds return value from the clone syscall. */
+    "ret\n"
+    ".previous\n");
+
+#undef __NR_CLONE
+#undef __NR_EXIT
+
+/* ---------------------------------------------------------------------
+   More thread stuff
+   ------------------------------------------------------------------ */
+
+/* riscv64 doesn't have any architecture specific thread stuff that needs to be
+   cleaned up. */
+void VG_(cleanup_thread)(ThreadArchState* arch) {}
+
+/* ---------------------------------------------------------------------
+   PRE/POST wrappers for riscv64/Linux-specific syscalls
+   ------------------------------------------------------------------ */
+
+#define PRE(name)  DEFN_PRE_TEMPLATE(riscv64_linux, name)
+#define POST(name) DEFN_POST_TEMPLATE(riscv64_linux, name)
+
+/* ARG3 is only used for pointers into the traced process's address space and
+   for offsets into the traced process's struct user_regs_struct. It is never
+   a pointer into this process's memory space, and we should therefore not check
+   anything it points to. */
+static PRE(sys_ptrace)
+{
+   PRINT("sys_ptrace ( %ld, %ld, %#lx, %#lx )", SARG1, SARG2, ARG3, ARG4);
+   PRE_REG_READ4(int, "ptrace", long, request, long, pid, long, addr, long,
+                 data);
+   switch (ARG1) {
+   case VKI_PTRACE_TRACEME:
+      break;
+   case VKI_PTRACE_PEEKTEXT:
+   case VKI_PTRACE_PEEKDATA:
+   case VKI_PTRACE_PEEKUSR:
+      PRE_MEM_WRITE("ptrace(peek)", ARG4, sizeof(long));
+      break;
+   case VKI_PTRACE_GETEVENTMSG:
+      PRE_MEM_WRITE("ptrace(geteventmsg)", ARG4, sizeof(unsigned long));
+      break;
+   case VKI_PTRACE_GETSIGINFO:
+      PRE_MEM_WRITE("ptrace(getsiginfo)", ARG4, sizeof(vki_siginfo_t));
+      break;
+   case VKI_PTRACE_SETSIGINFO:
+      PRE_MEM_READ("ptrace(setsiginfo)", ARG4, sizeof(vki_siginfo_t));
+      break;
+   case VKI_PTRACE_GETREGSET:
+      ML_(linux_PRE_getregset)(tid, ARG3, ARG4);
+      break;
+   case VKI_PTRACE_SETREGSET:
+      ML_(linux_PRE_setregset)(tid, ARG3, ARG4);
+      break;
+   default:
+      VG_(umsg)("WARNING: unhandled ptrace request %ld.\n", SARG1);
+      if (VG_(clo_verbosity) > 1)
+         VG_(get_and_pp_StackTrace)(tid, VG_(clo_backtrace_size));
+      break;
+   }
+}
+
+static POST(sys_ptrace)
+{
+   switch (ARG1) {
+   case VKI_PTRACE_TRACEME:
+      ML_(linux_POST_traceme)(tid);
+      break;
+   case VKI_PTRACE_PEEKTEXT:
+   case VKI_PTRACE_PEEKDATA:
+   case VKI_PTRACE_PEEKUSR:
+      POST_MEM_WRITE(ARG4, sizeof(long));
+      break;
+   case VKI_PTRACE_GETEVENTMSG:
+      POST_MEM_WRITE(ARG4, sizeof(unsigned long));
+      break;
+   case VKI_PTRACE_GETSIGINFO:
+      /* XXX: This is a simplification. Different parts of the siginfo_t are
+         valid depending on the type of signal. */
+      POST_MEM_WRITE(ARG4, sizeof(vki_siginfo_t));
+      break;
+   case VKI_PTRACE_GETREGSET:
+      ML_(linux_POST_getregset)(tid, ARG3, ARG4);
+      break;
+   default:
+      break;
+   }
+}
+
+static PRE(sys_rt_sigreturn)
+{
+   /* See comments on PRE(sys_rt_sigreturn) in syswrap-amd64-linux.c for
+      an explanation of what follows. */
+
+   PRINT("rt_sigreturn ( )");
+
+   vg_assert(VG_(is_valid_tid)(tid));
+   vg_assert(tid >= 1 && tid < VG_N_THREADS);
+   vg_assert(VG_(is_running_thread)(tid));
+
+   /* Restore register state from frame and remove it. */
+   VG_(sigframe_destroy)(tid, True);
+
+   /* Tell the driver not to update the guest state with the "result", and set
+      a bogus result to keep it happy. */
+   *flags |= SfNoWriteResult;
+   SET_STATUS_Success(0);
+
+   /* Check to see if any signals arose as a result of this. */
+   *flags |= SfPollAfter;
+}
+
+static PRE(sys_mmap)
+{
+   PRINT("sys_mmap ( %#lx, %lu, %lu, %#lx, %lu, %lu )", ARG1, ARG2, ARG3, ARG4,
+         ARG5, ARG6);
+   PRE_REG_READ6(long, "mmap", unsigned long, start, unsigned long, length,
+                 unsigned long, prot, unsigned long, flags, unsigned long, fd,
+                 unsigned long, offset);
+
+   SysRes r =
+      ML_(generic_PRE_sys_mmap)(tid, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
+   SET_STATUS_from_SysRes(r);
+}
+
+static PRE(sys_riscv_flush_icache)
+{
+   PRINT("sys_riscv_flush_icache ( %#lx, %lx, %#lx )", ARG1, ARG2, ARG3);
+   PRE_REG_READ3(long, "riscv_flush_icache", unsigned long, start,
+                 unsigned long, end, unsigned long, flags);
+
+   VG_(discard_translations)((Addr)ARG1, (ULong)ARG2 - (ULong)ARG1,
+                             "PRE(sys_riscv_flush_icache)");
+   SET_STATUS_Success(0);
+}
+
+#undef PRE
+#undef POST
+
+/* ---------------------------------------------------------------------
+   The riscv64/Linux syscall table
+   ------------------------------------------------------------------ */
+
+/* Add a riscv64-linux specific wrapper to a syscall table. */
+#define PLAX_(sysno, name) WRAPPER_ENTRY_X_(riscv64_linux, sysno, name)
+#define PLAXY(sysno, name) WRAPPER_ENTRY_XY(riscv64_linux, sysno, name)
+
+/* This table maps from __NR_xxx syscall numbers to the appropriate PRE/POST
+   sys_foo() wrappers on riscv64. */
+static SyscallTableEntry syscall_main_table[] = {
+   LINXY(__NR_io_setup, sys_io_setup),                             /* 0 */
+   LINX_(__NR_io_destroy, sys_io_destroy),                         /* 1 */
+   LINX_(__NR_io_submit, sys_io_submit),                           /* 2 */
+   LINXY(__NR_io_cancel, sys_io_cancel),                           /* 3 */
+   LINXY(__NR_io_getevents, sys_io_getevents),                     /* 4 */
+   LINX_(__NR_setxattr, sys_setxattr),                             /* 5 */
+   LINX_(__NR_lsetxattr, sys_lsetxattr),                           /* 6 */
+   LINX_(__NR_fsetxattr, sys_fsetxattr),                           /* 7 */
+   LINXY(__NR_getxattr, sys_getxattr),                             /* 8 */
+   LINXY(__NR_lgetxattr, sys_lgetxattr),                           /* 9 */
+   LINXY(__NR_fgetxattr, sys_fgetxattr),                           /* 10 */
+   LINXY(__NR_listxattr, sys_listxattr),                           /* 11 */
+   LINXY(__NR_llistxattr, sys_llistxattr),                         /* 12 */
+   LINXY(__NR_flistxattr, sys_flistxattr),                         /* 13 */
+   LINX_(__NR_removexattr, sys_removexattr),                       /* 14 */
+   LINX_(__NR_lremovexattr, sys_lremovexattr),                     /* 15 */
+   LINX_(__NR_fremovexattr, sys_fremovexattr),                     /* 16 */
+   GENXY(__NR_getcwd, sys_getcwd),                                 /* 17 */
+   LINXY(__NR_lookup_dcookie, sys_lookup_dcookie),                 /* 18 */
+   LINXY(__NR_eventfd2, sys_eventfd2),                             /* 19 */
+   LINXY(__NR_epoll_create1, sys_epoll_create1),                   /* 20 */
+   LINX_(__NR_epoll_ctl, sys_epoll_ctl),                           /* 21 */
+   LINXY(__NR_epoll_pwait, sys_epoll_pwait),                       /* 22 */
+   GENXY(__NR_dup, sys_dup),                                       /* 23 */
+   LINXY(__NR_dup3, sys_dup3),                                     /* 24 */
+   LINXY(__NR_fcntl, sys_fcntl),                                   /* 25 */
+   LINXY(__NR_inotify_init1, sys_inotify_init1),                   /* 26 */
+   LINX_(__NR_inotify_add_watch, sys_inotify_add_watch),           /* 27 */
+   LINX_(__NR_inotify_rm_watch, sys_inotify_rm_watch),             /* 28 */
+   LINXY(__NR_ioctl, sys_ioctl),                                   /* 29 */
+   LINX_(__NR_ioprio_set, sys_ioprio_set),                         /* 30 */
+   LINX_(__NR_ioprio_get, sys_ioprio_get),                         /* 31 */
+   GENX_(__NR_flock, sys_flock),                                   /* 32 */
+   LINX_(__NR_mknodat, sys_mknodat),                               /* 33 */
+   LINX_(__NR_mkdirat, sys_mkdirat),                               /* 34 */
+   LINX_(__NR_unlinkat, sys_unlinkat),                             /* 35 */
+   LINX_(__NR_symlinkat, sys_symlinkat),                           /* 36 */
+   LINX_(__NR_linkat, sys_linkat),                                 /* 37 */
+   LINX_(__NR_umount2, sys_umount),                                /* 39 */
+   LINX_(__NR_mount, sys_mount),                                   /* 40 */
+   LINX_(__NR_pivot_root, sys_pivot_root),                         /* 41 */
+   GENXY(__NR_statfs, sys_statfs),                                 /* 43 */
+   GENXY(__NR_fstatfs, sys_fstatfs),                               /* 44 */
+   GENX_(__NR_truncate, sys_truncate),                             /* 45 */
+   GENX_(__NR_ftruncate, sys_ftruncate),                           /* 46 */
+   LINX_(__NR_fallocate, sys_fallocate),                           /* 47 */
+   LINX_(__NR_faccessat, sys_faccessat),                           /* 48 */
+   GENX_(__NR_chdir, sys_chdir),                                   /* 49 */
+   GENX_(__NR_fchdir, sys_fchdir),                                 /* 50 */
+   GENX_(__NR_chroot, sys_chroot),                                 /* 51 */
+   GENX_(__NR_fchmod, sys_fchmod),                                 /* 52 */
+   LINX_(__NR_fchmodat, sys_fchmodat),                             /* 53 */
+   LINX_(__NR_fchownat, sys_fchownat),                             /* 54 */
+   GENX_(__NR_fchown, sys_fchown),                                 /* 55 */
+   LINXY(__NR_openat, sys_openat),                                 /* 56 */
+   GENX_(__NR_close, sys_close),                                   /* 57 */
+   LINX_(__NR_vhangup, sys_vhangup),                               /* 58 */
+   LINXY(__NR_pipe2, sys_pipe2),                                   /* 59 */
+   LINX_(__NR_quotactl, sys_quotactl),                             /* 60 */
+   GENXY(__NR_getdents64, sys_getdents64),                         /* 61 */
+   LINX_(__NR_lseek, sys_lseek),                                   /* 62 */
+   GENXY(__NR_read, sys_read),                                     /* 63 */
+   GENX_(__NR_write, sys_write),                                   /* 64 */
+   GENXY(__NR_readv, sys_readv),                                   /* 65 */
+   GENX_(__NR_writev, sys_writev),                                 /* 66 */
+   GENXY(__NR_pread64, sys_pread64),                               /* 67 */
+   GENX_(__NR_pwrite64, sys_pwrite64),                             /* 68 */
+   LINXY(__NR_preadv, sys_preadv),                                 /* 69 */
+   LINX_(__NR_pwritev, sys_pwritev),                               /* 70 */
+   LINXY(__NR_sendfile, sys_sendfile),                             /* 71 */
+   LINXY(__NR_pselect6, sys_pselect6),                             /* 72 */
+   LINXY(__NR_ppoll, sys_ppoll),                                   /* 73 */
+   LINXY(__NR_signalfd4, sys_signalfd4),                           /* 74 */
+   LINX_(__NR_vmsplice, sys_vmsplice),                             /* 75 */
+   LINX_(__NR_splice, sys_splice),                                 /* 76 */
+   LINX_(__NR_tee, sys_tee),                                       /* 77 */
+   LINXY(__NR_readlinkat, sys_readlinkat),                         /* 78 */
+   LINXY(__NR_newfstatat, sys_newfstatat),                         /* 79 */
+   GENXY(__NR_fstat, sys_newfstat),                                /* 80 */
+   GENX_(__NR_sync, sys_sync),                                     /* 81 */
+   GENX_(__NR_fsync, sys_fsync),                                   /* 82 */
+   GENX_(__NR_fdatasync, sys_fdatasync),                           /* 83 */
+   LINX_(__NR_sync_file_range, sys_sync_file_range),               /* 84 */
+   LINXY(__NR_timerfd_create, sys_timerfd_create),                 /* 85 */
+   LINXY(__NR_timerfd_settime, sys_timerfd_settime),               /* 86 */
+   LINXY(__NR_timerfd_gettime, sys_timerfd_gettime),               /* 87 */
+   LINX_(__NR_utimensat, sys_utimensat),                           /* 88 */
+   GENX_(__NR_acct, sys_acct),                                     /* 89 */
+   LINXY(__NR_capget, sys_capget),                                 /* 90 */
+   LINX_(__NR_capset, sys_capset),                                 /* 91 */
+   LINX_(__NR_personality, sys_personality),                       /* 92 */
+   GENX_(__NR_exit, sys_exit),                                     /* 93 */
+   LINX_(__NR_exit_group, sys_exit_group),                         /* 94 */
+   LINXY(__NR_waitid, sys_waitid),                                 /* 95 */
+   LINX_(__NR_set_tid_address, sys_set_tid_address),               /* 96 */
+   LINX_(__NR_unshare, sys_unshare),                               /* 97 */
+   LINXY(__NR_futex, sys_futex),                                   /* 98 */
+   LINX_(__NR_set_robust_list, sys_set_robust_list),               /* 99 */
+   LINXY(__NR_get_robust_list, sys_get_robust_list),               /* 100 */
+   GENXY(__NR_nanosleep, sys_nanosleep),                           /* 101 */
+   GENXY(__NR_getitimer, sys_getitimer),                           /* 102 */
+   GENXY(__NR_setitimer, sys_setitimer),                           /* 103 */
+   GENX_(__NR_kexec_load, sys_ni_syscall),                         /* 104 */
+   LINX_(__NR_init_module, sys_init_module),                       /* 105 */
+   LINX_(__NR_delete_module, sys_delete_module),                   /* 106 */
+   LINXY(__NR_timer_create, sys_timer_create),                     /* 107 */
+   LINXY(__NR_timer_gettime, sys_timer_gettime),                   /* 108 */
+   LINX_(__NR_timer_getoverrun, sys_timer_getoverrun),             /* 109 */
+   LINXY(__NR_timer_settime, sys_timer_settime),                   /* 110 */
+   LINX_(__NR_timer_delete, sys_timer_delete),                     /* 111 */
+   LINX_(__NR_clock_settime, sys_clock_settime),                   /* 112 */
+   LINXY(__NR_clock_gettime, sys_clock_gettime),                   /* 113 */
+   LINXY(__NR_clock_getres, sys_clock_getres),                     /* 114 */
+   LINXY(__NR_clock_nanosleep, sys_clock_nanosleep),               /* 115 */
+   LINXY(__NR_syslog, sys_syslog),                                 /* 116 */
+   PLAXY(__NR_ptrace, sys_ptrace),                                 /* 117 */
+   LINXY(__NR_sched_setparam, sys_sched_setparam),                 /* 118 */
+   LINX_(__NR_sched_setscheduler, sys_sched_setscheduler),         /* 119 */
+   LINX_(__NR_sched_getscheduler, sys_sched_getscheduler),         /* 120 */
+   LINXY(__NR_sched_getparam, sys_sched_getparam),                 /* 121 */
+   LINX_(__NR_sched_setaffinity, sys_sched_setaffinity),           /* 122 */
+   LINXY(__NR_sched_getaffinity, sys_sched_getaffinity),           /* 123 */
+   LINX_(__NR_sched_yield, sys_sched_yield),                       /* 124 */
+   LINX_(__NR_sched_get_priority_max, sys_sched_get_priority_max), /* 125 */
+   LINX_(__NR_sched_get_priority_min, sys_sched_get_priority_min), /* 126 */
+   LINXY(__NR_sched_rr_get_interval, sys_sched_rr_get_interval),   /* 127 */
+   GENX_(__NR_kill, sys_kill),                                     /* 129 */
+   LINXY(__NR_tkill, sys_tkill),                                   /* 130 */
+   LINX_(__NR_tgkill, sys_tgkill),                                 /* 131 */
+   GENXY(__NR_sigaltstack, sys_sigaltstack),                       /* 132 */
+   LINX_(__NR_rt_sigsuspend, sys_rt_sigsuspend),                   /* 133 */
+   LINXY(__NR_rt_sigaction, sys_rt_sigaction),                     /* 134 */
+   LINXY(__NR_rt_sigprocmask, sys_rt_sigprocmask),                 /* 135 */
+   LINXY(__NR_rt_sigpending, sys_rt_sigpending),                   /* 136 */
+   LINXY(__NR_rt_sigtimedwait, sys_rt_sigtimedwait),               /* 137 */
+   LINXY(__NR_rt_sigqueueinfo, sys_rt_sigqueueinfo),               /* 138 */
+   PLAX_(__NR_rt_sigreturn, sys_rt_sigreturn),                     /* 139 */
+   GENX_(__NR_setpriority, sys_setpriority),                       /* 140 */
+   GENX_(__NR_getpriority, sys_getpriority),                       /* 141 */
+   GENX_(__NR_setregid, sys_setregid),                             /* 143 */
+   GENX_(__NR_setgid, sys_setgid),                                 /* 144 */
+   GENX_(__NR_setreuid, sys_setreuid),                             /* 145 */
+   GENX_(__NR_setuid, sys_setuid),                                 /* 146 */
+   LINX_(__NR_setresuid, sys_setresuid),                           /* 147 */
+   LINXY(__NR_getresuid, sys_getresuid),                           /* 148 */
+   LINX_(__NR_setresgid, sys_setresgid),                           /* 149 */
+   LINXY(__NR_getresgid, sys_getresgid),                           /* 150 */
+   LINX_(__NR_setfsuid, sys_setfsuid),                             /* 151 */
+   LINX_(__NR_setfsgid, sys_setfsgid),                             /* 152 */
+   GENXY(__NR_times, sys_times),                                   /* 153 */
+   GENX_(__NR_setpgid, sys_setpgid),                               /* 154 */
+   GENX_(__NR_getpgid, sys_getpgid),                               /* 155 */
+   GENX_(__NR_getsid, sys_getsid),                                 /* 156 */
+   GENX_(__NR_setsid, sys_setsid),                                 /* 157 */
+   GENXY(__NR_getgroups, sys_getgroups),                           /* 158 */
+   GENX_(__NR_setgroups, sys_setgroups),                           /* 159 */
+   GENXY(__NR_uname, sys_newuname),                                /* 160 */
+   GENX_(__NR_sethostname, sys_sethostname),                       /* 161 */
+   GENXY(__NR_getrlimit, sys_getrlimit),                           /* 163 */
+   GENX_(__NR_setrlimit, sys_setrlimit),                           /* 164 */
+   GENXY(__NR_getrusage, sys_getrusage),                           /* 165 */
+   GENX_(__NR_umask, sys_umask),                                   /* 166 */
+   LINXY(__NR_prctl, sys_prctl),                                   /* 167 */
+   LINXY(__NR_getcpu, sys_getcpu),                                 /* 168 */
+   GENXY(__NR_gettimeofday, sys_gettimeofday),                     /* 169 */
+   GENX_(__NR_settimeofday, sys_settimeofday),                     /* 170 */
+   LINXY(__NR_adjtimex, sys_adjtimex),                             /* 171 */
+   GENX_(__NR_getpid, sys_getpid),                                 /* 172 */
+   GENX_(__NR_getppid, sys_getppid),                               /* 173 */
+   GENX_(__NR_getuid, sys_getuid),                                 /* 174 */
+   GENX_(__NR_geteuid, sys_geteuid),                               /* 175 */
+   GENX_(__NR_getgid, sys_getgid),                                 /* 176 */
+   GENX_(__NR_getegid, sys_getegid),                               /* 177 */
+   LINX_(__NR_gettid, sys_gettid),                                 /* 178 */
+   LINXY(__NR_sysinfo, sys_sysinfo),                               /* 179 */
+   LINXY(__NR_mq_open, sys_mq_open),                               /* 180 */
+   LINX_(__NR_mq_unlink, sys_mq_unlink),                           /* 181 */
+   LINX_(__NR_mq_timedsend, sys_mq_timedsend),                     /* 182 */
+   LINXY(__NR_mq_timedreceive, sys_mq_timedreceive),               /* 183 */
+   LINX_(__NR_mq_notify, sys_mq_notify),                           /* 184 */
+   LINXY(__NR_mq_getsetattr, sys_mq_getsetattr),                   /* 185 */
+   LINX_(__NR_msgget, sys_msgget),                                 /* 186 */
+   LINXY(__NR_msgctl, sys_msgctl),                                 /* 187 */
+   LINXY(__NR_msgrcv, sys_msgrcv),                                 /* 188 */
+   LINX_(__NR_msgsnd, sys_msgsnd),                                 /* 189 */
+   LINX_(__NR_semget, sys_semget),                                 /* 190 */
+   LINXY(__NR_semctl, sys_semctl),                                 /* 191 */
+   LINX_(__NR_semtimedop, sys_semtimedop),                         /* 192 */
+   LINX_(__NR_semop, sys_semop),                                   /* 193 */
+   LINX_(__NR_shmget, sys_shmget),                                 /* 194 */
+   LINXY(__NR_shmctl, sys_shmctl),                                 /* 195 */
+   LINXY(__NR_shmat, sys_shmat),                                   /* 196 */
+   LINXY(__NR_shmdt, sys_shmdt),                                   /* 197 */
+   LINXY(__NR_socket, sys_socket),                                 /* 198 */
+   LINXY(__NR_socketpair, sys_socketpair),                         /* 199 */
+   LINX_(__NR_bind, sys_bind),                                     /* 200 */
+   LINX_(__NR_listen, sys_listen),                                 /* 201 */
+   LINXY(__NR_accept, sys_accept),                                 /* 202 */
+   LINX_(__NR_connect, sys_connect),                               /* 203 */
+   LINXY(__NR_getsockname, sys_getsockname),                       /* 204 */
+   LINXY(__NR_getpeername, sys_getpeername),                       /* 205 */
+   LINX_(__NR_sendto, sys_sendto),                                 /* 206 */
+   LINXY(__NR_recvfrom, sys_recvfrom),                             /* 207 */
+   LINX_(__NR_setsockopt, sys_setsockopt),                         /* 208 */
+   LINXY(__NR_getsockopt, sys_getsockopt),                         /* 209 */
+   LINX_(__NR_shutdown, sys_shutdown),                             /* 210 */
+   LINX_(__NR_sendmsg, sys_sendmsg),                               /* 211 */
+   LINXY(__NR_recvmsg, sys_recvmsg),                               /* 212 */
+   LINX_(__NR_readahead, sys_readahead),                           /* 213 */
+   GENX_(__NR_brk, sys_brk),                                       /* 214 */
+   GENXY(__NR_munmap, sys_munmap),                                 /* 215 */
+   GENX_(__NR_mremap, sys_mremap),                                 /* 216 */
+   LINX_(__NR_add_key, sys_add_key),                               /* 217 */
+   LINX_(__NR_request_key, sys_request_key),                       /* 218 */
+   LINXY(__NR_keyctl, sys_keyctl),                                 /* 219 */
+   LINX_(__NR_clone, sys_clone),                                   /* 220 */
+   GENX_(__NR_execve, sys_execve),                                 /* 221 */
+   PLAX_(__NR_mmap, sys_mmap),                                     /* 222 */
+   GENX_(__NR_fadvise64, sys_ni_syscall),                          /* 223 */
+   GENXY(__NR_mprotect, sys_mprotect),                             /* 226 */
+   GENX_(__NR_msync, sys_msync),                                   /* 227 */
+   GENX_(__NR_mlock, sys_mlock),                                   /* 228 */
+   GENX_(__NR_munlock, sys_munlock),                               /* 229 */
+   GENX_(__NR_mlockall, sys_mlockall),                             /* 230 */
+   LINX_(__NR_munlockall, sys_munlockall),                         /* 231 */
+   GENXY(__NR_mincore, sys_mincore),                               /* 232 */
+   GENX_(__NR_madvise, sys_madvise),                               /* 233 */
+   LINX_(__NR_mbind, sys_mbind),                                   /* 235 */
+   LINXY(__NR_get_mempolicy, sys_get_mempolicy),                   /* 236 */
+   LINX_(__NR_set_mempolicy, sys_set_mempolicy),                   /* 237 */
+   LINXY(__NR_move_pages, sys_move_pages),                         /* 239 */
+   LINXY(__NR_rt_tgsigqueueinfo, sys_rt_tgsigqueueinfo),           /* 240 */
+   LINXY(__NR_perf_event_open, sys_perf_event_open),               /* 241 */
+   LINXY(__NR_accept4, sys_accept4),                               /* 242 */
+   LINXY(__NR_recvmmsg, sys_recvmmsg),                             /* 243 */
+   PLAX_(__NR_riscv_flush_icache, sys_riscv_flush_icache),         /* 259 */
+   GENXY(__NR_wait4, sys_wait4),                                   /* 260 */
+   LINXY(__NR_prlimit64, sys_prlimit64),                           /* 261 */
+   LINXY(__NR_fanotify_init, sys_fanotify_init),                   /* 262 */
+   LINX_(__NR_fanotify_mark, sys_fanotify_mark),                   /* 263 */
+   LINXY(__NR_name_to_handle_at, sys_name_to_handle_at),           /* 264 */
+   LINXY(__NR_open_by_handle_at, sys_open_by_handle_at),           /* 265 */
+   LINXY(__NR_clock_adjtime, sys_clock_adjtime),                   /* 266 */
+   LINX_(__NR_syncfs, sys_syncfs),                                 /* 267 */
+   LINX_(__NR_setns, sys_setns),                                   /* 268 */
+   LINXY(__NR_sendmmsg, sys_sendmmsg),                             /* 269 */
+   LINXY(__NR_process_vm_readv, sys_process_vm_readv),             /* 270 */
+   LINX_(__NR_process_vm_writev, sys_process_vm_writev),           /* 271 */
+   LINX_(__NR_kcmp, sys_kcmp),                                     /* 272 */
+   LINX_(__NR_finit_module, sys_finit_module),                     /* 273 */
+   LINX_(__NR_sched_setattr, sys_sched_setattr),                   /* 274 */
+   LINXY(__NR_sched_getattr, sys_sched_getattr),                   /* 275 */
+   LINX_(__NR_renameat2, sys_renameat2),                           /* 276 */
+   LINXY(__NR_getrandom, sys_getrandom),                           /* 278 */
+   LINXY(__NR_memfd_create, sys_memfd_create),                     /* 279 */
+   LINXY(__NR_bpf, sys_bpf),                                       /* 280 */
+   LINX_(__NR_execveat, sys_execveat),                             /* 281 */
+   LINX_(__NR_membarrier, sys_membarrier),                         /* 283 */
+   GENX_(__NR_mlock2, sys_mlock2),                                 /* 284 */
+   LINX_(__NR_copy_file_range, sys_copy_file_range),               /* 285 */
+   LINXY(__NR_preadv2, sys_preadv2),                               /* 286 */
+   LINX_(__NR_pwritev2, sys_pwritev2),                             /* 287 */
+   LINXY(__NR_statx, sys_statx),                                   /* 291 */
+   GENX_(__NR_rseq, sys_ni_syscall),                               /* 293 */
+   LINXY(__NR_io_uring_setup, sys_io_uring_setup),                 /* 425 */
+   LINXY(__NR_io_uring_enter, sys_io_uring_enter),                 /* 426 */
+   LINXY(__NR_io_uring_register, sys_io_uring_register),           /* 427 */
+   GENX_(__NR_clone3, sys_ni_syscall),                             /* 435 */
+   LINXY(__NR_close_range, sys_close_range),                       /* 436 */
+   LINX_(__NR_faccessat2, sys_faccessat2),                         /* 439 */
+   LINXY(__NR_memfd_secret, sys_memfd_secret),                     /* 447 */
+};
+
+SyscallTableEntry* ML_(get_linux_syscall_entry)(UInt sysno)
+{
+   const UInt syscall_main_table_size =
+      sizeof(syscall_main_table) / sizeof(syscall_main_table[0]);
+
+   /* Is it in the contiguous initial section of the table? */
+   if (sysno < syscall_main_table_size) {
+      SyscallTableEntry* sys = &syscall_main_table[sysno];
+      if (sys->before == NULL)
+         return NULL; /* no entry */
+      else
+         return sys;
+   }
+
+   /* Can't find a wrapper. */
+   return NULL;
+}
+
+#endif // defined(VGP_riscv64_linux)
+
+/*--------------------------------------------------------------------*/
+/*--- end                                  syswrap-riscv64-linux.c ---*/
+/*--------------------------------------------------------------------*/
diff --git a/docs/internals/qemu-riscv64-linux-HOWTO.txt b/docs/internals/qemu-riscv64-linux-HOWTO.txt
new file mode 100644 (file)
index 0000000..eb0ce4d
--- /dev/null
@@ -0,0 +1,46 @@
+
+How to install and configure a QEMU riscv64-linux installation.
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Last updated 25 March 2023
+
+This file is a variant of qemu-aarch64-linux-HOWTO.txt but for RISCV64. It
+differs in use of openSUSE Tumbleweed and an already prepared image.
+
+
+Use a distribution package manager to install QEMU with support for running
+a 64-bit RISC-V system. It should provide the qemu-system-riscv64 executable.
+Make sure the package comes with an OpenSBI binary which is normally stored at
+/usr/share/qemu/opensbi-riscv64-generic-fw_dynamic.bin.
+
+Get a Tumbleweed image and convert it to qcow2:
+
+mkdir tumbleweed && cd tumbleweed
+wget http://download.opensuse.org/ports/riscv/tumbleweed/images/openSUSE-Tumbleweed-RISC-V-JeOS-efi.riscv64.raw.xz
+unxz openSUSE-Tumbleweed-RISC-V-JeOS-efi.riscv64.raw.xz
+qemu-img convert -f raw -O qcow2 openSUSE-Tumbleweed-RISC-V-JeOS-efi.riscv64.raw image.qcow2
+qemu-img resize image.qcow2 20G
+
+Obtain a U-Boot loader:
+
+UBOOT=$(wget https://download.opensuse.org/ports/riscv/tumbleweed/repo/oss/INDEX.gz -O - | gunzip | grep 'u-boot-qemu-riscv64smode-[0123456789\.-]*\.riscv64\.rpm')
+wget --directory-prefix=u-boot https://download.opensuse.org/ports/riscv/tumbleweed/repo/oss/$UBOOT
+rpm2cpio u-boot/u-boot-qemu-riscv64smode-*.riscv64.rpm | cpio -D u-boot -idm
+
+Boot the system:
+
+qemu-system-riscv64 -nographic -machine virt -smp 4 -m 8G \
+  -kernel u-boot/boot/u-boot.bin \
+  -device virtio-blk-device,drive=hd0 -drive file=image.qcow2,format=qcow2,id=hd0 \
+  -device virtio-net-device,netdev=usernet -netdev user,id=usernet,hostfwd=tcp::5555-:22
+
+Now you can ssh into the VM and install stuff as usual:
+
+ssh -p 5555 root@localhost
+[The preset password is linux.]
+
+  (on the guest)
+  useradd username && passwd username
+  zypper install autoconf automake make gcc gcc-c++ git-core
+
+Hack on, etc.
diff --git a/include/vki/vki-posixtypes-riscv64-linux.h b/include/vki/vki-posixtypes-riscv64-linux.h
new file mode 100644 (file)
index 0000000..b8dfc9c
--- /dev/null
@@ -0,0 +1,66 @@
+
+/*--------------------------------------------------------------------*/
+/*--- riscv64/Linux-specific kernel interface: posix types.        ---*/
+/*---                               vki-posixtypes-riscv64-linux.h ---*/
+/*--------------------------------------------------------------------*/
+
+/*
+   This file is part of Valgrind, a dynamic binary instrumentation
+   framework.
+
+   Copyright (C) 2020-2023 Petr Pavlu
+      petr.pavlu@dagobah.cz
+
+   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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, see <http://www.gnu.org/licenses/>.
+
+   The GNU General Public License is contained in the file COPYING.
+*/
+
+#ifndef __VKI_POSIXTYPES_RISCV64_LINUX_H
+#define __VKI_POSIXTYPES_RISCV64_LINUX_H
+
+//----------------------------------------------------------------------
+// From linux-6.0/include/uapi/asm-generic/posix_types.h
+//----------------------------------------------------------------------
+
+typedef unsigned int   __vki_kernel_mode_t;
+typedef long           __vki_kernel_off_t;
+typedef int            __vki_kernel_pid_t;
+typedef int            __vki_kernel_ipc_pid_t;
+typedef unsigned int   __vki_kernel_uid_t;
+typedef unsigned int   __vki_kernel_gid_t;
+typedef unsigned long  __vki_kernel_size_t;
+typedef long           __vki_kernel_time_t;
+typedef long           __vki_kernel_suseconds_t;
+typedef long           __vki_kernel_clock_t;
+typedef int            __vki_kernel_timer_t;
+typedef int            __vki_kernel_clockid_t;
+typedef char *         __vki_kernel_caddr_t;
+typedef unsigned int   __vki_kernel_uid32_t;
+typedef unsigned int   __vki_kernel_gid32_t;
+
+typedef unsigned int   __vki_kernel_old_uid_t;
+typedef unsigned int   __vki_kernel_old_gid_t;
+
+typedef long long      __vki_kernel_loff_t;
+
+typedef struct {
+       int     val[2];
+} __vki_kernel_fsid_t;
+
+#endif // __VKI_POSIXTYPES_RISCV64_LINUX_H
+
+/*--------------------------------------------------------------------*/
+/*--- end                           vki-posixtypes-riscv64-linux.h ---*/
+/*--------------------------------------------------------------------*/
diff --git a/include/vki/vki-riscv64-linux.h b/include/vki/vki-riscv64-linux.h
new file mode 100644 (file)
index 0000000..5cc98b6
--- /dev/null
@@ -0,0 +1,635 @@
+
+/*--------------------------------------------------------------------*/
+/*--- riscv64/Linux-specific kernel interface. vki-riscv64-linux.h ---*/
+/*--------------------------------------------------------------------*/
+
+/*
+   This file is part of Valgrind, a dynamic binary instrumentation
+   framework.
+
+   Copyright (C) 2020-2023 Petr Pavlu
+      petr.pavlu@dagobah.cz
+
+   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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, see <http://www.gnu.org/licenses/>.
+
+   The GNU General Public License is contained in the file COPYING.
+*/
+
+#ifndef __VKI_RISCV64_LINUX_H
+#define __VKI_RISCV64_LINUX_H
+
+// riscv64 is little-endian.
+#define VKI_LITTLE_ENDIAN  1
+
+//----------------------------------------------------------------------
+// From linux-6.0/include/uapi/asm-generic/int-ll64.h
+//----------------------------------------------------------------------
+
+typedef unsigned char __vki_u8;
+
+typedef __signed__ short __vki_s16;
+typedef unsigned short __vki_u16;
+
+typedef __signed__ int __vki_s32;
+typedef unsigned int __vki_u32;
+
+typedef __signed__ long long __vki_s64;
+typedef unsigned long long __vki_u64;
+
+typedef unsigned short vki_u16;
+
+typedef unsigned int vki_u32;
+
+//----------------------------------------------------------------------
+// From linux-6.0/arch/riscv/include/asm/page.h
+//----------------------------------------------------------------------
+
+#define VKI_PAGE_SHIFT (12)
+#define VKI_PAGE_SIZE  (1UL << VKI_PAGE_SHIFT)
+#define VKI_MAX_PAGE_SHIFT     VKI_PAGE_SHIFT
+#define VKI_MAX_PAGE_SIZE      VKI_PAGE_SIZE
+
+//----------------------------------------------------------------------
+// From linux-6.0/include/asm-generic/shmparam.h
+//----------------------------------------------------------------------
+
+#define VKI_SHMLBA VKI_PAGE_SIZE       /* attach addr a multiple of this */
+
+//----------------------------------------------------------------------
+// From linux-6.0/include/uapi/asm-generic/signal-defs.h
+//----------------------------------------------------------------------
+
+#define VKI_SIG_BLOCK          0       /* for blocking signals */
+#define VKI_SIG_UNBLOCK        1       /* for unblocking signals */
+#define VKI_SIG_SETMASK        2       /* for setting the signal mask */
+
+typedef void __vki_signalfn_t(int);
+typedef __vki_signalfn_t __user *__vki_sighandler_t;
+
+#define VKI_SIG_DFL    ((__vki_sighandler_t)0) /* default signal handling */
+#define VKI_SIG_IGN    ((__vki_sighandler_t)1) /* ignore signal */
+
+//----------------------------------------------------------------------
+// From linux-6.0/include/uapi/asm-generic/signal.h
+//----------------------------------------------------------------------
+
+#define _VKI_NSIG      64
+#define _VKI_NSIG_BPW  64
+#define _VKI_NSIG_WORDS        (_VKI_NSIG / _VKI_NSIG_BPW)
+
+typedef unsigned long vki_old_sigset_t;
+
+typedef struct {
+       unsigned long sig[_VKI_NSIG_WORDS];
+} vki_sigset_t;
+
+#define VKI_SIGHUP              1
+#define VKI_SIGINT              2
+#define VKI_SIGQUIT             3
+#define VKI_SIGILL              4
+#define VKI_SIGTRAP             5
+#define VKI_SIGABRT             6
+#define VKI_SIGBUS              7
+#define VKI_SIGFPE              8
+#define VKI_SIGKILL             9
+#define VKI_SIGUSR1            10
+#define VKI_SIGSEGV            11
+#define VKI_SIGUSR2            12
+#define VKI_SIGPIPE            13
+#define VKI_SIGALRM            14
+#define VKI_SIGTERM            15
+#define VKI_SIGSTKFLT          16
+#define VKI_SIGCHLD            17
+#define VKI_SIGCONT            18
+#define VKI_SIGSTOP            19
+#define VKI_SIGTSTP            20
+#define VKI_SIGTTIN            21
+#define VKI_SIGTTOU            22
+#define VKI_SIGURG             23
+#define VKI_SIGXCPU            24
+#define VKI_SIGXFSZ            25
+#define VKI_SIGVTALRM          26
+#define VKI_SIGPROF            27
+#define VKI_SIGWINCH           28
+#define VKI_SIGIO              29
+#define VKI_SIGPWR             30
+#define VKI_SIGSYS             31
+#define        VKI_SIGUNUSED           31
+
+#define VKI_SIGRTMIN           32
+#define VKI_SIGRTMAX           _VKI_NSIG
+
+#define VKI_SA_NOCLDSTOP       0x00000001
+#define VKI_SA_NOCLDWAIT       0x00000002
+#define VKI_SA_SIGINFO         0x00000004
+#define VKI_SA_ONSTACK         0x08000000
+#define VKI_SA_RESTART         0x10000000
+#define VKI_SA_NODEFER         0x40000000
+#define VKI_SA_RESETHAND       0x80000000
+
+#define VKI_SA_NOMASK  VKI_SA_NODEFER
+#define VKI_SA_ONESHOT VKI_SA_RESETHAND
+
+#define VKI_MINSIGSTKSZ        2048
+
+struct vki_sigaction_base {
+       __vki_sighandler_t ksa_handler;
+       unsigned long sa_flags;
+       vki_sigset_t sa_mask;
+};
+
+/* On Linux we use the same type for passing sigactions to
+   and from the kernel.  Hence: */
+typedef  struct vki_sigaction_base  vki_sigaction_toK_t;
+typedef  struct vki_sigaction_base  vki_sigaction_fromK_t;
+
+typedef struct vki_sigaltstack {
+       void __user *ss_sp;
+       int ss_flags;
+       vki_size_t ss_size;
+} vki_stack_t;
+
+//----------------------------------------------------------------------
+// From linux-6.0/include/uapi/linux/signal.h
+//----------------------------------------------------------------------
+
+#define VKI_SS_ONSTACK 1
+#define VKI_SS_DISABLE 2
+
+//----------------------------------------------------------------------
+// From linux-6.0/include/uapi/asm-generic/mman-common.h
+//----------------------------------------------------------------------
+
+#define VKI_PROT_READ  0x1             /* page can be read */
+#define VKI_PROT_WRITE 0x2             /* page can be written */
+#define VKI_PROT_EXEC  0x4             /* page can be executed */
+#define VKI_PROT_NONE  0x0             /* page can not be accessed */
+#define VKI_PROT_GROWSDOWN     0x01000000      /* mprotect flag: extend change to start of growsdown vma */
+#define VKI_PROT_GROWSUP       0x02000000      /* mprotect flag: extend change to end of growsup vma */
+
+#define VKI_MAP_FIXED  0x10            /* Interpret addr exactly */
+#define VKI_MAP_ANONYMOUS      0x20    /* don't use a file */
+
+//----------------------------------------------------------------------
+// From linux-6.0/include/uapi/asm-generic/mman.h
+//----------------------------------------------------------------------
+
+#define VKI_MAP_NORESERVE       0x4000  /* don't check for reservations */
+
+//----------------------------------------------------------------------
+// From linux-6.0/include/uapi/linux/mman.h
+//----------------------------------------------------------------------
+
+#define VKI_MAP_SHARED 0x01            /* Share changes */
+#define VKI_MAP_PRIVATE        0x02            /* Changes are private */
+
+//----------------------------------------------------------------------
+// From linux-6.0/include/uapi/asm-generic/fcntl.h
+//----------------------------------------------------------------------
+
+#define VKI_O_ACCMODE       03
+#define VKI_O_RDONLY        00
+#define VKI_O_WRONLY        01
+#define VKI_O_RDWR          02
+#define VKI_O_CREAT       0100 /* not fcntl */
+#define VKI_O_EXCL        0200 /* not fcntl */
+#define VKI_O_TRUNC      01000 /* not fcntl */
+#define VKI_O_APPEND     02000
+#define VKI_O_NONBLOCK   04000
+#define VKI_O_LARGEFILE        0100000
+#define VKI_O_DIRECT   00040000
+
+#define VKI_F_DUPFD            0       /* dup */
+#define VKI_F_GETFD            1       /* get close_on_exec */
+#define VKI_F_SETFD            2       /* set/clear close_on_exec */
+#define VKI_F_GETFL            3       /* get file->f_flags */
+#define VKI_F_SETFL            4       /* set file->f_flags */
+#define VKI_F_GETLK            5
+#define VKI_F_SETLK            6
+#define VKI_F_SETLKW           7
+
+#define VKI_F_SETOWN           8       /*  for sockets. */
+#define VKI_F_GETOWN           9       /*  for sockets. */
+#define VKI_F_SETSIG           10      /*  for sockets. */
+#define VKI_F_GETSIG           11      /*  for sockets. */
+
+#define VKI_F_SETOWN_EX                15
+#define VKI_F_GETOWN_EX                16
+
+#define VKI_F_OFD_GETLK                36
+#define VKI_F_OFD_SETLK                37
+#define VKI_F_OFD_SETLKW       38
+
+struct vki_f_owner_ex {
+       int     type;
+       __vki_kernel_pid_t      pid;
+};
+
+#define VKI_FD_CLOEXEC 1       /* actually anything with low bit set goes */
+
+#define VKI_F_LINUX_SPECIFIC_BASE      1024
+
+//----------------------------------------------------------------------
+// From linux-6.0/include/uapi/linux/fcntl.h
+//----------------------------------------------------------------------
+
+#define VKI_AT_FDCWD           -100
+
+//----------------------------------------------------------------------
+// From linux-6.0/include/uapi/asm-generic/resource.h
+//----------------------------------------------------------------------
+
+#define VKI_RLIMIT_DATA                2       /* max data size */
+#define VKI_RLIMIT_STACK       3       /* max stack size */
+#define VKI_RLIMIT_CORE                4       /* max core file size */
+#define VKI_RLIMIT_NOFILE      7       /* max number of open files */
+
+//----------------------------------------------------------------------
+// From linux-6.0/include/uapi/asm-generic/socket.h
+//----------------------------------------------------------------------
+
+#define VKI_SOL_SOCKET 1
+
+#define VKI_SO_TYPE    3
+
+#define VKI_SO_ATTACH_FILTER   26
+
+//----------------------------------------------------------------------
+// From linux-6.0/include/uapi/asm-generic/sockios.h
+//----------------------------------------------------------------------
+
+#define VKI_SIOCSPGRP          0x8902
+#define VKI_SIOCGPGRP          0x8904
+#define VKI_SIOCATMARK         0x8905
+#define VKI_SIOCGSTAMP         0x8906          /* Get stamp (timeval) */
+#define VKI_SIOCGSTAMPNS       0x8907          /* Get stamp (timespec) */
+
+//----------------------------------------------------------------------
+// From linux-6.0/include/uapi/asm-generic/stat.h
+//----------------------------------------------------------------------
+
+struct vki_stat {
+       unsigned long   st_dev;         /* Device.  */
+       unsigned long   st_ino;         /* File serial number.  */
+       unsigned int    st_mode;        /* File mode.  */
+       unsigned int    st_nlink;       /* Link count.  */
+       unsigned int    st_uid;         /* User ID of the file's owner.  */
+       unsigned int    st_gid;         /* Group ID of the file's group. */
+       unsigned long   st_rdev;        /* Device number, if device.  */
+       unsigned long   __pad1;
+       long            st_size;        /* Size of file, in bytes.  */
+       int             st_blksize;     /* Optimal block size for I/O.  */
+       int             __pad2;
+       long            st_blocks;      /* Number 512-byte blocks allocated. */
+       long            st_atime;       /* Time of last access.  */
+       unsigned long   st_atime_nsec;
+       long            st_mtime;       /* Time of last modification.  */
+       unsigned long   st_mtime_nsec;
+       long            st_ctime;       /* Time of last status change.  */
+       unsigned long   st_ctime_nsec;
+       unsigned int    __unused4;
+       unsigned int    __unused5;
+};
+
+//----------------------------------------------------------------------
+// From linux-6.0/include/uapi/asm-generic/statfs.h
+//----------------------------------------------------------------------
+
+struct vki_statfs {
+       long f_type;
+       long f_bsize;
+       long f_blocks;
+       long f_bfree;
+       long f_bavail;
+       long f_files;
+       long f_ffree;
+       __vki_kernel_fsid_t f_fsid;
+       long f_namelen;
+       long f_frsize;
+       long f_flags;
+       long f_spare[4];
+};
+
+//----------------------------------------------------------------------
+// From linux-6.0/include/uapi/asm-generic/termios.h
+//----------------------------------------------------------------------
+
+struct vki_winsize {
+       unsigned short ws_row;
+       unsigned short ws_col;
+       unsigned short ws_xpixel;
+       unsigned short ws_ypixel;
+};
+
+#define VKI_NCC 8
+struct vki_termio {
+       unsigned short c_iflag;         /* input mode flags */
+       unsigned short c_oflag;         /* output mode flags */
+       unsigned short c_cflag;         /* control mode flags */
+       unsigned short c_lflag;         /* local mode flags */
+       unsigned char c_line;           /* line discipline */
+       unsigned char c_cc[VKI_NCC];    /* control characters */
+};
+
+//----------------------------------------------------------------------
+// From linux-6.0/include/uapi/asm-generic/termbits.h
+//----------------------------------------------------------------------
+
+typedef unsigned char  vki_cc_t;
+typedef unsigned int   vki_tcflag_t;
+
+#define VKI_NCCS 19
+struct vki_termios {
+       vki_tcflag_t c_iflag;           /* input mode flags */
+       vki_tcflag_t c_oflag;           /* output mode flags */
+       vki_tcflag_t c_cflag;           /* control mode flags */
+       vki_tcflag_t c_lflag;           /* local mode flags */
+       vki_cc_t c_line;                /* line discipline */
+       vki_cc_t c_cc[VKI_NCCS];        /* control characters */
+};
+
+//----------------------------------------------------------------------
+// From linux-6.0/include/uapi/asm-generic/ioctl.h
+//----------------------------------------------------------------------
+
+#define _VKI_IOC_NRBITS                8
+#define _VKI_IOC_TYPEBITS      8
+#define _VKI_IOC_SIZEBITS      14
+#define _VKI_IOC_DIRBITS       2
+
+#define _VKI_IOC_SIZEMASK      ((1 << _VKI_IOC_SIZEBITS)-1)
+#define _VKI_IOC_DIRMASK       ((1 << _VKI_IOC_DIRBITS)-1)
+
+#define _VKI_IOC_NRSHIFT       0
+#define _VKI_IOC_TYPESHIFT     (_VKI_IOC_NRSHIFT+_VKI_IOC_NRBITS)
+#define _VKI_IOC_SIZESHIFT     (_VKI_IOC_TYPESHIFT+_VKI_IOC_TYPEBITS)
+#define _VKI_IOC_DIRSHIFT      (_VKI_IOC_SIZESHIFT+_VKI_IOC_SIZEBITS)
+
+#define _VKI_IOC_NONE  0U
+#define _VKI_IOC_WRITE 1U
+#define _VKI_IOC_READ  2U
+
+#define _VKI_IOC(dir,type,nr,size) \
+       (((dir)  << _VKI_IOC_DIRSHIFT) | \
+        ((type) << _VKI_IOC_TYPESHIFT) | \
+        ((nr)   << _VKI_IOC_NRSHIFT) | \
+        ((size) << _VKI_IOC_SIZESHIFT))
+
+#define _VKI_IO(type,nr)       _VKI_IOC(_VKI_IOC_NONE,(type),(nr),0)
+#define _VKI_IOR(type,nr,size) _VKI_IOC(_VKI_IOC_READ,(type),(nr),sizeof(size))
+#define _VKI_IOW(type,nr,size) _VKI_IOC(_VKI_IOC_WRITE,(type),(nr),sizeof(size))
+#define _VKI_IOWR(type,nr,size)        _VKI_IOC(_VKI_IOC_READ|_VKI_IOC_WRITE,(type),(nr),sizeof(size))
+
+#define _VKI_IOC_DIR(nr)               (((nr) >> _VKI_IOC_DIRSHIFT) & _VKI_IOC_DIRMASK)
+#define _VKI_IOC_SIZE(nr)              (((nr) >> _VKI_IOC_SIZESHIFT) & _VKI_IOC_SIZEMASK)
+
+//----------------------------------------------------------------------
+// From linux-3.10.5/include/uapi/asm-generic/ioctls.h
+//----------------------------------------------------------------------
+
+#define VKI_TCGETS     0x5401
+#define VKI_TCSETS     0x5402
+#define VKI_TCSETSW    0x5403
+#define VKI_TCSETSF    0x5404
+#define VKI_TCGETA     0x5405
+#define VKI_TCSETA     0x5406
+#define VKI_TCSETAW    0x5407
+#define VKI_TCSETAF    0x5408
+#define VKI_TCSBRK     0x5409
+#define VKI_TCXONC     0x540A
+#define VKI_TCFLSH     0x540B
+#define VKI_TIOCSCTTY  0x540E
+#define VKI_TIOCGPGRP  0x540F
+#define VKI_TIOCSPGRP  0x5410
+#define VKI_TIOCOUTQ   0x5411
+#define VKI_TIOCGWINSZ 0x5413
+#define VKI_TIOCSWINSZ 0x5414
+#define VKI_TIOCMGET   0x5415
+#define VKI_TIOCMBIS   0x5416
+#define VKI_TIOCMBIC   0x5417
+#define VKI_TIOCMSET   0x5418
+#define VKI_FIONREAD   0x541B
+#define VKI_TIOCLINUX  0x541C
+#define VKI_TIOCGSERIAL        0x541E
+#define VKI_TIOCSSERIAL        0x541F
+#define VKI_FIONBIO    0x5421
+#define VKI_TIOCNOTTY  0x5422
+#define VKI_TCSBRKP    0x5425  /* Needed for POSIX tcsendbreak() */
+#define VKI_TIOCGPTN   _VKI_IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */
+#define VKI_TIOCSPTLCK _VKI_IOW('T',0x31, int) /* Lock/unlock Pty */
+
+#define VKI_FIONCLEX    0x5450
+#define VKI_FIOCLEX     0x5451
+#define VKI_FIOASYNC   0x5452
+#define VKI_TIOCSERGETLSR   0x5459 /* Get line status register */
+
+#define VKI_TIOCGICOUNT        0x545D  /* read serial port inline interrupt counts */
+
+//----------------------------------------------------------------------
+// From linux-6.0/include/uapi/asm-generic/poll.h
+//----------------------------------------------------------------------
+
+#define VKI_POLLIN             0x0001
+
+struct vki_pollfd {
+       int fd;
+       short events;
+       short revents;
+};
+
+//----------------------------------------------------------------------
+// From linux-6.0/arch/riscv/include/uapi/asm/ptrace.h
+//----------------------------------------------------------------------
+
+struct vki_user_regs_struct {
+       unsigned long pc;
+       unsigned long ra;
+       unsigned long sp;
+       unsigned long gp;
+       unsigned long tp;
+       unsigned long t0;
+       unsigned long t1;
+       unsigned long t2;
+       unsigned long s0;
+       unsigned long s1;
+       unsigned long a0;
+       unsigned long a1;
+       unsigned long a2;
+       unsigned long a3;
+       unsigned long a4;
+       unsigned long a5;
+       unsigned long a6;
+       unsigned long a7;
+       unsigned long s2;
+       unsigned long s3;
+       unsigned long s4;
+       unsigned long s5;
+       unsigned long s6;
+       unsigned long s7;
+       unsigned long s8;
+       unsigned long s9;
+       unsigned long s10;
+       unsigned long s11;
+       unsigned long t3;
+       unsigned long t4;
+       unsigned long t5;
+       unsigned long t6;
+};
+
+struct __vki_riscv_f_ext_state {
+       __vki_u32 f[32];
+       __vki_u32 fcsr;
+};
+
+struct __vki_riscv_d_ext_state {
+       __vki_u64 f[32];
+       __vki_u32 fcsr;
+};
+
+struct __vki_riscv_q_ext_state {
+       __vki_u64 f[64] __attribute__((aligned(16)));
+       __vki_u32 fcsr;
+       __vki_u32 reserved[3];
+};
+
+union __vki_riscv_fp_state {
+       struct __vki_riscv_f_ext_state f;
+       struct __vki_riscv_d_ext_state d;
+       struct __vki_riscv_q_ext_state q;
+};
+
+//----------------------------------------------------------------------
+// From linux-6.0/arch/riscv/include/uapi/asm/sigcontext.h
+//----------------------------------------------------------------------
+
+struct vki_sigcontext {
+       struct vki_user_regs_struct sc_regs;
+       union __vki_riscv_fp_state sc_fpregs;
+};
+
+//----------------------------------------------------------------------
+// From linux-6.0/arch/riscv/include/uapi/asm/elf.h
+//----------------------------------------------------------------------
+
+typedef unsigned long vki_elf_greg_t;
+typedef struct vki_user_regs_struct vki_elf_gregset_t;
+#define VKI_ELF_NGREG (sizeof (struct vki_elf_gregset_t) / sizeof(vki_elf_greg_t))
+
+typedef union __vki_riscv_fp_state vki_elf_fpregset_t;
+
+//----------------------------------------------------------------------
+// From linux-6.0/arch/riscv/include/uapi/asm/ucontext.h
+//----------------------------------------------------------------------
+
+struct vki_ucontext {
+       unsigned long           uc_flags;
+       struct vki_ucontext     *uc_link;
+       vki_stack_t             uc_stack;
+       vki_sigset_t            uc_sigmask;
+       __vki_u8                __unused[1024 / 8 - sizeof(vki_sigset_t)];
+       struct vki_sigcontext   uc_mcontext;
+};
+
+typedef char vki_modify_ldt_t;
+
+//----------------------------------------------------------------------
+// From linux-6.0/include/uapi/asm-generic/ipcbuf.h
+//----------------------------------------------------------------------
+
+struct vki_ipc64_perm {
+       __vki_kernel_key_t      key;
+       __vki_kernel_uid32_t    uid;
+       __vki_kernel_gid32_t    gid;
+       __vki_kernel_uid32_t    cuid;
+       __vki_kernel_gid32_t    cgid;
+       __vki_kernel_mode_t     mode;
+        unsigned char           __pad1[4 - sizeof(__vki_kernel_mode_t)];
+       unsigned short          seq;
+       unsigned short          __pad2;
+       unsigned long           __unused1;
+       unsigned long           __unused2;
+};
+
+//----------------------------------------------------------------------
+// From linux-6.0/include/uapi/asm-generic/sembuf.h
+//----------------------------------------------------------------------
+
+struct vki_semid64_ds {
+       struct vki_ipc64_perm sem_perm;         /* permissions .. see ipc.h */
+       __vki_kernel_time_t     sem_otime;              /* last semop time */
+       __vki_kernel_time_t     sem_ctime;              /* last change time */
+       unsigned long   sem_nsems;              /* no. of semaphores in array */
+       unsigned long   __unused3;
+       unsigned long   __unused4;
+};
+
+//----------------------------------------------------------------------
+// From linux-6.0/include/uapi/asm-generic/msgbuf.h
+//----------------------------------------------------------------------
+
+struct vki_msqid64_ds {
+       struct vki_ipc64_perm msg_perm;
+       __vki_kernel_time_t msg_stime;  /* last msgsnd time */
+       __vki_kernel_time_t msg_rtime;  /* last msgrcv time */
+       __vki_kernel_time_t msg_ctime;  /* last change time */
+       unsigned long  msg_cbytes;      /* current number of bytes on queue */
+       unsigned long  msg_qnum;        /* number of messages in queue */
+       unsigned long  msg_qbytes;      /* max number of bytes on queue */
+       __vki_kernel_pid_t msg_lspid;   /* pid of last msgsnd */
+       __vki_kernel_pid_t msg_lrpid;   /* last receive pid */
+       unsigned long  __unused4;
+       unsigned long  __unused5;
+};
+
+//----------------------------------------------------------------------
+// From linux-6.0/include/uapi/asm-generic/shmbuf.h
+//----------------------------------------------------------------------
+
+struct vki_shmid64_ds {
+       struct vki_ipc64_perm   shm_perm;       /* operation perms */
+       vki_size_t              shm_segsz;      /* size of segment (bytes) */
+       __vki_kernel_time_t     shm_atime;      /* last attach time */
+       __vki_kernel_time_t     shm_dtime;      /* last detach time */
+       __vki_kernel_time_t     shm_ctime;      /* last change time */
+       __vki_kernel_pid_t      shm_cpid;       /* pid of creator */
+       __vki_kernel_pid_t      shm_lpid;       /* pid of last operator */
+       unsigned long           shm_nattch;     /* no. of current attaches */
+       unsigned long           __unused4;
+       unsigned long           __unused5;
+};
+
+struct vki_shminfo64 {
+       unsigned long   shmmax;
+       unsigned long   shmmin;
+       unsigned long   shmmni;
+       unsigned long   shmseg;
+       unsigned long   shmall;
+       unsigned long   __unused1;
+       unsigned long   __unused2;
+       unsigned long   __unused3;
+       unsigned long   __unused4;
+};
+
+//----------------------------------------------------------------------
+// From linux-6.0/include/uapi/asm-generic/errno.h
+//----------------------------------------------------------------------
+
+#define        VKI_ENOSYS              38      /* Invalid system call number */
+#define        VKI_EOVERFLOW           75      /* Value too large for defined data type */
+
+#endif // __VKI_RISCV64_LINUX_H
+
+/*--------------------------------------------------------------------*/
+/*--- end                                      vki-riscv64-linux.h ---*/
+/*--------------------------------------------------------------------*/
diff --git a/include/vki/vki-scnums-riscv64-linux.h b/include/vki/vki-scnums-riscv64-linux.h
new file mode 100644 (file)
index 0000000..15ba930
--- /dev/null
@@ -0,0 +1,329 @@
+
+/*--------------------------------------------------------------------*/
+/*--- System call numbers for riscv64-linux.                       ---*/
+/*---                                   vki-scnums-riscv64-linux.h ---*/
+/*--------------------------------------------------------------------*/
+
+/*
+   This file is part of Valgrind, a dynamic binary instrumentation
+   framework.
+
+   Copyright (C) 2020-2023 Petr Pavlu
+      petr.pavlu@dagobah.cz
+
+   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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, see <http://www.gnu.org/licenses/>.
+
+   The GNU General Public License is contained in the file COPYING.
+*/
+
+#ifndef __VKI_SCNUMS_RISCV64_LINUX_H
+#define __VKI_SCNUMS_RISCV64_LINUX_H
+
+// From linux-6.0/arch/riscv/include/uapi/asm/unistd.h
+// is a #include of
+//      linux-6.0/include/uapi/asm-generic/unistd.h
+
+#define __NR_io_setup 0
+#define __NR_io_destroy 1
+#define __NR_io_submit 2
+#define __NR_io_cancel 3
+#define __NR_io_getevents 4
+#define __NR_setxattr 5
+#define __NR_lsetxattr 6
+#define __NR_fsetxattr 7
+#define __NR_getxattr 8
+#define __NR_lgetxattr 9
+#define __NR_fgetxattr 10
+#define __NR_listxattr 11
+#define __NR_llistxattr 12
+#define __NR_flistxattr 13
+#define __NR_removexattr 14
+#define __NR_lremovexattr 15
+#define __NR_fremovexattr 16
+#define __NR_getcwd 17
+#define __NR_lookup_dcookie 18
+#define __NR_eventfd2 19
+#define __NR_epoll_create1 20
+#define __NR_epoll_ctl 21
+#define __NR_epoll_pwait 22
+#define __NR_dup 23
+#define __NR_dup3 24
+#define __NR3264_fcntl 25
+#define __NR_inotify_init1 26
+#define __NR_inotify_add_watch 27
+#define __NR_inotify_rm_watch 28
+#define __NR_ioctl 29
+#define __NR_ioprio_set 30
+#define __NR_ioprio_get 31
+#define __NR_flock 32
+#define __NR_mknodat 33
+#define __NR_mkdirat 34
+#define __NR_unlinkat 35
+#define __NR_symlinkat 36
+#define __NR_linkat 37
+#define __NR_umount2 39
+#define __NR_mount 40
+#define __NR_pivot_root 41
+#define __NR3264_statfs 43
+#define __NR3264_fstatfs 44
+#define __NR3264_truncate 45
+#define __NR3264_ftruncate 46
+#define __NR_fallocate 47
+#define __NR_faccessat 48
+#define __NR_chdir 49
+#define __NR_fchdir 50
+#define __NR_chroot 51
+#define __NR_fchmod 52
+#define __NR_fchmodat 53
+#define __NR_fchownat 54
+#define __NR_fchown 55
+#define __NR_openat 56
+#define __NR_close 57
+#define __NR_vhangup 58
+#define __NR_pipe2 59
+#define __NR_quotactl 60
+#define __NR_getdents64 61
+#define __NR3264_lseek 62
+#define __NR_read 63
+#define __NR_write 64
+#define __NR_readv 65
+#define __NR_writev 66
+#define __NR_pread64 67
+#define __NR_pwrite64 68
+#define __NR_preadv 69
+#define __NR_pwritev 70
+#define __NR3264_sendfile 71
+#define __NR_pselect6 72
+#define __NR_ppoll 73
+#define __NR_signalfd4 74
+#define __NR_vmsplice 75
+#define __NR_splice 76
+#define __NR_tee 77
+#define __NR_readlinkat 78
+#define __NR3264_fstatat 79
+#define __NR3264_fstat 80
+#define __NR_sync 81
+#define __NR_fsync 82
+#define __NR_fdatasync 83
+#define __NR_sync_file_range 84
+#define __NR_timerfd_create 85
+#define __NR_timerfd_settime 86
+#define __NR_timerfd_gettime 87
+#define __NR_utimensat 88
+#define __NR_acct 89
+#define __NR_capget 90
+#define __NR_capset 91
+#define __NR_personality 92
+#define __NR_exit 93
+#define __NR_exit_group 94
+#define __NR_waitid 95
+#define __NR_set_tid_address 96
+#define __NR_unshare 97
+#define __NR_futex 98
+#define __NR_set_robust_list 99
+#define __NR_get_robust_list 100
+#define __NR_nanosleep 101
+#define __NR_getitimer 102
+#define __NR_setitimer 103
+#define __NR_kexec_load 104
+#define __NR_init_module 105
+#define __NR_delete_module 106
+#define __NR_timer_create 107
+#define __NR_timer_gettime 108
+#define __NR_timer_getoverrun 109
+#define __NR_timer_settime 110
+#define __NR_timer_delete 111
+#define __NR_clock_settime 112
+#define __NR_clock_gettime 113
+#define __NR_clock_getres 114
+#define __NR_clock_nanosleep 115
+#define __NR_syslog 116
+#define __NR_ptrace 117
+#define __NR_sched_setparam 118
+#define __NR_sched_setscheduler 119
+#define __NR_sched_getscheduler 120
+#define __NR_sched_getparam 121
+#define __NR_sched_setaffinity 122
+#define __NR_sched_getaffinity 123
+#define __NR_sched_yield 124
+#define __NR_sched_get_priority_max 125
+#define __NR_sched_get_priority_min 126
+#define __NR_sched_rr_get_interval 127
+#define __NR_kill 129
+#define __NR_tkill 130
+#define __NR_tgkill 131
+#define __NR_sigaltstack 132
+#define __NR_rt_sigsuspend 133
+#define __NR_rt_sigaction 134
+#define __NR_rt_sigprocmask 135
+#define __NR_rt_sigpending 136
+#define __NR_rt_sigtimedwait 137
+#define __NR_rt_sigqueueinfo 138
+#define __NR_rt_sigreturn 139
+#define __NR_setpriority 140
+#define __NR_getpriority 141
+#define __NR_setregid 143
+#define __NR_setgid 144
+#define __NR_setreuid 145
+#define __NR_setuid 146
+#define __NR_setresuid 147
+#define __NR_getresuid 148
+#define __NR_setresgid 149
+#define __NR_getresgid 150
+#define __NR_setfsuid 151
+#define __NR_setfsgid 152
+#define __NR_times 153
+#define __NR_setpgid 154
+#define __NR_getpgid 155
+#define __NR_getsid 156
+#define __NR_setsid 157
+#define __NR_getgroups 158
+#define __NR_setgroups 159
+#define __NR_uname 160
+#define __NR_sethostname 161
+#define __NR_getrlimit 163
+#define __NR_setrlimit 164
+#define __NR_getrusage 165
+#define __NR_umask 166
+#define __NR_prctl 167
+#define __NR_getcpu 168
+#define __NR_gettimeofday 169
+#define __NR_settimeofday 170
+#define __NR_adjtimex 171
+#define __NR_getpid 172
+#define __NR_getppid 173
+#define __NR_getuid 174
+#define __NR_geteuid 175
+#define __NR_getgid 176
+#define __NR_getegid 177
+#define __NR_gettid 178
+#define __NR_sysinfo 179
+#define __NR_mq_open 180
+#define __NR_mq_unlink 181
+#define __NR_mq_timedsend 182
+#define __NR_mq_timedreceive 183
+#define __NR_mq_notify 184
+#define __NR_mq_getsetattr 185
+#define __NR_msgget 186
+#define __NR_msgctl 187
+#define __NR_msgrcv 188
+#define __NR_msgsnd 189
+#define __NR_semget 190
+#define __NR_semctl 191
+#define __NR_semtimedop 192
+#define __NR_semop 193
+#define __NR_shmget 194
+#define __NR_shmctl 195
+#define __NR_shmat 196
+#define __NR_shmdt 197
+#define __NR_socket 198
+#define __NR_socketpair 199
+#define __NR_bind 200
+#define __NR_listen 201
+#define __NR_accept 202
+#define __NR_connect 203
+#define __NR_getsockname 204
+#define __NR_getpeername 205
+#define __NR_sendto 206
+#define __NR_recvfrom 207
+#define __NR_setsockopt 208
+#define __NR_getsockopt 209
+#define __NR_shutdown 210
+#define __NR_sendmsg 211
+#define __NR_recvmsg 212
+#define __NR_readahead 213
+#define __NR_brk 214
+#define __NR_munmap 215
+#define __NR_mremap 216
+#define __NR_add_key 217
+#define __NR_request_key 218
+#define __NR_keyctl 219
+#define __NR_clone 220
+#define __NR_execve 221
+#define __NR3264_mmap 222
+#define __NR3264_fadvise64 223
+#define __NR_mprotect 226
+#define __NR_msync 227
+#define __NR_mlock 228
+#define __NR_munlock 229
+#define __NR_mlockall 230
+#define __NR_munlockall 231
+#define __NR_mincore 232
+#define __NR_madvise 233
+#define __NR_mbind 235
+#define __NR_get_mempolicy 236
+#define __NR_set_mempolicy 237
+#define __NR_move_pages 239
+#define __NR_rt_tgsigqueueinfo 240
+#define __NR_perf_event_open 241
+#define __NR_accept4 242
+#define __NR_recvmmsg 243
+#define __NR_arch_specific_syscall 244
+#define __NR_wait4 260
+#define __NR_prlimit64 261
+#define __NR_fanotify_init 262
+#define __NR_fanotify_mark 263
+#define __NR_name_to_handle_at 264
+#define __NR_open_by_handle_at 265
+#define __NR_clock_adjtime 266
+#define __NR_syncfs 267
+#define __NR_setns 268
+#define __NR_sendmmsg 269
+#define __NR_process_vm_readv 270
+#define __NR_process_vm_writev 271
+#define __NR_kcmp 272
+#define __NR_finit_module 273
+#define __NR_sched_setattr 274
+#define __NR_sched_getattr 275
+#define __NR_renameat2 276
+#define __NR_getrandom 278
+#define __NR_memfd_create 279
+#define __NR_bpf 280
+#define __NR_execveat 281
+#define __NR_userfaultfd 282
+#define __NR_membarrier 283
+#define __NR_mlock2 284
+#define __NR_copy_file_range 285
+#define __NR_preadv2 286
+#define __NR_pwritev2 287
+#define __NR_pkey_free 290
+#define __NR_statx 291
+#define __NR_rseq 293
+#define __NR_io_uring_setup 425
+#define __NR_io_uring_enter 426
+#define __NR_io_uring_register 427
+#define __NR_clone3 435
+#define __NR_close_range 436
+#define __NR_faccessat2 439
+#define __NR_memfd_secret 447
+
+#define __NR_fcntl __NR3264_fcntl
+#define __NR_statfs __NR3264_statfs
+#define __NR_fstatfs __NR3264_fstatfs
+#define __NR_truncate __NR3264_truncate
+#define __NR_ftruncate __NR3264_ftruncate
+#define __NR_lseek __NR3264_lseek
+#define __NR_sendfile __NR3264_sendfile
+#define __NR_newfstatat __NR3264_fstatat
+#define __NR_fstat __NR3264_fstat
+#define __NR_mmap __NR3264_mmap
+#define __NR_fadvise64 __NR3264_fadvise64
+
+#define __NR_riscv_flush_icache (__NR_arch_specific_syscall + 15)
+
+#endif /* __VKI_SCNUMS_RISCV64_LINUX_H */
+
+/*--------------------------------------------------------------------*/
+/*--- end                               vki-scnums-riscv64-linux.h ---*/
+/*--------------------------------------------------------------------*/