1 ///Syscall definitions and direct calls that bypass our libc intercepts
2 module photon.linux.syscalls;
3 version(linux):
4 import core.sys.posix.sys.types;
5 import core.sys.posix.netinet.in_;
6 import core.sys.posix.poll;
7 import core.sys.linux.epoll;
8 import core.sys.linux.timerfd;
9 
10 import photon.linux.support;
11 
12 nothrow:
13 
14 version (X86) {
15     enum int SYS_READ = 0x3, SYS_SOCKETPAIR = 0x168; //TODO test on x86
16     int syscall(int ident, int n, int arg1, int arg2)
17     {
18         int ret;
19 
20         asm nothrow
21         {
22             mov EAX, ident;
23             mov EBX, n[EBP];
24             mov ECX, arg1[EBP];
25             mov EDX, arg2[EBP];
26             int 0x80;
27             mov ret, EAX;
28         }
29         return ret;
30     }
31 
32     int syscall(int ident, int n, int arg1, int arg2, int arg3)
33     {
34         int ret;
35 
36         asm nothrow
37         {
38             mov EAX, ident;
39             mov EBX, n[EBP];
40             mov ECX, arg1[EBP];
41             mov EDX, arg2[EBP];
42             mov ESI, arg3[EBP];
43             int 0x80;
44             mov ret, EAX;
45         }
46         return ret;
47     }
48 
49     int syscall(int ident, int n, int arg1, int arg2, int arg3, int arg4)
50     {
51         int ret;
52 
53         asm nothrow
54         {
55             mov EAX, ident;
56             mov EBX, n[EBP];
57             mov ECX, arg1[EBP];
58             mov EDX, arg2[EBP];
59             mov ESI, arg3[EBP];
60             mov EDI, arg4[EBP];
61             int 0x80;
62             mov ret, EAX;
63         }
64         return ret;
65     }
66 } else version (X86_64) {
67     enum int
68         SYS_READ = 0x0,
69         SYS_WRITE = 0x1,
70         SYS_CLOSE = 3,
71         SYS_POLL = 7,
72         SYS_GETTID = 186,
73         SYS_SOCKETPAIR = 0x35,
74         SYS_ACCEPT = 0x2b,
75         SYS_ACCEPT4 = 0x120,
76         SYS_CONNECT = 0x2a,
77         SYS_SENDTO = 0x2c,
78         SYS_RECVFROM = 45,
79         SYS_NANOSLEEP = 35;
80 
81     size_t syscall(size_t ident) nothrow
82     {
83         size_t ret;
84 
85         asm nothrow
86         {
87             mov RAX, ident;
88             syscall;
89             mov ret, RAX;
90         }
91         return ret;
92     }
93 
94     size_t syscall(size_t ident, size_t n) nothrow
95     {
96         size_t ret;
97 
98         asm nothrow
99         {
100             mov RAX, ident;
101             mov RDI, n;
102             syscall;
103             mov ret, RAX;
104         }
105         return ret;
106     }
107 
108     size_t syscall(size_t ident, size_t n, size_t arg1) nothrow
109     {
110         size_t ret;
111 
112         asm nothrow
113         {
114             mov RAX, ident;
115             mov RDI, n;
116             mov RSI, arg1;
117             syscall;
118             mov ret, RAX;
119         }
120         return ret;
121     }
122 
123     size_t syscall(size_t ident, size_t n, size_t arg1, size_t arg2) nothrow
124     {
125         size_t ret;
126 
127         asm nothrow
128         {
129             mov RAX, ident;
130             mov RDI, n;
131             mov RSI, arg1;
132             mov RDX, arg2;
133             syscall;
134             mov ret, RAX;
135         }
136         return ret;
137     }
138 
139     size_t syscall(size_t ident, size_t n, size_t arg1, size_t arg2, size_t arg3) nothrow
140     {
141         size_t ret;
142 
143         asm nothrow
144         {
145             mov RAX, ident;
146             mov RDI, n;
147             mov RSI, arg1;
148             mov RDX, arg2;
149             mov R10, arg3;
150             syscall;
151             mov ret, RAX;
152         }
153         return ret;
154     }
155 
156     size_t syscall(size_t ident, size_t n, size_t arg1, size_t arg2, size_t arg3, size_t arg4) nothrow
157     {
158         size_t ret;
159 
160         asm nothrow
161         {
162             mov RAX, ident;
163             mov RDI, n;
164             mov RSI, arg1;
165             mov RDX, arg2;
166             mov R10, arg3;
167             mov R8, arg4;
168             syscall;
169             mov ret, RAX;
170         }
171         return ret;
172     }
173 
174     size_t syscall(size_t ident, size_t n, size_t arg1, size_t arg2, size_t arg3, size_t arg4, size_t arg5) nothrow
175     {
176         size_t ret;
177 
178         asm nothrow
179         {
180             mov RAX, ident;
181             mov RDI, n;
182             mov RSI, arg1;
183             mov RDX, arg2;
184             mov R10, arg3;
185             mov R8, arg4;
186             mov R9, arg5;
187             syscall;
188             mov ret, RAX;
189         }
190         return ret;
191     }
192 }
193 
194 int gettid()
195 {
196     return cast(int)syscall(SYS_GETTID);
197 }
198 
199 ssize_t raw_read(int fd, void *buf, size_t count) nothrow {
200     logf("Raw read on FD=%d", fd);
201     return syscall(SYS_READ, fd, cast(ssize_t) buf, cast(ssize_t) count).withErrorno;
202 }
203 
204 ssize_t raw_write(int fd, const void *buf, size_t count) nothrow
205 {
206     logf("Raw write on FD=%d", fd);
207     return syscall(SYS_WRITE, fd, cast(size_t) buf, count).withErrorno;
208 }
209 
210 ssize_t raw_poll(pollfd *fds, nfds_t nfds, int timeout)
211 {
212     logf("Raw poll");
213     return syscall(SYS_POLL, cast(size_t)fds, cast(size_t) nfds, timeout).withErrorno;
214 }
215