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