From b0a209ac0f10f3fb02bde00a1f515dbe95cbfff7 Mon Sep 17 00:00:00 2001 From: Jer6y Date: Wed, 10 Apr 2024 19:22:19 +0800 Subject: [PATCH 1/2] riscv: add riscv arch support *add riscv arch support Signed-off-by: luojun --- src/GNUmakefile | 6 +- src/arch.h | 23 ++- src/loader/assembly-riscv64.h | 90 ++++++++++++ src/loader/loader.c | 2 + src/ptrace/ptrace.c | 4 + src/ptrace/user.c | 6 + src/syscall/sysnums-riscv64.h | 268 ++++++++++++++++++++++++++++++++++ src/tracee/event.c | 2 +- src/tracee/mem.c | 6 + src/tracee/reg.c | 36 ++++- src/tracee/tracee.h | 6 + test/ptrace-2.c | 26 ++++ test/ptrace-3.c | 6 + 13 files changed, 475 insertions(+), 6 deletions(-) create mode 100644 src/loader/assembly-riscv64.h create mode 100644 src/syscall/sysnums-riscv64.h diff --git a/src/GNUmakefile b/src/GNUmakefile index 168a044a..78e4a867 100644 --- a/src/GNUmakefile +++ b/src/GNUmakefile @@ -14,6 +14,7 @@ STRIP = $(CROSS_COMPILE)strip OBJCOPY = $(CROSS_COMPILE)objcopy OBJDUMP = $(CROSS_COMPILE)objdump PYTHON = python3 +ARCH = $(shell uname -m) HAS_SWIG := $(shell swig -version 2>/dev/null) PYTHON_MAJOR_VERSION = $(shell ${PYTHON} -c "import sys; print(sys.version_info.major)" 2>/dev/null) @@ -21,8 +22,11 @@ PYTHON_EMBED = $(shell ${PYTHON} -c "import sys; print('--embed' if sys.hexversi HAS_PYTHON_CONFIG := $(shell ${PYTHON}-config --ldflags ${PYTHON_EMBED} 2>/dev/null) CPPFLAGS += -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE -I. -I$(VPATH) -I$(VPATH)/../lib/uthash/include -CFLAGS += -g -Wall -Wextra -O2 +ifeq ($(ARCH),riscv64) +CFLAGS += -g -Wall -Wextra -O0 +else CFLAGS += $(shell pkg-config --cflags talloc) +endif LDFLAGS += -Wl,-z,noexecstack LDFLAGS += $(shell pkg-config --libs talloc) diff --git a/src/arch.h b/src/arch.h index 9218f690..0754e89c 100644 --- a/src/arch.h +++ b/src/arch.h @@ -38,7 +38,7 @@ typedef unsigned char byte_t; #define OFFSETOF_STATX_UID 20 #define OFFSETOF_STATX_GID 24 -#if !defined(ARCH_X86_64) && !defined(ARCH_ARM_EABI) && !defined(ARCH_X86) && !defined(ARCH_SH4) +#if !defined(ARCH_X86_64) && !defined(ARCH_ARM_EABI) && !defined(ARCH_X86) && !defined(ARCH_SH4) && !defined(ARCH_RISCV64) # if defined(__x86_64__) # define ARCH_X86_64 1 # elif defined(__ARM_EABI__) @@ -51,6 +51,8 @@ typedef unsigned char byte_t; # define ARCH_X86 1 # elif defined(__SH4__) # define ARCH_SH4 1 +# elif defined(__riscv) && __riscv_flen == 64 +# define ARCH_RISCV64 1 # else # error "Unsupported architecture" # endif @@ -110,6 +112,25 @@ typedef unsigned char byte_t; #define EXEC_PIC_ADDRESS 0x0f000000 #define INTERP_PIC_ADDRESS 0x1f000000 +#elif defined(ARCH_RISCV64) + + #define SYSNUMS_HEADER1 "syscall/sysnums-riscv64.h" + #define SYSNUMS_ABI1 sysnums_riscv64 + #define SYSTRAP_SIZE 4 + + #define SECCOMP_ARCHS { { .value = AUDIT_ARCH_RISCV64, .nb_abis = 1, .abis = { ABI_DEFAULT } } } + + #define user_regs_struct user_regs_struct + #define HOST_ELF_MACHINE {243}; + #define RED_ZONE_SIZE 0 + #define OFFSETOF_STAT_UID_32 0 + #define OFFSETOF_STAT_GID_32 0 + + #define EXEC_PIC_ADDRESS 0x10000 + + #define LOADER_ADDRESS 0x10000000 + #define INTERP_PIC_ADDRESS 0x1f000000 + #elif defined(ARCH_ARM64) #define SYSNUMS_HEADER1 "syscall/sysnums-arm64.h" diff --git a/src/loader/assembly-riscv64.h b/src/loader/assembly-riscv64.h new file mode 100644 index 00000000..8d77c340 --- /dev/null +++ b/src/loader/assembly-riscv64.h @@ -0,0 +1,90 @@ +/* -*- c-set-style: "K&R"; c-basic-offset: 8 -*- + * + * This file is part of PRoot. + * + * Copyright (C) 2024 STMicroelectronics + * + * 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. + */ + +/* + * - the instruction pointer (pc) + * - the stack pointer (sp) + * - the rtld_fini pointer (a0) + */ +#define BRANCH(stack_pointer, destination) do { \ + asm volatile ("add sp, %0, zero"::"r"(stack_pointer):"memory"); \ + asm volatile ("add a0, zero, zero"); \ + asm volatile ("jr %0"::"r"(destination):"memory","a0"); \ + __builtin_unreachable(); \ + } while (0) + +#define PREPARE_ARGS_1(arg1_) \ + register word_t arg1 asm("a0") = arg1_; \ + +#define PREPARE_ARGS_3(arg1_, arg2_, arg3_) \ + PREPARE_ARGS_1(arg1_) \ + register word_t arg2 asm("a1") = arg2_; \ + register word_t arg3 asm("a2") = arg3_; \ + +#define PREPARE_ARGS_4(arg1_, arg2_, arg3_, arg4_) \ + PREPARE_ARGS_3(arg1_, arg2_, arg3_) \ + register word_t arg4 asm("a3") = arg4_; \ + +#define PREPARE_ARGS_6(arg1_, arg2_, arg3_, arg4_, arg5_, arg6_) \ + PREPARE_ARGS_4(arg1_, arg2_, arg3_, arg4_) \ + register word_t arg5 asm("a4") = arg5_; \ + register word_t arg6 asm("a5") = arg6_; + + +#define OUTPUT_CONTRAINTS_1 \ + "r" (arg1) + +#define OUTPUT_CONTRAINTS_3 \ + OUTPUT_CONTRAINTS_1, \ + "r" (arg2), "r" (arg3) + +#define OUTPUT_CONTRAINTS_4 \ + OUTPUT_CONTRAINTS_3, \ + "r" (arg4) + +#define OUTPUT_CONTRAINTS_6 \ + OUTPUT_CONTRAINTS_4, \ + "r" (arg5), "r" (arg6) + + + +#define SYSCALL(number_, nb_args, args...) \ + ({ \ + register word_t number asm("a7") = number_; \ + register word_t result asm("a0"); \ + PREPARE_ARGS_##nb_args(args) \ + asm volatile ( \ + "ecall \n\t" \ + : "=r" (result) \ + : "r" (number), \ + OUTPUT_CONTRAINTS_##nb_args \ + : "memory"); \ + result; \ + }) + +#define OPENAT 56 +#define CLOSE 57 +#define MMAP 222 +#define EXECVE 221 +#define EXIT 93 +#define PRCTL 167 +#define MPROTECT 22 diff --git a/src/loader/loader.c b/src/loader/loader.c index 79e15f56..016d0cb9 100644 --- a/src/loader/loader.c +++ b/src/loader/loader.c @@ -43,6 +43,8 @@ # include "loader/assembly-x86.h" #elif defined(ARCH_ARM64) # include "loader/assembly-arm64.h" +#elif defined(ARCH_RISCV64) +# include "loader/assembly-riscv64.h" #else # error "Unsupported architecture" #endif diff --git a/src/ptrace/ptrace.c b/src/ptrace/ptrace.c index 8085b311..a2af5512 100644 --- a/src/ptrace/ptrace.c +++ b/src/ptrace/ptrace.c @@ -58,6 +58,10 @@ #define user_fpregs_struct user_fpsimd_struct #endif +#if defined(ARCH_RISCV64) +#define user_fpregs_struct __riscv_d_ext_state +#endif + static const char *stringify_ptrace(PTRACE_REQUEST_TYPE request) { #define CASE_STR(a) case a: return #a; break; diff --git a/src/ptrace/user.c b/src/ptrace/user.c index 669dbe62..50fc7fa6 100644 --- a/src/ptrace/user.c +++ b/src/ptrace/user.c @@ -30,6 +30,12 @@ #include "ptrace/user.h" #include "cli/note.h" +#if defined(ARCH_RISCV64) && defined(__GLIBC__) +/* ptrace user_regs in glibc for riscv is in asm/ptrace.h */ +/* not in sys/user.h */ +#include +#endif + #if defined(ARCH_X86_64) /** diff --git a/src/syscall/sysnums-riscv64.h b/src/syscall/sysnums-riscv64.h new file mode 100644 index 00000000..620678fa --- /dev/null +++ b/src/syscall/sysnums-riscv64.h @@ -0,0 +1,268 @@ +#include "syscall/sysnum.h" + +static const Sysnum sysnums_riscv64[] = { + [ 0 ] = PR_io_setup, + [ 1 ] = PR_io_destroy, + [ 2 ] = PR_io_submit, + [ 3 ] = PR_io_cancel, + [ 4 ] = PR_io_getevents, + [ 5 ] = PR_setxattr, + [ 6 ] = PR_lsetxattr, + [ 7 ] = PR_fsetxattr, + [ 8 ] = PR_getxattr, + [ 9 ] = PR_lgetxattr, + [ 10 ] = PR_fgetxattr, + [ 11 ] = PR_listxattr, + [ 12 ] = PR_llistxattr, + [ 13 ] = PR_flistxattr, + [ 14 ] = PR_removexattr, + [ 15 ] = PR_lremovexattr, + [ 16 ] = PR_fremovexattr, + [ 17 ] = PR_getcwd, + [ 18 ] = PR_lookup_dcookie, + [ 19 ] = PR_eventfd2, + [ 20 ] = PR_epoll_create1, + [ 21 ] = PR_epoll_ctl, + [ 22 ] = PR_epoll_pwait, + [ 23 ] = PR_dup, + [ 24 ] = PR_dup3, + [ 25 ] = PR_fcntl, + [ 26 ] = PR_inotify_init1, + [ 27 ] = PR_inotify_add_watch, + [ 28 ] = PR_inotify_rm_watch, + [ 29 ] = PR_ioctl, + [ 30 ] = PR_ioprio_set, + [ 31 ] = PR_ioprio_get, + [ 32 ] = PR_flock, + [ 33 ] = PR_mknodat, + [ 34 ] = PR_mkdirat, + [ 35 ] = PR_unlinkat, + [ 36 ] = PR_symlinkat, + [ 37 ] = PR_linkat, + [ 38 ] = PR_renameat, + [ 39 ] = PR_umount2, + [ 40 ] = PR_mount, + [ 41 ] = PR_pivot_root, + [ 42 ] = PR_nfsservctl, + [ 43 ] = PR_statfs, + [ 44 ] = PR_fstatfs, + [ 45 ] = PR_truncate, + [ 46 ] = PR_ftruncate, + [ 47 ] = PR_fallocate, + [ 48 ] = PR_faccessat, + [ 49 ] = PR_chdir, + [ 50 ] = PR_fchdir, + [ 51 ] = PR_chroot, + [ 52 ] = PR_fchmod, + [ 53 ] = PR_fchmodat, + [ 54 ] = PR_fchownat, + [ 55 ] = PR_fchown, + [ 56 ] = PR_openat, + [ 57 ] = PR_close, + [ 58 ] = PR_vhangup, + [ 59 ] = PR_pipe2, + [ 60 ] = PR_quotactl, + [ 61 ] = PR_getdents64, + [ 62 ] = PR_lseek, + [ 63 ] = PR_read, + [ 64 ] = PR_write, + [ 65 ] = PR_readv, + [ 66 ] = PR_writev, + [ 67 ] = PR_pread64, + [ 68 ] = PR_pwrite64, + [ 69 ] = PR_preadv, + [ 70 ] = PR_pwritev, + [ 71 ] = PR_sendfile, + [ 72 ] = PR_pselect6, + [ 73 ] = PR_ppoll, + [ 74 ] = PR_signalfd4, + [ 75 ] = PR_vmsplice, + [ 76 ] = PR_splice, + [ 77 ] = PR_tee, + [ 78 ] = PR_readlinkat, + [ 79 ] = PR_fstatat64, + [ 80 ] = PR_fstat, + [ 81 ] = PR_sync, + [ 82 ] = PR_fsync, + [ 83 ] = PR_fdatasync, + [ 84 ] = PR_sync_file_range, + [ 85 ] = PR_timerfd_create, + [ 86 ] = PR_timerfd_settime, + [ 87 ] = PR_timerfd_gettime, + [ 88 ] = PR_utimensat, + [ 89 ] = PR_acct, + [ 90 ] = PR_capget, + [ 91 ] = PR_capset, + [ 92 ] = PR_personality, + [ 93 ] = PR_exit, + [ 94 ] = PR_exit_group, + [ 95 ] = PR_waitid, + [ 96 ] = PR_set_tid_address, + [ 97 ] = PR_unshare, + [ 98 ] = PR_futex, + [ 99 ] = PR_set_robust_list, + [ 100 ] = PR_get_robust_list, + [ 101 ] = PR_nanosleep, + [ 102 ] = PR_getitimer, + [ 103 ] = PR_setitimer, + [ 104 ] = PR_kexec_load, + [ 105 ] = PR_init_module, + [ 106 ] = PR_delete_module, + [ 107 ] = PR_timer_create, + [ 108 ] = PR_timer_gettime, + [ 109 ] = PR_timer_getoverrun, + [ 110 ] = PR_timer_settime, + [ 111 ] = PR_timer_delete, + [ 112 ] = PR_clock_settime, + [ 113 ] = PR_clock_gettime, + [ 114 ] = PR_clock_getres, + [ 115 ] = PR_clock_nanosleep, + [ 116 ] = PR_syslog, + [ 117 ] = PR_ptrace, + [ 118 ] = PR_sched_setparam, + [ 119 ] = PR_sched_setscheduler, + [ 120 ] = PR_sched_getscheduler, + [ 121 ] = PR_sched_getparam, + [ 122 ] = PR_sched_setaffinity, + [ 123 ] = PR_sched_getaffinity, + [ 124 ] = PR_sched_yield, + [ 125 ] = PR_sched_get_priority_max, + [ 126 ] = PR_sched_get_priority_min, + [ 127 ] = PR_sched_rr_get_interval, + [ 128 ] = PR_restart_syscall, + [ 129 ] = PR_kill, + [ 130 ] = PR_tkill, + [ 131 ] = PR_tgkill, + [ 132 ] = PR_sigaltstack, + [ 133 ] = PR_rt_sigsuspend, + [ 134 ] = PR_rt_sigaction, + [ 135 ] = PR_rt_sigprocmask, + [ 136 ] = PR_rt_sigpending, + [ 137 ] = PR_rt_sigtimedwait, + [ 138 ] = PR_rt_sigqueueinfo, + [ 139 ] = PR_rt_sigreturn, + [ 140 ] = PR_setpriority, + [ 141 ] = PR_getpriority, + [ 142 ] = PR_reboot, + [ 143 ] = PR_setregid, + [ 144 ] = PR_setgid, + [ 145 ] = PR_setreuid, + [ 146 ] = PR_setuid, + [ 147 ] = PR_setresuid, + [ 148 ] = PR_getresuid, + [ 149 ] = PR_setresgid, + [ 150 ] = PR_getresgid, + [ 151 ] = PR_setfsuid, + [ 152 ] = PR_setfsgid, + [ 153 ] = PR_times, + [ 154 ] = PR_setpgid, + [ 155 ] = PR_getpgid, + [ 156 ] = PR_getsid, + [ 157 ] = PR_setsid, + [ 158 ] = PR_getgroups, + [ 159 ] = PR_setgroups, + [ 160 ] = PR_uname, + [ 161 ] = PR_sethostname, + [ 162 ] = PR_setdomainname, + [ 163 ] = PR_getrlimit, + [ 164 ] = PR_setrlimit, + [ 165 ] = PR_getrusage, + [ 166 ] = PR_umask, + [ 167 ] = PR_prctl, + [ 168 ] = PR_getcpu, + [ 169 ] = PR_gettimeofday, + [ 170 ] = PR_settimeofday, + [ 171 ] = PR_adjtimex, + [ 172 ] = PR_getpid, + [ 173 ] = PR_getppid, + [ 174 ] = PR_getuid, + [ 175 ] = PR_geteuid, + [ 176 ] = PR_getgid, + [ 177 ] = PR_getegid, + [ 178 ] = PR_gettid, + [ 179 ] = PR_sysinfo, + [ 180 ] = PR_mq_open, + [ 181 ] = PR_mq_unlink, + [ 182 ] = PR_mq_timedsend, + [ 183 ] = PR_mq_timedreceive, + [ 184 ] = PR_mq_notify, + [ 185 ] = PR_mq_getsetattr, + [ 186 ] = PR_msgget, + [ 187 ] = PR_msgctl, + [ 188 ] = PR_msgrcv, + [ 189 ] = PR_msgsnd, + [ 190 ] = PR_semget, + [ 191 ] = PR_semctl, + [ 192 ] = PR_semtimedop, + [ 193 ] = PR_semop, + [ 194 ] = PR_shmget, + [ 195 ] = PR_shmctl, + [ 196 ] = PR_shmat, + [ 197 ] = PR_shmdt, + [ 198 ] = PR_socket, + [ 199 ] = PR_socketpair, + [ 200 ] = PR_bind, + [ 201 ] = PR_listen, + [ 202 ] = PR_accept, + [ 203 ] = PR_connect, + [ 204 ] = PR_getsockname, + [ 205 ] = PR_getpeername, + [ 206 ] = PR_sendto, + [ 207 ] = PR_recvfrom, + [ 208 ] = PR_setsockopt, + [ 209 ] = PR_getsockopt, + [ 210 ] = PR_shutdown, + [ 211 ] = PR_sendmsg, + [ 212 ] = PR_recvmsg, + [ 213 ] = PR_readahead, + [ 214 ] = PR_brk, + [ 215 ] = PR_munmap, + [ 216 ] = PR_mremap, + [ 217 ] = PR_add_key, + [ 218 ] = PR_request_key, + [ 219 ] = PR_keyctl, + [ 220 ] = PR_clone, + [ 221 ] = PR_execve, + [ 222 ] = PR_mmap, + [ 223 ] = PR_fadvise64, + [ 224 ] = PR_swapon, + [ 225 ] = PR_swapoff, + [ 226 ] = PR_mprotect, + [ 227 ] = PR_msync, + [ 228 ] = PR_mlock, + [ 229 ] = PR_munlock, + [ 230 ] = PR_mlockall, + [ 231 ] = PR_munlockall, + [ 232 ] = PR_mincore, + [ 233 ] = PR_madvise, + [ 234 ] = PR_remap_file_pages, + [ 235 ] = PR_mbind, + [ 236 ] = PR_get_mempolicy, + [ 237 ] = PR_set_mempolicy, + [ 238 ] = PR_migrate_pages, + [ 239 ] = PR_move_pages, + [ 240 ] = PR_rt_tgsigqueueinfo, + [ 241 ] = PR_perf_event_open, + [ 242 ] = PR_accept4, + [ 243 ] = PR_recvmmsg, + [ 244 ] = PR_arch_specific_syscall, + [ 260 ] = PR_wait4, + [ 261 ] = PR_prlimit64, + [ 262 ] = PR_fanotify_init, + [ 263 ] = PR_fanotify_mark, + [ 264 ] = PR_name_to_handle_at, + [ 265 ] = PR_open_by_handle_at, + [ 266 ] = PR_clock_adjtime, + [ 267 ] = PR_syncfs, + [ 268 ] = PR_setns, + [ 269 ] = PR_sendmmsg, + [ 270 ] = PR_process_vm_readv, + [ 271 ] = PR_process_vm_writev, + [ 272 ] = PR_kcmp, + [ 273 ] = PR_finit_module, + [ 274 ] = PR_sched_setattr, + [ 275 ] = PR_sched_getattr, + [ 276 ] = PR_renameat2, + [ 291 ] = PR_statx, + [ 435 ] = PR_clone3, +}; diff --git a/src/tracee/event.c b/src/tracee/event.c index ce59f075..0c91ddf0 100644 --- a/src/tracee/event.c +++ b/src/tracee/event.c @@ -50,6 +50,7 @@ #include "attribute.h" #include "compat.h" +#include "linux/elf.h" /** * Start @tracee->exe with the given @argv[]. This function @@ -855,7 +856,6 @@ bool restart_tracee(Tracee *tracee, int signal) /* Put in the "stopped"/"waiting for ptracee" state?. */ if (tracee->as_ptracer.wait_pid != 0 || signal == -1) return false; - /* Restart the tracee and stop it at the next instruction, or * at the next entry or exit of a system call. */ status = ptrace(tracee->restart_how, tracee->pid, NULL, signal); diff --git a/src/tracee/mem.c b/src/tracee/mem.c index 368daeca..a661359e 100644 --- a/src/tracee/mem.c +++ b/src/tracee/mem.c @@ -41,6 +41,12 @@ #include "build.h" /* HAVE_PROCESS_VM, */ #include "cli/note.h" +#if defined(ARCH_RISCV64) && defined(__GLIBC__) +/* ptrace user_regs in glibc for riscv is in asm/ptrace.h */ +/* not in sys/user.h */ +#include +#endif + /** * Load the word at the given @address, potentially *not* aligned. */ diff --git a/src/tracee/reg.c b/src/tracee/reg.c index a0c1784e..88e7c7df 100644 --- a/src/tracee/reg.c +++ b/src/tracee/reg.c @@ -34,7 +34,13 @@ #include "arch.h" -#if defined(ARCH_ARM64) +#if defined(ARCH_RISCV64) +/* ptrace user_regs for riscv is in asm/ptrace.h */ +/* not in sys/user.h */ +#include +#endif + +#if defined(ARCH_ARM64) || defined(ARCH_RISCV64) #include /* NT_PRSTATUS */ #endif @@ -96,6 +102,24 @@ ? (((uint8_t *) &tracee->_regs[version]) + reg_offset_x86[index]) \ : (((uint8_t *) &tracee->_regs[version]) + reg_offset[index]))) +#elif defined(ARCH_RISCV64) + #undef USER_REGS_OFFSET + #define USER_REGS_OFFSET(reg_name) (offsetof(struct user_regs_struct, reg_name)) + + static off_t reg_offset[] = { + [SYSARG_NUM] = USER_REGS_OFFSET(a7), + [SYSARG_1] = USER_REGS_OFFSET(a0), + [SYSARG_2] = USER_REGS_OFFSET(a1), + [SYSARG_3] = USER_REGS_OFFSET(a2), + [SYSARG_4] = USER_REGS_OFFSET(a3), + [SYSARG_5] = USER_REGS_OFFSET(a4), + [SYSARG_6] = USER_REGS_OFFSET(a5), + [SYSARG_RESULT] = USER_REGS_OFFSET(a0), + [STACK_POINTER] = USER_REGS_OFFSET(sp), + [INSTR_POINTER] = USER_REGS_OFFSET(pc), + [USERARG_1] = USER_REGS_OFFSET(a0), + }; + #elif defined(ARCH_ARM_EABI) static off_t reg_offset[] = { @@ -246,7 +270,7 @@ int fetch_regs(Tracee *tracee) { int status; -#if defined(ARCH_ARM64) +#if defined(ARCH_ARM64) || defined(ARCH_RISCV64) struct iovec regs; regs.iov_base = &tracee->_regs[CURRENT]; @@ -317,8 +341,14 @@ int push_regs(Tracee *tracee) /* Update other registers. */ regs.iov_base = &tracee->_regs[CURRENT]; regs.iov_len = sizeof(tracee->_regs[CURRENT]); - status = ptrace(PTRACE_SETREGSET, tracee->pid, NT_PRSTATUS, ®s); +#elif defined(ARCH_RISCV64) + struct iovec regs; + regs.iov_base = &tracee->_regs[CURRENT]; + regs.iov_len = sizeof(tracee->_regs[CURRENT]); + // for riscv we also use PTRACE_SETREGSET option to update regs + // because PTRACE_SETREGS not support yet + status = ptrace(PTRACE_SETREGSET, tracee->pid, NT_PRSTATUS, ®s); #else # if defined(ARCH_ARM_EABI) /* On ARM, a special ptrace request is required to diff --git a/src/tracee/tracee.h b/src/tracee/tracee.h index 3e71e7da..fd44e359 100644 --- a/src/tracee/tracee.h +++ b/src/tracee/tracee.h @@ -40,6 +40,12 @@ #define PTRACE_REQUEST_TYPE int #endif +#if defined(ARCH_RISCV64) && defined(__GLIBC__) +/* ptrace user_regs in glibc for riscv is in asm/ptrace.h */ +/* not in sys/user.h */ +#include +#endif + typedef enum { CURRENT = 0, ORIGINAL = 1, diff --git a/test/ptrace-2.c b/test/ptrace-2.c index 9d1339d4..4b888e9e 100644 --- a/test/ptrace-2.c +++ b/test/ptrace-2.c @@ -35,6 +35,12 @@ #include /* struct iovec */ #include /* NT_PRSTATUS */ +#if defined(ARCH_RISCV64) && defined(__GLIBC__) +/* ptrace user_regs in glibc for riscv is in asm/ptrace.h */ +/* not in sys/user.h */ +#include +#endif + #include "../src/arch.h" #if !defined(ARCH_X86_64) && !defined(ARCH_ARM_EABI) && !defined(ARCH_X86) && !defined(ARCH_SH4) @@ -44,6 +50,8 @@ # define ARCH_ARM_EABI 1 # elif defined(__aarch64__) # define ARCH_ARM64 1 +# elif defined(__riscv) && __riscv_flen == 64 +# define ARCH_RISCV64 1 # elif defined(__arm__) # error "Only EABI is currently supported for ARM" # elif defined(__i386__) @@ -147,6 +155,24 @@ typedef enum { [INSTR_POINTER] = USER_REGS_OFFSET(pc), }; +#elif defined(ARCH_RISCV64) + + #undef USER_REGS_OFFSET + #define USER_REGS_OFFSET(reg_name) (offsetof(struct user_regs_struct, reg_name)) + + static off_t reg_offset[] = { + [SYSARG_NUM] = USER_REGS_OFFSET(a7), + [SYSARG_1] = USER_REGS_OFFSET(a0), + [SYSARG_2] = USER_REGS_OFFSET(a1), + [SYSARG_3] = USER_REGS_OFFSET(a2), + [SYSARG_4] = USER_REGS_OFFSET(a3), + [SYSARG_5] = USER_REGS_OFFSET(a4), + [SYSARG_6] = USER_REGS_OFFSET(a5), + [SYSARG_RESULT] = USER_REGS_OFFSET(a0), + [STACK_POINTER] = USER_REGS_OFFSET(sp), + [INSTR_POINTER] = USER_REGS_OFFSET(pc), + }; + #elif defined(ARCH_X86) static off_t reg_offset[] = { diff --git a/test/ptrace-3.c b/test/ptrace-3.c index 5738d98e..247d20cb 100644 --- a/test/ptrace-3.c +++ b/test/ptrace-3.c @@ -8,6 +8,12 @@ #include /* errno(3), */ #include /* struct user*, */ +#if defined(ARCH_RISCV64) && defined(__GLIBC__) +/* ptrace user_regs in glibc for riscv is in asm/ptrace.h */ +/* not in sys/user.h */ +#include +#endif + int main(int argc, char **argv) { enum __ptrace_request restart_how; From 43b61ac308b41442cacd5eb045f0a06b47317e0d Mon Sep 17 00:00:00 2001 From: Jer6y Date: Sun, 14 Apr 2024 20:34:24 +0800 Subject: [PATCH 2/2] fix: fix bug on riscv for loader mprotect syscall *fix bug on riscv for loader mprotect syscall Signed-off-by: luojun --- src/loader/assembly-riscv64.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/loader/assembly-riscv64.h b/src/loader/assembly-riscv64.h index 8d77c340..c752ff9a 100644 --- a/src/loader/assembly-riscv64.h +++ b/src/loader/assembly-riscv64.h @@ -87,4 +87,4 @@ #define EXECVE 221 #define EXIT 93 #define PRCTL 167 -#define MPROTECT 22 +#define MPROTECT 226