Merge branch 'core-rcu.2021.08.28a' of git://git.kernel.org/pub/scm/linux/kernel...
[linux-2.6-microblaze.git] / tools / include / nolibc / nolibc.h
1 /* SPDX-License-Identifier: LGPL-2.1 OR MIT */
2 /* nolibc.h
3  * Copyright (C) 2017-2018 Willy Tarreau <w@1wt.eu>
4  */
5
6 /*
7  * This file is designed to be used as a libc alternative for minimal programs
8  * with very limited requirements. It consists of a small number of syscall and
9  * type definitions, and the minimal startup code needed to call main().
10  * All syscalls are declared as static functions so that they can be optimized
11  * away by the compiler when not used.
12  *
13  * Syscalls are split into 3 levels:
14  *   - The lower level is the arch-specific syscall() definition, consisting in
15  *     assembly code in compound expressions. These are called my_syscall0() to
16  *     my_syscall6() depending on the number of arguments. The MIPS
17  *     implementation is limited to 5 arguments. All input arguments are cast
18  *     to a long stored in a register. These expressions always return the
19  *     syscall's return value as a signed long value which is often either a
20  *     pointer or the negated errno value.
21  *
22  *   - The second level is mostly architecture-independent. It is made of
23  *     static functions called sys_<name>() which rely on my_syscallN()
24  *     depending on the syscall definition. These functions are responsible
25  *     for exposing the appropriate types for the syscall arguments (int,
26  *     pointers, etc) and for setting the appropriate return type (often int).
27  *     A few of them are architecture-specific because the syscalls are not all
28  *     mapped exactly the same among architectures. For example, some archs do
29  *     not implement select() and need pselect6() instead, so the sys_select()
30  *     function will have to abstract this.
31  *
32  *   - The third level is the libc call definition. It exposes the lower raw
33  *     sys_<name>() calls in a way that looks like what a libc usually does,
34  *     takes care of specific input values, and of setting errno upon error.
35  *     There can be minor variations compared to standard libc calls. For
36  *     example the open() call always takes 3 args here.
37  *
38  * The errno variable is declared static and unused. This way it can be
39  * optimized away if not used. However this means that a program made of
40  * multiple C files may observe different errno values (one per C file). For
41  * the type of programs this project targets it usually is not a problem. The
42  * resulting program may even be reduced by defining the NOLIBC_IGNORE_ERRNO
43  * macro, in which case the errno value will never be assigned.
44  *
45  * Some stdint-like integer types are defined. These are valid on all currently
46  * supported architectures, because signs are enforced, ints are assumed to be
47  * 32 bits, longs the size of a pointer and long long 64 bits. If more
48  * architectures have to be supported, this may need to be adapted.
49  *
50  * Some macro definitions like the O_* values passed to open(), and some
51  * structures like the sys_stat struct depend on the architecture.
52  *
53  * The definitions start with the architecture-specific parts, which are picked
54  * based on what the compiler knows about the target architecture, and are
55  * completed with the generic code. Since it is the compiler which sets the
56  * target architecture, cross-compiling normally works out of the box without
57  * having to specify anything.
58  *
59  * Finally some very common libc-level functions are provided. It is the case
60  * for a few functions usually found in string.h, ctype.h, or stdlib.h. Nothing
61  * is currently provided regarding stdio emulation.
62  *
63  * The macro NOLIBC is always defined, so that it is possible for a program to
64  * check this macro to know if it is being built against and decide to disable
65  * some features or simply not to include some standard libc files.
66  *
67  * Ideally this file should be split in multiple files for easier long term
68  * maintenance, but provided as a single file as it is now, it's quite
69  * convenient to use. Maybe some variations involving a set of includes at the
70  * top could work.
71  *
72  * A simple static executable may be built this way :
73  *      $ gcc -fno-asynchronous-unwind-tables -fno-ident -s -Os -nostdlib \
74  *            -static -include nolibc.h -o hello hello.c -lgcc
75  *
76  * A very useful calling convention table may be found here :
77  *      http://man7.org/linux/man-pages/man2/syscall.2.html
78  *
79  * This doc is quite convenient though not necessarily up to date :
80  *      https://w3challs.com/syscalls/
81  *
82  */
83
84 #include <asm/unistd.h>
85 #include <asm/ioctls.h>
86 #include <asm/errno.h>
87 #include <linux/fs.h>
88 #include <linux/loop.h>
89 #include <linux/time.h>
90
91 #define NOLIBC
92
93 /* this way it will be removed if unused */
94 static int errno;
95
96 #ifndef NOLIBC_IGNORE_ERRNO
97 #define SET_ERRNO(v) do { errno = (v); } while (0)
98 #else
99 #define SET_ERRNO(v) do { } while (0)
100 #endif
101
102 /* errno codes all ensure that they will not conflict with a valid pointer
103  * because they all correspond to the highest addressable memory page.
104  */
105 #define MAX_ERRNO 4095
106
107 /* Declare a few quite common macros and types that usually are in stdlib.h,
108  * stdint.h, ctype.h, unistd.h and a few other common locations.
109  */
110
111 #define NULL ((void *)0)
112
113 /* stdint types */
114 typedef unsigned char       uint8_t;
115 typedef   signed char        int8_t;
116 typedef unsigned short     uint16_t;
117 typedef   signed short      int16_t;
118 typedef unsigned int       uint32_t;
119 typedef   signed int        int32_t;
120 typedef unsigned long long uint64_t;
121 typedef   signed long long  int64_t;
122 typedef unsigned long        size_t;
123 typedef   signed long       ssize_t;
124 typedef unsigned long     uintptr_t;
125 typedef   signed long      intptr_t;
126 typedef   signed long     ptrdiff_t;
127
128 /* for stat() */
129 typedef unsigned int          dev_t;
130 typedef unsigned long         ino_t;
131 typedef unsigned int         mode_t;
132 typedef   signed int          pid_t;
133 typedef unsigned int          uid_t;
134 typedef unsigned int          gid_t;
135 typedef unsigned long       nlink_t;
136 typedef   signed long         off_t;
137 typedef   signed long     blksize_t;
138 typedef   signed long      blkcnt_t;
139 typedef   signed long        time_t;
140
141 /* for poll() */
142 struct pollfd {
143         int fd;
144         short int events;
145         short int revents;
146 };
147
148 /* for getdents64() */
149 struct linux_dirent64 {
150         uint64_t       d_ino;
151         int64_t        d_off;
152         unsigned short d_reclen;
153         unsigned char  d_type;
154         char           d_name[];
155 };
156
157 /* commonly an fd_set represents 256 FDs */
158 #define FD_SETSIZE 256
159 typedef struct { uint32_t fd32[FD_SETSIZE/32]; } fd_set;
160
161 /* needed by wait4() */
162 struct rusage {
163         struct timeval ru_utime;
164         struct timeval ru_stime;
165         long   ru_maxrss;
166         long   ru_ixrss;
167         long   ru_idrss;
168         long   ru_isrss;
169         long   ru_minflt;
170         long   ru_majflt;
171         long   ru_nswap;
172         long   ru_inblock;
173         long   ru_oublock;
174         long   ru_msgsnd;
175         long   ru_msgrcv;
176         long   ru_nsignals;
177         long   ru_nvcsw;
178         long   ru_nivcsw;
179 };
180
181 /* stat flags (WARNING, octal here) */
182 #define S_IFDIR       0040000
183 #define S_IFCHR       0020000
184 #define S_IFBLK       0060000
185 #define S_IFREG       0100000
186 #define S_IFIFO       0010000
187 #define S_IFLNK       0120000
188 #define S_IFSOCK      0140000
189 #define S_IFMT        0170000
190
191 #define S_ISDIR(mode)  (((mode) & S_IFDIR) == S_IFDIR)
192 #define S_ISCHR(mode)  (((mode) & S_IFCHR) == S_IFCHR)
193 #define S_ISBLK(mode)  (((mode) & S_IFBLK) == S_IFBLK)
194 #define S_ISREG(mode)  (((mode) & S_IFREG) == S_IFREG)
195 #define S_ISFIFO(mode) (((mode) & S_IFIFO) == S_IFIFO)
196 #define S_ISLNK(mode)  (((mode) & S_IFLNK) == S_IFLNK)
197 #define S_ISSOCK(mode) (((mode) & S_IFSOCK) == S_IFSOCK)
198
199 #define DT_UNKNOWN 0
200 #define DT_FIFO    1
201 #define DT_CHR     2
202 #define DT_DIR     4
203 #define DT_BLK     6
204 #define DT_REG     8
205 #define DT_LNK    10
206 #define DT_SOCK   12
207
208 /* all the *at functions */
209 #ifndef AT_FDCWD
210 #define AT_FDCWD             -100
211 #endif
212
213 /* lseek */
214 #define SEEK_SET        0
215 #define SEEK_CUR        1
216 #define SEEK_END        2
217
218 /* reboot */
219 #define LINUX_REBOOT_MAGIC1         0xfee1dead
220 #define LINUX_REBOOT_MAGIC2         0x28121969
221 #define LINUX_REBOOT_CMD_HALT       0xcdef0123
222 #define LINUX_REBOOT_CMD_POWER_OFF  0x4321fedc
223 #define LINUX_REBOOT_CMD_RESTART    0x01234567
224 #define LINUX_REBOOT_CMD_SW_SUSPEND 0xd000fce2
225
226
227 /* The format of the struct as returned by the libc to the application, which
228  * significantly differs from the format returned by the stat() syscall flavours.
229  */
230 struct stat {
231         dev_t     st_dev;     /* ID of device containing file */
232         ino_t     st_ino;     /* inode number */
233         mode_t    st_mode;    /* protection */
234         nlink_t   st_nlink;   /* number of hard links */
235         uid_t     st_uid;     /* user ID of owner */
236         gid_t     st_gid;     /* group ID of owner */
237         dev_t     st_rdev;    /* device ID (if special file) */
238         off_t     st_size;    /* total size, in bytes */
239         blksize_t st_blksize; /* blocksize for file system I/O */
240         blkcnt_t  st_blocks;  /* number of 512B blocks allocated */
241         time_t    st_atime;   /* time of last access */
242         time_t    st_mtime;   /* time of last modification */
243         time_t    st_ctime;   /* time of last status change */
244 };
245
246 #define WEXITSTATUS(status)   (((status) & 0xff00) >> 8)
247 #define WIFEXITED(status)     (((status) & 0x7f) == 0)
248
249 /* for SIGCHLD */
250 #include <asm/signal.h>
251
252 /* Below comes the architecture-specific code. For each architecture, we have
253  * the syscall declarations and the _start code definition. This is the only
254  * global part. On all architectures the kernel puts everything in the stack
255  * before jumping to _start just above us, without any return address (_start
256  * is not a function but an entry pint). So at the stack pointer we find argc.
257  * Then argv[] begins, and ends at the first NULL. Then we have envp which
258  * starts and ends with a NULL as well. So envp=argv+argc+1.
259  */
260
261 #if defined(__x86_64__)
262 /* Syscalls for x86_64 :
263  *   - registers are 64-bit
264  *   - syscall number is passed in rax
265  *   - arguments are in rdi, rsi, rdx, r10, r8, r9 respectively
266  *   - the system call is performed by calling the syscall instruction
267  *   - syscall return comes in rax
268  *   - rcx and r8..r11 may be clobbered, others are preserved.
269  *   - the arguments are cast to long and assigned into the target registers
270  *     which are then simply passed as registers to the asm code, so that we
271  *     don't have to experience issues with register constraints.
272  *   - the syscall number is always specified last in order to allow to force
273  *     some registers before (gcc refuses a %-register at the last position).
274  */
275
276 #define my_syscall0(num)                                                      \
277 ({                                                                            \
278         long _ret;                                                            \
279         register long _num  asm("rax") = (num);                               \
280                                                                               \
281         asm volatile (                                                        \
282                 "syscall\n"                                                   \
283                 : "=a" (_ret)                                                 \
284                 : "0"(_num)                                                   \
285                 : "rcx", "r8", "r9", "r10", "r11", "memory", "cc"             \
286         );                                                                    \
287         _ret;                                                                 \
288 })
289
290 #define my_syscall1(num, arg1)                                                \
291 ({                                                                            \
292         long _ret;                                                            \
293         register long _num  asm("rax") = (num);                               \
294         register long _arg1 asm("rdi") = (long)(arg1);                        \
295                                                                               \
296         asm volatile (                                                        \
297                 "syscall\n"                                                   \
298                 : "=a" (_ret)                                                 \
299                 : "r"(_arg1),                                                 \
300                   "0"(_num)                                                   \
301                 : "rcx", "r8", "r9", "r10", "r11", "memory", "cc"             \
302         );                                                                    \
303         _ret;                                                                 \
304 })
305
306 #define my_syscall2(num, arg1, arg2)                                          \
307 ({                                                                            \
308         long _ret;                                                            \
309         register long _num  asm("rax") = (num);                               \
310         register long _arg1 asm("rdi") = (long)(arg1);                        \
311         register long _arg2 asm("rsi") = (long)(arg2);                        \
312                                                                               \
313         asm volatile (                                                        \
314                 "syscall\n"                                                   \
315                 : "=a" (_ret)                                                 \
316                 : "r"(_arg1), "r"(_arg2),                                     \
317                   "0"(_num)                                                   \
318                 : "rcx", "r8", "r9", "r10", "r11", "memory", "cc"             \
319         );                                                                    \
320         _ret;                                                                 \
321 })
322
323 #define my_syscall3(num, arg1, arg2, arg3)                                    \
324 ({                                                                            \
325         long _ret;                                                            \
326         register long _num  asm("rax") = (num);                               \
327         register long _arg1 asm("rdi") = (long)(arg1);                        \
328         register long _arg2 asm("rsi") = (long)(arg2);                        \
329         register long _arg3 asm("rdx") = (long)(arg3);                        \
330                                                                               \
331         asm volatile (                                                        \
332                 "syscall\n"                                                   \
333                 : "=a" (_ret)                                                 \
334                 : "r"(_arg1), "r"(_arg2), "r"(_arg3),                         \
335                   "0"(_num)                                                   \
336                 : "rcx", "r8", "r9", "r10", "r11", "memory", "cc"             \
337         );                                                                    \
338         _ret;                                                                 \
339 })
340
341 #define my_syscall4(num, arg1, arg2, arg3, arg4)                              \
342 ({                                                                            \
343         long _ret;                                                            \
344         register long _num  asm("rax") = (num);                               \
345         register long _arg1 asm("rdi") = (long)(arg1);                        \
346         register long _arg2 asm("rsi") = (long)(arg2);                        \
347         register long _arg3 asm("rdx") = (long)(arg3);                        \
348         register long _arg4 asm("r10") = (long)(arg4);                        \
349                                                                               \
350         asm volatile (                                                        \
351                 "syscall\n"                                                   \
352                 : "=a" (_ret), "=r"(_arg4)                                    \
353                 : "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg4),             \
354                   "0"(_num)                                                   \
355                 : "rcx", "r8", "r9", "r11", "memory", "cc"                    \
356         );                                                                    \
357         _ret;                                                                 \
358 })
359
360 #define my_syscall5(num, arg1, arg2, arg3, arg4, arg5)                        \
361 ({                                                                            \
362         long _ret;                                                            \
363         register long _num  asm("rax") = (num);                               \
364         register long _arg1 asm("rdi") = (long)(arg1);                        \
365         register long _arg2 asm("rsi") = (long)(arg2);                        \
366         register long _arg3 asm("rdx") = (long)(arg3);                        \
367         register long _arg4 asm("r10") = (long)(arg4);                        \
368         register long _arg5 asm("r8")  = (long)(arg5);                        \
369                                                                               \
370         asm volatile (                                                        \
371                 "syscall\n"                                                   \
372                 : "=a" (_ret), "=r"(_arg4), "=r"(_arg5)                       \
373                 : "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg4), "r"(_arg5), \
374                   "0"(_num)                                                   \
375                 : "rcx", "r9", "r11", "memory", "cc"                          \
376         );                                                                    \
377         _ret;                                                                 \
378 })
379
380 #define my_syscall6(num, arg1, arg2, arg3, arg4, arg5, arg6)                  \
381 ({                                                                            \
382         long _ret;                                                            \
383         register long _num  asm("rax") = (num);                               \
384         register long _arg1 asm("rdi") = (long)(arg1);                        \
385         register long _arg2 asm("rsi") = (long)(arg2);                        \
386         register long _arg3 asm("rdx") = (long)(arg3);                        \
387         register long _arg4 asm("r10") = (long)(arg4);                        \
388         register long _arg5 asm("r8")  = (long)(arg5);                        \
389         register long _arg6 asm("r9")  = (long)(arg6);                        \
390                                                                               \
391         asm volatile (                                                        \
392                 "syscall\n"                                                   \
393                 : "=a" (_ret), "=r"(_arg4), "=r"(_arg5)                       \
394                 : "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg4), "r"(_arg5), \
395                   "r"(_arg6), "0"(_num)                                       \
396                 : "rcx", "r11", "memory", "cc"                                \
397         );                                                                    \
398         _ret;                                                                 \
399 })
400
401 /* startup code */
402 asm(".section .text\n"
403     ".global _start\n"
404     "_start:\n"
405     "pop %rdi\n"                // argc   (first arg, %rdi)
406     "mov %rsp, %rsi\n"          // argv[] (second arg, %rsi)
407     "lea 8(%rsi,%rdi,8),%rdx\n" // then a NULL then envp (third arg, %rdx)
408     "and $-16, %rsp\n"          // x86 ABI : esp must be 16-byte aligned when
409     "sub $8, %rsp\n"            // entering the callee
410     "call main\n"               // main() returns the status code, we'll exit with it.
411     "movzb %al, %rdi\n"         // retrieve exit code from 8 lower bits
412     "mov $60, %rax\n"           // NR_exit == 60
413     "syscall\n"                 // really exit
414     "hlt\n"                     // ensure it does not return
415     "");
416
417 /* fcntl / open */
418 #define O_RDONLY            0
419 #define O_WRONLY            1
420 #define O_RDWR              2
421 #define O_CREAT          0x40
422 #define O_EXCL           0x80
423 #define O_NOCTTY        0x100
424 #define O_TRUNC         0x200
425 #define O_APPEND        0x400
426 #define O_NONBLOCK      0x800
427 #define O_DIRECTORY   0x10000
428
429 /* The struct returned by the stat() syscall, equivalent to stat64(). The
430  * syscall returns 116 bytes and stops in the middle of __unused.
431  */
432 struct sys_stat_struct {
433         unsigned long st_dev;
434         unsigned long st_ino;
435         unsigned long st_nlink;
436         unsigned int  st_mode;
437         unsigned int  st_uid;
438
439         unsigned int  st_gid;
440         unsigned int  __pad0;
441         unsigned long st_rdev;
442         long          st_size;
443         long          st_blksize;
444
445         long          st_blocks;
446         unsigned long st_atime;
447         unsigned long st_atime_nsec;
448         unsigned long st_mtime;
449
450         unsigned long st_mtime_nsec;
451         unsigned long st_ctime;
452         unsigned long st_ctime_nsec;
453         long          __unused[3];
454 };
455
456 #elif defined(__i386__) || defined(__i486__) || defined(__i586__) || defined(__i686__)
457 /* Syscalls for i386 :
458  *   - mostly similar to x86_64
459  *   - registers are 32-bit
460  *   - syscall number is passed in eax
461  *   - arguments are in ebx, ecx, edx, esi, edi, ebp respectively
462  *   - all registers are preserved (except eax of course)
463  *   - the system call is performed by calling int $0x80
464  *   - syscall return comes in eax
465  *   - the arguments are cast to long and assigned into the target registers
466  *     which are then simply passed as registers to the asm code, so that we
467  *     don't have to experience issues with register constraints.
468  *   - the syscall number is always specified last in order to allow to force
469  *     some registers before (gcc refuses a %-register at the last position).
470  *
471  * Also, i386 supports the old_select syscall if newselect is not available
472  */
473 #define __ARCH_WANT_SYS_OLD_SELECT
474
475 #define my_syscall0(num)                                                      \
476 ({                                                                            \
477         long _ret;                                                            \
478         register long _num asm("eax") = (num);                                \
479                                                                               \
480         asm volatile (                                                        \
481                 "int $0x80\n"                                                 \
482                 : "=a" (_ret)                                                 \
483                 : "0"(_num)                                                   \
484                 : "memory", "cc"                                              \
485         );                                                                    \
486         _ret;                                                                 \
487 })
488
489 #define my_syscall1(num, arg1)                                                \
490 ({                                                                            \
491         long _ret;                                                            \
492         register long _num asm("eax") = (num);                                \
493         register long _arg1 asm("ebx") = (long)(arg1);                        \
494                                                                               \
495         asm volatile (                                                        \
496                 "int $0x80\n"                                                 \
497                 : "=a" (_ret)                                                 \
498                 : "r"(_arg1),                                                 \
499                   "0"(_num)                                                   \
500                 : "memory", "cc"                                              \
501         );                                                                    \
502         _ret;                                                                 \
503 })
504
505 #define my_syscall2(num, arg1, arg2)                                          \
506 ({                                                                            \
507         long _ret;                                                            \
508         register long _num asm("eax") = (num);                                \
509         register long _arg1 asm("ebx") = (long)(arg1);                        \
510         register long _arg2 asm("ecx") = (long)(arg2);                        \
511                                                                               \
512         asm volatile (                                                        \
513                 "int $0x80\n"                                                 \
514                 : "=a" (_ret)                                                 \
515                 : "r"(_arg1), "r"(_arg2),                                     \
516                   "0"(_num)                                                   \
517                 : "memory", "cc"                                              \
518         );                                                                    \
519         _ret;                                                                 \
520 })
521
522 #define my_syscall3(num, arg1, arg2, arg3)                                    \
523 ({                                                                            \
524         long _ret;                                                            \
525         register long _num asm("eax") = (num);                                \
526         register long _arg1 asm("ebx") = (long)(arg1);                        \
527         register long _arg2 asm("ecx") = (long)(arg2);                        \
528         register long _arg3 asm("edx") = (long)(arg3);                        \
529                                                                               \
530         asm volatile (                                                        \
531                 "int $0x80\n"                                                 \
532                 : "=a" (_ret)                                                 \
533                 : "r"(_arg1), "r"(_arg2), "r"(_arg3),                         \
534                   "0"(_num)                                                   \
535                 : "memory", "cc"                                              \
536         );                                                                    \
537         _ret;                                                                 \
538 })
539
540 #define my_syscall4(num, arg1, arg2, arg3, arg4)                              \
541 ({                                                                            \
542         long _ret;                                                            \
543         register long _num asm("eax") = (num);                                \
544         register long _arg1 asm("ebx") = (long)(arg1);                        \
545         register long _arg2 asm("ecx") = (long)(arg2);                        \
546         register long _arg3 asm("edx") = (long)(arg3);                        \
547         register long _arg4 asm("esi") = (long)(arg4);                        \
548                                                                               \
549         asm volatile (                                                        \
550                 "int $0x80\n"                                                 \
551                 : "=a" (_ret)                                                 \
552                 : "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg4),             \
553                   "0"(_num)                                                   \
554                 : "memory", "cc"                                              \
555         );                                                                    \
556         _ret;                                                                 \
557 })
558
559 #define my_syscall5(num, arg1, arg2, arg3, arg4, arg5)                        \
560 ({                                                                            \
561         long _ret;                                                            \
562         register long _num asm("eax") = (num);                                \
563         register long _arg1 asm("ebx") = (long)(arg1);                        \
564         register long _arg2 asm("ecx") = (long)(arg2);                        \
565         register long _arg3 asm("edx") = (long)(arg3);                        \
566         register long _arg4 asm("esi") = (long)(arg4);                        \
567         register long _arg5 asm("edi") = (long)(arg5);                        \
568                                                                               \
569         asm volatile (                                                        \
570                 "int $0x80\n"                                                 \
571                 : "=a" (_ret)                                                 \
572                 : "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg4), "r"(_arg5), \
573                   "0"(_num)                                                   \
574                 : "memory", "cc"                                              \
575         );                                                                    \
576         _ret;                                                                 \
577 })
578
579 /* startup code */
580 asm(".section .text\n"
581     ".global _start\n"
582     "_start:\n"
583     "pop %eax\n"                // argc   (first arg, %eax)
584     "mov %esp, %ebx\n"          // argv[] (second arg, %ebx)
585     "lea 4(%ebx,%eax,4),%ecx\n" // then a NULL then envp (third arg, %ecx)
586     "and $-16, %esp\n"          // x86 ABI : esp must be 16-byte aligned when
587     "push %ecx\n"               // push all registers on the stack so that we
588     "push %ebx\n"               // support both regparm and plain stack modes
589     "push %eax\n"
590     "call main\n"               // main() returns the status code in %eax
591     "movzbl %al, %ebx\n"        // retrieve exit code from lower 8 bits
592     "movl   $1, %eax\n"         // NR_exit == 1
593     "int    $0x80\n"            // exit now
594     "hlt\n"                     // ensure it does not
595     "");
596
597 /* fcntl / open */
598 #define O_RDONLY            0
599 #define O_WRONLY            1
600 #define O_RDWR              2
601 #define O_CREAT          0x40
602 #define O_EXCL           0x80
603 #define O_NOCTTY        0x100
604 #define O_TRUNC         0x200
605 #define O_APPEND        0x400
606 #define O_NONBLOCK      0x800
607 #define O_DIRECTORY   0x10000
608
609 /* The struct returned by the stat() syscall, 32-bit only, the syscall returns
610  * exactly 56 bytes (stops before the unused array).
611  */
612 struct sys_stat_struct {
613         unsigned long  st_dev;
614         unsigned long  st_ino;
615         unsigned short st_mode;
616         unsigned short st_nlink;
617         unsigned short st_uid;
618         unsigned short st_gid;
619
620         unsigned long  st_rdev;
621         unsigned long  st_size;
622         unsigned long  st_blksize;
623         unsigned long  st_blocks;
624
625         unsigned long  st_atime;
626         unsigned long  st_atime_nsec;
627         unsigned long  st_mtime;
628         unsigned long  st_mtime_nsec;
629
630         unsigned long  st_ctime;
631         unsigned long  st_ctime_nsec;
632         unsigned long  __unused[2];
633 };
634
635 #elif defined(__ARM_EABI__)
636 /* Syscalls for ARM in ARM or Thumb modes :
637  *   - registers are 32-bit
638  *   - stack is 8-byte aligned
639  *     ( http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/ka4127.html)
640  *   - syscall number is passed in r7
641  *   - arguments are in r0, r1, r2, r3, r4, r5
642  *   - the system call is performed by calling svc #0
643  *   - syscall return comes in r0.
644  *   - only lr is clobbered.
645  *   - the arguments are cast to long and assigned into the target registers
646  *     which are then simply passed as registers to the asm code, so that we
647  *     don't have to experience issues with register constraints.
648  *   - the syscall number is always specified last in order to allow to force
649  *     some registers before (gcc refuses a %-register at the last position).
650  *
651  * Also, ARM supports the old_select syscall if newselect is not available
652  */
653 #define __ARCH_WANT_SYS_OLD_SELECT
654
655 #define my_syscall0(num)                                                      \
656 ({                                                                            \
657         register long _num asm("r7") = (num);                                 \
658         register long _arg1 asm("r0");                                        \
659                                                                               \
660         asm volatile (                                                        \
661                 "svc #0\n"                                                    \
662                 : "=r"(_arg1)                                                 \
663                 : "r"(_num)                                                   \
664                 : "memory", "cc", "lr"                                        \
665         );                                                                    \
666         _arg1;                                                                \
667 })
668
669 #define my_syscall1(num, arg1)                                                \
670 ({                                                                            \
671         register long _num asm("r7") = (num);                                 \
672         register long _arg1 asm("r0") = (long)(arg1);                         \
673                                                                               \
674         asm volatile (                                                        \
675                 "svc #0\n"                                                    \
676                 : "=r"(_arg1)                                                 \
677                 : "r"(_arg1),                                                 \
678                   "r"(_num)                                                   \
679                 : "memory", "cc", "lr"                                        \
680         );                                                                    \
681         _arg1;                                                                \
682 })
683
684 #define my_syscall2(num, arg1, arg2)                                          \
685 ({                                                                            \
686         register long _num asm("r7") = (num);                                 \
687         register long _arg1 asm("r0") = (long)(arg1);                         \
688         register long _arg2 asm("r1") = (long)(arg2);                         \
689                                                                               \
690         asm volatile (                                                        \
691                 "svc #0\n"                                                    \
692                 : "=r"(_arg1)                                                 \
693                 : "r"(_arg1), "r"(_arg2),                                     \
694                   "r"(_num)                                                   \
695                 : "memory", "cc", "lr"                                        \
696         );                                                                    \
697         _arg1;                                                                \
698 })
699
700 #define my_syscall3(num, arg1, arg2, arg3)                                    \
701 ({                                                                            \
702         register long _num asm("r7") = (num);                                 \
703         register long _arg1 asm("r0") = (long)(arg1);                         \
704         register long _arg2 asm("r1") = (long)(arg2);                         \
705         register long _arg3 asm("r2") = (long)(arg3);                         \
706                                                                               \
707         asm volatile (                                                        \
708                 "svc #0\n"                                                    \
709                 : "=r"(_arg1)                                                 \
710                 : "r"(_arg1), "r"(_arg2), "r"(_arg3),                         \
711                   "r"(_num)                                                   \
712                 : "memory", "cc", "lr"                                        \
713         );                                                                    \
714         _arg1;                                                                \
715 })
716
717 #define my_syscall4(num, arg1, arg2, arg3, arg4)                              \
718 ({                                                                            \
719         register long _num asm("r7") = (num);                                 \
720         register long _arg1 asm("r0") = (long)(arg1);                         \
721         register long _arg2 asm("r1") = (long)(arg2);                         \
722         register long _arg3 asm("r2") = (long)(arg3);                         \
723         register long _arg4 asm("r3") = (long)(arg4);                         \
724                                                                               \
725         asm volatile (                                                        \
726                 "svc #0\n"                                                    \
727                 : "=r"(_arg1)                                                 \
728                 : "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg4),             \
729                   "r"(_num)                                                   \
730                 : "memory", "cc", "lr"                                        \
731         );                                                                    \
732         _arg1;                                                                \
733 })
734
735 #define my_syscall5(num, arg1, arg2, arg3, arg4, arg5)                        \
736 ({                                                                            \
737         register long _num asm("r7") = (num);                                 \
738         register long _arg1 asm("r0") = (long)(arg1);                         \
739         register long _arg2 asm("r1") = (long)(arg2);                         \
740         register long _arg3 asm("r2") = (long)(arg3);                         \
741         register long _arg4 asm("r3") = (long)(arg4);                         \
742         register long _arg5 asm("r4") = (long)(arg5);                         \
743                                                                               \
744         asm volatile (                                                        \
745                 "svc #0\n"                                                    \
746                 : "=r" (_arg1)                                                \
747                 : "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg4), "r"(_arg5), \
748                   "r"(_num)                                                   \
749                 : "memory", "cc", "lr"                                        \
750         );                                                                    \
751         _arg1;                                                                \
752 })
753
754 /* startup code */
755 asm(".section .text\n"
756     ".global _start\n"
757     "_start:\n"
758 #if defined(__THUMBEB__) || defined(__THUMBEL__)
759     /* We enter here in 32-bit mode but if some previous functions were in
760      * 16-bit mode, the assembler cannot know, so we need to tell it we're in
761      * 32-bit now, then switch to 16-bit (is there a better way to do it than
762      * adding 1 by hand ?) and tell the asm we're now in 16-bit mode so that
763      * it generates correct instructions. Note that we do not support thumb1.
764      */
765     ".code 32\n"
766     "add     r0, pc, #1\n"
767     "bx      r0\n"
768     ".code 16\n"
769 #endif
770     "pop {%r0}\n"                 // argc was in the stack
771     "mov %r1, %sp\n"              // argv = sp
772     "add %r2, %r1, %r0, lsl #2\n" // envp = argv + 4*argc ...
773     "add %r2, %r2, $4\n"          //        ... + 4
774     "and %r3, %r1, $-8\n"         // AAPCS : sp must be 8-byte aligned in the
775     "mov %sp, %r3\n"              //         callee, an bl doesn't push (lr=pc)
776     "bl main\n"                   // main() returns the status code, we'll exit with it.
777     "and %r0, %r0, $0xff\n"       // limit exit code to 8 bits
778     "movs r7, $1\n"               // NR_exit == 1
779     "svc $0x00\n"
780     "");
781
782 /* fcntl / open */
783 #define O_RDONLY            0
784 #define O_WRONLY            1
785 #define O_RDWR              2
786 #define O_CREAT          0x40
787 #define O_EXCL           0x80
788 #define O_NOCTTY        0x100
789 #define O_TRUNC         0x200
790 #define O_APPEND        0x400
791 #define O_NONBLOCK      0x800
792 #define O_DIRECTORY    0x4000
793
794 /* The struct returned by the stat() syscall, 32-bit only, the syscall returns
795  * exactly 56 bytes (stops before the unused array). In big endian, the format
796  * differs as devices are returned as short only.
797  */
798 struct sys_stat_struct {
799 #if defined(__ARMEB__)
800         unsigned short st_dev;
801         unsigned short __pad1;
802 #else
803         unsigned long  st_dev;
804 #endif
805         unsigned long  st_ino;
806         unsigned short st_mode;
807         unsigned short st_nlink;
808         unsigned short st_uid;
809         unsigned short st_gid;
810 #if defined(__ARMEB__)
811         unsigned short st_rdev;
812         unsigned short __pad2;
813 #else
814         unsigned long  st_rdev;
815 #endif
816         unsigned long  st_size;
817         unsigned long  st_blksize;
818         unsigned long  st_blocks;
819         unsigned long  st_atime;
820         unsigned long  st_atime_nsec;
821         unsigned long  st_mtime;
822         unsigned long  st_mtime_nsec;
823         unsigned long  st_ctime;
824         unsigned long  st_ctime_nsec;
825         unsigned long  __unused[2];
826 };
827
828 #elif defined(__aarch64__)
829 /* Syscalls for AARCH64 :
830  *   - registers are 64-bit
831  *   - stack is 16-byte aligned
832  *   - syscall number is passed in x8
833  *   - arguments are in x0, x1, x2, x3, x4, x5
834  *   - the system call is performed by calling svc 0
835  *   - syscall return comes in x0.
836  *   - the arguments are cast to long and assigned into the target registers
837  *     which are then simply passed as registers to the asm code, so that we
838  *     don't have to experience issues with register constraints.
839  *
840  * On aarch64, select() is not implemented so we have to use pselect6().
841  */
842 #define __ARCH_WANT_SYS_PSELECT6
843
844 #define my_syscall0(num)                                                      \
845 ({                                                                            \
846         register long _num  asm("x8") = (num);                                \
847         register long _arg1 asm("x0");                                        \
848                                                                               \
849         asm volatile (                                                        \
850                 "svc #0\n"                                                    \
851                 : "=r"(_arg1)                                                 \
852                 : "r"(_num)                                                   \
853                 : "memory", "cc"                                              \
854         );                                                                    \
855         _arg1;                                                                \
856 })
857
858 #define my_syscall1(num, arg1)                                                \
859 ({                                                                            \
860         register long _num  asm("x8") = (num);                                \
861         register long _arg1 asm("x0") = (long)(arg1);                         \
862                                                                               \
863         asm volatile (                                                        \
864                 "svc #0\n"                                                    \
865                 : "=r"(_arg1)                                                 \
866                 : "r"(_arg1),                                                 \
867                   "r"(_num)                                                   \
868                 : "memory", "cc"                                              \
869         );                                                                    \
870         _arg1;                                                                \
871 })
872
873 #define my_syscall2(num, arg1, arg2)                                          \
874 ({                                                                            \
875         register long _num  asm("x8") = (num);                                \
876         register long _arg1 asm("x0") = (long)(arg1);                         \
877         register long _arg2 asm("x1") = (long)(arg2);                         \
878                                                                               \
879         asm volatile (                                                        \
880                 "svc #0\n"                                                    \
881                 : "=r"(_arg1)                                                 \
882                 : "r"(_arg1), "r"(_arg2),                                     \
883                   "r"(_num)                                                   \
884                 : "memory", "cc"                                              \
885         );                                                                    \
886         _arg1;                                                                \
887 })
888
889 #define my_syscall3(num, arg1, arg2, arg3)                                    \
890 ({                                                                            \
891         register long _num  asm("x8") = (num);                                \
892         register long _arg1 asm("x0") = (long)(arg1);                         \
893         register long _arg2 asm("x1") = (long)(arg2);                         \
894         register long _arg3 asm("x2") = (long)(arg3);                         \
895                                                                               \
896         asm volatile (                                                        \
897                 "svc #0\n"                                                    \
898                 : "=r"(_arg1)                                                 \
899                 : "r"(_arg1), "r"(_arg2), "r"(_arg3),                         \
900                   "r"(_num)                                                   \
901                 : "memory", "cc"                                              \
902         );                                                                    \
903         _arg1;                                                                \
904 })
905
906 #define my_syscall4(num, arg1, arg2, arg3, arg4)                              \
907 ({                                                                            \
908         register long _num  asm("x8") = (num);                                \
909         register long _arg1 asm("x0") = (long)(arg1);                         \
910         register long _arg2 asm("x1") = (long)(arg2);                         \
911         register long _arg3 asm("x2") = (long)(arg3);                         \
912         register long _arg4 asm("x3") = (long)(arg4);                         \
913                                                                               \
914         asm volatile (                                                        \
915                 "svc #0\n"                                                    \
916                 : "=r"(_arg1)                                                 \
917                 : "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg4),             \
918                   "r"(_num)                                                   \
919                 : "memory", "cc"                                              \
920         );                                                                    \
921         _arg1;                                                                \
922 })
923
924 #define my_syscall5(num, arg1, arg2, arg3, arg4, arg5)                        \
925 ({                                                                            \
926         register long _num  asm("x8") = (num);                                \
927         register long _arg1 asm("x0") = (long)(arg1);                         \
928         register long _arg2 asm("x1") = (long)(arg2);                         \
929         register long _arg3 asm("x2") = (long)(arg3);                         \
930         register long _arg4 asm("x3") = (long)(arg4);                         \
931         register long _arg5 asm("x4") = (long)(arg5);                         \
932                                                                               \
933         asm volatile (                                                        \
934                 "svc #0\n"                                                    \
935                 : "=r" (_arg1)                                                \
936                 : "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg4), "r"(_arg5), \
937                   "r"(_num)                                                   \
938                 : "memory", "cc"                                              \
939         );                                                                    \
940         _arg1;                                                                \
941 })
942
943 #define my_syscall6(num, arg1, arg2, arg3, arg4, arg5, arg6)                  \
944 ({                                                                            \
945         register long _num  asm("x8") = (num);                                \
946         register long _arg1 asm("x0") = (long)(arg1);                         \
947         register long _arg2 asm("x1") = (long)(arg2);                         \
948         register long _arg3 asm("x2") = (long)(arg3);                         \
949         register long _arg4 asm("x3") = (long)(arg4);                         \
950         register long _arg5 asm("x4") = (long)(arg5);                         \
951         register long _arg6 asm("x5") = (long)(arg6);                         \
952                                                                               \
953         asm volatile (                                                        \
954                 "svc #0\n"                                                    \
955                 : "=r" (_arg1)                                                \
956                 : "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg4), "r"(_arg5), \
957                   "r"(_arg6), "r"(_num)                                       \
958                 : "memory", "cc"                                              \
959         );                                                                    \
960         _arg1;                                                                \
961 })
962
963 /* startup code */
964 asm(".section .text\n"
965     ".global _start\n"
966     "_start:\n"
967     "ldr x0, [sp]\n"              // argc (x0) was in the stack
968     "add x1, sp, 8\n"             // argv (x1) = sp
969     "lsl x2, x0, 3\n"             // envp (x2) = 8*argc ...
970     "add x2, x2, 8\n"             //           + 8 (skip null)
971     "add x2, x2, x1\n"            //           + argv
972     "and sp, x1, -16\n"           // sp must be 16-byte aligned in the callee
973     "bl main\n"                   // main() returns the status code, we'll exit with it.
974     "and x0, x0, 0xff\n"          // limit exit code to 8 bits
975     "mov x8, 93\n"                // NR_exit == 93
976     "svc #0\n"
977     "");
978
979 /* fcntl / open */
980 #define O_RDONLY            0
981 #define O_WRONLY            1
982 #define O_RDWR              2
983 #define O_CREAT          0x40
984 #define O_EXCL           0x80
985 #define O_NOCTTY        0x100
986 #define O_TRUNC         0x200
987 #define O_APPEND        0x400
988 #define O_NONBLOCK      0x800
989 #define O_DIRECTORY    0x4000
990
991 /* The struct returned by the newfstatat() syscall. Differs slightly from the
992  * x86_64's stat one by field ordering, so be careful.
993  */
994 struct sys_stat_struct {
995         unsigned long   st_dev;
996         unsigned long   st_ino;
997         unsigned int    st_mode;
998         unsigned int    st_nlink;
999         unsigned int    st_uid;
1000         unsigned int    st_gid;
1001
1002         unsigned long   st_rdev;
1003         unsigned long   __pad1;
1004         long            st_size;
1005         int             st_blksize;
1006         int             __pad2;
1007
1008         long            st_blocks;
1009         long            st_atime;
1010         unsigned long   st_atime_nsec;
1011         long            st_mtime;
1012
1013         unsigned long   st_mtime_nsec;
1014         long            st_ctime;
1015         unsigned long   st_ctime_nsec;
1016         unsigned int    __unused[2];
1017 };
1018
1019 #elif defined(__mips__) && defined(_ABIO32)
1020 /* Syscalls for MIPS ABI O32 :
1021  *   - WARNING! there's always a delayed slot!
1022  *   - WARNING again, the syntax is different, registers take a '$' and numbers
1023  *     do not.
1024  *   - registers are 32-bit
1025  *   - stack is 8-byte aligned
1026  *   - syscall number is passed in v0 (starts at 0xfa0).
1027  *   - arguments are in a0, a1, a2, a3, then the stack. The caller needs to
1028  *     leave some room in the stack for the callee to save a0..a3 if needed.
1029  *   - Many registers are clobbered, in fact only a0..a2 and s0..s8 are
1030  *     preserved. See: https://www.linux-mips.org/wiki/Syscall as well as
1031  *     scall32-o32.S in the kernel sources.
1032  *   - the system call is performed by calling "syscall"
1033  *   - syscall return comes in v0, and register a3 needs to be checked to know
1034  *     if an error occurred, in which case errno is in v0.
1035  *   - the arguments are cast to long and assigned into the target registers
1036  *     which are then simply passed as registers to the asm code, so that we
1037  *     don't have to experience issues with register constraints.
1038  */
1039
1040 #define my_syscall0(num)                                                      \
1041 ({                                                                            \
1042         register long _num asm("v0") = (num);                                 \
1043         register long _arg4 asm("a3");                                        \
1044                                                                               \
1045         asm volatile (                                                        \
1046                 "addiu $sp, $sp, -32\n"                                       \
1047                 "syscall\n"                                                   \
1048                 "addiu $sp, $sp, 32\n"                                        \
1049                 : "=r"(_num), "=r"(_arg4)                                     \
1050                 : "r"(_num)                                                   \
1051                 : "memory", "cc", "at", "v1", "hi", "lo",                     \
1052                   "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", "t8", "t9"  \
1053         );                                                                    \
1054         _arg4 ? -_num : _num;                                                 \
1055 })
1056
1057 #define my_syscall1(num, arg1)                                                \
1058 ({                                                                            \
1059         register long _num asm("v0") = (num);                                 \
1060         register long _arg1 asm("a0") = (long)(arg1);                         \
1061         register long _arg4 asm("a3");                                        \
1062                                                                               \
1063         asm volatile (                                                        \
1064                 "addiu $sp, $sp, -32\n"                                       \
1065                 "syscall\n"                                                   \
1066                 "addiu $sp, $sp, 32\n"                                        \
1067                 : "=r"(_num), "=r"(_arg4)                                     \
1068                 : "0"(_num),                                                  \
1069                   "r"(_arg1)                                                  \
1070                 : "memory", "cc", "at", "v1", "hi", "lo",                     \
1071                   "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", "t8", "t9"  \
1072         );                                                                    \
1073         _arg4 ? -_num : _num;                                                 \
1074 })
1075
1076 #define my_syscall2(num, arg1, arg2)                                          \
1077 ({                                                                            \
1078         register long _num asm("v0") = (num);                                 \
1079         register long _arg1 asm("a0") = (long)(arg1);                         \
1080         register long _arg2 asm("a1") = (long)(arg2);                         \
1081         register long _arg4 asm("a3");                                        \
1082                                                                               \
1083         asm volatile (                                                        \
1084                 "addiu $sp, $sp, -32\n"                                       \
1085                 "syscall\n"                                                   \
1086                 "addiu $sp, $sp, 32\n"                                        \
1087                 : "=r"(_num), "=r"(_arg4)                                     \
1088                 : "0"(_num),                                                  \
1089                   "r"(_arg1), "r"(_arg2)                                      \
1090                 : "memory", "cc", "at", "v1", "hi", "lo",                     \
1091                   "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", "t8", "t9"  \
1092         );                                                                    \
1093         _arg4 ? -_num : _num;                                                 \
1094 })
1095
1096 #define my_syscall3(num, arg1, arg2, arg3)                                    \
1097 ({                                                                            \
1098         register long _num asm("v0")  = (num);                                \
1099         register long _arg1 asm("a0") = (long)(arg1);                         \
1100         register long _arg2 asm("a1") = (long)(arg2);                         \
1101         register long _arg3 asm("a2") = (long)(arg3);                         \
1102         register long _arg4 asm("a3");                                        \
1103                                                                               \
1104         asm volatile (                                                        \
1105                 "addiu $sp, $sp, -32\n"                                       \
1106                 "syscall\n"                                                   \
1107                 "addiu $sp, $sp, 32\n"                                        \
1108                 : "=r"(_num), "=r"(_arg4)                                     \
1109                 : "0"(_num),                                                  \
1110                   "r"(_arg1), "r"(_arg2), "r"(_arg3)                          \
1111                 : "memory", "cc", "at", "v1", "hi", "lo",                     \
1112                   "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", "t8", "t9"  \
1113         );                                                                    \
1114         _arg4 ? -_num : _num;                                                 \
1115 })
1116
1117 #define my_syscall4(num, arg1, arg2, arg3, arg4)                              \
1118 ({                                                                            \
1119         register long _num asm("v0") = (num);                                 \
1120         register long _arg1 asm("a0") = (long)(arg1);                         \
1121         register long _arg2 asm("a1") = (long)(arg2);                         \
1122         register long _arg3 asm("a2") = (long)(arg3);                         \
1123         register long _arg4 asm("a3") = (long)(arg4);                         \
1124                                                                               \
1125         asm volatile (                                                        \
1126                 "addiu $sp, $sp, -32\n"                                       \
1127                 "syscall\n"                                                   \
1128                 "addiu $sp, $sp, 32\n"                                        \
1129                 : "=r" (_num), "=r"(_arg4)                                    \
1130                 : "0"(_num),                                                  \
1131                   "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg4)              \
1132                 : "memory", "cc", "at", "v1", "hi", "lo",                     \
1133                   "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", "t8", "t9"  \
1134         );                                                                    \
1135         _arg4 ? -_num : _num;                                                 \
1136 })
1137
1138 #define my_syscall5(num, arg1, arg2, arg3, arg4, arg5)                        \
1139 ({                                                                            \
1140         register long _num asm("v0") = (num);                                 \
1141         register long _arg1 asm("a0") = (long)(arg1);                         \
1142         register long _arg2 asm("a1") = (long)(arg2);                         \
1143         register long _arg3 asm("a2") = (long)(arg3);                         \
1144         register long _arg4 asm("a3") = (long)(arg4);                         \
1145         register long _arg5 = (long)(arg5);                                   \
1146                                                                               \
1147         asm volatile (                                                        \
1148                 "addiu $sp, $sp, -32\n"                                       \
1149                 "sw %7, 16($sp)\n"                                            \
1150                 "syscall\n  "                                                 \
1151                 "addiu $sp, $sp, 32\n"                                        \
1152                 : "=r" (_num), "=r"(_arg4)                                    \
1153                 : "0"(_num),                                                  \
1154                   "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg4), "r"(_arg5)  \
1155                 : "memory", "cc", "at", "v1", "hi", "lo",                     \
1156                   "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", "t8", "t9"  \
1157         );                                                                    \
1158         _arg4 ? -_num : _num;                                                 \
1159 })
1160
1161 /* startup code, note that it's called __start on MIPS */
1162 asm(".section .text\n"
1163     ".set nomips16\n"
1164     ".global __start\n"
1165     ".set    noreorder\n"
1166     ".option pic0\n"
1167     ".ent __start\n"
1168     "__start:\n"
1169     "lw $a0,($sp)\n"              // argc was in the stack
1170     "addiu  $a1, $sp, 4\n"        // argv = sp + 4
1171     "sll $a2, $a0, 2\n"           // a2 = argc * 4
1172     "add   $a2, $a2, $a1\n"       // envp = argv + 4*argc ...
1173     "addiu $a2, $a2, 4\n"         //        ... + 4
1174     "li $t0, -8\n"
1175     "and $sp, $sp, $t0\n"         // sp must be 8-byte aligned
1176     "addiu $sp,$sp,-16\n"         // the callee expects to save a0..a3 there!
1177     "jal main\n"                  // main() returns the status code, we'll exit with it.
1178     "nop\n"                       // delayed slot
1179     "and $a0, $v0, 0xff\n"        // limit exit code to 8 bits
1180     "li $v0, 4001\n"              // NR_exit == 4001
1181     "syscall\n"
1182     ".end __start\n"
1183     "");
1184
1185 /* fcntl / open */
1186 #define O_RDONLY            0
1187 #define O_WRONLY            1
1188 #define O_RDWR              2
1189 #define O_APPEND       0x0008
1190 #define O_NONBLOCK     0x0080
1191 #define O_CREAT        0x0100
1192 #define O_TRUNC        0x0200
1193 #define O_EXCL         0x0400
1194 #define O_NOCTTY       0x0800
1195 #define O_DIRECTORY   0x10000
1196
1197 /* The struct returned by the stat() syscall. 88 bytes are returned by the
1198  * syscall.
1199  */
1200 struct sys_stat_struct {
1201         unsigned int  st_dev;
1202         long          st_pad1[3];
1203         unsigned long st_ino;
1204         unsigned int  st_mode;
1205         unsigned int  st_nlink;
1206         unsigned int  st_uid;
1207         unsigned int  st_gid;
1208         unsigned int  st_rdev;
1209         long          st_pad2[2];
1210         long          st_size;
1211         long          st_pad3;
1212         long          st_atime;
1213         long          st_atime_nsec;
1214         long          st_mtime;
1215         long          st_mtime_nsec;
1216         long          st_ctime;
1217         long          st_ctime_nsec;
1218         long          st_blksize;
1219         long          st_blocks;
1220         long          st_pad4[14];
1221 };
1222
1223 #elif defined(__riscv)
1224
1225 #if   __riscv_xlen == 64
1226 #define PTRLOG "3"
1227 #define SZREG  "8"
1228 #elif __riscv_xlen == 32
1229 #define PTRLOG "2"
1230 #define SZREG  "4"
1231 #endif
1232
1233 /* Syscalls for RISCV :
1234  *   - stack is 16-byte aligned
1235  *   - syscall number is passed in a7
1236  *   - arguments are in a0, a1, a2, a3, a4, a5
1237  *   - the system call is performed by calling ecall
1238  *   - syscall return comes in a0
1239  *   - the arguments are cast to long and assigned into the target
1240  *     registers which are then simply passed as registers to the asm code,
1241  *     so that we don't have to experience issues with register constraints.
1242  */
1243
1244 #define my_syscall0(num)                                                      \
1245 ({                                                                            \
1246         register long _num  asm("a7") = (num);                                \
1247         register long _arg1 asm("a0");                                        \
1248                                                                               \
1249         asm volatile (                                                        \
1250                 "ecall\n\t"                                                   \
1251                 : "=r"(_arg1)                                                 \
1252                 : "r"(_num)                                                   \
1253                 : "memory", "cc"                                              \
1254         );                                                                    \
1255         _arg1;                                                                \
1256 })
1257
1258 #define my_syscall1(num, arg1)                                                \
1259 ({                                                                            \
1260         register long _num  asm("a7") = (num);                                \
1261         register long _arg1 asm("a0") = (long)(arg1);                         \
1262                                                                               \
1263         asm volatile (                                                        \
1264                 "ecall\n"                                                     \
1265                 : "+r"(_arg1)                                                 \
1266                 : "r"(_num)                                                   \
1267                 : "memory", "cc"                                              \
1268         );                                                                    \
1269         _arg1;                                                                \
1270 })
1271
1272 #define my_syscall2(num, arg1, arg2)                                          \
1273 ({                                                                            \
1274         register long _num  asm("a7") = (num);                                \
1275         register long _arg1 asm("a0") = (long)(arg1);                         \
1276         register long _arg2 asm("a1") = (long)(arg2);                         \
1277                                                                               \
1278         asm volatile (                                                        \
1279                 "ecall\n"                                                     \
1280                 : "+r"(_arg1)                                                 \
1281                 : "r"(_arg2),                                                 \
1282                   "r"(_num)                                                   \
1283                 : "memory", "cc"                                              \
1284         );                                                                    \
1285         _arg1;                                                                \
1286 })
1287
1288 #define my_syscall3(num, arg1, arg2, arg3)                                    \
1289 ({                                                                            \
1290         register long _num  asm("a7") = (num);                                \
1291         register long _arg1 asm("a0") = (long)(arg1);                         \
1292         register long _arg2 asm("a1") = (long)(arg2);                         \
1293         register long _arg3 asm("a2") = (long)(arg3);                         \
1294                                                                               \
1295         asm volatile (                                                        \
1296                 "ecall\n\t"                                                   \
1297                 : "+r"(_arg1)                                                 \
1298                 : "r"(_arg2), "r"(_arg3),                                     \
1299                   "r"(_num)                                                   \
1300                 : "memory", "cc"                                              \
1301         );                                                                    \
1302         _arg1;                                                                \
1303 })
1304
1305 #define my_syscall4(num, arg1, arg2, arg3, arg4)                              \
1306 ({                                                                            \
1307         register long _num  asm("a7") = (num);                                \
1308         register long _arg1 asm("a0") = (long)(arg1);                         \
1309         register long _arg2 asm("a1") = (long)(arg2);                         \
1310         register long _arg3 asm("a2") = (long)(arg3);                         \
1311         register long _arg4 asm("a3") = (long)(arg4);                         \
1312                                                                               \
1313         asm volatile (                                                        \
1314                 "ecall\n"                                                     \
1315                 : "+r"(_arg1)                                                 \
1316                 : "r"(_arg2), "r"(_arg3), "r"(_arg4),                         \
1317                   "r"(_num)                                                   \
1318                 : "memory", "cc"                                              \
1319         );                                                                    \
1320         _arg1;                                                                \
1321 })
1322
1323 #define my_syscall5(num, arg1, arg2, arg3, arg4, arg5)                        \
1324 ({                                                                            \
1325         register long _num  asm("a7") = (num);                                \
1326         register long _arg1 asm("a0") = (long)(arg1);                         \
1327         register long _arg2 asm("a1") = (long)(arg2);                         \
1328         register long _arg3 asm("a2") = (long)(arg3);                         \
1329         register long _arg4 asm("a3") = (long)(arg4);                         \
1330         register long _arg5 asm("a4") = (long)(arg5);                         \
1331                                                                               \
1332         asm volatile (                                                        \
1333                 "ecall\n"                                                     \
1334                 : "+r"(_arg1)                                                 \
1335                 : "r"(_arg2), "r"(_arg3), "r"(_arg4), "r"(_arg5),             \
1336                   "r"(_num)                                                   \
1337                 : "memory", "cc"                                              \
1338         );                                                                    \
1339         _arg1;                                                                \
1340 })
1341
1342 #define my_syscall6(num, arg1, arg2, arg3, arg4, arg5, arg6)                  \
1343 ({                                                                            \
1344         register long _num  asm("a7") = (num);                                \
1345         register long _arg1 asm("a0") = (long)(arg1);                         \
1346         register long _arg2 asm("a1") = (long)(arg2);                         \
1347         register long _arg3 asm("a2") = (long)(arg3);                         \
1348         register long _arg4 asm("a3") = (long)(arg4);                         \
1349         register long _arg5 asm("a4") = (long)(arg5);                         \
1350         register long _arg6 asm("a5") = (long)(arg6);                         \
1351                                                                               \
1352         asm volatile (                                                        \
1353                 "ecall\n"                                                     \
1354                 : "+r"(_arg1)                                                 \
1355                 : "r"(_arg2), "r"(_arg3), "r"(_arg4), "r"(_arg5), "r"(_arg6), \
1356                   "r"(_num)                                                   \
1357                 : "memory", "cc"                                              \
1358         );                                                                    \
1359         _arg1;                                                                \
1360 })
1361
1362 /* startup code */
1363 asm(".section .text\n"
1364     ".global _start\n"
1365     "_start:\n"
1366     ".option push\n"
1367     ".option norelax\n"
1368     "lla   gp, __global_pointer$\n"
1369     ".option pop\n"
1370     "ld    a0, 0(sp)\n"          // argc (a0) was in the stack
1371     "add   a1, sp, "SZREG"\n"    // argv (a1) = sp
1372     "slli  a2, a0, "PTRLOG"\n"   // envp (a2) = SZREG*argc ...
1373     "add   a2, a2, "SZREG"\n"    //             + SZREG (skip null)
1374     "add   a2,a2,a1\n"           //             + argv
1375     "andi  sp,a1,-16\n"          // sp must be 16-byte aligned
1376     "call  main\n"               // main() returns the status code, we'll exit with it.
1377     "andi  a0, a0, 0xff\n"       // limit exit code to 8 bits
1378     "li a7, 93\n"                // NR_exit == 93
1379     "ecall\n"
1380     "");
1381
1382 /* fcntl / open */
1383 #define O_RDONLY            0
1384 #define O_WRONLY            1
1385 #define O_RDWR              2
1386 #define O_CREAT         0x100
1387 #define O_EXCL          0x200
1388 #define O_NOCTTY        0x400
1389 #define O_TRUNC        0x1000
1390 #define O_APPEND       0x2000
1391 #define O_NONBLOCK     0x4000
1392 #define O_DIRECTORY  0x200000
1393
1394 struct sys_stat_struct {
1395         unsigned long   st_dev;         /* Device.  */
1396         unsigned long   st_ino;         /* File serial number.  */
1397         unsigned int    st_mode;        /* File mode.  */
1398         unsigned int    st_nlink;       /* Link count.  */
1399         unsigned int    st_uid;         /* User ID of the file's owner.  */
1400         unsigned int    st_gid;         /* Group ID of the file's group. */
1401         unsigned long   st_rdev;        /* Device number, if device.  */
1402         unsigned long   __pad1;
1403         long            st_size;        /* Size of file, in bytes.  */
1404         int             st_blksize;     /* Optimal block size for I/O.  */
1405         int             __pad2;
1406         long            st_blocks;      /* Number 512-byte blocks allocated. */
1407         long            st_atime;       /* Time of last access.  */
1408         unsigned long   st_atime_nsec;
1409         long            st_mtime;       /* Time of last modification.  */
1410         unsigned long   st_mtime_nsec;
1411         long            st_ctime;       /* Time of last status change.  */
1412         unsigned long   st_ctime_nsec;
1413         unsigned int    __unused4;
1414         unsigned int    __unused5;
1415 };
1416
1417 #endif
1418
1419
1420 /* Below are the C functions used to declare the raw syscalls. They try to be
1421  * architecture-agnostic, and return either a success or -errno. Declaring them
1422  * static will lead to them being inlined in most cases, but it's still possible
1423  * to reference them by a pointer if needed.
1424  */
1425 static __attribute__((unused))
1426 void *sys_brk(void *addr)
1427 {
1428         return (void *)my_syscall1(__NR_brk, addr);
1429 }
1430
1431 static __attribute__((noreturn,unused))
1432 void sys_exit(int status)
1433 {
1434         my_syscall1(__NR_exit, status & 255);
1435         while(1); // shut the "noreturn" warnings.
1436 }
1437
1438 static __attribute__((unused))
1439 int sys_chdir(const char *path)
1440 {
1441         return my_syscall1(__NR_chdir, path);
1442 }
1443
1444 static __attribute__((unused))
1445 int sys_chmod(const char *path, mode_t mode)
1446 {
1447 #ifdef __NR_fchmodat
1448         return my_syscall4(__NR_fchmodat, AT_FDCWD, path, mode, 0);
1449 #elif defined(__NR_chmod)
1450         return my_syscall2(__NR_chmod, path, mode);
1451 #else
1452 #error Neither __NR_fchmodat nor __NR_chmod defined, cannot implement sys_chmod()
1453 #endif
1454 }
1455
1456 static __attribute__((unused))
1457 int sys_chown(const char *path, uid_t owner, gid_t group)
1458 {
1459 #ifdef __NR_fchownat
1460         return my_syscall5(__NR_fchownat, AT_FDCWD, path, owner, group, 0);
1461 #elif defined(__NR_chown)
1462         return my_syscall3(__NR_chown, path, owner, group);
1463 #else
1464 #error Neither __NR_fchownat nor __NR_chown defined, cannot implement sys_chown()
1465 #endif
1466 }
1467
1468 static __attribute__((unused))
1469 int sys_chroot(const char *path)
1470 {
1471         return my_syscall1(__NR_chroot, path);
1472 }
1473
1474 static __attribute__((unused))
1475 int sys_close(int fd)
1476 {
1477         return my_syscall1(__NR_close, fd);
1478 }
1479
1480 static __attribute__((unused))
1481 int sys_dup(int fd)
1482 {
1483         return my_syscall1(__NR_dup, fd);
1484 }
1485
1486 #ifdef __NR_dup3
1487 static __attribute__((unused))
1488 int sys_dup3(int old, int new, int flags)
1489 {
1490         return my_syscall3(__NR_dup3, old, new, flags);
1491 }
1492 #endif
1493
1494 static __attribute__((unused))
1495 int sys_dup2(int old, int new)
1496 {
1497 #ifdef __NR_dup3
1498         return my_syscall3(__NR_dup3, old, new, 0);
1499 #elif defined(__NR_dup2)
1500         return my_syscall2(__NR_dup2, old, new);
1501 #else
1502 #error Neither __NR_dup3 nor __NR_dup2 defined, cannot implement sys_dup2()
1503 #endif
1504 }
1505
1506 static __attribute__((unused))
1507 int sys_execve(const char *filename, char *const argv[], char *const envp[])
1508 {
1509         return my_syscall3(__NR_execve, filename, argv, envp);
1510 }
1511
1512 static __attribute__((unused))
1513 pid_t sys_fork(void)
1514 {
1515 #ifdef __NR_clone
1516         /* note: some archs only have clone() and not fork(). Different archs
1517          * have a different API, but most archs have the flags on first arg and
1518          * will not use the rest with no other flag.
1519          */
1520         return my_syscall5(__NR_clone, SIGCHLD, 0, 0, 0, 0);
1521 #elif defined(__NR_fork)
1522         return my_syscall0(__NR_fork);
1523 #else
1524 #error Neither __NR_clone nor __NR_fork defined, cannot implement sys_fork()
1525 #endif
1526 }
1527
1528 static __attribute__((unused))
1529 int sys_fsync(int fd)
1530 {
1531         return my_syscall1(__NR_fsync, fd);
1532 }
1533
1534 static __attribute__((unused))
1535 int sys_getdents64(int fd, struct linux_dirent64 *dirp, int count)
1536 {
1537         return my_syscall3(__NR_getdents64, fd, dirp, count);
1538 }
1539
1540 static __attribute__((unused))
1541 pid_t sys_getpgid(pid_t pid)
1542 {
1543         return my_syscall1(__NR_getpgid, pid);
1544 }
1545
1546 static __attribute__((unused))
1547 pid_t sys_getpgrp(void)
1548 {
1549         return sys_getpgid(0);
1550 }
1551
1552 static __attribute__((unused))
1553 pid_t sys_getpid(void)
1554 {
1555         return my_syscall0(__NR_getpid);
1556 }
1557
1558 static __attribute__((unused))
1559 int sys_gettimeofday(struct timeval *tv, struct timezone *tz)
1560 {
1561         return my_syscall2(__NR_gettimeofday, tv, tz);
1562 }
1563
1564 static __attribute__((unused))
1565 int sys_ioctl(int fd, unsigned long req, void *value)
1566 {
1567         return my_syscall3(__NR_ioctl, fd, req, value);
1568 }
1569
1570 static __attribute__((unused))
1571 int sys_kill(pid_t pid, int signal)
1572 {
1573         return my_syscall2(__NR_kill, pid, signal);
1574 }
1575
1576 static __attribute__((unused))
1577 int sys_link(const char *old, const char *new)
1578 {
1579 #ifdef __NR_linkat
1580         return my_syscall5(__NR_linkat, AT_FDCWD, old, AT_FDCWD, new, 0);
1581 #elif defined(__NR_link)
1582         return my_syscall2(__NR_link, old, new);
1583 #else
1584 #error Neither __NR_linkat nor __NR_link defined, cannot implement sys_link()
1585 #endif
1586 }
1587
1588 static __attribute__((unused))
1589 off_t sys_lseek(int fd, off_t offset, int whence)
1590 {
1591         return my_syscall3(__NR_lseek, fd, offset, whence);
1592 }
1593
1594 static __attribute__((unused))
1595 int sys_mkdir(const char *path, mode_t mode)
1596 {
1597 #ifdef __NR_mkdirat
1598         return my_syscall3(__NR_mkdirat, AT_FDCWD, path, mode);
1599 #elif defined(__NR_mkdir)
1600         return my_syscall2(__NR_mkdir, path, mode);
1601 #else
1602 #error Neither __NR_mkdirat nor __NR_mkdir defined, cannot implement sys_mkdir()
1603 #endif
1604 }
1605
1606 static __attribute__((unused))
1607 long sys_mknod(const char *path, mode_t mode, dev_t dev)
1608 {
1609 #ifdef __NR_mknodat
1610         return my_syscall4(__NR_mknodat, AT_FDCWD, path, mode, dev);
1611 #elif defined(__NR_mknod)
1612         return my_syscall3(__NR_mknod, path, mode, dev);
1613 #else
1614 #error Neither __NR_mknodat nor __NR_mknod defined, cannot implement sys_mknod()
1615 #endif
1616 }
1617
1618 static __attribute__((unused))
1619 int sys_mount(const char *src, const char *tgt, const char *fst,
1620               unsigned long flags, const void *data)
1621 {
1622         return my_syscall5(__NR_mount, src, tgt, fst, flags, data);
1623 }
1624
1625 static __attribute__((unused))
1626 int sys_open(const char *path, int flags, mode_t mode)
1627 {
1628 #ifdef __NR_openat
1629         return my_syscall4(__NR_openat, AT_FDCWD, path, flags, mode);
1630 #elif defined(__NR_open)
1631         return my_syscall3(__NR_open, path, flags, mode);
1632 #else
1633 #error Neither __NR_openat nor __NR_open defined, cannot implement sys_open()
1634 #endif
1635 }
1636
1637 static __attribute__((unused))
1638 int sys_pivot_root(const char *new, const char *old)
1639 {
1640         return my_syscall2(__NR_pivot_root, new, old);
1641 }
1642
1643 static __attribute__((unused))
1644 int sys_poll(struct pollfd *fds, int nfds, int timeout)
1645 {
1646 #if defined(__NR_ppoll)
1647         struct timespec t;
1648
1649         if (timeout >= 0) {
1650                 t.tv_sec  = timeout / 1000;
1651                 t.tv_nsec = (timeout % 1000) * 1000000;
1652         }
1653         return my_syscall4(__NR_ppoll, fds, nfds, (timeout >= 0) ? &t : NULL, NULL);
1654 #elif defined(__NR_poll)
1655         return my_syscall3(__NR_poll, fds, nfds, timeout);
1656 #else
1657 #error Neither __NR_ppoll nor __NR_poll defined, cannot implement sys_poll()
1658 #endif
1659 }
1660
1661 static __attribute__((unused))
1662 ssize_t sys_read(int fd, void *buf, size_t count)
1663 {
1664         return my_syscall3(__NR_read, fd, buf, count);
1665 }
1666
1667 static __attribute__((unused))
1668 ssize_t sys_reboot(int magic1, int magic2, int cmd, void *arg)
1669 {
1670         return my_syscall4(__NR_reboot, magic1, magic2, cmd, arg);
1671 }
1672
1673 static __attribute__((unused))
1674 int sys_sched_yield(void)
1675 {
1676         return my_syscall0(__NR_sched_yield);
1677 }
1678
1679 static __attribute__((unused))
1680 int sys_select(int nfds, fd_set *rfds, fd_set *wfds, fd_set *efds, struct timeval *timeout)
1681 {
1682 #if defined(__ARCH_WANT_SYS_OLD_SELECT) && !defined(__NR__newselect)
1683         struct sel_arg_struct {
1684                 unsigned long n;
1685                 fd_set *r, *w, *e;
1686                 struct timeval *t;
1687         } arg = { .n = nfds, .r = rfds, .w = wfds, .e = efds, .t = timeout };
1688         return my_syscall1(__NR_select, &arg);
1689 #elif defined(__ARCH_WANT_SYS_PSELECT6) && defined(__NR_pselect6)
1690         struct timespec t;
1691
1692         if (timeout) {
1693                 t.tv_sec  = timeout->tv_sec;
1694                 t.tv_nsec = timeout->tv_usec * 1000;
1695         }
1696         return my_syscall6(__NR_pselect6, nfds, rfds, wfds, efds, timeout ? &t : NULL, NULL);
1697 #elif defined(__NR__newselect) || defined(__NR_select)
1698 #ifndef __NR__newselect
1699 #define __NR__newselect __NR_select
1700 #endif
1701         return my_syscall5(__NR__newselect, nfds, rfds, wfds, efds, timeout);
1702 #else
1703 #error None of __NR_select, __NR_pselect6, nor __NR__newselect defined, cannot implement sys_select()
1704 #endif
1705 }
1706
1707 static __attribute__((unused))
1708 int sys_setpgid(pid_t pid, pid_t pgid)
1709 {
1710         return my_syscall2(__NR_setpgid, pid, pgid);
1711 }
1712
1713 static __attribute__((unused))
1714 pid_t sys_setsid(void)
1715 {
1716         return my_syscall0(__NR_setsid);
1717 }
1718
1719 static __attribute__((unused))
1720 int sys_stat(const char *path, struct stat *buf)
1721 {
1722         struct sys_stat_struct stat;
1723         long ret;
1724
1725 #ifdef __NR_newfstatat
1726         /* only solution for arm64 */
1727         ret = my_syscall4(__NR_newfstatat, AT_FDCWD, path, &stat, 0);
1728 #elif defined(__NR_stat)
1729         ret = my_syscall2(__NR_stat, path, &stat);
1730 #else
1731 #error Neither __NR_newfstatat nor __NR_stat defined, cannot implement sys_stat()
1732 #endif
1733         buf->st_dev     = stat.st_dev;
1734         buf->st_ino     = stat.st_ino;
1735         buf->st_mode    = stat.st_mode;
1736         buf->st_nlink   = stat.st_nlink;
1737         buf->st_uid     = stat.st_uid;
1738         buf->st_gid     = stat.st_gid;
1739         buf->st_rdev    = stat.st_rdev;
1740         buf->st_size    = stat.st_size;
1741         buf->st_blksize = stat.st_blksize;
1742         buf->st_blocks  = stat.st_blocks;
1743         buf->st_atime   = stat.st_atime;
1744         buf->st_mtime   = stat.st_mtime;
1745         buf->st_ctime   = stat.st_ctime;
1746         return ret;
1747 }
1748
1749
1750 static __attribute__((unused))
1751 int sys_symlink(const char *old, const char *new)
1752 {
1753 #ifdef __NR_symlinkat
1754         return my_syscall3(__NR_symlinkat, old, AT_FDCWD, new);
1755 #elif defined(__NR_symlink)
1756         return my_syscall2(__NR_symlink, old, new);
1757 #else
1758 #error Neither __NR_symlinkat nor __NR_symlink defined, cannot implement sys_symlink()
1759 #endif
1760 }
1761
1762 static __attribute__((unused))
1763 mode_t sys_umask(mode_t mode)
1764 {
1765         return my_syscall1(__NR_umask, mode);
1766 }
1767
1768 static __attribute__((unused))
1769 int sys_umount2(const char *path, int flags)
1770 {
1771         return my_syscall2(__NR_umount2, path, flags);
1772 }
1773
1774 static __attribute__((unused))
1775 int sys_unlink(const char *path)
1776 {
1777 #ifdef __NR_unlinkat
1778         return my_syscall3(__NR_unlinkat, AT_FDCWD, path, 0);
1779 #elif defined(__NR_unlink)
1780         return my_syscall1(__NR_unlink, path);
1781 #else
1782 #error Neither __NR_unlinkat nor __NR_unlink defined, cannot implement sys_unlink()
1783 #endif
1784 }
1785
1786 static __attribute__((unused))
1787 pid_t sys_wait4(pid_t pid, int *status, int options, struct rusage *rusage)
1788 {
1789         return my_syscall4(__NR_wait4, pid, status, options, rusage);
1790 }
1791
1792 static __attribute__((unused))
1793 pid_t sys_waitpid(pid_t pid, int *status, int options)
1794 {
1795         return sys_wait4(pid, status, options, 0);
1796 }
1797
1798 static __attribute__((unused))
1799 pid_t sys_wait(int *status)
1800 {
1801         return sys_waitpid(-1, status, 0);
1802 }
1803
1804 static __attribute__((unused))
1805 ssize_t sys_write(int fd, const void *buf, size_t count)
1806 {
1807         return my_syscall3(__NR_write, fd, buf, count);
1808 }
1809
1810
1811 /* Below are the libc-compatible syscalls which return x or -1 and set errno.
1812  * They rely on the functions above. Similarly they're marked static so that it
1813  * is possible to assign pointers to them if needed.
1814  */
1815
1816 static __attribute__((unused))
1817 int brk(void *addr)
1818 {
1819         void *ret = sys_brk(addr);
1820
1821         if (!ret) {
1822                 SET_ERRNO(ENOMEM);
1823                 return -1;
1824         }
1825         return 0;
1826 }
1827
1828 static __attribute__((noreturn,unused))
1829 void exit(int status)
1830 {
1831         sys_exit(status);
1832 }
1833
1834 static __attribute__((unused))
1835 int chdir(const char *path)
1836 {
1837         int ret = sys_chdir(path);
1838
1839         if (ret < 0) {
1840                 SET_ERRNO(-ret);
1841                 ret = -1;
1842         }
1843         return ret;
1844 }
1845
1846 static __attribute__((unused))
1847 int chmod(const char *path, mode_t mode)
1848 {
1849         int ret = sys_chmod(path, mode);
1850
1851         if (ret < 0) {
1852                 SET_ERRNO(-ret);
1853                 ret = -1;
1854         }
1855         return ret;
1856 }
1857
1858 static __attribute__((unused))
1859 int chown(const char *path, uid_t owner, gid_t group)
1860 {
1861         int ret = sys_chown(path, owner, group);
1862
1863         if (ret < 0) {
1864                 SET_ERRNO(-ret);
1865                 ret = -1;
1866         }
1867         return ret;
1868 }
1869
1870 static __attribute__((unused))
1871 int chroot(const char *path)
1872 {
1873         int ret = sys_chroot(path);
1874
1875         if (ret < 0) {
1876                 SET_ERRNO(-ret);
1877                 ret = -1;
1878         }
1879         return ret;
1880 }
1881
1882 static __attribute__((unused))
1883 int close(int fd)
1884 {
1885         int ret = sys_close(fd);
1886
1887         if (ret < 0) {
1888                 SET_ERRNO(-ret);
1889                 ret = -1;
1890         }
1891         return ret;
1892 }
1893
1894 static __attribute__((unused))
1895 int dup(int fd)
1896 {
1897         int ret = sys_dup(fd);
1898
1899         if (ret < 0) {
1900                 SET_ERRNO(-ret);
1901                 ret = -1;
1902         }
1903         return ret;
1904 }
1905
1906 static __attribute__((unused))
1907 int dup2(int old, int new)
1908 {
1909         int ret = sys_dup2(old, new);
1910
1911         if (ret < 0) {
1912                 SET_ERRNO(-ret);
1913                 ret = -1;
1914         }
1915         return ret;
1916 }
1917
1918 #ifdef __NR_dup3
1919 static __attribute__((unused))
1920 int dup3(int old, int new, int flags)
1921 {
1922         int ret = sys_dup3(old, new, flags);
1923
1924         if (ret < 0) {
1925                 SET_ERRNO(-ret);
1926                 ret = -1;
1927         }
1928         return ret;
1929 }
1930 #endif
1931
1932 static __attribute__((unused))
1933 int execve(const char *filename, char *const argv[], char *const envp[])
1934 {
1935         int ret = sys_execve(filename, argv, envp);
1936
1937         if (ret < 0) {
1938                 SET_ERRNO(-ret);
1939                 ret = -1;
1940         }
1941         return ret;
1942 }
1943
1944 static __attribute__((unused))
1945 pid_t fork(void)
1946 {
1947         pid_t ret = sys_fork();
1948
1949         if (ret < 0) {
1950                 SET_ERRNO(-ret);
1951                 ret = -1;
1952         }
1953         return ret;
1954 }
1955
1956 static __attribute__((unused))
1957 int fsync(int fd)
1958 {
1959         int ret = sys_fsync(fd);
1960
1961         if (ret < 0) {
1962                 SET_ERRNO(-ret);
1963                 ret = -1;
1964         }
1965         return ret;
1966 }
1967
1968 static __attribute__((unused))
1969 int getdents64(int fd, struct linux_dirent64 *dirp, int count)
1970 {
1971         int ret = sys_getdents64(fd, dirp, count);
1972
1973         if (ret < 0) {
1974                 SET_ERRNO(-ret);
1975                 ret = -1;
1976         }
1977         return ret;
1978 }
1979
1980 static __attribute__((unused))
1981 pid_t getpgid(pid_t pid)
1982 {
1983         pid_t ret = sys_getpgid(pid);
1984
1985         if (ret < 0) {
1986                 SET_ERRNO(-ret);
1987                 ret = -1;
1988         }
1989         return ret;
1990 }
1991
1992 static __attribute__((unused))
1993 pid_t getpgrp(void)
1994 {
1995         pid_t ret = sys_getpgrp();
1996
1997         if (ret < 0) {
1998                 SET_ERRNO(-ret);
1999                 ret = -1;
2000         }
2001         return ret;
2002 }
2003
2004 static __attribute__((unused))
2005 pid_t getpid(void)
2006 {
2007         pid_t ret = sys_getpid();
2008
2009         if (ret < 0) {
2010                 SET_ERRNO(-ret);
2011                 ret = -1;
2012         }
2013         return ret;
2014 }
2015
2016 static __attribute__((unused))
2017 int gettimeofday(struct timeval *tv, struct timezone *tz)
2018 {
2019         int ret = sys_gettimeofday(tv, tz);
2020
2021         if (ret < 0) {
2022                 SET_ERRNO(-ret);
2023                 ret = -1;
2024         }
2025         return ret;
2026 }
2027
2028 static __attribute__((unused))
2029 int ioctl(int fd, unsigned long req, void *value)
2030 {
2031         int ret = sys_ioctl(fd, req, value);
2032
2033         if (ret < 0) {
2034                 SET_ERRNO(-ret);
2035                 ret = -1;
2036         }
2037         return ret;
2038 }
2039
2040 static __attribute__((unused))
2041 int kill(pid_t pid, int signal)
2042 {
2043         int ret = sys_kill(pid, signal);
2044
2045         if (ret < 0) {
2046                 SET_ERRNO(-ret);
2047                 ret = -1;
2048         }
2049         return ret;
2050 }
2051
2052 static __attribute__((unused))
2053 int link(const char *old, const char *new)
2054 {
2055         int ret = sys_link(old, new);
2056
2057         if (ret < 0) {
2058                 SET_ERRNO(-ret);
2059                 ret = -1;
2060         }
2061         return ret;
2062 }
2063
2064 static __attribute__((unused))
2065 off_t lseek(int fd, off_t offset, int whence)
2066 {
2067         off_t ret = sys_lseek(fd, offset, whence);
2068
2069         if (ret < 0) {
2070                 SET_ERRNO(-ret);
2071                 ret = -1;
2072         }
2073         return ret;
2074 }
2075
2076 static __attribute__((unused))
2077 int mkdir(const char *path, mode_t mode)
2078 {
2079         int ret = sys_mkdir(path, mode);
2080
2081         if (ret < 0) {
2082                 SET_ERRNO(-ret);
2083                 ret = -1;
2084         }
2085         return ret;
2086 }
2087
2088 static __attribute__((unused))
2089 int mknod(const char *path, mode_t mode, dev_t dev)
2090 {
2091         int ret = sys_mknod(path, mode, dev);
2092
2093         if (ret < 0) {
2094                 SET_ERRNO(-ret);
2095                 ret = -1;
2096         }
2097         return ret;
2098 }
2099
2100 static __attribute__((unused))
2101 int mount(const char *src, const char *tgt,
2102           const char *fst, unsigned long flags,
2103           const void *data)
2104 {
2105         int ret = sys_mount(src, tgt, fst, flags, data);
2106
2107         if (ret < 0) {
2108                 SET_ERRNO(-ret);
2109                 ret = -1;
2110         }
2111         return ret;
2112 }
2113
2114 static __attribute__((unused))
2115 int open(const char *path, int flags, mode_t mode)
2116 {
2117         int ret = sys_open(path, flags, mode);
2118
2119         if (ret < 0) {
2120                 SET_ERRNO(-ret);
2121                 ret = -1;
2122         }
2123         return ret;
2124 }
2125
2126 static __attribute__((unused))
2127 int pivot_root(const char *new, const char *old)
2128 {
2129         int ret = sys_pivot_root(new, old);
2130
2131         if (ret < 0) {
2132                 SET_ERRNO(-ret);
2133                 ret = -1;
2134         }
2135         return ret;
2136 }
2137
2138 static __attribute__((unused))
2139 int poll(struct pollfd *fds, int nfds, int timeout)
2140 {
2141         int ret = sys_poll(fds, nfds, timeout);
2142
2143         if (ret < 0) {
2144                 SET_ERRNO(-ret);
2145                 ret = -1;
2146         }
2147         return ret;
2148 }
2149
2150 static __attribute__((unused))
2151 ssize_t read(int fd, void *buf, size_t count)
2152 {
2153         ssize_t ret = sys_read(fd, buf, count);
2154
2155         if (ret < 0) {
2156                 SET_ERRNO(-ret);
2157                 ret = -1;
2158         }
2159         return ret;
2160 }
2161
2162 static __attribute__((unused))
2163 int reboot(int cmd)
2164 {
2165         int ret = sys_reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, cmd, 0);
2166
2167         if (ret < 0) {
2168                 SET_ERRNO(-ret);
2169                 ret = -1;
2170         }
2171         return ret;
2172 }
2173
2174 static __attribute__((unused))
2175 void *sbrk(intptr_t inc)
2176 {
2177         void *ret;
2178
2179         /* first call to find current end */
2180         if ((ret = sys_brk(0)) && (sys_brk(ret + inc) == ret + inc))
2181                 return ret + inc;
2182
2183         SET_ERRNO(ENOMEM);
2184         return (void *)-1;
2185 }
2186
2187 static __attribute__((unused))
2188 int sched_yield(void)
2189 {
2190         int ret = sys_sched_yield();
2191
2192         if (ret < 0) {
2193                 SET_ERRNO(-ret);
2194                 ret = -1;
2195         }
2196         return ret;
2197 }
2198
2199 static __attribute__((unused))
2200 int select(int nfds, fd_set *rfds, fd_set *wfds, fd_set *efds, struct timeval *timeout)
2201 {
2202         int ret = sys_select(nfds, rfds, wfds, efds, timeout);
2203
2204         if (ret < 0) {
2205                 SET_ERRNO(-ret);
2206                 ret = -1;
2207         }
2208         return ret;
2209 }
2210
2211 static __attribute__((unused))
2212 int setpgid(pid_t pid, pid_t pgid)
2213 {
2214         int ret = sys_setpgid(pid, pgid);
2215
2216         if (ret < 0) {
2217                 SET_ERRNO(-ret);
2218                 ret = -1;
2219         }
2220         return ret;
2221 }
2222
2223 static __attribute__((unused))
2224 pid_t setsid(void)
2225 {
2226         pid_t ret = sys_setsid();
2227
2228         if (ret < 0) {
2229                 SET_ERRNO(-ret);
2230                 ret = -1;
2231         }
2232         return ret;
2233 }
2234
2235 static __attribute__((unused))
2236 unsigned int sleep(unsigned int seconds)
2237 {
2238         struct timeval my_timeval = { seconds, 0 };
2239
2240         if (sys_select(0, 0, 0, 0, &my_timeval) < 0)
2241                 return my_timeval.tv_sec + !!my_timeval.tv_usec;
2242         else
2243                 return 0;
2244 }
2245
2246 static __attribute__((unused))
2247 int msleep(unsigned int msecs)
2248 {
2249         struct timeval my_timeval = { msecs / 1000, (msecs % 1000) * 1000 };
2250
2251         if (sys_select(0, 0, 0, 0, &my_timeval) < 0)
2252                 return (my_timeval.tv_sec * 1000) +
2253                         (my_timeval.tv_usec / 1000) +
2254                         !!(my_timeval.tv_usec % 1000);
2255         else
2256                 return 0;
2257 }
2258
2259 static __attribute__((unused))
2260 int stat(const char *path, struct stat *buf)
2261 {
2262         int ret = sys_stat(path, buf);
2263
2264         if (ret < 0) {
2265                 SET_ERRNO(-ret);
2266                 ret = -1;
2267         }
2268         return ret;
2269 }
2270
2271 static __attribute__((unused))
2272 int symlink(const char *old, const char *new)
2273 {
2274         int ret = sys_symlink(old, new);
2275
2276         if (ret < 0) {
2277                 SET_ERRNO(-ret);
2278                 ret = -1;
2279         }
2280         return ret;
2281 }
2282
2283 static __attribute__((unused))
2284 int tcsetpgrp(int fd, pid_t pid)
2285 {
2286         return ioctl(fd, TIOCSPGRP, &pid);
2287 }
2288
2289 static __attribute__((unused))
2290 mode_t umask(mode_t mode)
2291 {
2292         return sys_umask(mode);
2293 }
2294
2295 static __attribute__((unused))
2296 int umount2(const char *path, int flags)
2297 {
2298         int ret = sys_umount2(path, flags);
2299
2300         if (ret < 0) {
2301                 SET_ERRNO(-ret);
2302                 ret = -1;
2303         }
2304         return ret;
2305 }
2306
2307 static __attribute__((unused))
2308 int unlink(const char *path)
2309 {
2310         int ret = sys_unlink(path);
2311
2312         if (ret < 0) {
2313                 SET_ERRNO(-ret);
2314                 ret = -1;
2315         }
2316         return ret;
2317 }
2318
2319 static __attribute__((unused))
2320 pid_t wait4(pid_t pid, int *status, int options, struct rusage *rusage)
2321 {
2322         pid_t ret = sys_wait4(pid, status, options, rusage);
2323
2324         if (ret < 0) {
2325                 SET_ERRNO(-ret);
2326                 ret = -1;
2327         }
2328         return ret;
2329 }
2330
2331 static __attribute__((unused))
2332 pid_t waitpid(pid_t pid, int *status, int options)
2333 {
2334         pid_t ret = sys_waitpid(pid, status, options);
2335
2336         if (ret < 0) {
2337                 SET_ERRNO(-ret);
2338                 ret = -1;
2339         }
2340         return ret;
2341 }
2342
2343 static __attribute__((unused))
2344 pid_t wait(int *status)
2345 {
2346         pid_t ret = sys_wait(status);
2347
2348         if (ret < 0) {
2349                 SET_ERRNO(-ret);
2350                 ret = -1;
2351         }
2352         return ret;
2353 }
2354
2355 static __attribute__((unused))
2356 ssize_t write(int fd, const void *buf, size_t count)
2357 {
2358         ssize_t ret = sys_write(fd, buf, count);
2359
2360         if (ret < 0) {
2361                 SET_ERRNO(-ret);
2362                 ret = -1;
2363         }
2364         return ret;
2365 }
2366
2367 /* some size-optimized reimplementations of a few common str* and mem*
2368  * functions. They're marked static, except memcpy() and raise() which are used
2369  * by libgcc on ARM, so they are marked weak instead in order not to cause an
2370  * error when building a program made of multiple files (not recommended).
2371  */
2372
2373 static __attribute__((unused))
2374 void *memmove(void *dst, const void *src, size_t len)
2375 {
2376         ssize_t pos = (dst <= src) ? -1 : (long)len;
2377         void *ret = dst;
2378
2379         while (len--) {
2380                 pos += (dst <= src) ? 1 : -1;
2381                 ((char *)dst)[pos] = ((char *)src)[pos];
2382         }
2383         return ret;
2384 }
2385
2386 static __attribute__((unused))
2387 void *memset(void *dst, int b, size_t len)
2388 {
2389         char *p = dst;
2390
2391         while (len--)
2392                 *(p++) = b;
2393         return dst;
2394 }
2395
2396 static __attribute__((unused))
2397 int memcmp(const void *s1, const void *s2, size_t n)
2398 {
2399         size_t ofs = 0;
2400         char c1 = 0;
2401
2402         while (ofs < n && !(c1 = ((char *)s1)[ofs] - ((char *)s2)[ofs])) {
2403                 ofs++;
2404         }
2405         return c1;
2406 }
2407
2408 static __attribute__((unused))
2409 char *strcpy(char *dst, const char *src)
2410 {
2411         char *ret = dst;
2412
2413         while ((*dst++ = *src++));
2414         return ret;
2415 }
2416
2417 static __attribute__((unused))
2418 char *strchr(const char *s, int c)
2419 {
2420         while (*s) {
2421                 if (*s == (char)c)
2422                         return (char *)s;
2423                 s++;
2424         }
2425         return NULL;
2426 }
2427
2428 static __attribute__((unused))
2429 char *strrchr(const char *s, int c)
2430 {
2431         const char *ret = NULL;
2432
2433         while (*s) {
2434                 if (*s == (char)c)
2435                         ret = s;
2436                 s++;
2437         }
2438         return (char *)ret;
2439 }
2440
2441 static __attribute__((unused))
2442 size_t nolibc_strlen(const char *str)
2443 {
2444         size_t len;
2445
2446         for (len = 0; str[len]; len++);
2447         return len;
2448 }
2449
2450 #define strlen(str) ({                          \
2451         __builtin_constant_p((str)) ?           \
2452                 __builtin_strlen((str)) :       \
2453                 nolibc_strlen((str));           \
2454 })
2455
2456 static __attribute__((unused))
2457 int isdigit(int c)
2458 {
2459         return (unsigned int)(c - '0') <= 9;
2460 }
2461
2462 static __attribute__((unused))
2463 long atol(const char *s)
2464 {
2465         unsigned long ret = 0;
2466         unsigned long d;
2467         int neg = 0;
2468
2469         if (*s == '-') {
2470                 neg = 1;
2471                 s++;
2472         }
2473
2474         while (1) {
2475                 d = (*s++) - '0';
2476                 if (d > 9)
2477                         break;
2478                 ret *= 10;
2479                 ret += d;
2480         }
2481
2482         return neg ? -ret : ret;
2483 }
2484
2485 static __attribute__((unused))
2486 int atoi(const char *s)
2487 {
2488         return atol(s);
2489 }
2490
2491 static __attribute__((unused))
2492 const char *ltoa(long in)
2493 {
2494         /* large enough for -9223372036854775808 */
2495         static char buffer[21];
2496         char       *pos = buffer + sizeof(buffer) - 1;
2497         int         neg = in < 0;
2498         unsigned long n = neg ? -in : in;
2499
2500         *pos-- = '\0';
2501         do {
2502                 *pos-- = '0' + n % 10;
2503                 n /= 10;
2504                 if (pos < buffer)
2505                         return pos + 1;
2506         } while (n);
2507
2508         if (neg)
2509                 *pos-- = '-';
2510         return pos + 1;
2511 }
2512
2513 __attribute__((weak,unused))
2514 void *memcpy(void *dst, const void *src, size_t len)
2515 {
2516         return memmove(dst, src, len);
2517 }
2518
2519 /* needed by libgcc for divide by zero */
2520 __attribute__((weak,unused))
2521 int raise(int signal)
2522 {
2523         return kill(getpid(), signal);
2524 }
2525
2526 /* Here come a few helper functions */
2527
2528 static __attribute__((unused))
2529 void FD_ZERO(fd_set *set)
2530 {
2531         memset(set, 0, sizeof(*set));
2532 }
2533
2534 static __attribute__((unused))
2535 void FD_SET(int fd, fd_set *set)
2536 {
2537         if (fd < 0 || fd >= FD_SETSIZE)
2538                 return;
2539         set->fd32[fd / 32] |= 1 << (fd & 31);
2540 }
2541
2542 /* WARNING, it only deals with the 4096 first majors and 256 first minors */
2543 static __attribute__((unused))
2544 dev_t makedev(unsigned int major, unsigned int minor)
2545 {
2546         return ((major & 0xfff) << 8) | (minor & 0xff);
2547 }