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