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 version (X86) {
13     enum int SYS_READ = 0x3, SYS_SOCKETPAIR = 0x168; //TODO test on x86
14     int syscall(int ident, int n, int arg1, int arg2)
15     {
16         int ret;
17 
18         asm nothrow
19         {
20             mov EAX, ident;
21             mov EBX, n[EBP];
22             mov ECX, arg1[EBP];
23             mov EDX, arg2[EBP];
24             int 0x80;
25             mov ret, EAX;
26         }
27         return ret;
28     }
29 
30     int syscall(int ident, int n, int arg1, int arg2, int arg3)
31     {
32         int ret;
33 
34         asm nothrow
35         {
36             mov EAX, ident;
37             mov EBX, n[EBP];
38             mov ECX, arg1[EBP];
39             mov EDX, arg2[EBP];
40             mov ESI, arg3[EBP];
41             int 0x80;
42             mov ret, EAX;
43         }
44         return ret;
45     }
46 
47     int syscall(int ident, int n, int arg1, int arg2, int arg3, int arg4)
48     {
49         int ret;
50 
51         asm nothrow
52         {
53             mov EAX, ident;
54             mov EBX, n[EBP];
55             mov ECX, arg1[EBP];
56             mov EDX, arg2[EBP];
57             mov ESI, arg3[EBP];
58             mov EDI, arg4[EBP];
59             int 0x80;
60             mov ret, EAX;
61         }
62         return ret;
63     }
64 } else version (X86_64) {
65     enum int
66         SYS_READ = 0x0,
67         SYS_WRITE = 0x1,
68         SYS_CLOSE = 3,
69         SYS_POLL = 7,
70         SYS_GETTID = 186,
71         SYS_SOCKETPAIR = 0x35,
72         SYS_ACCEPT = 0x2b,
73         SYS_ACCEPT4 = 0x120,
74         SYS_CONNECT = 0x2a,
75         SYS_SENDTO = 0x2c,
76         SYS_RECVFROM = 45;
77 
78     size_t syscall(size_t ident) nothrow
79     {
80         size_t ret;
81 
82         asm nothrow
83         {
84             mov RAX, ident;
85             syscall;
86             mov ret, RAX;
87         }
88         return ret;
89     }
90 
91     size_t syscall(size_t ident, size_t n) nothrow
92     {
93         size_t ret;
94 
95         asm nothrow
96         {
97             mov RAX, ident;
98             mov RDI, n;
99             syscall;
100             mov ret, RAX;
101         }
102         return ret;
103     }
104 
105     size_t syscall(size_t ident, size_t n, size_t arg1, size_t arg2) nothrow
106     {
107         size_t ret;
108 
109         asm nothrow
110         {
111             mov RAX, ident;
112             mov RDI, n;
113             mov RSI, arg1;
114             mov RDX, arg2;
115             syscall;
116             mov ret, RAX;
117         }
118         return ret;
119     }
120 
121     size_t syscall(size_t ident, size_t n, size_t arg1, size_t arg2, size_t arg3) nothrow
122     {
123         size_t ret;
124 
125         asm nothrow
126         {
127             mov RAX, ident;
128             mov RDI, n;
129             mov RSI, arg1;
130             mov RDX, arg2;
131             mov R10, arg3;
132             syscall;
133             mov ret, RAX;
134         }
135         return ret;
136     }
137 
138     size_t syscall(size_t ident, size_t n, size_t arg1, size_t arg2, size_t arg3, size_t arg4) nothrow
139     {
140         size_t ret;
141 
142         asm nothrow
143         {
144             mov RAX, ident;
145             mov RDI, n;
146             mov RSI, arg1;
147             mov RDX, arg2;
148             mov R10, arg3;
149             mov R8, arg4;
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, size_t arg5) 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             mov R9, arg5;
169             syscall;
170             mov ret, RAX;
171         }
172         return ret;
173     }
174 }
175 
176 int gettid()
177 {
178     return cast(int)syscall(SYS_GETTID);
179 }
180 
181 ssize_t raw_read(int fd, void *buf, size_t count) nothrow {
182     logf("Raw read on FD=%d", fd);
183     return syscall(SYS_READ, fd, cast(ssize_t) buf, cast(ssize_t) count).withErrorno;
184 }
185 
186 ssize_t raw_write(int fd, const void *buf, size_t count) nothrow
187 {
188     logf("Raw write on FD=%d", fd);
189     return syscall(SYS_WRITE, fd, cast(size_t) buf, count).withErrorno;
190 }
191 
192 ssize_t raw_poll(pollfd *fds, nfds_t nfds, int timeout)
193 {
194     logf("Raw poll");
195     return syscall(SYS_POLL, cast(size_t)fds, cast(size_t) nfds, timeout).withErrorno;
196 }
197