summaryrefslogtreecommitdiff
path: root/arch/i386/syscall.h
blob: cd3c51659d9f37007985545e9da59e21c2aea7d6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
#ifndef _SYSCALL_H
#define _SYSCALL_H

#include <sys/syscall.h>

#define SYSCALL_LL(x) \
((union { long long ll; long l[2]; }){ .ll = x }).l[0], \
((union { long long ll; long l[2]; }){ .ll = x }).l[1]

#define SYSCALL_SIGSET_SIZE 8

#if defined(SYSCALL_NORETURN)
static inline long __syscall_ret(unsigned long r)
{
	for(;;);
	return 0;
}
#elif defined(SYSCALL_RETURN_ERRNO)
static inline long __syscall_ret(unsigned long r)
{
	return -r;
}
#else
extern long __syscall_ret(unsigned long);
#endif

static inline long syscall0(long n)
{
	unsigned long ret;
	__asm__ __volatile__ ("int $128" : "=a"(ret) : "a"(n) : "memory");
	return __syscall_ret(ret);
}

#ifndef __PIC__

static inline long syscall1(long n, long a1)
{
	unsigned long ret;
	__asm__ __volatile__ ("int $128" : "=a"(ret) : "a"(n), "b"(a1) : "memory");
	return __syscall_ret(ret);
}

static inline long syscall2(long n, long a1, long a2)
{
	unsigned long ret;
	__asm__ __volatile__ ("int $128" : "=a"(ret) : "a"(n), "b"(a1), "c"(a2) : "memory");
	return __syscall_ret(ret);
}

static inline long syscall3(long n, long a1, long a2, long a3)
{
	unsigned long ret;
	__asm__ __volatile__ ("int $128" : "=a"(ret) : "a"(n), "b"(a1), "c"(a2), "d"(a3) : "memory");
	return __syscall_ret(ret);
}

static inline long syscall4(long n, long a1, long a2, long a3, long a4)
{
	unsigned long ret;
	__asm__ __volatile__ ("int $128" : "=a"(ret) : "a"(n), "b"(a1), "c"(a2), "d"(a3), "S"(a4) : "memory");
	return __syscall_ret(ret);
}

static inline long syscall5(long n, long a1, long a2, long a3, long a4, long a5)
{
	unsigned long ret;
	__asm__ __volatile__ ("int $128" : "=a"(ret) : "a"(n), "b"(a1), "c"(a2), "d"(a3), "S"(a4), "D"(a5) : "memory");
	return __syscall_ret(ret);
}

static inline long syscall6(long n, long a1, long a2, long a3, long a4, long a5, long a6)
{
	unsigned long ret;
	__asm__ __volatile__ ("pushl %%ebp ; mov %%eax,%%ebp ; movl %1,%%eax ; int $128 ; popl %%ebp"
		: "=a"(ret) : "i"(n), "b"(a1), "c"(a2), "d"(a3), "S"(a4), "D"(a5), "a"(a6) : "memory");
	return __syscall_ret(ret);
}

#else

static inline long syscall1(long n, long a1)
{
	unsigned long ret;
	__asm__ __volatile__ ("xchg %2,%%ebx ; int $128 ; xchg %2,%%ebx"
		: "=a"(ret) : "a"(n), "r"(a1) : "memory");
	return __syscall_ret(ret);
}

static inline long syscall2(long n, long a1, long a2)
{
	unsigned long ret;
	__asm__ __volatile__ ("xchg %2,%%ebx ; int $128 ; xchg %2,%%ebx"
		: "=a"(ret) : "a"(n), "r"(a1), "c"(a2) : "memory");
	return __syscall_ret(ret);
}

static inline long syscall3(long n, long a1, long a2, long a3)
{
	unsigned long ret;
	__asm__ __volatile__ ("xchg %2,%%ebx ; int $128 ; xchg %2,%%ebx"
		: "=a"(ret) : "a"(n), "r"(a1), "c"(a2), "d"(a3) : "memory");
	return __syscall_ret(ret);
}

static inline long syscall4(long n, long a1, long a2, long a3, long a4)
{
	unsigned long ret;
	__asm__ __volatile__ ("xchg %2,%%ebx ; int $128 ; xchg %2,%%ebx"
		: "=a"(ret) : "a"(n), "r"(a1), "c"(a2), "d"(a3), "S"(a4) : "memory");
	return __syscall_ret(ret);
}

static inline long syscall5(long n, long a1, long a2, long a3, long a4, long a5)
{
	unsigned long ret;
	__asm__ __volatile__ ("pushl %%ebx ; mov %%eax,%%ebx ; movl %1,%%eax ; int $128 ; popl %%ebx"
		: "=a"(ret) : "i"(n), "a"(a1), "c"(a2), "d"(a3), "S"(a4), "D"(a5) : "memory");
	return __syscall_ret(ret);
}

#define syscall6(n,a1,a2,a3,a4,a5,a6) __syscall((n),(a1),(a2),(a3),(a4),(a5),(a6))

#endif

#define __SC_socket      1
#define __SC_bind        2
#define __SC_connect     3
#define __SC_listen      4
#define __SC_accept      5
#define __SC_getsockname 6
#define __SC_getpeername 7
#define __SC_socketpair  8
#define __SC_send        9
#define __SC_recv        10
#define __SC_sendto      11
#define __SC_recvfrom    12
#define __SC_shutdown    13
#define __SC_setsockopt  14
#define __SC_getsockopt  15
#define __SC_sendmsg     16
#define __SC_recvmsg     17


#define socketcall(nm, a, b, c, d, e, f) syscall2(__NR_socketcall, __SC_##nm, \
    (long)(long [6]){ (long)a, (long)b, (long)c, (long)d, (long)e, (long)f })


#undef O_LARGEFILE
#define O_LARGEFILE 0100000

/* the following are needed for iso c functions to use */
#define __syscall_open(filename, flags, mode) syscall3(__NR_open, (long)(filename), (flags)|O_LARGEFILE, (mode))
#define __syscall_read(fd, buf, len)          syscall3(__NR_read, (fd), (long)(buf), (len))
#define __syscall_write(fd, buf, len)         syscall3(__NR_write, (fd), (long)(buf), (len))
#define __syscall_close(fd)                   syscall1(__NR_close, (fd))
#define __syscall_fcntl(fd, cmd, arg)         syscall3(__NR_fcntl64, (fd), (cmd), (long)(arg))
#define __syscall_dup2(old, new)              syscall2(__NR_dup2, (old), (new))
#define __syscall_unlink(path)                syscall1(__NR_unlink, (long)(path))
#define __syscall_getpid()                    syscall0(__NR_getpid)
#define __syscall_kill(pid,sig)               syscall2(__NR_kill, (pid), (sig))
#define __syscall_sigaction(sig,new,old)      syscall4(__NR_rt_sigaction, (sig), (long)(new), (long)(old), SYSCALL_SIGSET_SIZE)
#define __syscall_ioctl(fd,ioc,arg)           syscall3(__NR_ioctl, (fd), (ioc), (long)(arg))
#define __syscall_exit(code)                  syscall1(__NR_exit, code)

long __syscall(long, ...);

#endif