From: Petr Pavlu Date: Tue, 11 Apr 2023 19:30:42 +0000 (+0000) Subject: riscv64: Add initial support: new port-specific Valgrind files X-Git-Tag: VALGRIND_3_25_0~136 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=949abd0472161a7fc0aa5e869f89b533793f0948;p=thirdparty%2Fvalgrind.git riscv64: Add initial support: new port-specific Valgrind files The following people contributed to the initial RISC-V support: Petr Pavlu Xeonacid laokz Chelsea E. Manning zhaomingxin Jojo R Some integration fixes were added by Mark Wielaard - 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 --- diff --git a/README.riscv64 b/README.riscv64 new file mode 100644 index 000000000..04f2bc957 --- /dev/null +++ b/README.riscv64 @@ -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 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 index 000000000..c4941e457 --- /dev/null +++ b/coregrind/m_dispatch/dispatch-riscv64-linux.S @@ -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 . + + 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 index 000000000..22c7dd038 --- /dev/null +++ b/coregrind/m_gdbserver/riscv64-cpu-valgrind-s1.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/coregrind/m_gdbserver/riscv64-cpu-valgrind-s2.xml b/coregrind/m_gdbserver/riscv64-cpu-valgrind-s2.xml new file mode 100644 index 000000000..095a992fc --- /dev/null +++ b/coregrind/m_gdbserver/riscv64-cpu-valgrind-s2.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/coregrind/m_gdbserver/riscv64-cpu.xml b/coregrind/m_gdbserver/riscv64-cpu.xml new file mode 100644 index 000000000..2d31a6e19 --- /dev/null +++ b/coregrind/m_gdbserver/riscv64-cpu.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/coregrind/m_gdbserver/riscv64-fpu-valgrind-s1.xml b/coregrind/m_gdbserver/riscv64-fpu-valgrind-s1.xml new file mode 100644 index 000000000..263a3fffb --- /dev/null +++ b/coregrind/m_gdbserver/riscv64-fpu-valgrind-s1.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/coregrind/m_gdbserver/riscv64-fpu-valgrind-s2.xml b/coregrind/m_gdbserver/riscv64-fpu-valgrind-s2.xml new file mode 100644 index 000000000..1992c03f2 --- /dev/null +++ b/coregrind/m_gdbserver/riscv64-fpu-valgrind-s2.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/coregrind/m_gdbserver/riscv64-fpu.xml b/coregrind/m_gdbserver/riscv64-fpu.xml new file mode 100644 index 000000000..ff42b4a21 --- /dev/null +++ b/coregrind/m_gdbserver/riscv64-fpu.xml @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/coregrind/m_gdbserver/riscv64-linux-valgrind.xml b/coregrind/m_gdbserver/riscv64-linux-valgrind.xml new file mode 100644 index 000000000..0227f2ee7 --- /dev/null +++ b/coregrind/m_gdbserver/riscv64-linux-valgrind.xml @@ -0,0 +1,21 @@ + + + + + + riscv + + + + + + + + + + + \ 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 index 000000000..7c8631220 --- /dev/null +++ b/coregrind/m_gdbserver/riscv64-linux.xml @@ -0,0 +1,17 @@ + + + + + + riscv + + + + + + + \ 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 index 000000000..75088fc1e --- /dev/null +++ b/coregrind/m_gdbserver/valgrind-low-riscv64.c @@ -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 index 000000000..8ef05407e --- /dev/null +++ b/coregrind/m_sigframe/sigframe-riscv64-linux.c @@ -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 . + + 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 index 000000000..cf976cee1 --- /dev/null +++ b/coregrind/m_syswrap/syscall-riscv64-linux.S @@ -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 . + + 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 index 000000000..68c53b0bd --- /dev/null +++ b/coregrind/m_syswrap/syswrap-riscv64-linux.c @@ -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 . + + 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 index 000000000..eb0ce4dc0 --- /dev/null +++ b/docs/internals/qemu-riscv64-linux-HOWTO.txt @@ -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 index 000000000..b8dfc9ce7 --- /dev/null +++ b/include/vki/vki-posixtypes-riscv64-linux.h @@ -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 . + + 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 index 000000000..5cc98b6ab --- /dev/null +++ b/include/vki/vki-riscv64-linux.h @@ -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 . + + 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 index 000000000..15ba9308d --- /dev/null +++ b/include/vki/vki-scnums-riscv64-linux.h @@ -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 . + + 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 ---*/ +/*--------------------------------------------------------------------*/