~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/tools/testing/selftests/rcutorture/bin/nolibc.h

Version: ~ [ linux-6.2-rc3 ] ~ [ linux-6.1.5 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.87 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.162 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.228 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.269 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.302 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.302 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

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

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp