2011-09-23 12:00:45 +04:00
|
|
|
#ifndef CR_SYSCALL_H_
|
|
|
|
#define CR_SYSCALL_H_
|
|
|
|
|
|
|
|
#include <sys/types.h>
|
2012-01-24 16:43:21 +04:00
|
|
|
#include <sys/time.h>
|
2011-09-23 12:00:45 +04:00
|
|
|
|
2011-11-07 14:47:04 +04:00
|
|
|
#include "types.h"
|
2011-09-23 12:00:45 +04:00
|
|
|
#include "compiler.h"
|
2011-10-19 13:09:01 +04:00
|
|
|
#include "syscall-codes.h"
|
2011-09-23 12:00:45 +04:00
|
|
|
|
|
|
|
#ifdef CONFIG_X86_64
|
|
|
|
|
2011-10-24 22:18:13 +04:00
|
|
|
static always_inline long syscall0(int nr)
|
2011-09-23 12:00:45 +04:00
|
|
|
{
|
|
|
|
long ret;
|
2011-11-03 00:11:33 +04:00
|
|
|
asm volatile(
|
|
|
|
"movl %1, %%eax \t\n"
|
|
|
|
"syscall \t\n"
|
|
|
|
"movq %%rax, %0 \t\n"
|
|
|
|
: "=r"(ret)
|
|
|
|
: "g" ((int)nr)
|
|
|
|
: "rax", "memory");
|
2011-09-23 12:00:45 +04:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2011-10-24 22:18:13 +04:00
|
|
|
static always_inline long syscall1(int nr, unsigned long arg0)
|
2011-09-23 12:00:45 +04:00
|
|
|
{
|
|
|
|
long ret;
|
2011-11-03 00:11:33 +04:00
|
|
|
asm volatile(
|
|
|
|
"movl %1, %%eax \t\n"
|
|
|
|
"movq %2, %%rdi \t\n"
|
|
|
|
"syscall \t\n"
|
|
|
|
"movq %%rax, %0 \t\n"
|
|
|
|
: "=r"(ret)
|
|
|
|
: "g" ((int)nr), "g" (arg0)
|
|
|
|
: "rax", "rdi", "memory");
|
2011-09-23 12:00:45 +04:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2011-10-24 22:18:13 +04:00
|
|
|
static always_inline long syscall2(int nr, unsigned long arg0, unsigned long arg1)
|
2011-09-23 12:00:45 +04:00
|
|
|
{
|
|
|
|
long ret;
|
2011-11-03 00:11:33 +04:00
|
|
|
asm volatile(
|
|
|
|
"movl %1, %%eax \t\n"
|
|
|
|
"movq %2, %%rdi \t\n"
|
|
|
|
"movq %3, %%rsi \t\n"
|
|
|
|
"syscall \t\n"
|
|
|
|
"movq %%rax, %0 \t\n"
|
|
|
|
: "=r"(ret)
|
|
|
|
: "g" ((int)nr), "g" (arg0), "g" (arg1)
|
|
|
|
: "rax", "rdi", "rsi", "memory");
|
2011-09-23 12:00:45 +04:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2011-10-24 22:18:13 +04:00
|
|
|
static always_inline long syscall3(int nr, unsigned long arg0, unsigned long arg1,
|
2011-10-31 16:33:43 +04:00
|
|
|
unsigned long arg2)
|
2011-09-23 12:00:45 +04:00
|
|
|
{
|
|
|
|
long ret;
|
2011-11-03 00:11:33 +04:00
|
|
|
asm volatile(
|
|
|
|
"movl %1, %%eax \t\n"
|
|
|
|
"movq %2, %%rdi \t\n"
|
|
|
|
"movq %3, %%rsi \t\n"
|
|
|
|
"movq %4, %%rdx \t\n"
|
|
|
|
"syscall \t\n"
|
|
|
|
"movq %%rax, %0 \t\n"
|
|
|
|
: "=r"(ret)
|
|
|
|
: "g" ((int)nr), "g" (arg0), "g" (arg1), "g" (arg2)
|
|
|
|
: "rax", "rdi", "rsi", "rdx", "memory");
|
2011-09-23 12:00:45 +04:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2011-10-24 22:18:13 +04:00
|
|
|
static always_inline long syscall4(int nr, unsigned long arg0, unsigned long arg1,
|
2011-10-31 16:33:43 +04:00
|
|
|
unsigned long arg2, unsigned long arg3)
|
2011-09-23 12:00:45 +04:00
|
|
|
{
|
|
|
|
long ret;
|
2011-10-31 16:33:43 +04:00
|
|
|
asm volatile(
|
|
|
|
"movl %1, %%eax \t\n"
|
|
|
|
"movq %2, %%rdi \t\n"
|
|
|
|
"movq %3, %%rsi \t\n"
|
|
|
|
"movq %4, %%rdx \t\n"
|
|
|
|
"movq %5, %%r10 \t\n"
|
|
|
|
"syscall \t\n"
|
|
|
|
"movq %%rax, %0 \t\n"
|
|
|
|
: "=r"(ret)
|
|
|
|
: "g" ((int)nr), "g" (arg0), "g" (arg1), "g" (arg2),
|
|
|
|
"g" (arg3)
|
|
|
|
: "rax", "rdi", "rsi", "rdx", "r10", "memory");
|
2011-09-23 12:00:45 +04:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2011-10-24 22:18:13 +04:00
|
|
|
static long always_inline syscall5(int nr, unsigned long arg0, unsigned long arg1,
|
2011-10-31 16:33:43 +04:00
|
|
|
unsigned long arg2, unsigned long arg3,
|
|
|
|
unsigned long arg4)
|
2011-09-23 12:00:45 +04:00
|
|
|
{
|
|
|
|
long ret;
|
2011-10-31 16:33:43 +04:00
|
|
|
asm volatile(
|
|
|
|
"movl %1, %%eax \t\n"
|
|
|
|
"movq %2, %%rdi \t\n"
|
|
|
|
"movq %3, %%rsi \t\n"
|
|
|
|
"movq %4, %%rdx \t\n"
|
|
|
|
"movq %5, %%r10 \t\n"
|
|
|
|
"movq %6, %%r8 \t\n"
|
|
|
|
"syscall \t\n"
|
|
|
|
"movq %%rax, %0 \t\n"
|
|
|
|
: "=r"(ret)
|
|
|
|
: "g" ((int)nr), "g" (arg0), "g" (arg1), "g" (arg2),
|
|
|
|
"g" (arg3), "g" (arg4)
|
|
|
|
: "rax", "rdi", "rsi", "rdx", "r10", "r8", "memory");
|
2011-09-23 12:00:45 +04:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2011-10-24 22:18:13 +04:00
|
|
|
static long always_inline syscall6(int nr, unsigned long arg0, unsigned long arg1,
|
2011-10-31 16:33:43 +04:00
|
|
|
unsigned long arg2, unsigned long arg3,
|
|
|
|
unsigned long arg4, unsigned long arg5)
|
2011-09-23 12:00:45 +04:00
|
|
|
{
|
|
|
|
long ret;
|
2011-10-31 16:33:43 +04:00
|
|
|
asm volatile(
|
|
|
|
"movl %1, %%eax \t\n"
|
|
|
|
"movq %2, %%rdi \t\n"
|
|
|
|
"movq %3, %%rsi \t\n"
|
|
|
|
"movq %4, %%rdx \t\n"
|
|
|
|
"movq %5, %%r10 \t\n"
|
|
|
|
"movq %6, %%r8 \t\n"
|
|
|
|
"movq %7, %%r9 \t\n"
|
|
|
|
"syscall \t\n"
|
|
|
|
"movq %%rax, %0 \t\n"
|
|
|
|
: "=r"(ret)
|
|
|
|
: "g" ((int)nr), "g" (arg0), "g" (arg1), "g" (arg2),
|
|
|
|
"g" (arg3), "g" (arg4), "g" (arg5)
|
|
|
|
: "rax", "rdi", "rsi", "rdx", "r10", "r8", "r9", "memory");
|
2011-09-23 12:00:45 +04:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2011-10-24 22:18:13 +04:00
|
|
|
static always_inline unsigned long sys_pause(void)
|
2011-09-23 12:00:45 +04:00
|
|
|
{
|
|
|
|
return syscall0(__NR_pause);
|
|
|
|
}
|
|
|
|
|
2011-10-24 22:18:13 +04:00
|
|
|
static always_inline unsigned long sys_mmap(void *addr, unsigned long len, unsigned long prot,
|
2011-10-31 16:33:43 +04:00
|
|
|
unsigned long flags, unsigned long fd, unsigned long offset)
|
2011-09-23 12:00:45 +04:00
|
|
|
{
|
|
|
|
return syscall6(__NR_mmap, (unsigned long)addr,
|
|
|
|
len, prot, flags, fd, offset);
|
|
|
|
}
|
|
|
|
|
2011-10-24 22:18:13 +04:00
|
|
|
static always_inline unsigned long sys_munmap(void *addr,unsigned long len)
|
2011-09-23 12:00:45 +04:00
|
|
|
{
|
|
|
|
return syscall2(__NR_munmap, (unsigned long)addr, len);
|
|
|
|
}
|
|
|
|
|
2011-10-24 22:18:13 +04:00
|
|
|
static always_inline long sys_open(const char *filename, unsigned long flags, unsigned long mode)
|
2011-09-23 12:00:45 +04:00
|
|
|
{
|
|
|
|
return syscall3(__NR_open, (unsigned long)filename, flags, mode);
|
|
|
|
}
|
|
|
|
|
2011-12-03 17:24:05 +04:00
|
|
|
static always_inline long sys_sigaction(int signum, const rt_sigaction_t *act, rt_sigaction_t *oldact)
|
2011-11-29 15:12:25 +03:00
|
|
|
{
|
2011-12-03 17:24:05 +04:00
|
|
|
return syscall4(__NR_rt_sigaction, signum, (unsigned long)act, (unsigned long)oldact, sizeof(rt_sigset_t));
|
2011-11-29 15:12:25 +03:00
|
|
|
}
|
|
|
|
|
2012-01-24 16:43:21 +04:00
|
|
|
static always_inline long sys_getitimer(int which, const struct itimerval *val)
|
|
|
|
{
|
|
|
|
return syscall2(__NR_getitimer, (unsigned long)which, (unsigned long)val);
|
|
|
|
}
|
|
|
|
|
|
|
|
static always_inline long sys_setitimer(int which, const struct itimerval *val, struct itimerval *old)
|
|
|
|
{
|
|
|
|
return syscall3(__NR_setitimer, (unsigned long)which, (unsigned long)val, (unsigned long)old);
|
|
|
|
}
|
|
|
|
|
2011-10-24 22:18:13 +04:00
|
|
|
static always_inline long sys_close(int fd)
|
2011-09-23 12:00:45 +04:00
|
|
|
{
|
|
|
|
return syscall1(__NR_close, fd);
|
|
|
|
}
|
|
|
|
|
2011-10-24 22:18:13 +04:00
|
|
|
static always_inline long sys_write(unsigned long fd, const void *buf, unsigned long count)
|
2011-09-23 12:00:45 +04:00
|
|
|
{
|
|
|
|
return syscall3(__NR_write, fd, (unsigned long)buf, count);
|
|
|
|
}
|
|
|
|
|
2011-10-24 22:18:13 +04:00
|
|
|
static always_inline long sys_mincore(unsigned long addr, unsigned long size, void *vec)
|
2011-09-23 12:00:45 +04:00
|
|
|
{
|
|
|
|
return syscall3(__NR_mincore, addr, size, (unsigned long)vec);
|
|
|
|
}
|
|
|
|
|
2011-10-24 22:18:13 +04:00
|
|
|
static always_inline long sys_lseek(unsigned long fd, unsigned long offset, unsigned long origin)
|
2011-09-23 12:00:45 +04:00
|
|
|
{
|
|
|
|
return syscall3(__NR_lseek, fd, offset, origin);
|
|
|
|
}
|
|
|
|
|
2011-10-24 22:18:13 +04:00
|
|
|
static always_inline long sys_mprotect(unsigned long start, unsigned long len, unsigned long prot)
|
2011-09-23 12:00:45 +04:00
|
|
|
{
|
|
|
|
return syscall3(__NR_mprotect, start, len, prot);
|
|
|
|
}
|
|
|
|
|
2011-10-24 22:18:13 +04:00
|
|
|
static always_inline long sys_nanosleep(struct timespec *req, struct timespec *rem)
|
2011-09-23 12:00:45 +04:00
|
|
|
{
|
|
|
|
return syscall2(__NR_nanosleep, (unsigned long)req, (unsigned long)rem);
|
|
|
|
}
|
|
|
|
|
2011-10-24 22:18:13 +04:00
|
|
|
static always_inline long sys_read(unsigned long fd, void *buf, unsigned long count)
|
2011-09-23 12:00:45 +04:00
|
|
|
{
|
|
|
|
return syscall3(__NR_read, fd, (unsigned long)buf, count);
|
|
|
|
}
|
|
|
|
|
2012-01-19 01:33:17 +03:00
|
|
|
static always_inline long sys_waitpid(int pid, int *status, int options)
|
|
|
|
{
|
|
|
|
return syscall4(__NR_wait4, pid, (unsigned long)status, options, 0);
|
|
|
|
}
|
|
|
|
|
2011-10-26 10:58:10 +04:00
|
|
|
static always_inline long sys_exit(unsigned long error_code)
|
|
|
|
{
|
|
|
|
return syscall1(__NR_exit, error_code);
|
|
|
|
}
|
|
|
|
|
2011-10-28 00:40:20 +04:00
|
|
|
static always_inline unsigned long sys_getpid(void)
|
|
|
|
{
|
|
|
|
return syscall0(__NR_getpid);
|
|
|
|
}
|
|
|
|
|
2011-12-02 00:52:02 +04:00
|
|
|
static always_inline unsigned long sys_gettid(void)
|
|
|
|
{
|
|
|
|
return syscall0(__NR_gettid);
|
|
|
|
}
|
|
|
|
|
2011-10-28 14:03:59 +04:00
|
|
|
static always_inline long sys_unlink(char *pathname)
|
|
|
|
{
|
|
|
|
return syscall1(__NR_unlink, (unsigned long)pathname);
|
|
|
|
}
|
|
|
|
|
2011-10-24 17:17:39 +04:00
|
|
|
/*
|
|
|
|
* Note this call expects a signal frame on stack
|
|
|
|
* (regs->sp) so be very carefull here!
|
|
|
|
*/
|
2011-10-24 22:18:13 +04:00
|
|
|
static always_inline long sys_rt_sigreturn(void)
|
2011-10-24 17:17:39 +04:00
|
|
|
{
|
|
|
|
return syscall0(__NR_rt_sigreturn);
|
|
|
|
}
|
|
|
|
|
2011-11-07 14:47:04 +04:00
|
|
|
static always_inline long sys_set_thread_area(user_desc_t *info)
|
|
|
|
{
|
|
|
|
return syscall1(__NR_set_thread_area, (long)info);
|
|
|
|
}
|
|
|
|
|
|
|
|
static always_inline long sys_get_thread_area(user_desc_t *info)
|
|
|
|
{
|
|
|
|
return syscall1(__NR_get_thread_area, (long)info);
|
|
|
|
}
|
|
|
|
|
2011-11-07 15:24:07 +04:00
|
|
|
static always_inline long sys_arch_prctl(int code, void *addr)
|
|
|
|
{
|
|
|
|
return syscall2(__NR_arch_prctl, code, (unsigned long)addr);
|
|
|
|
}
|
2011-11-07 14:47:04 +04:00
|
|
|
|
2011-11-08 16:39:21 +04:00
|
|
|
static always_inline long sys_prctl(int code, unsigned long arg2, unsigned long arg3,
|
|
|
|
unsigned long arg4, unsigned long arg5)
|
|
|
|
{
|
|
|
|
return syscall5(__NR_prctl, code, arg2, arg3, arg4, arg5);
|
|
|
|
}
|
|
|
|
|
2012-02-12 00:30:24 +04:00
|
|
|
static always_inline long sys_brk(unsigned long arg)
|
|
|
|
{
|
|
|
|
return syscall1(__NR_brk, arg);
|
|
|
|
}
|
|
|
|
|
2011-11-12 19:26:40 +04:00
|
|
|
static always_inline long sys_clone(unsigned long flags, void *child_stack,
|
|
|
|
void *parent_tid, void *child_tid)
|
|
|
|
{
|
|
|
|
return syscall4(__NR_clone, flags, (unsigned long)child_stack,
|
|
|
|
(unsigned long)parent_tid, (unsigned long)child_tid);
|
|
|
|
}
|
|
|
|
|
|
|
|
static always_inline long sys_futex(u32 *uaddr, int op, u32 val,
|
|
|
|
struct timespec *utime,
|
|
|
|
u32 *uaddr2, u32 val3)
|
|
|
|
{
|
|
|
|
return syscall6(__NR_futex, (unsigned long)uaddr,
|
|
|
|
(unsigned long)op, (unsigned long)val,
|
|
|
|
(unsigned long)utime,
|
|
|
|
(unsigned long)uaddr2,
|
|
|
|
(unsigned long)val3);
|
|
|
|
}
|
|
|
|
|
2011-12-01 19:59:03 +04:00
|
|
|
static always_inline long sys_flock(unsigned long fd, unsigned long cmd)
|
|
|
|
{
|
|
|
|
return syscall2(__NR_flock, fd, cmd);
|
|
|
|
}
|
|
|
|
|
2011-11-12 19:26:40 +04:00
|
|
|
static void always_inline local_sleep(long seconds)
|
|
|
|
{
|
|
|
|
struct timespec req, rem;
|
|
|
|
|
|
|
|
req = (struct timespec){
|
|
|
|
.tv_sec = seconds,
|
|
|
|
.tv_nsec = 0,
|
|
|
|
};
|
|
|
|
|
|
|
|
sys_nanosleep(&req, &rem);
|
|
|
|
}
|
|
|
|
|
2012-01-19 01:33:18 +03:00
|
|
|
static long always_inline sys_kill(long pid, int sig)
|
|
|
|
{
|
|
|
|
return syscall2(__NR_kill, pid, (long)sig);
|
|
|
|
}
|
|
|
|
|
2011-12-26 15:53:14 +04:00
|
|
|
static long always_inline sys_tgkill(long tgid, long pid, int sig)
|
|
|
|
{
|
|
|
|
return syscall3(__NR_tgkill, tgid, pid, (long)sig);
|
|
|
|
}
|
|
|
|
|
2012-01-02 21:36:11 +04:00
|
|
|
static long always_inline sys_msync(void *addr, unsigned long length, int flags)
|
|
|
|
{
|
|
|
|
return syscall3(__NR_msync, (long)addr, length, (long)flags);
|
|
|
|
}
|
|
|
|
|
2012-01-26 15:27:00 +04:00
|
|
|
static long always_inline sys_setns(int fd, int nstype)
|
|
|
|
{
|
|
|
|
return syscall2(__NR_setns, (long)fd, (long)nstype);
|
|
|
|
}
|
|
|
|
|
2012-01-27 21:39:14 +04:00
|
|
|
static long sys_setresuid(int uid, int euid, int suid)
|
|
|
|
{
|
|
|
|
return syscall3(__NR_setresuid, (long)uid, (long)euid, (long)suid);
|
|
|
|
}
|
|
|
|
|
|
|
|
static long sys_setresgid(int gid, int egid, int sgid)
|
|
|
|
{
|
|
|
|
return syscall3(__NR_setresgid, (long)gid, (long)egid, (long)sgid);
|
|
|
|
}
|
|
|
|
|
|
|
|
static long sys_setfsuid(int fsuid)
|
|
|
|
{
|
|
|
|
return syscall1(__NR_setfsuid, (long)fsuid);
|
|
|
|
}
|
|
|
|
|
|
|
|
static long sys_setfsgid(int fsgid)
|
|
|
|
{
|
|
|
|
return syscall1(__NR_setfsgid, (long)fsgid);
|
|
|
|
}
|
|
|
|
|
|
|
|
struct cap_header {
|
|
|
|
u32 version;
|
|
|
|
int pid;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct cap_data {
|
|
|
|
u32 eff;
|
|
|
|
u32 prm;
|
|
|
|
u32 inh;
|
|
|
|
};
|
|
|
|
|
|
|
|
static long sys_capset(struct cap_header *h, struct cap_data *d)
|
|
|
|
{
|
|
|
|
return syscall2(__NR_capset, (long)h, (long)d);
|
|
|
|
}
|
|
|
|
|
2012-02-01 13:00:48 +03:00
|
|
|
static int sys_socket(int domain, int type, int protocol)
|
|
|
|
{
|
|
|
|
return syscall3(__NR_socket, (long) domain, (long) type, (long) protocol);
|
|
|
|
}
|
|
|
|
|
2012-02-10 17:32:08 +04:00
|
|
|
struct sockaddr;
|
2012-02-01 13:00:48 +03:00
|
|
|
static int sys_bind(int sockfd, const struct sockaddr *addr, int addrlen)
|
|
|
|
{
|
|
|
|
return syscall3(__NR_bind, (long)sockfd, (long)addr, (long) addrlen);
|
|
|
|
}
|
|
|
|
|
|
|
|
struct msghdr;
|
|
|
|
static long sys_sendmsg(int sockfd, const struct msghdr *msg, int flags)
|
|
|
|
{
|
|
|
|
return syscall3(__NR_sendmsg, (long)sockfd, (long)msg, (long) flags);
|
|
|
|
}
|
|
|
|
|
|
|
|
static long sys_recvmsg(int sockfd, struct msghdr *msg, int flags)
|
|
|
|
{
|
|
|
|
return syscall3(__NR_recvmsg, (long)sockfd, (long)msg, (long) flags);
|
|
|
|
}
|
|
|
|
|
2012-02-02 13:14:59 +03:00
|
|
|
static void sys_set_tid_address(int *tid_addr) {
|
|
|
|
syscall1(__NR_set_tid_address, (long) tid_addr);
|
|
|
|
}
|
|
|
|
|
2012-01-26 15:28:00 +04:00
|
|
|
#ifndef CLONE_NEWUTS
|
|
|
|
#define CLONE_NEWUTS 0x04000000
|
|
|
|
#endif
|
|
|
|
|
2012-01-31 22:28:55 +04:00
|
|
|
#ifndef CLONE_NEWIPC
|
|
|
|
#define CLONE_NEWIPC 0x08000000
|
|
|
|
#endif
|
|
|
|
|
2012-01-26 15:27:00 +04:00
|
|
|
#define setns sys_setns
|
|
|
|
|
2011-09-23 12:00:45 +04:00
|
|
|
#else /* CONFIG_X86_64 */
|
|
|
|
# error x86-32 bit mode not yet implemented
|
|
|
|
#endif /* CONFIG_X86_64 */
|
|
|
|
|
|
|
|
#endif /* CR_SYSCALL_H_ */
|