实现底层api

//
// Created by lichao26 on 2017/8/16 0016.
//

#include <sys/types.h>
#include <unistd.h>
#include <syscall.h>

#define str(s) #s

#if defined(__arm__) || defined(__i386__)

#if defined(__arm__)
#define linux_syscall_0(syscallnum) {\
    static_assert(sizeof(asm_ret) <= 4, "linux_syscall wrong return size"); \
    asm volatile(                           \
        "PUSH   {R0,R7}\n"                  \
        "MOV    R7, " str(syscallnum) "\n"  \
        "SWI    #0\n"                       \
        "MOV    %[ret_],R0\n"               \
        "POP    {R0,R7}\n"                  \
        :[ret_]"=r"(asm_ret)                \
        :                                   \
        :"r0");                             \
}
#elif defined(__i386__)
#define linux_syscall_0(syscallnum) {\
    static_assert(sizeof(asm_ret) <= 4, "linux_syscall wrong return size"); \
    asm volatile(                           \
        "PUSHL  %%EAX\n"                    \
        "MOVL   $" str(syscallnum) ", %%EAX\n"\
        "INT    $0x80\n"                    \
        "MOVL   %%EAX,%[ret_]\n"            \
        "POPL   %%EAX\n"                    \
        :[ret_]"=r"(asm_ret)                \
        :                                   \
        :);                       \
}
#else
#define linux_syscall_0(syscallnum) static_assert(false, "linux_syscall wrong arch")
#endif

#if defined(__arm__)
#define linux_syscall_1(syscallnum, arg0) {\
    static_assert(sizeof(asm_ret) <= 4, "linux_syscall wrong return size"); \
    asm volatile(                           \
        "PUSH   {R0,R7}\n"                  \
        "MOV    R0, %[arg0_]\n"             \
        "MOV    R7, " str(syscallnum) "\n"  \
        "SWI    #0\n"                       \
        "MOV    %[ret_],R0\n"               \
        "POP    {R0,R7}\n"                  \
        :[ret_]"=r"(asm_ret)                \
        :[arg0_]"r"(arg0)                   \
        :"r0");                             \
}
#elif defined(__i386__)
#define linux_syscall_1(syscallnum, arg0) {\
    static_assert(sizeof(asm_ret) <= 4, "linux_syscall wrong return size"); \
    asm volatile(                           \
        "PUSHL  %%EAX\n"                    \
        "PUSHL  %%EBX\n"                    \
        "MOVL   8(%%EBP),%%EBX\n"           \
        "MOVL   $" str(syscallnum) ",%%EAX\n"\
        "INT    $0x80\n"                    \
        "MOVL   %%EAX,%[ret_]\n"            \
        "POPL   %%EBX\n"                    \
        "POPL   %%EAX\n"                    \
        :[ret_]"=r"(asm_ret)                \
        :                                   \
        :"ebx");                            \
}
#else
#define linux_syscall_1(syscallnum, arg0) static_assert(false, "linux_syscall wrong arch")
#endif

#if defined(__arm__)
#define linux_syscall_2(syscallnum, arg0, arg1) {\
    static_assert(sizeof(asm_ret) <= 4, "linux_syscall wrong return size"); \
    asm volatile(                           \
        "PUSH   {R0-R1,R7}\n"               \
        "MOV    R0, %[arg0_]\n"             \
        "MOV    R1, %[arg1_]\n"             \
        "MOV    R7, " str(syscallnum) "\n"  \
        "SWI    #0\n"                       \
        "MOV    %[ret_],R0\n"               \
        "POP    {R0-R1,R7}\n"               \
        :[ret_]"=r"(asm_ret)                \
        :[arg0_]"r"(arg0), [arg1_]"r"(arg1) \
        :"r0", "r1");                       \
}
#elif defined(__i386__)
#define linux_syscall_2(syscallnum, arg0, arg1) {\
    static_assert(sizeof(asm_ret) <= 4, "linux_syscall wrong return size"); \
    asm volatile(                           \
        "PUSHL  %%EAX\n"                    \
        "PUSHL  %%EBX\n"                    \
        "PUSHL  %%ECX\n"               \
        "MOVL   8(%%EBP),%%EBX\n"           \
        "MOVL  12(%%EBP),%%ECX\n"       \
        "MOVL   $" str(syscallnum) ",%%EAX\n"\
        "INT    $0x80\n"                    \
        "MOVL   %%EAX,%[ret_]\n"            \
        "POPL  %%ECX\n"               \
        "POPL   %%EBX\n"                    \
        "POPL   %%EAX\n"                    \
        :[ret_]"=r"(asm_ret)                \
        :                                   \
        :"ebx", "ecx");                     \
}
#else
#define linux_syscall_2(syscallnum, arg0, arg1) static_assert(false, "linux_syscall wrong arch")
#endif

#if defined(__arm__)
#define linux_syscall_3(syscallnum, arg0, arg1, arg2) {\
    static_assert(sizeof(asm_ret) <= 4, "linux_syscall wrong return size"); \
    asm volatile(                           \
        "PUSH   {R0-R2,R7}\n"               \
        "MOV    R0, %[arg0_]\n"             \
        "MOV    R1, %[arg1_]\n"             \
        "MOV    R2, %[arg2_]\n"             \
        "MOV    R7, " str(syscallnum) "\n"  \
        "SWI    #0\n"                       \
        "MOV    %[ret_],R0\n"               \
        "POP    {R0-R2,R7}\n"               \
        :[ret_]"=r"(asm_ret)                \
        :[arg0_]"r"(arg0), [arg1_]"r"(arg1), [arg2_]"r"(arg2)\
        :"r0", "r1", "r2");                 \
}
#elif defined(__i386__)
#define linux_syscall_3(syscallnum, arg0, arg1, arg2) {\
    static_assert(sizeof(asm_ret) <= 4, "linux_syscall wrong return size"); \
    asm volatile(                           \
        "PUSHL  %%EAX\n"                    \
        "PUSHL  %%EBX\n"                    \
        "PUSHL  %%ECX\n"               \
        "PUSHL %%EDX\n"               \
        "MOVL   8(%%EBP),%%EBX\n"           \
        "MOVL  12(%%EBP),%%ECX\n"       \
        "MOVL  16(%%EBP),%%EDX\n"       \
        "MOVL   $" str(syscallnum) ",%%EAX\n"\
        "INT    $0x80\n"                    \
        "MOVL   %%EAX,%[ret_]\n"            \
        "POPL  %%EDX\n"               \
        "POPL  %%ECX\n"               \
        "POPL   %%EBX\n"                    \
        "POPL   %%EAX\n"                    \
        :[ret_]"=r"(asm_ret)                \
        :                                   \
        :"ebx", "ecx", "edx");              \
}
#else
#define linux_syscall_3(syscallnum, arg0, arg1, arg2) \
    static_assert(false, "linux_syscall wrong arch")
#endif

#if defined(__arm__)
#define linux_syscall_4(syscallnum, arg0, arg1, arg2, arg3) {\
    static_assert(sizeof(asm_ret) <= 4, "linux_syscall wrong return size"); \
    asm volatile(                           \
        "PUSH   {R0-R3,R7}\n"               \
        "MOV    R0, %[arg0_]\n"             \
        "MOV    R1, %[arg1_]\n"             \
        "MOV    R2, %[arg2_]\n"             \
        "MOV    R3, %[arg3_]\n"             \
        "MOV    R7, " str(syscallnum) "\n"  \
        "SWI    #0\n"                       \
        "MOV    %[ret_],R0\n"               \
        "POP    {R0-R3,R7}\n"               \
        :[ret_]"=r"(asm_ret)                \
        :[arg0_]"r"(arg0), [arg1_]"r"(arg1), [arg2_]"r"(arg2), [arg3_]"r"(arg3)\
        :"r0", "r1", "r2", "r3");           \
}
#elif defined(__i386__)
#define linux_syscall_4(syscallnum, arg0, arg1, arg2, arg3) {\
    static_assert(sizeof(asm_ret) <= 4, "linux_syscall wrong return size"); \
    asm volatile(                           \
        "PUSHL  %%EAX\n"                    \
        "PUSHL  %%EBX\n"                    \
        "PUSHL  %%ECX\n"               \
        "PUSHL %%EDX\n"               \
        "PUSHL %%ESI\n"               \
        "MOVL   8(%%EBP),%%EBX\n"           \
        "MOVL  12(%%EBP),%%ECX\n"       \
        "MOVL  16(%%EBP),%%EDX\n"       \
        "MOVL  20(%%EBP),%%ESI\n"       \
        "MOVL   $" str(syscallnum) ",%%EAX\n"\
        "INT    $0x80\n"                    \
        "MOVL   %%EAX,%[ret_]\n"            \
        "POPL  %%ESI\n"               \
        "POPL  %%EDX\n"               \
        "POPL  %%ECX\n"               \
        "POPL   %%EBX\n"                    \
        "POPL   %%EAX\n"                    \
        :[ret_]"=r"(asm_ret)                \
        :                                   \
        :"ebx", "ecx", "edx", "esi");       \
}
#else
#define linux_syscall_4(syscallnum, arg0, arg1, arg2, arg3) \
    static_assert(false, "linux_syscall wrong arch")
#endif

#define _syscall_exit(status) linux_syscall_1(__NR_exit_group, status) // not __NR_exit
#define _syscall_fork() linux_syscall_0(__NR_fork)
#define _syscall_read(fd, buf, count) linux_syscall_3(__NR_read, fd, buf, count)
#define _syscall_write(fd, buf, count) linux_syscall_3(__NR_write, fd, buf, count)
#define _syscall_open(pathname, flags) linux_syscall_2(__NR_open, pathname, flags)
#define _syscall_close(fd) linux_syscall_1(__NR_close, fd)
#define _syscall_unlink(pathname) linux_syscall_1(__NR_unlink, pathname)
#define _syscall_execve(filename, argv, envp) linux_syscall_3(__NR_execve, filename, argv, envp)
#define _syscall_chmod(path, mode) linux_syscall_2(__NR_chmod, path, (int)mode)
#define _syscall_lseek(fd, offset, whence) linux_syscall_3(__NR_lseek, fd, offset, whence)
#define _syscall_getpid() linux_syscall_0(__NR_getpid)
#define _syscall_ptrace(req, pid, addr, data) linux_syscall_4(__NR_ptrace, req, pid, addr, data)
#define _syscall_access(pathname, mode) linux_syscall_2(__NR_access, pathname, (int)mode)
#define _syscall_kill(pid, sig) linux_syscall_2(__NR_kill, pid, sig)
#define _syscall_mkdir(pathname, mode) linux_syscall_2(__NR_mkdir, pathname, (int)mode)
#define _syscall_rmdir(pathname) linux_syscall_1(__NR_rmdir, pathname)
#define _syscall_getppid()  linux_syscall_0(__NR_getppid)
#define _syscall_sigaction(signum, act, oldact) linux_syscall_3(__NR_sigaction, signum, act, oldact)
#define _syscall_symlink(oldpath, newpath) linux_syscall_2(__NR_symlink, oldpath, newpath)
#define _syscall_readlink(path, buf, bufsize) linux_syscall_3(__NR_readlink, path, buf, bufsize)
#define _syscall_stat(path, buf) linux_syscall_2(__NR_stat, path, buf)
#define _syscall_mprotect(addr, len, prot) linux_syscall_3(__NR_mprotect, addr, len, prot)
// callnumber > 255  => MOV R7,num error

void safe_exit(int status) {
    void *asm_ret;
    _syscall_exit(status);
    return;
}

pid_t safe_fork(void) {
    pid_t asm_ret;
    _syscall_fork();
    return asm_ret;
}

ssize_t safe_read(int fd, void *buf, size_t count) {
    ssize_t asm_ret;
    _syscall_read(fd, buf, count);
    return asm_ret;
}

ssize_t safe_write(int fd, const void *buf, size_t count) {
    ssize_t asm_ret;
    _syscall_write(fd, buf, count);
    return asm_ret;
}

int safe_open(const char *pathname, int flags) {
    ssize_t asm_ret;
    _syscall_open(pathname, flags);
    return asm_ret;
}

int safe_close(int fd) {
    int asm_ret;
    _syscall_close(fd);
    return asm_ret;
}

int safe_unlink(const char *pathname) {
    int asm_ret;
    _syscall_unlink(pathname);
    return asm_ret;
}

int safe_execve(const char *filename, char *const argv[], char *const envp[]) {
    int asm_ret;
    _syscall_execve(filename, argv, envp);
    return asm_ret;
}

int safe_chmod(const char *path, mode_t mode) {
    int asm_ret;
    _syscall_chmod(path, mode);
    return asm_ret;
}

off_t safe_lseek(int fd, off_t offset, int whence) {
    off_t asm_ret;
    _syscall_lseek(fd, offset, whence);
    return asm_ret;
}

pid_t safe_getpid() {
    pid_t asm_ret;
    _syscall_getpid();
    return asm_ret;
}

long safe_ptrace(int request, pid_t pid, void *addr, void *data) {
    long asm_ret;
    _syscall_ptrace(request, pid, addr, data);
    return asm_ret;
}

int safe_access(const char *pathname, int mode) {
    int asm_ret;
    _syscall_access(pathname, mode);
    return asm_ret;
}

int safe_kill(pid_t pid, int sig) {
    int asm_ret;
    _syscall_kill(pid, sig);
    return asm_ret;
}

int safe_mkdir(const char *pathname, mode_t mode) {
    int asm_ret;
    _syscall_mkdir(pathname, mode);
    return asm_ret;
}

int safe_rmdir(const char *pathname) {
    int asm_ret;
    _syscall_rmdir(pathname);
    return asm_ret;
}

pid_t safe_getppid() {
    pid_t asm_ret;
    _syscall_getppid();
    return asm_ret;
}

int safe_sigaction(int signum, const struct sigaction *act, struct sigaction *oldact) {
    int asm_ret;
    _syscall_sigaction(signum, act, oldact);
    return asm_ret;
}

int safe_symlink(const char *oldpath, const char *newpath) {
    int asm_ret;
    _syscall_symlink(oldpath, newpath);
    return asm_ret;
}

ssize_t safe_readlink(const char *path, char *buf, size_t bufsize) {
    ssize_t asm_ret;
    _syscall_readlink(path, buf, bufsize);
    return asm_ret;
}

int safe_stat(const char *path, struct stat *buf) {
    int asm_ret;
    _syscall_stat(path, buf);
    return asm_ret;
}

int safe_mprotect(void *addr, size_t len, int prot) {
    int asm_ret;
    _syscall_mprotect(addr, len, prot);
    return asm_ret;
}

#endif
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值