Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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