最下位apiの実装
44213 ワード
//
// Created by lichao26 on 2017/8/16 0016.
//
#include
#include
#include
#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}
" \
"MOV R7, " str(syscallnum) "
" \
"SWI #0
" \
"MOV %[ret_],R0
" \
"POP {R0,R7}
" \
:[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
" \
"MOVL $" str(syscallnum) ", %%EAX
"\
"INT $0x80
" \
"MOVL %%EAX,%[ret_]
" \
"POPL %%EAX
" \
:[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}
" \
"MOV R0, %[arg0_]
" \
"MOV R7, " str(syscallnum) "
" \
"SWI #0
" \
"MOV %[ret_],R0
" \
"POP {R0,R7}
" \
:[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
" \
"PUSHL %%EBX
" \
"MOVL 8(%%EBP),%%EBX
" \
"MOVL $" str(syscallnum) ",%%EAX
"\
"INT $0x80
" \
"MOVL %%EAX,%[ret_]
" \
"POPL %%EBX
" \
"POPL %%EAX
" \
:[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}
" \
"MOV R0, %[arg0_]
" \
"MOV R1, %[arg1_]
" \
"MOV R7, " str(syscallnum) "
" \
"SWI #0
" \
"MOV %[ret_],R0
" \
"POP {R0-R1,R7}
" \
:[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
" \
"PUSHL %%EBX
" \
"PUSHL %%ECX
" \
"MOVL 8(%%EBP),%%EBX
" \
"MOVL 12(%%EBP),%%ECX
" \
"MOVL $" str(syscallnum) ",%%EAX
"\
"INT $0x80
" \
"MOVL %%EAX,%[ret_]
" \
"POPL %%ECX
" \
"POPL %%EBX
" \
"POPL %%EAX
" \
:[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}
" \
"MOV R0, %[arg0_]
" \
"MOV R1, %[arg1_]
" \
"MOV R2, %[arg2_]
" \
"MOV R7, " str(syscallnum) "
" \
"SWI #0
" \
"MOV %[ret_],R0
" \
"POP {R0-R2,R7}
" \
:[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
" \
"PUSHL %%EBX
" \
"PUSHL %%ECX
" \
"PUSHL %%EDX
" \
"MOVL 8(%%EBP),%%EBX
" \
"MOVL 12(%%EBP),%%ECX
" \
"MOVL 16(%%EBP),%%EDX
" \
"MOVL $" str(syscallnum) ",%%EAX
"\
"INT $0x80
" \
"MOVL %%EAX,%[ret_]
" \
"POPL %%EDX
" \
"POPL %%ECX
" \
"POPL %%EBX
" \
"POPL %%EAX
" \
:[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}
" \
"MOV R0, %[arg0_]
" \
"MOV R1, %[arg1_]
" \
"MOV R2, %[arg2_]
" \
"MOV R3, %[arg3_]
" \
"MOV R7, " str(syscallnum) "
" \
"SWI #0
" \
"MOV %[ret_],R0
" \
"POP {R0-R3,R7}
" \
:[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
" \
"PUSHL %%EBX
" \
"PUSHL %%ECX
" \
"PUSHL %%EDX
" \
"PUSHL %%ESI
" \
"MOVL 8(%%EBP),%%EBX
" \
"MOVL 12(%%EBP),%%ECX
" \
"MOVL 16(%%EBP),%%EDX
" \
"MOVL 20(%%EBP),%%ESI
" \
"MOVL $" str(syscallnum) ",%%EAX
"\
"INT $0x80
" \
"MOVL %%EAX,%[ret_]
" \
"POPL %%ESI
" \
"POPL %%EDX
" \
"POPL %%ECX
" \
"POPL %%EBX
" \
"POPL %%EAX
" \
:[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