openGauss-server/bbox_syscall_support.cpp

603 lines
20 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/* -------------------------------------------------------------------------
* 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