mirror of
https://github.com/checkpoint-restore/criu
synced 2025-08-22 09:58:09 +00:00
compel: add loongarch64 support
Signed-off-by: znley <shanjiantao@loongson.cn>
This commit is contained in:
parent
b304106e6b
commit
c9df09eeab
10
Makefile
10
Makefile
@ -19,7 +19,7 @@ endif
|
||||
|
||||
#
|
||||
# Supported Architectures
|
||||
ifneq ($(filter-out x86 arm aarch64 ppc64 s390 mips,$(ARCH)),)
|
||||
ifneq ($(filter-out x86 arm aarch64 ppc64 s390 mips loongarch64,$(ARCH)),)
|
||||
$(error "The architecture $(ARCH) isn't supported")
|
||||
endif
|
||||
|
||||
@ -80,6 +80,10 @@ ifeq ($(ARCH),mips)
|
||||
DEFINES := -DCONFIG_MIPS
|
||||
endif
|
||||
|
||||
ifeq ($(ARCH),loongarch64)
|
||||
DEFINES := -DCONFIG_LOONGARCH64
|
||||
endif
|
||||
|
||||
#
|
||||
# CFLAGS_PIE:
|
||||
#
|
||||
@ -122,6 +126,10 @@ ifeq ($(ARCH),mips)
|
||||
WARNINGS := -rdynamic
|
||||
endif
|
||||
|
||||
ifeq ($(ARCH),loongarch64)
|
||||
WARNINGS := -Wno-implicit-function-declaration
|
||||
endif
|
||||
|
||||
ifneq ($(GCOV),)
|
||||
LDFLAGS += -lgcov
|
||||
CFLAGS += $(CFLAGS-GCOV)
|
||||
|
@ -33,7 +33,7 @@ lib-y += arch/$(ARCH)/src/lib/thread_area.o
|
||||
endif
|
||||
|
||||
# handle_elf() has no support of ELF relocations on ARM (yet?)
|
||||
ifneq ($(filter arm aarch64,$(ARCH)),)
|
||||
ifneq ($(filter arm aarch64 loongarch64,$(ARCH)),)
|
||||
CFLAGS += -DNO_RELOCS
|
||||
HOSTCFLAGS += -DNO_RELOCS
|
||||
endif
|
||||
|
35
compel/arch/loongarch64/plugins/include/asm/prologue.h
Normal file
35
compel/arch/loongarch64/plugins/include/asm/prologue.h
Normal file
@ -0,0 +1,35 @@
|
||||
#ifndef __ASM_PROLOGUE_H__
|
||||
#define __ASM_PROLOGUE_H__
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#define sys_recv(sockfd, ubuf, size, flags) sys_recvfrom(sockfd, ubuf, size, flags, NULL, NULL)
|
||||
|
||||
typedef struct prologue_init_args {
|
||||
struct sockaddr_un ctl_sock_addr;
|
||||
unsigned int ctl_sock_addr_len;
|
||||
|
||||
unsigned int arg_s;
|
||||
void *arg_p;
|
||||
|
||||
void *sigframe;
|
||||
} prologue_init_args_t;
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
/*
|
||||
* Reserve enough space for sigframe.
|
||||
*
|
||||
* FIXME It is rather should be taken from sigframe header.
|
||||
*/
|
||||
#define PROLOGUE_SGFRAME_SIZE 4096
|
||||
|
||||
#define PROLOGUE_INIT_ARGS_SIZE 1024
|
||||
|
||||
#endif /* __ASM_PROLOGUE_H__ */
|
30
compel/arch/loongarch64/plugins/include/asm/syscall-types.h
Normal file
30
compel/arch/loongarch64/plugins/include/asm/syscall-types.h
Normal file
@ -0,0 +1,30 @@
|
||||
#ifndef COMPEL_ARCH_SYSCALL_TYPES_H__
|
||||
#define COMPEL_ARCH_SYSCALL_TYPES_H__
|
||||
|
||||
#include <common/asm/bitsperlong.h>
|
||||
/* Types for sigaction, sigprocmask syscalls */
|
||||
typedef void rt_signalfn_t(int, siginfo_t *, void *);
|
||||
typedef rt_signalfn_t *rt_sighandler_t;
|
||||
|
||||
typedef void rt_restorefn_t(void);
|
||||
typedef rt_restorefn_t *rt_sigrestore_t;
|
||||
|
||||
/* refer to arch/loongarch/include/uapi/asm/signal.h */
|
||||
#define _KNSIG 64
|
||||
#define _NSIG_BPW BITS_PER_LONG
|
||||
#define _KNSIG_WORDS (_KNSIG / _NSIG_BPW)
|
||||
|
||||
typedef struct {
|
||||
uint64_t sig[_KNSIG_WORDS];
|
||||
} k_rtsigset_t;
|
||||
|
||||
typedef struct {
|
||||
rt_sighandler_t rt_sa_handler;
|
||||
unsigned long rt_sa_flags;
|
||||
rt_sigrestore_t rt_sa_restorer;
|
||||
k_rtsigset_t rt_sa_mask;
|
||||
} rt_sigaction_t;
|
||||
|
||||
#define SA_RESTORER 0x04000000
|
||||
|
||||
#endif /* COMPEL_ARCH_SYSCALL_TYPES_H__ */
|
4
compel/arch/loongarch64/plugins/include/features.h
Normal file
4
compel/arch/loongarch64/plugins/include/features.h
Normal file
@ -0,0 +1,4 @@
|
||||
#ifndef __COMPEL_ARCH_FEATURES_H
|
||||
#define __COMPEL_ARCH_FEATURES_H
|
||||
|
||||
#endif /* __COMPEL_ARCH_FEATURES_H */
|
9
compel/arch/loongarch64/plugins/std/parasite-head.S
Normal file
9
compel/arch/loongarch64/plugins/std/parasite-head.S
Normal file
@ -0,0 +1,9 @@
|
||||
|
||||
#include "common/asm/linkage.h"
|
||||
|
||||
.section .head.text, "ax"
|
||||
ENTRY(__export_parasite_head_start)
|
||||
bl parasite_service;
|
||||
break 0;
|
||||
END(__export_parasite_head_start)
|
||||
|
117
compel/arch/loongarch64/plugins/std/syscalls/Makefile.syscalls
Normal file
117
compel/arch/loongarch64/plugins/std/syscalls/Makefile.syscalls
Normal file
@ -0,0 +1,117 @@
|
||||
std-lib-y += ./$(PLUGIN_ARCH_DIR)/std/syscalls-64.o
|
||||
sys-proto-types := $(obj)/include/uapi/std/syscall-types.h
|
||||
sys-proto-generic := $(obj)/include/uapi/std/syscall.h
|
||||
sys-codes-generic := $(obj)/include/uapi/std/syscall-codes.h
|
||||
sys-codes = $(obj)/include/uapi/std/syscall-codes-$(1).h
|
||||
sys-proto = $(obj)/include/uapi/std/syscall-$(1).h
|
||||
sys-def = $(PLUGIN_ARCH_DIR)/std/syscalls/syscall_$(1).tbl
|
||||
sys-asm = $(PLUGIN_ARCH_DIR)/std/syscalls-$(1).S
|
||||
sys-asm-common-name = std/syscalls/syscall-common-loongarch-$(1).S
|
||||
sys-asm-common = $(PLUGIN_ARCH_DIR)/$(sys-asm-common-name)
|
||||
sys-asm-types := $(obj)/include/uapi/std/asm/syscall-types.h
|
||||
sys-exec-tbl = $(PLUGIN_ARCH_DIR)/std/sys-exec-tbl-$(1).c
|
||||
|
||||
sys-bits := 64
|
||||
|
||||
AV := $$$$
|
||||
|
||||
define gen-rule-sys-codes
|
||||
$(sys-codes): $(sys-def) $(sys-proto-types)
|
||||
$(call msg-gen, $$@)
|
||||
$(Q) echo "/* Autogenerated, don't edit */" > $$@
|
||||
$(Q) echo "#ifndef ASM_SYSCALL_CODES_H_$(1)__" >> $$@
|
||||
$(Q) echo "#define ASM_SYSCALL_CODES_H_$(1)__" >> $$@
|
||||
$(Q) cat $$< | awk '/^__NR/{SYSN=$(AV)1; \
|
||||
sub("^__NR", "SYS", SYSN); \
|
||||
print "\n#ifndef ", $(AV)1; \
|
||||
print "#define", $(AV)1, $(AV)2; \
|
||||
print "#endif"; \
|
||||
print "\n#ifndef ", SYSN; \
|
||||
print "#define ", SYSN, $(AV)1; \
|
||||
print "#endif";}' >> $$@
|
||||
$(Q) echo "#endif /* ASM_SYSCALL_CODES_H_$(1)__ */" >> $$@
|
||||
endef
|
||||
|
||||
define gen-rule-sys-proto
|
||||
$(sys-proto): $(sys-def) $(sys-proto-types)
|
||||
$(call msg-gen, $$@)
|
||||
$(Q) echo "/* Autogenerated, don't edit */" > $$@
|
||||
$(Q) echo "#ifndef ASM_SYSCALL_PROTO_H_$(1)__" >> $$@
|
||||
$(Q) echo "#define ASM_SYSCALL_PROTO_H_$(1)__" >> $$@
|
||||
$(Q) echo '#include <compel/plugins/std/syscall-codes-$(1).h>' >> $$@
|
||||
$(Q) echo '#include <compel/plugins/std/syscall-types.h>' >> $$@
|
||||
ifeq ($(1),32)
|
||||
$(Q) echo '#include "asm/syscall32.h"' >> $$@
|
||||
endif
|
||||
$(Q) cat $$< | awk '/^__NR/{print "extern long", $(AV)3, \
|
||||
substr($(AV)0, index($(AV)0,$(AV)4)), ";"}' >> $$@
|
||||
$(Q) echo "#endif /* ASM_SYSCALL_PROTO_H_$(1)__ */" >> $$@
|
||||
endef
|
||||
|
||||
define gen-rule-sys-asm
|
||||
$(sys-asm): $(sys-def) $(sys-asm-common) $(sys-codes) $(sys-proto) $(sys-proto-types)
|
||||
$(call msg-gen, $$@)
|
||||
$(Q) echo "/* Autogenerated, don't edit */" > $$@
|
||||
$(Q) echo '#include <compel/plugins/std/syscall-codes-$(1).h>' >> $$@
|
||||
$(Q) echo '#include "$(sys-asm-common-name)"' >> $$@
|
||||
$(Q) cat $$< | awk '/^__NR/{print "SYSCALL(", $(AV)3, ",", $(AV)2, ")"}' >> $$@
|
||||
endef
|
||||
|
||||
define gen-rule-sys-exec-tbl
|
||||
$(sys-exec-tbl): $(sys-def) $(sys-codes) $(sys-proto) $(sys-proto-generic) $(sys-proto-types)
|
||||
$(call msg-gen, $$@)
|
||||
$(Q) echo "/* Autogenerated, don't edit */" > $$@
|
||||
$(Q) cat $$< | awk '/^__NR/{print \
|
||||
"SYSCALL(", substr($(AV)3, 5), ",", $(AV)2, ")"}' >> $$@
|
||||
endef
|
||||
|
||||
$(sys-codes-generic): $(sys-proto-types)
|
||||
$(call msg-gen, $@)
|
||||
$(Q) echo "/* Autogenerated, don't edit */" > $@
|
||||
$(Q) echo "#ifndef __ASM_CR_SYSCALL_CODES_H__" >> $@
|
||||
$(Q) echo "#define __ASM_CR_SYSCALL_CODES_H__" >> $@
|
||||
$(Q) echo '#include <compel/plugins/std/syscall-codes-64.h>' >> $@
|
||||
$(Q) cat $< | awk '/^__NR/{NR32=$$1; \
|
||||
sub("^__NR", "__NR32", NR32); \
|
||||
print "\n#ifndef ", NR32; \
|
||||
print "#define ", NR32, $$2; \
|
||||
print "#endif";}' >> $@
|
||||
$(Q) echo "#endif /* __ASM_CR_SYSCALL_CODES_H__ */" >> $@
|
||||
mrproper-y += $(sys-codes-generic)
|
||||
|
||||
$(sys-proto-generic): $(strip $(call map,sys-proto,$(sys-bits))) $(sys-proto-types)
|
||||
$(call msg-gen, $@)
|
||||
$(Q) echo "/* Autogenerated, don't edit */" > $@
|
||||
$(Q) echo "#ifndef __ASM_CR_SYSCALL_PROTO_H__" >> $@
|
||||
$(Q) echo "#define __ASM_CR_SYSCALL_PROTO_H__" >> $@
|
||||
$(Q) echo "" >> $@
|
||||
$(Q) echo '#include <compel/plugins/std/syscall-64.h>' >> $@
|
||||
$(Q) echo "" >> $@
|
||||
$(Q) echo "#endif /* __ASM_CR_SYSCALL_PROTO_H__ */" >> $@
|
||||
mrproper-y += $(sys-proto-generic)
|
||||
|
||||
define gen-rule-sys-exec-tbl
|
||||
$(sys-exec-tbl): $(sys-def) $(sys-codes) $(sys-proto) $(sys-proto-generic)
|
||||
$(call msg-gen, $$@)
|
||||
$(Q) echo "/* Autogenerated, don't edit */" > $$@
|
||||
$(Q) cat $$< | awk '/^__NR/{print \
|
||||
"SYSCALL(", substr($(AV)3, 5), ",", $(AV)2, ")"}' >> $$@
|
||||
endef
|
||||
|
||||
$(eval $(call map,gen-rule-sys-codes,$(sys-bits)))
|
||||
$(eval $(call map,gen-rule-sys-proto,$(sys-bits)))
|
||||
$(eval $(call map,gen-rule-sys-asm,$(sys-bits)))
|
||||
$(eval $(call map,gen-rule-sys-exec-tbl,$(sys-bits)))
|
||||
|
||||
$(sys-asm-types): $(PLUGIN_ARCH_DIR)/include/asm/syscall-types.h
|
||||
$(call msg-gen, $@)
|
||||
$(Q) ln -s ../../../../../../$(PLUGIN_ARCH_DIR)/include/asm/syscall-types.h $(sys-asm-types)
|
||||
|
||||
std-headers-deps += $(call sys-codes,$(sys-bits))
|
||||
std-headers-deps += $(call sys-proto,$(sys-bits))
|
||||
std-headers-deps += $(call sys-asm,$(sys-bits))
|
||||
std-headers-deps += $(call sys-exec-tbl,$(sys-bits))
|
||||
std-headers-deps += $(sys-codes-generic)
|
||||
std-headers-deps += $(sys-proto-generic)
|
||||
std-headers-deps += $(sys-asm-types)
|
||||
mrproper-y += $(std-headers-deps)
|
@ -0,0 +1,44 @@
|
||||
#include "common/asm/linkage.h"
|
||||
|
||||
#define SYSCALL(name, opcode) \
|
||||
ENTRY(name); \
|
||||
addi.d $a7, $zero, opcode; \
|
||||
syscall 0; \
|
||||
jirl $r0, $r1, 0; \
|
||||
END(name)
|
||||
|
||||
#ifndef AT_FDCWD
|
||||
#define AT_FDCWD -100
|
||||
#endif
|
||||
|
||||
#ifndef AT_REMOVEDIR
|
||||
#define AT_REMOVEDIR 0x200
|
||||
#endif
|
||||
|
||||
ENTRY(sys_open)
|
||||
or $a3, $zero, $a2
|
||||
or $a2, $zero, $a1
|
||||
or $a1, $zero, $a0
|
||||
addi.d $a0, $zero, AT_FDCWD
|
||||
b sys_openat
|
||||
END(sys_open)
|
||||
|
||||
ENTRY(sys_mkdir)
|
||||
or $a3, $zero, $a2
|
||||
or $a2, $zero, $a1
|
||||
or $a1, $zero, $a0
|
||||
addi.d $a0, $zero, AT_FDCWD
|
||||
b sys_mkdirat
|
||||
END(sys_mkdir)
|
||||
|
||||
ENTRY(sys_rmdir)
|
||||
addi.d $a2, $zero, AT_REMOVEDIR
|
||||
or $a1, $zero, $a0
|
||||
addi.d $a0, $zero, AT_FDCWD
|
||||
b sys_unlinkat
|
||||
END(sys_rmdir)
|
||||
|
||||
ENTRY(__cr_restore_rt)
|
||||
addi.d $a7, $zero, __NR_rt_sigreturn
|
||||
syscall 0
|
||||
END(__cr_restore_rt)
|
121
compel/arch/loongarch64/plugins/std/syscalls/syscall_64.tbl
Normal file
121
compel/arch/loongarch64/plugins/std/syscalls/syscall_64.tbl
Normal file
@ -0,0 +1,121 @@
|
||||
#
|
||||
# System calls table, please make sure the table consist only the syscalls
|
||||
# really used somewhere in project.
|
||||
# from kernel/linux-3.10.84/arch/mips/include/uapi/asm/unistd.h Linux 64-bit syscalls are in the range from 5000 to 5999.
|
||||
#
|
||||
# __NR_name code name arguments
|
||||
# -------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
__NR_io_setup 0 sys_io_setup (unsigned nr_events, aio_context_t *ctx)
|
||||
__NR_io_submit 2 sys_io_submit (aio_context_t ctx, long nr, struct iocb **iocbpp)
|
||||
__NR_io_getevents 4 sys_io_getevents (aio_context_t ctx, long min_nr, long nr, struct io_event *evs, struct timespec *tmo)
|
||||
__NR_fcntl 25 sys_fcntl (int fd, int type, long arg)
|
||||
__NR_ioctl 29 sys_ioctl (unsigned int fd, unsigned int cmd, unsigned long arg)
|
||||
__NR_flock 32 sys_flock (int fd, unsigned long cmd)
|
||||
__NR_mkdirat 34 sys_mkdirat (int dfd, const char *pathname, int flag)
|
||||
__NR_unlinkat 35 sys_unlinkat (int dfd, const char *pathname, int flag)
|
||||
__NR_umount2 39 sys_umount2 (char *name, int flags)
|
||||
__NR_mount 40 sys_mount (char *dev_nmae, char *dir_name, char *type, unsigned long flags, void *data)
|
||||
__NR_fallocate 47 sys_fallocate (int fd, int mode, loff_t offset, loff_t len)
|
||||
__NR_close 57 sys_close (int fd)
|
||||
__NR_openat 56 sys_openat (int dfd, const char *filename, int flags, int mode)
|
||||
__NR_lseek 62 sys_lseek (int fd, unsigned long offset, unsigned long origin)
|
||||
__NR_read 63 sys_read (int fd, void *buf, unsigned long count)
|
||||
__NR_write 64 sys_write (int fd, const void *buf, unsigned long count)
|
||||
__NR_pread64 67 sys_pread (unsigned int fd, char *buf, size_t count, loff_t pos)
|
||||
__NR_preadv 69 sys_preadv_raw (int fd, struct iovec *iov, unsigned long nr, unsigned long pos_l, unsigned long pos_h)
|
||||
__NR_ppoll 73 sys_ppoll (struct pollfd *fds, unsigned int nfds, const struct timespec *tmo, const sigset_t *sigmask, size_t sigsetsize)
|
||||
__NR_signalfd4 74 sys_signalfd (int fd, k_rtsigset_t *mask, size_t sizemask, int flags)
|
||||
__NR_vmsplice 75 sys_vmsplice (int fd, const struct iovec *iov, unsigned long nr_segs, unsigned int flags)
|
||||
__NR_readlinkat 78 sys_readlinkat (int fd, const char *path, char *buf, int bufsize)
|
||||
__NR_timerfd_settime 86 sys_timerfd_settime (int ufd, int flags, const struct itimerspec *utmr, struct itimerspec *otmr)
|
||||
__NR_capget 90 sys_capget (struct cap_header *h, struct cap_data *d)
|
||||
__NR_capset 91 sys_capset (struct cap_header *h, struct cap_data *d)
|
||||
__NR_personality 92 sys_personality (unsigned int personality)
|
||||
__NR_exit 93 sys_exit (unsigned long error_code)
|
||||
__NR_exit_group 94 sys_exit_group (int error_code)
|
||||
__NR_waitid 95 sys_waitid (int which, pid_t pid, struct siginfo *infop, int options, struct rusage *ru)
|
||||
__NR_set_tid_address 96 sys_set_tid_address (int *tid_addr)
|
||||
__NR_futex 98 sys_futex (uint32_t *uaddr, int op, uint32_t val, struct timespec *utime, uint32_t *uaddr2, uint32_t val3)
|
||||
__NR_set_robust_list 99 sys_set_robust_list (struct robust_list_head *head, size_t len)
|
||||
__NR_get_robust_list 100 sys_get_robust_list (int pid, struct robust_list_head **head_ptr, size_t *len_ptr)
|
||||
__NR_nanosleep 101 sys_nanosleep (struct timespec *req, struct timespec *rem)
|
||||
__NR_getitimer 102 sys_getitimer (int which, const struct itimerval *val)
|
||||
__NR_setitimer 103 sys_setitimer (int which, const struct itimerval *val, struct itimerval *old)
|
||||
__NR_sys_timer_create 107 sys_timer_create (clockid_t which_clock, struct sigevent *timer_event_spec, kernel_timer_t *created_timer_id)
|
||||
__NR_sys_timer_gettime 108 sys_timer_gettime (int timer_id, const struct itimerspec *setting)
|
||||
__NR_sys_timer_getoverrun 109 sys_timer_getoverrun (int timer_id)
|
||||
__NR_sys_timer_settime 110 sys_timer_settime (kernel_timer_t timer_id, int flags, const struct itimerspec *new_setting, struct itimerspec *old_setting)
|
||||
__NR_sys_timer_delete 111 sys_timer_delete (kernel_timer_t timer_id)
|
||||
__NR_clock_gettime 113 sys_clock_gettime (const clockid_t which_clock, const struct timespec *tp)
|
||||
__NR_sched_setscheduler 119 sys_sched_setscheduler (int pid, int policy, struct sched_param *p)
|
||||
__NR_restart_syscall 128 sys_restart_syscall (void)
|
||||
__NR_kill 129 sys_kill (long pid, int sig)
|
||||
__NR_sigaltstack 132 sys_sigaltstack (const void *uss, void *uoss)
|
||||
__NR_rt_sigaction 134 sys_sigaction (int signum, const rt_sigaction_t *act, rt_sigaction_t *oldact, size_t sigsetsize)
|
||||
__NR_rt_sigprocmask 135 sys_sigprocmask (int how, k_rtsigset_t *set, k_rtsigset_t *old, size_t sigsetsize)
|
||||
__NR_rt_sigqueueinfo 138 sys_rt_sigqueueinfo (pid_t pid, int sig, siginfo_t *info)
|
||||
__NR_rt_sigreturn 139 sys_rt_sigreturn (void)
|
||||
__NR_setpriority 140 sys_setpriority (int which, int who, int nice)
|
||||
__NR_setresuid 147 sys_setresuid (int uid, int euid, int suid)
|
||||
__NR_getresuid 148 sys_getresuid (int *uid, int *euid, int *suid)
|
||||
__NR_setresgid 149 sys_setresgid (int gid, int egid, int sgid)
|
||||
__NR_getresgid 150 sys_getresgid (int *gid, int *egid, int *sgid)
|
||||
__NR_getpgid 155 sys_getpgid (pid_t pid)
|
||||
__NR_setfsuid 151 sys_setfsuid (int fsuid)
|
||||
__NR_setfsgid 152 sys_setfsgid (int fsgid)
|
||||
__NR_getsid 156 sys_getsid (void)
|
||||
__NR_getgroups 158 sys_getgroups (int gsize, unsigned int *groups)
|
||||
__NR_setgroups 159 sys_setgroups (int gsize, unsigned int *groups)
|
||||
__NR_setrlimit 164 sys_setrlimit (int resource, struct krlimit *rlim)
|
||||
__NR_umask 166 sys_umask (int mask)
|
||||
__NR_prctl 167 sys_prctl (int option, unsigned long arg2, unsigned long arg3, unsigned long arg4, unsigned long arg5)
|
||||
__NR_gettimeofday 169 sys_gettimeofday (struct timeval *tv, struct timezone *tz)
|
||||
__NR_getpid 172 sys_getpid (void)
|
||||
__NR_ptrace 177 sys_ptrace (long request, pid_t pid, void *addr, void *data)
|
||||
__NR_gettid 178 sys_gettid (void)
|
||||
__NR_shmat 196 sys_shmat (int shmid, void *shmaddr, int shmflag)
|
||||
__NR_socket 198 sys_socket (int domain, int type, int protocol)
|
||||
__NR_bind 200 sys_bind (int sockfd, const struct sockaddr *addr, int addrlen)
|
||||
__NR_connect 203 sys_connect (int sockfd, struct sockaddr *addr, int addrlen)
|
||||
__NR_sendto 206 sys_sendto (int sockfd, void *buff, size_t len, unsigned int flags, struct sockaddr *addr, int addr_len)
|
||||
__NR_recvfrom 207 sys_recvfrom (int sockfd, void *ubuf, size_t size, unsigned int flags, struct sockaddr *addr, int *addr_len)
|
||||
__NR_setsockopt 208 sys_setsockopt (int sockfd, int level, int optname, const void *optval, socklen_t optlen)
|
||||
__NR_getsockopt 209 sys_getsockopt (int sockfd, int level, int optname, const void *optval, socklen_t *optlen)
|
||||
__NR_shutdown 210 sys_shutdown (int sockfd, int how)
|
||||
__NR_sendmsg 211 sys_sendmsg (int sockfd, const struct msghdr *msg, int flags)
|
||||
__NR_recvmsg 212 sys_recvmsg (int sockfd, struct msghdr *msg, int flags)
|
||||
__NR_brk 214 sys_brk (void *addr)
|
||||
__NR_munmap 215 sys_munmap (void *addr, unsigned long len)
|
||||
__NR_mremap 216 sys_mremap (unsigned long addr, unsigned long old_len, unsigned long new_len, unsigned long flags, unsigned long new_addr)
|
||||
__NR_clone 220 sys_clone (unsigned long flags, void *child_stack, void *parent_tid, unsigned long newtls, void *child_tid)
|
||||
__NR_mmap 222 sys_mmap (void *addr, unsigned long len, unsigned long prot, unsigned long flags, unsigned long fd, unsigned long offset)
|
||||
__NR_mprotect 226 sys_mprotect (const void *addr, unsigned long len, unsigned long prot)
|
||||
__NR_mincore 232 sys_mincore (void *addr, unsigned long size, unsigned char *vec)
|
||||
__NR_madvise 233 sys_madvise (unsigned long start, size_t len, int behavior)
|
||||
__NR_rt_tgsigqueueinfo 240 sys_rt_tgsigqueueinfo (pid_t tgid, pid_t pid, int sig, siginfo_t *info)
|
||||
__NR_wait4 260 sys_wait4 (int pid, int *status, int options, struct rusage *ru)
|
||||
__NR_fanotify_init 262 sys_fanotify_init (unsigned int flags, unsigned int event_f_flags)
|
||||
__NR_fanotify_mark 263 sys_fanotify_mark (int fanotify_fd, unsigned int flags, uint64_t mask, int dfd, const char *pathname)
|
||||
__NR_open_by_handle_at 265 sys_open_by_handle_at (int mountdirfd, struct file_handle *handle, int flags)
|
||||
__NR_setns 268 sys_setns (int fd, int nstype)
|
||||
__NR_kcmp 272 sys_kcmp (pid_t pid1, pid_t pid2, int type, unsigned long idx1, unsigned long idx2)
|
||||
__NR_seccomp 277 sys_seccomp (unsigned int op, unsigned int flags, const char *uargs)
|
||||
__NR_memfd_create 279 sys_memfd_create (const char *name, unsigned int flags)
|
||||
__NR_userfaultfd 282 sys_userfaultfd (int flags)
|
||||
__NR_rseq 293 sys_rseq (void *rseq, uint32_t rseq_len, int flags, uint32_t sig)
|
||||
__NR_open_tree 428 sys_open_tree (int dirfd, const char *pathname, unsigned int flags)
|
||||
__NR_move_mount 429 sys_move_mount (int from_dfd, const char *from_pathname, int to_dfd, const char *to_pathname, int flags)
|
||||
__NR_fsopen 430 sys_fsopen (char *fsname, unsigned int flags)
|
||||
__NR_fsconfig 431 sys_fsconfig (int fd, unsigned int cmd, const char *key, const char *value, int aux)
|
||||
__NR_fsmount 432 sys_fsmount (int fd, unsigned int flags, unsigned int attr_flags)
|
||||
__NR_pidfd_open 434 sys_pidfd_open (pid_t pid, unsigned int flags)
|
||||
__NR_clone3 435 sys_clone3 (struct clone_args *uargs, size_t size)
|
||||
__NR_openat2 437 sys_openat2 (int dirfd, char *pathname, struct open_how *how, size_t size)
|
||||
__NR_pidfd_getfd 438 sys_pidfd_getfd (int pidfd, int targetfd, unsigned int flags)
|
||||
#__NR_dup2 ! sys_dup2 (int oldfd, int newfd)
|
||||
#__NR_rmdir ! sys_rmdir (const char *name)
|
||||
#__NR_unlink ! sys_unlink (char *pathname)
|
||||
#__NR_cacheflush ! sys_cacheflush (char *addr, int nbytes, int cache)
|
||||
#__NR_set_thread_area ! sys_set_thread_area (unsigned long *addr)
|
||||
#__NR_mkdir ! sys_mkdir (const char *name, int mode)
|
||||
#__NR_open ! sys_open (const char *filename, unsigned long flags, unsigned long mode)
|
32
compel/arch/loongarch64/scripts/compel-pack.lds.S
Normal file
32
compel/arch/loongarch64/scripts/compel-pack.lds.S
Normal file
@ -0,0 +1,32 @@
|
||||
OUTPUT_ARCH(loongarch)
|
||||
EXTERN(__export_parasite_head_start)
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
.crblob 0x0 : {
|
||||
*(.head.text)
|
||||
ASSERT(DEFINED(__export_parasite_head_start),
|
||||
"Symbol __export_parasite_head_start is missing");
|
||||
*(.text*)
|
||||
. = ALIGN(32);
|
||||
*(.data*)
|
||||
. = ALIGN(32);
|
||||
*(.rodata*)
|
||||
. = ALIGN(32);
|
||||
*(.bss*)
|
||||
. = ALIGN(32);
|
||||
*(.got*)
|
||||
. = ALIGN(32);
|
||||
*(.toc*)
|
||||
. = ALIGN(32);
|
||||
} =0x00000000,
|
||||
|
||||
/DISCARD/ : {
|
||||
*(.debug*)
|
||||
*(.comment*)
|
||||
*(.note*)
|
||||
*(.group*)
|
||||
*(.eh_frame*)
|
||||
*(*)
|
||||
}
|
||||
}
|
41
compel/arch/loongarch64/src/lib/cpu.c
Normal file
41
compel/arch/loongarch64/src/lib/cpu.c
Normal file
@ -0,0 +1,41 @@
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "compel-cpu.h"
|
||||
#include "common/bitops.h"
|
||||
#include "common/compiler.h"
|
||||
#include "log.h"
|
||||
|
||||
#undef LOG_PREFIX
|
||||
#define LOG_PREFIX "cpu: "
|
||||
|
||||
static compel_cpuinfo_t rt_info;
|
||||
static bool rt_info_done = false;
|
||||
|
||||
void compel_set_cpu_cap(compel_cpuinfo_t *c, unsigned int feature)
|
||||
{
|
||||
}
|
||||
|
||||
void compel_clear_cpu_cap(compel_cpuinfo_t *c, unsigned int feature)
|
||||
{
|
||||
}
|
||||
|
||||
int compel_test_cpu_cap(compel_cpuinfo_t *c, unsigned int feature)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int compel_cpuid(compel_cpuinfo_t *c)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool compel_cpu_has_feature(unsigned int feature)
|
||||
{
|
||||
if (!rt_info_done) {
|
||||
compel_cpuid(&rt_info);
|
||||
rt_info_done = true;
|
||||
}
|
||||
|
||||
return compel_test_cpu_cap(&rt_info, feature);
|
||||
}
|
22
compel/arch/loongarch64/src/lib/handle-elf-host.c
Normal file
22
compel/arch/loongarch64/src/lib/handle-elf-host.c
Normal file
@ -0,0 +1,22 @@
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "handle-elf.h"
|
||||
#include "piegen.h"
|
||||
#include "log.h"
|
||||
|
||||
static const unsigned char __maybe_unused elf_ident_64_le[EI_NIDENT] = {
|
||||
0x7f, 0x45, 0x4c, 0x46, 0x02, 0x01, 0x01, 0x00, /* clang-format */
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
};
|
||||
|
||||
extern int __handle_elf(void *mem, size_t size);
|
||||
|
||||
int handle_binary(void *mem, size_t size)
|
||||
{
|
||||
if (memcmp(mem, elf_ident_64_le, sizeof(elf_ident_64_le)) == 0)
|
||||
return __handle_elf(mem, size);
|
||||
|
||||
pr_err("Unsupported Elf format detected\n");
|
||||
return -EINVAL;
|
||||
}
|
22
compel/arch/loongarch64/src/lib/handle-elf.c
Normal file
22
compel/arch/loongarch64/src/lib/handle-elf.c
Normal file
@ -0,0 +1,22 @@
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "handle-elf.h"
|
||||
#include "piegen.h"
|
||||
#include "log.h"
|
||||
|
||||
static const unsigned char __maybe_unused elf_ident_64_le[EI_NIDENT] = {
|
||||
0x7f, 0x45, 0x4c, 0x46, 0x02, 0x01, 0x01, 0x00, /* clang-format */
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
};
|
||||
|
||||
extern int __handle_elf(void *mem, size_t size);
|
||||
|
||||
int handle_binary(void *mem, size_t size)
|
||||
{
|
||||
if (memcmp(mem, elf_ident_64_le, sizeof(elf_ident_64_le)) == 0)
|
||||
return __handle_elf(mem, size);
|
||||
|
||||
pr_err("Unsupported Elf format detected\n");
|
||||
return -EINVAL;
|
||||
}
|
8
compel/arch/loongarch64/src/lib/include/handle-elf.h
Normal file
8
compel/arch/loongarch64/src/lib/include/handle-elf.h
Normal file
@ -0,0 +1,8 @@
|
||||
#ifndef COMPEL_HANDLE_ELF_H__
|
||||
#define COMPEL_HANDLE_ELF_H__
|
||||
|
||||
#include "elf64-types.h"
|
||||
|
||||
#define arch_is_machine_supported(e_machine) (e_machine == EM_LOONGARCH)
|
||||
|
||||
#endif /* COMPEL_HANDLE_ELF_H__ */
|
8
compel/arch/loongarch64/src/lib/include/syscall.h
Normal file
8
compel/arch/loongarch64/src/lib/include/syscall.h
Normal file
@ -0,0 +1,8 @@
|
||||
#ifndef __COMPEL_SYSCALL_H__
|
||||
#define __COMPEL_SYSCALL_H__
|
||||
|
||||
#ifndef SIGSTKFLT
|
||||
#define SIGSTKFLT 16
|
||||
#endif
|
||||
|
||||
#endif
|
@ -0,0 +1,6 @@
|
||||
#ifndef __COMPEL_BREAKPOINTS_H__
|
||||
#define __COMPEL_BREAKPOINTS_H__
|
||||
#define ARCH_SI_TRAP TRAP_BRKPT
|
||||
extern int ptrace_set_breakpoint(pid_t pid, void *addr);
|
||||
extern int ptrace_flush_breakpoints(pid_t pid);
|
||||
#endif
|
6
compel/arch/loongarch64/src/lib/include/uapi/asm/cpu.h
Normal file
6
compel/arch/loongarch64/src/lib/include/uapi/asm/cpu.h
Normal file
@ -0,0 +1,6 @@
|
||||
#ifndef __CR_ASM_CPU_H__
|
||||
#define __CR_ASM_CPU_H__
|
||||
|
||||
typedef struct {
|
||||
} compel_cpuinfo_t;
|
||||
#endif /* __CR_ASM_CPU_H__ */
|
4
compel/arch/loongarch64/src/lib/include/uapi/asm/fpu.h
Normal file
4
compel/arch/loongarch64/src/lib/include/uapi/asm/fpu.h
Normal file
@ -0,0 +1,4 @@
|
||||
#ifndef __CR_ASM_FPU_H__
|
||||
#define __CR_ASM_FPU_H__
|
||||
|
||||
#endif /* __CR_ASM_FPU_H__ */
|
@ -0,0 +1,67 @@
|
||||
#ifndef UAPI_COMPEL_ASM_TYPES_H__
|
||||
#define UAPI_COMPEL_ASM_TYPES_H__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define SIGMAX 64
|
||||
#define SIGMAX_OLD 31
|
||||
|
||||
/*
|
||||
* From the Linux kernel header arch/loongarch/include/uapi/asm/ptrace.h
|
||||
*
|
||||
* A thread LoongArch CPU context
|
||||
*
|
||||
* struct user_fp_state {
|
||||
* uint64_t fpr[32];
|
||||
* uint64_t fcc;
|
||||
* uint32_t fcsr;
|
||||
* };
|
||||
*
|
||||
* struct user_pt_regs {
|
||||
* unsigned long regs[32];
|
||||
* unsigned long csr_era;
|
||||
* unsigned long csr_badv;
|
||||
* unsigned long reserved[11];
|
||||
* };
|
||||
*/
|
||||
|
||||
struct user_gp_regs {
|
||||
uint64_t regs[32];
|
||||
uint64_t orig_a0;
|
||||
uint64_t pc;
|
||||
uint64_t csr_badv;
|
||||
uint64_t reserved[10];
|
||||
} __attribute__((aligned(8)));
|
||||
|
||||
struct user_fp_regs {
|
||||
uint64_t regs[32];
|
||||
uint64_t fcc;
|
||||
uint32_t fcsr;
|
||||
};
|
||||
|
||||
typedef struct user_gp_regs user_regs_struct_t;
|
||||
typedef struct user_fp_regs user_fpregs_struct_t;
|
||||
|
||||
#define user_regs_native(regs) true
|
||||
|
||||
#define __compel_arch_fetch_thread_area(tid, th) 0
|
||||
#define compel_arch_fetch_thread_area(tctl) 0
|
||||
#define compel_arch_get_tls_task(ctl, tls)
|
||||
#define compel_arch_get_tls_thread(tctl, tls)
|
||||
|
||||
#define REG_RES(r) ((uint64_t)(r).regs[4])
|
||||
#define REG_IP(r) ((uint64_t)(r).pc)
|
||||
#define REG_SP(r) ((uint64_t)(r).regs[3])
|
||||
#define REG_SYSCALL_NR(r) ((uint64_t)(r).regs[11])
|
||||
#define SET_REG_IP(r, val) ((r).pc = (val))
|
||||
|
||||
#define GPR_NUM 32
|
||||
#define FPR_NUM 32
|
||||
|
||||
#define __NR(syscall, compat) \
|
||||
({ \
|
||||
(void)compat; \
|
||||
__NR_##syscall; \
|
||||
})
|
||||
|
||||
#endif /* UAPI_COMPEL_ASM_TYPES_H__ */
|
86
compel/arch/loongarch64/src/lib/include/uapi/asm/sigframe.h
Normal file
86
compel/arch/loongarch64/src/lib/include/uapi/asm/sigframe.h
Normal file
@ -0,0 +1,86 @@
|
||||
#ifndef UAPI_COMPEL_ASM_SIGFRAME_H__
|
||||
#define UAPI_COMPEL_ASM_SIGFRAME_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <compel/asm/fpu.h>
|
||||
#include <compel/plugins/std/syscall-codes.h>
|
||||
|
||||
#include <asm/types.h>
|
||||
|
||||
#define rt_sigcontext sigcontext
|
||||
/* sigcontext defined in usr/include/uapi/asm/sigcontext.h*/
|
||||
#include <compel/sigframe-common.h>
|
||||
typedef __u32 u32;
|
||||
|
||||
typedef struct sigcontext_t {
|
||||
__u64 pc;
|
||||
__u64 regs[32];
|
||||
__u32 flags;
|
||||
__u64 extcontext[0] __attribute__((__aligned__(16)));
|
||||
} sigcontext_t;
|
||||
|
||||
typedef struct context_info_t {
|
||||
__u32 magic;
|
||||
__u32 size;
|
||||
__u64 padding;
|
||||
} context_info_t;
|
||||
|
||||
#define FPU_CTX_MAGIC 0x46505501
|
||||
#define FPU_CTX_ALIGN 8
|
||||
typedef struct fpu_context_t {
|
||||
__u64 regs[32];
|
||||
__u64 fcc;
|
||||
__u64 fcsr;
|
||||
} fpu_context_t;
|
||||
|
||||
typedef struct ucontext {
|
||||
unsigned long uc_flags;
|
||||
struct ucontext *uc_link;
|
||||
stack_t uc_stack;
|
||||
sigset_t uc_sigmask;
|
||||
__u8 __unused[1024 / 8 - sizeof(sigset_t)];
|
||||
sigcontext_t uc_mcontext;
|
||||
} ucontext;
|
||||
|
||||
/* Copy from the kernel source arch/loongarch/kernel/signal.c */
|
||||
struct rt_sigframe {
|
||||
rt_siginfo_t rs_info;
|
||||
ucontext rs_uc;
|
||||
};
|
||||
|
||||
#define RT_SIGFRAME_UC(rt_sigframe) (&(rt_sigframe->rs_uc))
|
||||
#define RT_SIGFRAME_SIGMASK(rt_sigframe) ((k_rtsigset_t *)&RT_SIGFRAME_UC(rt_sigframe)->uc_sigmask)
|
||||
#define RT_SIGFRAME_SIGCTX(rt_sigframe) (&(RT_SIGFRAME_UC(rt_sigframe)->uc_mcontext))
|
||||
#define RT_SIGFRAME_REGIP(rt_sigframe) ((long unsigned int)(RT_SIGFRAME_SIGCTX(rt_sigframe)->pc))
|
||||
#define RT_SIGFRAME_HAS_FPU(rt_sigframe) (1)
|
||||
|
||||
#define RT_SIGFRAME_FPU(rt_sigframe) \
|
||||
({ \
|
||||
context_info_t *ctx = (context_info_t *)RT_SIGFRAME_SIGCTX(rt_sigframe)->extcontext; \
|
||||
ctx->magic = FPU_CTX_MAGIC; \
|
||||
ctx->size = sizeof(context_info_t) + sizeof(fpu_context_t); \
|
||||
(fpu_context_t *)((char *)ctx + sizeof(context_info_t)); \
|
||||
})
|
||||
|
||||
#define RT_SIGFRAME_OFFSET(rt_sigframe) 0
|
||||
|
||||
/* clang-format off */
|
||||
#define ARCH_RT_SIGRETURN(new_sp, rt_sigframe) \
|
||||
asm volatile( \
|
||||
"addi.d $sp, %0, 0 \n" \
|
||||
"addi.d $a7, $zero, "__stringify(__NR_rt_sigreturn)" \n" \
|
||||
"syscall 0" \
|
||||
: \
|
||||
:"r"(new_sp) \
|
||||
: "$a7", "memory")
|
||||
/* clang-format on */
|
||||
|
||||
int sigreturn_prep_fpu_frame(struct rt_sigframe *sigframe, struct rt_sigframe *rsigframe);
|
||||
|
||||
#define rt_sigframe_erase_sigset(sigframe) memset(RT_SIGFRAME_SIGMASK(sigframe), 0, sizeof(k_rtsigset_t))
|
||||
#define rt_sigframe_copy_sigset(sigframe, from) memcpy(RT_SIGFRAME_SIGMASK(sigframe), from, sizeof(k_rtsigset_t))
|
||||
|
||||
#endif /* UAPI_COMPEL_ASM_SIGFRAME_H__ */
|
204
compel/arch/loongarch64/src/lib/infect.c
Normal file
204
compel/arch/loongarch64/src/lib/infect.c
Normal file
@ -0,0 +1,204 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/uio.h>
|
||||
#include <sys/auxv.h>
|
||||
#include <sys/mman.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <compel/asm/fpu.h>
|
||||
#include <compel/cpu.h>
|
||||
#include "errno.h"
|
||||
#include <compel/plugins/std/syscall-codes.h>
|
||||
#include <compel/plugins/std/syscall.h>
|
||||
#include "common/err.h"
|
||||
#include "common/page.h"
|
||||
#include "asm/infect-types.h"
|
||||
#include "ptrace.h"
|
||||
#include "infect.h"
|
||||
#include "infect-priv.h"
|
||||
#include "log.h"
|
||||
#include "common/bug.h"
|
||||
|
||||
/*
|
||||
* Injected syscall instruction
|
||||
* loongarch64 is Little Endian
|
||||
*/
|
||||
const char code_syscall[] = {
|
||||
0x00, 0x00, 0x2b, 0x00, /* syscall */
|
||||
0x00, 0x00, 0x2a, 0x00 /* break */
|
||||
};
|
||||
|
||||
int sigreturn_prep_regs_plain(struct rt_sigframe *sigframe, user_regs_struct_t *regs, user_fpregs_struct_t *fpregs)
|
||||
{
|
||||
sigcontext_t *sc;
|
||||
fpu_context_t *fpu;
|
||||
|
||||
sc = RT_SIGFRAME_SIGCTX(sigframe);
|
||||
memcpy(sc->regs, regs->regs, sizeof(regs->regs));
|
||||
sc->pc = regs->pc;
|
||||
|
||||
fpu = RT_SIGFRAME_FPU(sigframe);
|
||||
memcpy(fpu->regs, fpregs->regs, sizeof(fpregs->regs));
|
||||
fpu->fcc = fpregs->fcc;
|
||||
fpu->fcsr = fpregs->fcsr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sigreturn_prep_fpu_frame_plain(struct rt_sigframe *sigframe, struct rt_sigframe *rsigframe)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int compel_get_task_regs(pid_t pid, user_regs_struct_t *regs, user_fpregs_struct_t *ext_regs, save_regs_t save,
|
||||
void *arg, __maybe_unused unsigned long flags)
|
||||
{
|
||||
user_fpregs_struct_t tmp, *fpregs = ext_regs ? ext_regs : &tmp;
|
||||
struct iovec iov;
|
||||
int ret;
|
||||
|
||||
pr_info("Dumping GP/FPU registers for %d\n", pid);
|
||||
|
||||
iov.iov_base = regs;
|
||||
iov.iov_len = sizeof(user_regs_struct_t);
|
||||
if ((ret = ptrace(PTRACE_GETREGSET, pid, NT_PRSTATUS, &iov))) {
|
||||
pr_perror("Failed to obtain CPU registers for %d", pid);
|
||||
goto err;
|
||||
}
|
||||
|
||||
/*
|
||||
* Refer to Linux kernel arch/loongarch/kernel/signal.c
|
||||
*/
|
||||
if (regs->regs[0]) {
|
||||
switch (regs->regs[4]) {
|
||||
case -ERESTARTNOHAND:
|
||||
case -ERESTARTSYS:
|
||||
case -ERESTARTNOINTR:
|
||||
regs->regs[4] = regs->orig_a0;
|
||||
regs->pc -= 4;
|
||||
break;
|
||||
case -ERESTART_RESTARTBLOCK:
|
||||
regs->regs[4] = regs->orig_a0;
|
||||
regs->regs[11] = __NR_restart_syscall;
|
||||
regs->pc -= 4;
|
||||
break;
|
||||
}
|
||||
regs->regs[0] = 0; /* Don't deal with this again. */
|
||||
}
|
||||
|
||||
iov.iov_base = fpregs;
|
||||
iov.iov_len = sizeof(user_fpregs_struct_t);
|
||||
if ((ret = ptrace(PTRACE_GETREGSET, pid, NT_PRFPREG, &iov))) {
|
||||
pr_perror("Failed to obtain FPU registers for %d", pid);
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = save(arg, regs, fpregs);
|
||||
err:
|
||||
return 0;
|
||||
}
|
||||
|
||||
int compel_set_task_ext_regs(pid_t pid, user_fpregs_struct_t *ext_regs)
|
||||
{
|
||||
struct iovec iov;
|
||||
|
||||
pr_info("Restoring GP/FPU registers for %d\n", pid);
|
||||
|
||||
iov.iov_base = ext_regs;
|
||||
iov.iov_len = sizeof(*ext_regs);
|
||||
if (ptrace(PTRACE_SETREGSET, pid, NT_PRFPREG, &iov)) {
|
||||
pr_perror("Failed to set FPU registers for %d", pid);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Registers $4 ~ $11 represents arguments a0 ~ a7, especially a7 is
|
||||
* used as syscall number.
|
||||
*/
|
||||
int compel_syscall(struct parasite_ctl *ctl, int nr, long *ret, unsigned long arg1, unsigned long arg2,
|
||||
unsigned long arg3, unsigned long arg4, unsigned long arg5, unsigned long arg6)
|
||||
{
|
||||
int err;
|
||||
user_regs_struct_t regs = ctl->orig.regs;
|
||||
|
||||
regs.regs[11] = (unsigned long)nr;
|
||||
regs.regs[4] = arg1;
|
||||
regs.regs[5] = arg2;
|
||||
regs.regs[6] = arg3;
|
||||
regs.regs[7] = arg4;
|
||||
regs.regs[8] = arg5;
|
||||
regs.regs[9] = arg6;
|
||||
err = compel_execute_syscall(ctl, ®s, code_syscall);
|
||||
|
||||
*ret = regs.regs[4];
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
void *remote_mmap(struct parasite_ctl *ctl, void *addr, size_t length, int prot, int flags, int fd, off_t offset)
|
||||
{
|
||||
long map;
|
||||
int err;
|
||||
|
||||
err = compel_syscall(ctl, __NR_mmap, &map, (unsigned long)addr, length, prot, flags, fd, offset >> PAGE_SHIFT);
|
||||
|
||||
if (err < 0 || IS_ERR_VALUE(map)) {
|
||||
pr_err("remote mmap() failed: %s\n", strerror(-map));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return (void *)map;
|
||||
}
|
||||
|
||||
/*
|
||||
* regs must be inited when calling this function from original context
|
||||
*/
|
||||
void parasite_setup_regs(unsigned long new_ip, void *stack, user_regs_struct_t *regs)
|
||||
{
|
||||
regs->pc = new_ip;
|
||||
if (stack)
|
||||
regs->regs[4] = (unsigned long)stack;
|
||||
}
|
||||
|
||||
bool arch_can_dump_task(struct parasite_ctl *ctl)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
int arch_fetch_sas(struct parasite_ctl *ctl, struct rt_sigframe *s)
|
||||
{
|
||||
long ret;
|
||||
int err;
|
||||
|
||||
err = compel_syscall(ctl, __NR_sigaltstack, &ret, 0, (unsigned long)&s->rs_uc.uc_stack, 0, 0, 0, 0);
|
||||
return err ? err : ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* TODO: add feature
|
||||
*/
|
||||
int ptrace_set_breakpoint(pid_t pid, void *addr)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ptrace_flush_breakpoints(pid_t pid)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Refer to Linux kernel arch/loongarch/include/asm/processor.h
|
||||
*/
|
||||
#define TASK_SIZE32 (1UL) << 31
|
||||
#define TASK_SIZE64_MIN (1UL) << 40
|
||||
#define TASK_SIZE64_MAX (1UL) << 48
|
||||
|
||||
unsigned long compel_task_size(void)
|
||||
{
|
||||
unsigned long task_size;
|
||||
for (task_size = TASK_SIZE64_MIN; task_size < TASK_SIZE64_MAX; task_size <<= 1)
|
||||
if (munmap((void *)task_size, page_size()))
|
||||
break;
|
||||
return task_size;
|
||||
}
|
@ -57,6 +57,9 @@ static const flags_t flags = {
|
||||
#elif defined CONFIG_MIPS
|
||||
.arch = "mips",
|
||||
.cflags = COMPEL_CFLAGS_PIE,
|
||||
#elif defined CONFIG_LOONGARCH64
|
||||
.arch = "loongarch64",
|
||||
.cflags = COMPEL_CFLAGS_PIE,
|
||||
#else
|
||||
#error "CONFIG_<ARCH> not defined, or unsupported ARCH"
|
||||
#endif
|
||||
|
@ -20,7 +20,8 @@ ARCH ?= $(shell echo $(SUBARCH) | sed \
|
||||
-e s/ppc64.*/ppc64/ \
|
||||
-e s/mips.*/mips/ \
|
||||
-e s/sh[234].*/sh/ \
|
||||
-e s/aarch64.*/aarch64/)
|
||||
-e s/aarch64.*/aarch64/ \
|
||||
-e s/loongarch64.*/loongarch64/)
|
||||
|
||||
export SUBARCH ARCH
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user