forked from huawei/openGauss-server
603 lines
20 KiB
C++
603 lines
20 KiB
C++
/* -------------------------------------------------------------------------
|
||
* Portions Copyright (c) 2020 Huawei Technologies Co.,Ltd.
|
||
* Portions Copyright (c) 2005-2008, Google Inc.
|
||
*
|
||
*
|
||
* bbox_syscall_support.cpp
|
||
*
|
||
* IDENTIFICATION
|
||
* src/gausskernel/cbb/bbox/bbox_syscall_support.cpp
|
||
*
|
||
*
|
||
*/
|
||
#include "bbox_syscall_support.h"
|
||
#include "../../src/include/securec.h"
|
||
#include "../../src/include/securec_check.h"
|
||
__syscall0(long, gettid);
|
||
__syscall0(long, getpid);
|
||
__syscall0(long, getppid);
|
||
__syscall0(long, geteuid);
|
||
__syscall0(long, getegid);
|
||
__syscall1(long, getsid, pid_t, pid);
|
||
__syscall2(long, gettimeofday, struct kernel_timeval*, tv, struct kernel_timezone*, tz);
|
||
__syscall4(long, ptrace, long, request, long, pid, void*, addr, void*, data);
|
||
__syscall2(long, sigaltstack, const stack_t*, uss, const stack_t*, uoss);
|
||
__syscall2(long, getpriority, int, which, int, who);
|
||
__syscall2(long, getrlimit, unsigned int, resource, struct kernel_rlimit*, rlim);
|
||
__syscall1(long, close, int, fd);
|
||
__syscall3(long, read, unsigned int, fd, void*, buf, size_t, count);
|
||
__syscall3(long, write, unsigned int, fd, const void*, buf, size_t, count);
|
||
__syscall3(long, lseek, unsigned int, fd, off_t, offset, unsigned int, origin);
|
||
__syscall3(long, fcntl, unsigned int, fd, unsigned int, cmd, unsigned long, arg);
|
||
__syscall2(long, fstat, int, fd, struct kernel_stat*, statbuf);
|
||
__syscall1(long, dup, unsigned int, fildes);
|
||
__syscall2(long, nanosleep, struct kernel_timespec*, rqtp, struct kernel_timespec*, rmtp);
|
||
__syscall3(long, execve, char*, name, char**, argv, char**, envp);
|
||
__syscall4(long, wait4, pid_t, upid, int*, stat_addr, int, options, struct rusage*, ru);
|
||
__syscall2(long, kill, pid_t, pid, int, sig);
|
||
__syscall0(long, sched_yield);
|
||
__syscall1(long, exit, int, error_code);
|
||
__syscall1(long, exit_group, int, error_code);
|
||
__syscall5(
|
||
long, prctl, int, option, unsigned long, arg2, unsigned long, arg3, unsigned long, arg4, unsigned long, arg5);
|
||
__syscall4(
|
||
long, rt_sigprocmask, int, how, struct kernel_sigset_t*, set, struct kernel_sigset_t*, oset, size_t, sigsetsize);
|
||
__syscall4(long, rt_sigaction, int, sig, const struct kernel_sigaction*, act, struct kernel_sigaction*, oact, size_t,
|
||
sigsetsize);
|
||
|
||
#if (defined(__aarch64__))
|
||
__syscall1(long, getpgid, long, pid);
|
||
__syscall4(long, openat, int, dfd, const char*, filename, int, flags, int, mode);
|
||
__syscall3(long, getdents64, unsigned int, fd, struct linux_dirent*, dirent, unsigned int, count);
|
||
__syscall4(long, readlinkat, int, dfd, const char*, path, char*, buf, int, bufsiz);
|
||
__syscall4(long, newfstatat, int, dfd, const char*, filename, struct kernel_stat*, statbuf, int, flag);
|
||
__syscall3(long, mkdirat, int, dfd, const char*, pathname, int, mode);
|
||
__syscall3(long, unlinkat, int, dfd, const char*, pathname, int, flag);
|
||
__syscall4(long, renameat, int, olddfd, const char*, oldname, int, newdfd, const char*, newname);
|
||
__syscall3(long, fchmodat, int, dfd, const char*, filename, mode_t, mode);
|
||
__syscall2(long, pipe2, int*, fildes, int, flags);
|
||
__syscall3(long, dup3, unsigned int, oldfd, unsigned int, newfd, int, flags);
|
||
__syscall5(
|
||
long, clone, unsigned long, clone_flags, unsigned long, newsp, int*, parent_tid, void*, newtls, int*, child_tid);
|
||
|
||
long SYS_NAME(getpgrp)(void)
|
||
{
|
||
return sys_getpgid(sys_getpid());
|
||
}
|
||
|
||
long SYS_NAME(open)(const char* filename, int flags, int mode)
|
||
{
|
||
return sys_openat(AT_FDCWD, filename, flags, mode);
|
||
}
|
||
|
||
long SYS_NAME(getdents)(unsigned int fd, struct linux_dirent* dirent, unsigned int count)
|
||
{
|
||
return sys_getdents64(fd, dirent, count);
|
||
}
|
||
|
||
long SYS_NAME(readlink)(const char* path, char* buf, int bufsiz)
|
||
{
|
||
return sys_readlinkat(AT_FDCWD, path, buf, bufsiz);
|
||
}
|
||
|
||
long SYS_NAME(stat)(char* filename, struct kernel_stat* statbuf)
|
||
{
|
||
return sys_newfstatat(AT_FDCWD, filename, statbuf, 0);
|
||
}
|
||
|
||
long SYS_NAME(mkdir)(const char* pathname, int mode)
|
||
{
|
||
return sys_mkdirat(AT_FDCWD, pathname, mode);
|
||
}
|
||
|
||
long SYS_NAME(unlink)(const char* pathname)
|
||
{
|
||
return sys_unlinkat(AT_FDCWD, pathname, 0);
|
||
}
|
||
|
||
long SYS_NAME(rename)(const char* oldname, const char* newname)
|
||
{
|
||
return sys_renameat(AT_FDCWD, oldname, AT_FDCWD, newname);
|
||
}
|
||
|
||
long SYS_NAME(chmod)(const char* filename, mode_t mode)
|
||
{
|
||
return sys_fchmodat(AT_FDCWD, filename, mode);
|
||
}
|
||
|
||
long SYS_NAME(pipe)(int* fildes)
|
||
{
|
||
return sys_pipe2(fildes, 0);
|
||
}
|
||
|
||
long SYS_NAME(dup2)(unsigned int oldfd, unsigned int newfd)
|
||
{
|
||
return sys_dup3(oldfd, newfd, 0);
|
||
}
|
||
|
||
long SYS_NAME(fork)(void)
|
||
{
|
||
return sys_clone(SIGCHLD, 0, 0, NULL, NULL);
|
||
}
|
||
|
||
#else
|
||
|
||
__syscall0(long, getpgrp);
|
||
__syscall3(long, open, const char*, filename, int, flags, int, mode);
|
||
__syscall3(long, getdents, unsigned int, fd, struct linux_dirent*, dirent, unsigned int, count);
|
||
__syscall3(long, readlink, const char*, path, char*, buf, int, bufsiz);
|
||
__syscall2(long, stat, char*, filename, struct kernel_stat*, statbuf);
|
||
__syscall2(long, mkdir, const char*, pathname, int, mode);
|
||
__syscall1(long, unlink, const char*, pathname);
|
||
__syscall2(long, rename, const char*, oldname, const char*, newname);
|
||
__syscall2(long, chmod, const char*, filename, mode_t, mode);
|
||
__syscall1(long, pipe, int*, fildes);
|
||
__syscall2(long, dup2, unsigned int, oldfd, unsigned int, newfd);
|
||
__syscall0(long, vfork);
|
||
__syscall0(long, fork);
|
||
|
||
#endif
|
||
|
||
int SYS_NAME(sysconf)(int name)
|
||
{
|
||
switch (name) {
|
||
case _SC_PAGESIZE:
|
||
return getpagesize(); // <20><><EFBFBD><EFBFBD>ϵͳҳ<CDB3><D2B3><EFBFBD><EFBFBD>С
|
||
case _SC_OPEN_MAX: {
|
||
struct kernel_rlimit limit = {0}; // <20><><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>kernel_rlimit<69>ṹ<EFBFBD>壬<EFBFBD><E5A3AC><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC>Ϊ0
|
||
if (sys_getrlimit(RLIMIT_NOFILE, &limit) >= 0) { // <20><><EFBFBD><EFBFBD>sys_getrlimit<69><74><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>RLIMIT_NOFILE<4C><45>Դ<EFBFBD><D4B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD>洢<EFBFBD><E6B4A2>limit<69><74>
|
||
return limit.rlim_cur; // <20><><EFBFBD>ص<EFBFBD>ǰ<EFBFBD><C7B0><EFBFBD>̵<EFBFBD><CCB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD>
|
||
} else {
|
||
/* Default maximum open files for per process */
|
||
return 8192; // <20><><EFBFBD><EFBFBD>Ĭ<EFBFBD>ϵ<EFBFBD><CFB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD>Ϊ8192
|
||
}
|
||
}
|
||
default:
|
||
errno = ENOSYS; // <20><><EFBFBD><EFBFBD>name<6D><65>ƥ<EFBFBD><C6A5>_SC_PAGESIZE<5A><45>_SC_OPEN_MAX<41><58><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>errnoΪENOSYS<59><53>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD>δʵ<CEB4><CAB5>
|
||
return -1;
|
||
}
|
||
}
|
||
|
||
int SYS_NAME(sigemptyset)(struct kernel_sigset_t* set)
|
||
{
|
||
errno_t rc = memset_s(set->sig, sizeof(set->sig), 0, sizeof(set->sig)); // ʹ<><CAB9>memset_s<5F><73><EFBFBD><EFBFBD><EFBFBD><EFBFBD>set->sig<69><67>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD>Ϊ0
|
||
securec_check_c(rc, "\0", "\0");
|
||
return 0;
|
||
}
|
||
|
||
int SYS_NAME(sigfillset)(struct kernel_sigset_t* set)
|
||
{
|
||
errno_t rc = memset_s(set->sig, sizeof(set->sig), 0xFF, sizeof(set->sig)); // ʹ<><CAB9>memset_s<5F><73><EFBFBD><EFBFBD><EFBFBD><EFBFBD>set->sig<69><67>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD>Ϊ0xFF
|
||
securec_check_c(rc, "\0", "\0");
|
||
return 0;
|
||
}
|
||
|
||
int SYS_NAME(sigaddset)(struct kernel_sigset_t* set, int __signum)
|
||
{
|
||
int signo = (int)(8 * sizeof(set->sig)); // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD>źż<C5BA><C5BC><EFBFBD>λ<EFBFBD><CEBB>
|
||
|
||
if (__signum < 1 || __signum > signo) {
|
||
errno = EINVAL; // <20><><EFBFBD><EFBFBD>__signumС<6D><D0A1>1<EFBFBD><31><EFBFBD><EFBFBD><EFBFBD><EFBFBD>signo<6E><6F><EFBFBD><EFBFBD><EFBFBD><EFBFBD>errnoΪEINVAL<41><4C>ʾ<EFBFBD><CABE>Ч<EFBFBD><D0A7><EFBFBD><EFBFBD>
|
||
return -1;
|
||
} else {
|
||
set->sig[(__signum - 1) / (8 * sizeof(set->sig[0]))] |= 1UL << ((__signum - 1) % (8 * sizeof(set->sig[0]))); // <20><>__signum<75><6D>Ӧ<EFBFBD><D3A6>λ<EFBFBD><CEBB><EFBFBD><EFBFBD>Ϊ1
|
||
return 0;
|
||
}
|
||
}
|
||
|
||
int SYS_NAME(sigdelset)(struct kernel_sigset_t* set, int __signum)
|
||
{
|
||
int signo = (int)(8 * sizeof(set->sig)); // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD>źż<C5BA><C5BC><EFBFBD>λ<EFBFBD><CEBB>
|
||
|
||
if (__signum < 1 || __signum > signo) {
|
||
errno = EINVAL; // <20><><EFBFBD><EFBFBD>__signumС<6D><D0A1>1<EFBFBD><31><EFBFBD><EFBFBD><EFBFBD><EFBFBD>signo<6E><6F><EFBFBD><EFBFBD><EFBFBD><EFBFBD>errnoΪEINVAL<41><4C>ʾ<EFBFBD><CABE>Ч<EFBFBD><D0A7><EFBFBD><EFBFBD>
|
||
return -1;
|
||
} else {
|
||
set->sig[(__signum - 1) / (8 * sizeof(set->sig[0]))] &= ~(1UL << ((__signum - 1) % (8 * sizeof(set->sig[0])))); // <20><>__signum<75><6D>Ӧ<EFBFBD><D3A6>λ<EFBFBD><CEBB><EFBFBD><EFBFBD>Ϊ0
|
||
return 0;
|
||
}
|
||
}
|
||
|
||
int SYS_NAME(sigismember)(struct kernel_sigset_t* set, int __signum)
|
||
{
|
||
int signo = (int)(8 * sizeof(set->sig)); // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD>źż<C5BA><C5BC><EFBFBD>λ<EFBFBD><CEBB>
|
||
|
||
if (__signum < 1 || __signum > signo) {
|
||
errno = EINVAL; // <20><><EFBFBD><EFBFBD>__signumС<6D><D0A1>1<EFBFBD><31><EFBFBD><EFBFBD><EFBFBD><EFBFBD>signo<6E><6F><EFBFBD><EFBFBD><EFBFBD><EFBFBD>errnoΪEINVAL<41><4C>ʾ<EFBFBD><CABE>Ч<EFBFBD><D0A7><EFBFBD><EFBFBD>
|
||
return -1;
|
||
} else {
|
||
return !!(set->sig[(__signum - 1) / (8 * sizeof(set->sig[0]))] &
|
||
(1UL << ((__signum - 1) % (8 * sizeof(set->sig[0]))))); // <20><><EFBFBD><EFBFBD>__signum<75><6D>Ӧ<EFBFBD><D3A6>λ<EFBFBD>Ƿ<EFBFBD>Ϊ1<CEAA><31><EFBFBD><EFBFBD><EFBFBD>ؽ<EFBFBD><D8BD><EFBFBD>
|
||
}
|
||
}
|
||
|
||
long SYS_NAME(sigprocmask)(int how, struct kernel_sigset_t* set, struct kernel_sigset_t* oldset)
|
||
{
|
||
long ret = 0;
|
||
|
||
ret = SYS_NAME(rt_sigprocmask)(how, set, oldset, (KERNEL_NSIG + 7) / 8); // <20><><EFBFBD><EFBFBD>SYS_NAME(rt_sigprocmask)<29><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ź<EFBFBD><C5BA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
return ret;
|
||
}
|
||
|
||
#if defined(__x86_64__)
|
||
__syscall3(long, socket, int, family, int, type, int, protocol);
|
||
__syscall4(long, clone, unsigned long, clone_flags, unsigned long, newsp, int*, parent_tidptr, int*, child_tidptr);
|
||
long SYS_NAME(waitpid)(pid_t pid, int* status, int options)
|
||
{
|
||
return SYS_NAME(wait4)(pid, status, options, 0);
|
||
}
|
||
|
||
long SYS_NAME(signal)(int __signum, void (*handler)(int))
|
||
{
|
||
struct kernel_sigaction sa;
|
||
|
||
errno_t rc = memset_s(&sa, sizeof(sa), 0, sizeof(sa));
|
||
securec_check_c(rc, "\0", "\0");
|
||
|
||
sys_sigfillset(&sa.sa_mask);
|
||
sa.sa_flags |= SA_RESTORER | SA_RESTART;
|
||
sa.handle.sa_handler_ = handler;
|
||
|
||
return SYS_NAME(rt_sigaction)(__signum, &sa, NULL, (KERNEL_NSIG + 7) / 8);
|
||
}
|
||
|
||
#define CLONE_SYSCALL_X86_64 \
|
||
"movq %2,%%rax\n" \
|
||
"syscall\n" \
|
||
"testq %%rax,%%rax\n" \
|
||
"jnz 1f\n" \
|
||
"xorq %%rbp,%%rbp\n" \
|
||
"popq %%rax\n" \
|
||
"popq %%rdi\n" \
|
||
"call *%%rax\n" \
|
||
"movq %%rax,%%rdi\n" \
|
||
"movq %3,%%rax\n" \
|
||
"syscall\n"
|
||
|
||
long SYS_NAME(_clone)(
|
||
int (*fn)(void*), void* child_stack, int flags, void* arg, int* parent_tidptr, void* newtls, int* child_tidptr)
|
||
{
|
||
long ___res;
|
||
{
|
||
register void* __tls __asm__("r8") = newtls;
|
||
register int* __ctid __asm__("r10") = child_tidptr;
|
||
|
||
__asm__ __volatile__(
|
||
|
||
/* example: if (fn == NULL) return -EINVAL; */
|
||
"testq %4,%4\n"
|
||
"jz 1f\n"
|
||
|
||
/* example: if (child_stack == NULL) return -EINVAL; */
|
||
"testq %5,%5\n"
|
||
"jz 1f\n"
|
||
|
||
"subq $0x10,%5\n"
|
||
|
||
/* Push "arg" and "fn" onto the stack that will be
|
||
* used by the child.
|
||
*/
|
||
"movq %7,0x8(%5)\n"
|
||
"movq %4,0x0(%5)\n"
|
||
|
||
/* example: %rax = syscall(%rax = __NR_clone,
|
||
* %rdi = flags,
|
||
* %rsi = child_stack,
|
||
* %rdx = parent_tidptr,
|
||
* %r8 = new_tls,
|
||
* %r10 = child_tidptr)
|
||
*/
|
||
CLONE_SYSCALL_X86_64
|
||
|
||
/* Return to parent.
|
||
*/
|
||
"1:\n"
|
||
: "=a"(___res)
|
||
: "0"(-EINVAL),
|
||
"i"(__NR_clone),
|
||
"i"(__NR_exit),
|
||
"r"(fn),
|
||
"S"(child_stack),
|
||
"D"(flags),
|
||
"r"(arg),
|
||
"d"(parent_tidptr),
|
||
"r"(__tls),
|
||
"r"(__ctid)
|
||
: "memory", "r11", "rcx");
|
||
}
|
||
___syscall_return(int, ___res);
|
||
}
|
||
|
||
#elif (defined(__i386__))
|
||
__syscall3(long, waitpid, pid_t, pid, int*, stat_addr, int, options);
|
||
__syscall2(long, signal, int, sig, __sighandler_t, handler);
|
||
__syscall2(long, socketcall, int, call, va_list, args);
|
||
__syscall5(
|
||
long, clone, unsigned long, clone_flags, unsigned long, newsp, int*, parent_tid, void*, newtls, int*, child_tid);
|
||
|
||
long do_syscall(int number, ...)
|
||
{
|
||
register long result;
|
||
__asm__ volatile("push %ebx; push %esi; push %edi");
|
||
__asm__ volatile("mov 28(%%ebp),%%edi;"
|
||
"mov 24(%%ebp),%%esi;"
|
||
"mov 20(%%ebp),%%edx;"
|
||
"mov 16(%%ebp),%%ecx;"
|
||
"mov 12(%%ebp),%%ebx;"
|
||
"mov 8(%%ebp),%%eax;"
|
||
"int $0x80"
|
||
: "=a"(result));
|
||
__asm__ volatile("pop %edi; pop %esi; pop %ebx");
|
||
return result;
|
||
}
|
||
|
||
long SYS_NAME(_socketcall)(int op, ...)
|
||
{
|
||
int ret;
|
||
ret = 0;
|
||
va_list ap;
|
||
va_start(ap, op);
|
||
ret = SYS_NAME(socketcall)(op, ap);
|
||
va_end(ap);
|
||
return ret;
|
||
}
|
||
|
||
long SYS_NAME(socket)(int domain, int type, int protocol)
|
||
{
|
||
return SYS_NAME(_socketcall)(1, domain, type, protocol);
|
||
}
|
||
|
||
#define CLONE_SYSCALL_X86_32 \
|
||
"movl %8,%%esi\n" \
|
||
"movl %5,%%eax\n" \
|
||
"movl %7,%%edx\n" \
|
||
"movl %9,%%edi\n" \
|
||
"pushl %%ebx\n" \
|
||
"movl %%eax,%%ebx\n" \
|
||
"movl %2,%%eax\n" \
|
||
"int $0x80\n" \
|
||
"popl %%ebx\n" \
|
||
"test %%eax,%%eax\n" \
|
||
"jnz 1f\n" \
|
||
"movl $0x0,%%ebp\n" \
|
||
"call *%%ebx\n" \
|
||
"movl %%eax,%%ebx\n" \
|
||
"movl $0x1,%%eax\n" \
|
||
"int $0x80\n"
|
||
|
||
long SYS_NAME(_clone)(
|
||
int (*fn)(void*), void* child_stack, int flags, void* arg, int* parent_tidptr, void* newtls, int* child_tidptr)
|
||
{
|
||
long ___res;
|
||
|
||
__asm__ __volatile__(
|
||
/* example: if (fn == NULL) return -EINVAL; */
|
||
"movl %3,%%ecx\n"
|
||
"jecxz 1f\n"
|
||
|
||
/* example: if (child_stack == NULL) return -EINVAL; */
|
||
"movl %4,%%ecx\n"
|
||
"jecxz 1f\n"
|
||
|
||
/* Set up alignment of the child stack:
|
||
* example: child_stack = (child_stack & ~0xF) - 20;
|
||
*/
|
||
"andl $-16,%%ecx\n"
|
||
"subl $0x14,%%ecx\n"
|
||
|
||
/* Push "arg" and "fn" onto the stack that will be
|
||
* used by the child.
|
||
*/
|
||
"movl %6,%%eax\n"
|
||
"movl %%eax,4(%%ecx)\n"
|
||
"movl %3,%%eax\n"
|
||
"movl %%eax,(%%ecx)\n"
|
||
|
||
/* example: %eax = syscall(%eax = __NR_clone,
|
||
* %ebx = flags,
|
||
* %ecx = child_stack,
|
||
* %edx = parent_tidptr,
|
||
* %esi = newtls,
|
||
* %edi = child_tidptr)
|
||
* Also, make sure that %ebx gets preserved as it is
|
||
* used in PIC mode.
|
||
*/
|
||
CLONE_SYSCALL_X86_32
|
||
|
||
/* Return to parent.
|
||
*/
|
||
"1:\n"
|
||
: "=a"(___res)
|
||
: "0"(-EINVAL),
|
||
"i"(__NR_clone),
|
||
"m"(fn),
|
||
"m"(child_stack),
|
||
"m"(flags),
|
||
"m"(arg),
|
||
"m"(parent_tidptr),
|
||
"m"(newtls),
|
||
"m"(child_tidptr)
|
||
: "memory", "ecx", "edx", "esi", "edi");
|
||
___syscall_return(int, ___res);
|
||
}
|
||
|
||
#elif (defined(__ARM_ARCH_5TE__)) || (defined(__ARM_ARCH_7A__))
|
||
__syscall3(long, socket, int, d, int, t, int, p);
|
||
__syscall5(
|
||
long, clone, unsigned long, clone_flags, unsigned long, newsp, int*, parent_tid, void*, newtls, int*, child_tid);
|
||
|
||
long SYS_NAME(waitpid)(pid_t pid, int* status, int options)
|
||
{
|
||
return SYS_NAME(wait4)(pid, status, options, 0); // <20><><EFBFBD><EFBFBD>SYS_NAME(wait4)<29><><EFBFBD><EFBFBD><EFBFBD>ȴ<EFBFBD><C8B4>ӽ<EFBFBD><D3BD>̽<EFBFBD><CCBD><EFBFBD>
|
||
}
|
||
|
||
long SYS_NAME(signal)(int __signum, void (*handler)(int))
|
||
{
|
||
struct kernel_sigaction _sa;
|
||
struct kernel_sigaction old;
|
||
|
||
errno_t rc = memset_s(&_sa, sizeof(_sa), 0, sizeof(_sa)); // ʹ<><CAB9>memset_s<5F><73><EFBFBD><EFBFBD><EFBFBD><EFBFBD>_sa<73><61>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD>Ϊ0
|
||
securec_check_c(rc, "\0", "\0");
|
||
sys_sigfillset(&_sa.sa_mask); // <20><>_sa.sa_mask<73><6B><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ<EFBFBD><CEBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ1
|
||
_sa.sa_flags |= SA_RESTORER | SA_RESTART; // <20><><EFBFBD><EFBFBD>_sa.sa_flags<67>ı<EFBFBD>־λ
|
||
_sa.handle.sa_handler_ = handler; // <20><><EFBFBD><EFBFBD>_sa.handle.sa_handler_Ϊ<5F><CEAA><EFBFBD><EFBFBD><EFBFBD><EFBFBD>handler<65><72><EFBFBD><EFBFBD>
|
||
|
||
return SYS_NAME(rt_sigaction)(__signum, &_sa, &old, (KERNEL_NSIG + 7) / 8); // <20><><EFBFBD><EFBFBD>SYS_NAME(rt_sigaction)<29><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>źŴ<C5BA><C5B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
}
|
||
/*
|
||
long SYS_NAME(_clone)(int (fn)(void), void* child_stack, int flags, void* arg, int* parent_tidptr, void* newtls, int* child_tidptr)<29><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD><DAB4><EFBFBD>һ<EFBFBD><D2BB><EFBFBD>µĽ<C2B5><C4BD>̣<EFBFBD><CCA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>½<EFBFBD><C2BD><EFBFBD><EFBFBD><EFBFBD>ִ<EFBFBD><D6B4>ָ<EFBFBD><D6B8><EFBFBD>ĺ<EFBFBD><C4BA><EFBFBD><EFBFBD><EFBFBD>
|
||
*/
|
||
long SYS_NAME(_clone)(int (*fn)(void*), void* child_stack, int flags, void* arg, int* parent_tidptr, void* newtls, int* child_tidptr)
|
||
{
|
||
register long ___res __asm__("r5");
|
||
|
||
{
|
||
if (fn == NULL || child_stack == NULL) { // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ĺ<EFBFBD><C4BA><EFBFBD>ָ<EFBFBD><D6B8>ΪNULL<4C><4C><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӽ<EFBFBD><D3BD><EFBFBD>ջָ<D5BB><D6B8>ΪNULL<4C><4C><EFBFBD><EFBFBD>EINVAL<41><4C><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
___res = -EINVAL;
|
||
goto _clone_exit;
|
||
}
|
||
|
||
/* stash first 4 arguments on stack first because we can only load
|
||
* them after all function calls.
|
||
*/
|
||
int tmp_flags = flags; // <20><><EFBFBD><EFBFBD>flags<67><73>ֵ `tmp_flags`<60><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڱ<EFBFBD><DAB1><EFBFBD>`flags`<60><>ֵ<EFBFBD><D6B5>
|
||
|
||
int* tmp_stack = (int*)child_stack; // <20><><EFBFBD>ӽ<EFBFBD><D3BD><EFBFBD>ջָ<D5BB><D6B8>ת<EFBFBD><D7AA>Ϊint<6E><74><EFBFBD><EFBFBD>ָ<EFBFBD>벢<EFBFBD><EBB2A2><EFBFBD><EFBFBD>Ϊtmp_stack
|
||
void* tmp_ptid = parent_tidptr; // <20><><EFBFBD><EFBFBD>parent_tidptr<74><72>ֵ
|
||
void* tmp_tls = newtls; // <20><><EFBFBD><EFBFBD>newtls<6C><73>ֵ
|
||
|
||
register int* ___ctid __asm__("r4") = child_tidptr; // <20><>child_tidptr<74><72><EFBFBD>浽___ctid<69>Ĵ<EFBFBD><C4B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
|
||
/* Push "arg" and "fn" onto the stack that will be
|
||
* used by the child.
|
||
*/
|
||
*(--tmp_stack) = (int)arg; // <20><>arg<72><67>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD><EFBFBD>ӽ<EFBFBD><D3BD><EFBFBD>ջ<EFBFBD><D5BB>
|
||
*(--tmp_stack) = (int)fn; // <20><>fn<66><6E>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD><EFBFBD>ӽ<EFBFBD><D3BD><EFBFBD>ջ<EFBFBD><D5BB>
|
||
|
||
/* We must load r0..r3 last after all possible function calls. */
|
||
register int ___flags __asm__("r0") = tmp_flags; // <20><>tmp_flags<67><73><EFBFBD>浽___flags<67>Ĵ<EFBFBD><C4B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
register void* ___stack __asm__("r1") = tmp_stack; // <20><>tmp_stack<63><6B><EFBFBD>浽___stack<63>Ĵ<EFBFBD><C4B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
register void* ___ptid __asm__("r2") = tmp_ptid; // <20><>tmp_ptid<69><64><EFBFBD>浽___ptid<69>Ĵ<EFBFBD><C4B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
register void* ___tls __asm__("r3") = tmp_tls; // <20><>tmp_tls<6C><73><EFBFBD>浽___tls<6C>Ĵ<EFBFBD><C4B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
|
||
/* example: %r0 = syscall(%r0 = flags,
|
||
* %r1 = child_stack,
|
||
* %r2 = parent_tidptr,
|
||
* %r3 = newtls,
|
||
* %r4 = child_tidptr)
|
||
*/
|
||
__SYS_REG(clone) // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>__SYS_REG(clone)
|
||
|
||
__asm__ __volatile__(
|
||
"push {r7}\n" // <20><>r7<72>Ĵ<EFBFBD><C4B4><EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD><D6B5><EFBFBD>浽ջ<E6B5BD><D5BB>
|
||
"mov r7,%1\n" __syscall(clone) "\n" // <20><><EFBFBD><EFBFBD>ϵͳ<CFB5><CDB3><EFBFBD><EFBFBD>clone
|
||
|
||
"movs %0,r0\n" // <20><>r0<72><30>ֵ<EFBFBD><D6B5><EFBFBD>浽___res<65>У<EFBFBD><D0A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
"bne 1f\n" // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>벻<EFBFBD><EBB2BB><EFBFBD><EFBFBD>0<EFBFBD><30><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ת<EFBFBD><D7AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD>1<EFBFBD><31>
|
||
|
||
"ldr r0,[sp, #4]\n" // <20><>sp<73><70><EFBFBD><EFBFBD>4<EFBFBD><34><EFBFBD>õ<EFBFBD><C3B5><EFBFBD>ַ<EFBFBD><D6B7>Ȼ<EFBFBD>õ<F3BDABB8>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݱ<EFBFBD><DDB1>浽r0<72>Ĵ<EFBFBD><C4B4><EFBFBD><EFBFBD><EFBFBD>
|
||
"mov lr,pc\n" // <20><>pc<70><63>ֵ<EFBFBD><D6B5><EFBFBD>浽lr<6C>Ĵ<EFBFBD><C4B4><EFBFBD><EFBFBD><EFBFBD>
|
||
"ldr pc,[sp]\n" // <20><>sp<73><70>ֵ<EFBFBD><D6B5><EFBFBD>浽pc<70>Ĵ<EFBFBD><C4B4><EFBFBD><EFBFBD><EFBFBD>
|
||
|
||
"mov r7,%2\n" __syscall(exit) "\n" // <20><><EFBFBD><EFBFBD>ϵͳ<CFB5><CDB3><EFBFBD><EFBFBD>exit
|
||
|
||
"1: pop {r7}\n" // <20><>ջ<EFBFBD>е<EFBFBD>ֵ<EFBFBD><D6B5><EFBFBD>浽r7<72>Ĵ<EFBFBD><C4B4><EFBFBD><EFBFBD><EFBFBD>
|
||
: "=r"(___res) // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>浽___res<65>Ĵ<EFBFBD><C4B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
: "r"(__sysreg), "i"(__NR_exit), "r"(___stack), "r"(___flags), "r"(___ptid), "r"(___tls), "r"(___ctid) // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
: "cc", "lr", "memory"); // <20><EFBFBD><DEB8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>룬lr<6C>Ĵ<EFBFBD><C4B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Լ<EFBFBD><D4BC>ڴ<EFBFBD>
|
||
}
|
||
|
||
_clone_exit:
|
||
___syscall_return(int, ___res); // <20><><EFBFBD><EFBFBD>___syscall_return<72><6E><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ؽ<EFBFBD><D8BD><EFBFBD>
|
||
}
|
||
|
||
#elif (defined(__aarch64__))
|
||
__syscall3(long, socket, int, family, int, type, int, protocol);
|
||
|
||
long SYS_NAME(waitpid)(pid_t pid, int* status, int options)
|
||
{
|
||
return SYS_NAME(wait4)(pid, status, options, 0);
|
||
}
|
||
|
||
long SYS_NAME(signal)(int __signum, void (*handler)(int))
|
||
{
|
||
struct kernel_sigaction _sa;
|
||
struct kernel_sigaction old;
|
||
|
||
errno_t rc = memset_s(&_sa, sizeof(_sa), 0, sizeof(_sa));
|
||
securec_check_c(rc, "\0", "\0");
|
||
sys_sigfillset(&_sa.sa_mask);
|
||
_sa.sa_flags |= SA_RESTORER | SA_RESTART;
|
||
_sa.handle.sa_handler_ = handler;
|
||
|
||
return SYS_NAME(rt_sigaction)(__signum, &_sa, &old, (KERNEL_NSIG + 7) / 8);
|
||
}
|
||
|
||
long SYS_NAME(_clone)(
|
||
int (*fn)(void*), void* child_stack, int flags, void* arg, int* parent_tidptr, void* newtls, int* child_tidptr)
|
||
{
|
||
register long __res_x0 __asm__("x0");
|
||
long ___res;
|
||
{
|
||
register int (*__fn)(void*) __asm__("x0") = fn;
|
||
register void* __stack __asm__("x1") = child_stack;
|
||
register int __flags __asm__("x2") = flags;
|
||
register void* __arg __asm__("x3") = arg;
|
||
register int* __ptid __asm__("x4") = parent_tidptr;
|
||
register void* __tls __asm__("x5") = newtls;
|
||
register int* __ctid __asm__("x6") = child_tidptr;
|
||
|
||
__asm__ __volatile__(
|
||
|
||
/* example: if (fn == NULL || child_stack == NULL) return -EINVAL; */
|
||
"cbz x0,1f\n"
|
||
"cbz x1,1f\n"
|
||
|
||
/* Push "arg" and "fn" onto the stack that will be
|
||
* used by the child.
|
||
*/
|
||
"stp x0,x3, [x1, #-16]!\n"
|
||
|
||
"mov x0,x2\n" /* flags */
|
||
"mov x2,x4\n" /* ptid */
|
||
"mov x3,x5\n" /* tls */
|
||
"mov x4,x6\n" /* ctid */
|
||
"mov x8,%9\n" /* clone */
|
||
|
||
"svc 0x0\n"
|
||
|
||
/* example: if (%r0 != 0) return %r0; */
|
||
"cmp x0, #0\n"
|
||
"bne 2f\n"
|
||
|
||
/* In the child, now. Call "fn(arg)".
|
||
*/
|
||
"ldp x1, x0, [sp], #16\n"
|
||
"blr x1\n"
|
||
|
||
/* example: Call _exit(%r0).
|
||
*/
|
||
"mov x8, %10\n"
|
||
"svc 0x0\n"
|
||
"1:\n"
|
||
"mov x8, %1\n"
|
||
"2:\n"
|
||
: "=r"(__res_x0)
|
||
: "i"(-EINVAL),
|
||
"r"(__fn),
|
||
"r"(__stack),
|
||
"r"(__flags),
|
||
"r"(__arg),
|
||
"r"(__ptid),
|
||
"r"(__tls),
|
||
"r"(__ctid),
|
||
"i"(__NR_clone),
|
||
"i"(__NR_exit)
|
||
: "x30", "memory");
|
||
}
|
||
___res = __res_x0;
|
||
___syscall_return(int, ___res);
|
||
}
|
||
|
||
#endif
|