Commit | Line | Data |
---|---|---|
66b6f755 WT |
1 | /* SPDX-License-Identifier: LGPL-2.1 OR MIT */ |
2 | /* nolibc.h | |
3 | * Copyright (C) 2017-2018 Willy Tarreau <w@1wt.eu> | |
4 | */ | |
5 | ||
cc72a509 WT |
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 | |
c4486e97 | 60 | * for a few functions usually found in string.h, ctype.h, or stdlib.h. |
cc72a509 | 61 | * |
c4486e97 WT |
62 | * The nolibc.h file is only a convenient entry point which includes all other |
63 | * files. It also defines the NOLIBC macro, so that it is possible for a | |
64 | * program to check this macro to know if it is being built against and decide | |
65 | * to disable some features or simply not to include some standard libc files. | |
cc72a509 WT |
66 | * |
67 | * A simple static executable may be built this way : | |
68 | * $ gcc -fno-asynchronous-unwind-tables -fno-ident -s -Os -nostdlib \ | |
3c6ce7a5 | 69 | * -static -include nolibc.h -o hello hello.c -lgcc |
cc72a509 | 70 | * |
c4486e97 WT |
71 | * Simple programs meant to be reasonably portable to various libc and using |
72 | * only a few common includes, may also be built by simply making the include | |
73 | * path point to the nolibc directory: | |
74 | * $ gcc -fno-asynchronous-unwind-tables -fno-ident -s -Os -nostdlib \ | |
75 | * -I../nolibc -o hello hello.c -lgcc | |
76 | * | |
77 | * The available standard (but limited) include files are: | |
78 | * ctype.h, errno.h, signal.h, stdio.h, stdlib.h, string.h, time.h | |
79 | * | |
80 | * In addition, the following ones are expected to be provided by the compiler: | |
81 | * float.h, stdarg.h, stddef.h | |
82 | * | |
83 | * The following ones which are part to the C standard are not provided: | |
84 | * assert.h, locale.h, math.h, setjmp.h, limits.h | |
85 | * | |
cc72a509 WT |
86 | * A very useful calling convention table may be found here : |
87 | * http://man7.org/linux/man-pages/man2/syscall.2.html | |
88 | * | |
89 | * This doc is quite convenient though not necessarily up to date : | |
90 | * https://w3challs.com/syscalls/ | |
91 | * | |
92 | */ | |
930c4acc WT |
93 | #ifndef _NOLIBC_H |
94 | #define _NOLIBC_H | |
cc72a509 | 95 | |
967cce19 | 96 | #include "std.h" |
271661c1 | 97 | #include "arch.h" |
cc7a492a | 98 | #include "types.h" |
bd8c8fbb | 99 | #include "sys.h" |
62a2af07 | 100 | #include "ctype.h" |
99cb50ab | 101 | #include "signal.h" |
4e383a66 | 102 | #include "stdio.h" |
06fdba53 | 103 | #include "stdlib.h" |
c91eb033 | 104 | #include "string.h" |
cec15053 | 105 | #include "time.h" |
4619de34 | 106 | #include "unistd.h" |
7188d463 | 107 | #include "stackprotector.h" |
66b6f755 | 108 | |
cc7a492a | 109 | /* Used by programs to avoid std includes */ |
66b6f755 WT |
110 | #define NOLIBC |
111 | ||
930c4acc | 112 | #endif /* _NOLIBC_H */ |