1 1.8 riastrad $NetBSD: README,v 1.8 2026/05/15 14:07:17 riastradh Exp $ 2 1.1 riastrad 3 1.1 riastrad libc: The C library. 4 1.1 riastrad 5 1.1 riastrad * ELF symbols and source names 6 1.1 riastrad 7 1.1 riastrad libc contains symbols for: 8 1.1 riastrad 9 1.1 riastrad (a) standard library routines in C and POSIX, 10 1.1 riastrad (b) published NetBSD-specific nonstandard extensions, 11 1.4 riastrad (c) internal symbols, and 12 1.4 riastrad (d) old versions of any published library routines. 13 1.4 riastrad 14 1.4 riastrad ** Standard library routines 15 1.1 riastrad 16 1.1 riastrad If a library routine is standard and its signature has never changed, 17 1.5 riastrad it is provided as an ELF global symbol. Its name is declared normally 18 1.1 riastrad in the appropriate header file. 19 1.1 riastrad 20 1.5 riastrad => Example: The names `malloc' and `free' are declared normally in 21 1.5 riastrad <stdlib.h> (src/include/stdlib.h): 22 1.5 riastrad 23 1.5 riastrad void *malloc(size_t); 24 1.5 riastrad void free(void *); 25 1.5 riastrad 26 1.5 riastrad libc provides the following ELF symbols: 27 1.5 riastrad 28 1.5 riastrad malloc global 29 1.5 riastrad free global 30 1.5 riastrad 31 1.5 riastrad In the implementation of libc, malloc and free are defined normally 32 1.8 riastrad in src/lib/libc/stdlib/jemalloc.c (on some ports, though it is 33 1.8 riastrad buried in the guts of src/external/bsd/jemalloc/dist/src/* on newer 34 1.8 riastrad ports): 35 1.5 riastrad 36 1.5 riastrad void * 37 1.5 riastrad malloc(size_t size) 38 1.5 riastrad { 39 1.5 riastrad ... 40 1.5 riastrad 41 1.5 riastrad void 42 1.5 riastrad free(void *ptr) 43 1.5 riastrad { 44 1.5 riastrad ... 45 1.1 riastrad 46 1.4 riastrad ** NetBSD-specific nonstandard extensions 47 1.4 riastrad 48 1.1 riastrad If a library routine is nonstandard but published and its signature has 49 1.5 riastrad never changed, it is provided as an ELF weak symbol aliasing an ELF 50 1.1 riastrad global symbol of the same name with an underscore prefix. 51 1.1 riastrad 52 1.1 riastrad The name is declared normally in the appropriate header file, provided 53 1.1 riastrad that the relevant feature macro, such as _NETBSD_SOURCE, is defined. 54 1.1 riastrad 55 1.1 riastrad Within libc, the name is defined in "namespace.h" 56 1.1 riastrad (src/lib/libc/include/namespace.h) as a macro expanding to the 57 1.5 riastrad underscored name, which is included before the relevant header file, so 58 1.5 riastrad that 59 1.5 riastrad 60 1.5 riastrad (a) the definition in a .c file will define the underscored ELF global 61 1.5 riastrad symbol, and 62 1.5 riastrad 63 1.5 riastrad (b) the declaration in the standard header file will match the 64 1.5 riastrad definition in the .c file. 65 1.1 riastrad 66 1.1 riastrad Alongside the definition in the .c file is a __weak_alias directive to 67 1.1 riastrad create the ELF weak symbol alias. 68 1.1 riastrad 69 1.5 riastrad => Example: For the nonstandard extension consttime_memequal, the 70 1.5 riastrad header file <string.h> (src/include/string.h) declares 71 1.5 riastrad `consttime_memequal' normally, if the caller defines _NETBSD_SOURCE: 72 1.5 riastrad 73 1.5 riastrad #if defined(_NETBSD_SOURCE) 74 1.5 riastrad ... 75 1.5 riastrad int consttime_memequal(const void *, const void *, size_t); 76 1.5 riastrad ... 77 1.5 riastrad #endif /* _NETBSD_SOURCE */ 78 1.5 riastrad 79 1.5 riastrad libc provides the following ELF symbols: 80 1.5 riastrad 81 1.5 riastrad _consttime_memequal global 82 1.5 riastrad consttime_memequal weak alias for _consttime_memequal 83 1.5 riastrad 84 1.5 riastrad In the implementation of libc, the header file "namespace.h" 85 1.5 riastrad (src/lib/libc/include/namespace.h) defines `consttime_memequal' as a 86 1.5 riastrad macro expanding to `_consttime_memequal': 87 1.1 riastrad 88 1.5 riastrad #define consttime_memequal _consttime_memequal 89 1.3 riastrad 90 1.3 riastrad The source file src/common/lib/libc/string/consttime_memequal.c 91 1.3 riastrad includes "namespace.h" and <string.h>, and defines 92 1.5 riastrad `consttime_memequal' normally: 93 1.1 riastrad 94 1.5 riastrad int 95 1.5 riastrad consttime_memequal(const void *b1, const void *b2, size_t len) 96 1.5 riastrad { 97 1.5 riastrad ... 98 1.5 riastrad 99 1.5 riastrad Macro expansion replaces `consttime_memequal' by 100 1.5 riastrad `_consttime_memequal', which is the ELF global symbol this defines. 101 1.1 riastrad Alongside the definition is 102 1.1 riastrad 103 1.1 riastrad __weak_alias(consttime_memequal,_consttime_memequal) 104 1.1 riastrad 105 1.1 riastrad to provide `consttime_memequal' as an ELF weak symbol aliasing 106 1.1 riastrad `_consttime_memequal'. 107 1.1 riastrad 108 1.4 riastrad ** Internal symbols 109 1.4 riastrad 110 1.1 riastrad If a library routine is internal to libc, it is defined as an ELF 111 1.2 riastrad global symbol with an underscore prefix. Its name is declared in the 112 1.2 riastrad appropriate internal header file. 113 1.1 riastrad 114 1.5 riastrad => Example: The implementations of opendir and rewinddir use a common 115 1.5 riastrad subroutine _initdir, which is not part of the libc API or ABI -- it 116 1.5 riastrad is just an internal subroutine. 117 1.5 riastrad 118 1.5 riastrad libc provides the following ELF symbols: 119 1.5 riastrad 120 1.5 riastrad _initdir global 121 1.5 riastrad 122 1.5 riastrad The name `_initdir' is declared normally in 123 1.5 riastrad src/lib/libc/gen/dirent_private.h: 124 1.5 riastrad 125 1.5 riastrad int _initdir(DIR *, int, const char *); 126 1.5 riastrad 127 1.5 riastrad The name `_initdir' is defined normally in 128 1.5 riastrad src/lib/libc/gen/initdir.c: 129 1.5 riastrad 130 1.5 riastrad int 131 1.5 riastrad _initdir(DIR *dirp, int fd, const char *name) 132 1.5 riastrad { 133 1.5 riastrad ... 134 1.1 riastrad 135 1.4 riastrad ** Old versions of library routines 136 1.4 riastrad 137 1.1 riastrad If the signature or semantics of a library routine foo changed in (for 138 1.1 riastrad example) NetBSD 6.0, then libc provides 139 1.1 riastrad 140 1.1 riastrad (1) an ELF global symbol `_foo' implementing its old signature, 141 1.1 riastrad (2) an ELF weak symbol `foo' aliasing `_foo', and 142 1.1 riastrad (3) an ELF global symbol `__foo50' implementing its new signature (yes, 143 1.1 riastrad `__foo50', not `__foo60'). 144 1.1 riastrad 145 1.1 riastrad The name foo is declared in the appropriate header file, under any 146 1.1 riastrad relevant feature macros, with a __RENAME directive so that for calls to 147 1.1 riastrad foo, the compiler will generate relocations for __foo50. Old programs, 148 1.1 riastrad compiled with the old signature, will continue to use the old symbol. 149 1.1 riastrad 150 1.1 riastrad => Example: In NetBSD 5.0, time_t was int32_t on every machine. In 151 1.1 riastrad NetBSD 6.0 and onward, time_t is int64_t on every machine. 152 1.1 riastrad Consequently, the signature of time(3), written as 153 1.1 riastrad 154 1.5 riastrad time_t time(time_t *); 155 1.1 riastrad 156 1.5 riastrad was effectively 157 1.1 riastrad 158 1.5 riastrad int32_t time(int32_t *); 159 1.1 riastrad 160 1.5 riastrad before NetBSD 6.0. In NetBSD 6.0, it changed to be effectively 161 1.1 riastrad 162 1.1 riastrad int64_t time(int64_t *); 163 1.1 riastrad 164 1.5 riastrad Before NetBSD 6.0, libc provided the following libc symbols: 165 1.5 riastrad 166 1.5 riastrad _time global (implementing the old signature) 167 1.5 riastrad time weak alias for _time 168 1.5 riastrad 169 1.5 riastrad In NetBSD 6.0 and later, libc provides the following ELF symbols: 170 1.1 riastrad 171 1.5 riastrad _time global (implementing the old signature) 172 1.5 riastrad time weak alias for _time 173 1.5 riastrad __time50 global (implementing the new signature) 174 1.5 riastrad 175 1.5 riastrad (Note that the only change is to add __time50, so that existing 176 1.5 riastrad programs linked against old versions of libc will see the same 177 1.5 riastrad semantics for the symbols that were already there.) 178 1.1 riastrad 179 1.2 riastrad The header file <time.h> (src/include/time.h) declares 180 1.1 riastrad 181 1.5 riastrad time_t time(time_t *) __RENAME(__time50); 182 1.1 riastrad 183 1.1 riastrad so that compiling C programs that call time will yield objects that 184 1.1 riastrad use the __time50 symbol from libc. However, old programs that were 185 1.1 riastrad compiled against the 32-bit declaration will continue to use the 186 1.1 riastrad 32-bit symbol from libc. 187 1.2 riastrad 188 1.2 riastrad The header file "namespace.h" (src/lib/libc/include/namespace.h) 189 1.5 riastrad defines `time' as a macro expanding to `_time': 190 1.5 riastrad 191 1.5 riastrad #define time _time 192 1.2 riastrad 193 1.2 riastrad The source file src/lib/libc/gen/time.c includes "namespace.h" and 194 1.5 riastrad <time.h> and defines `time' normally: 195 1.5 riastrad 196 1.5 riastrad time_t 197 1.5 riastrad time(time_t *t) 198 1.5 riastrad { 199 1.5 riastrad ... 200 1.5 riastrad 201 1.5 riastrad Macro expansion replaces `time' by `_time', but the 202 1.5 riastrad `__RENAME(__time50)' directive on the declaration <time.h> (to which 203 1.5 riastrad the "namespace.h" macro expansion also applies) means the ELF global 204 1.5 riastrad symbol defined here is actually `__time50'. 205 1.2 riastrad 206 1.2 riastrad The header file <compat/include/time.h> 207 1.2 riastrad (src/lib/libc/compat/include/time.h) declares 208 1.2 riastrad 209 1.5 riastrad int32_t time(int32_t *); 210 1.2 riastrad 211 1.2 riastrad The source file src/lib/libc/compat/gen/compat_time.c includes 212 1.2 riastrad "namespace.h", <compat/include/time.h>, and <time.h>, but suppresses 213 1.2 riastrad the normal declaration of `time' in <time.h> by defining 214 1.7 riastrad __LIBC12_SOURCE__ and thus gets it from <compat/include/time.h> 215 1.7 riastrad instead. Then compat_time.c defines `time' normally: 216 1.5 riastrad 217 1.6 riastrad int32_t 218 1.6 riastrad time(int32_t *t) 219 1.5 riastrad { 220 1.5 riastrad ... 221 1.5 riastrad 222 1.5 riastrad Again, macro expansion replaces `time' by `_time', but since there 223 1.5 riastrad is no __RENAME directive in <compat/include/time.h>, the resulting 224 1.6 riastrad ELF global symbol is `_time'. (Actually, compat_time.c just has 225 1.6 riastrad `#define time_t int32_t' and `#include "gen/time.c"' to get the same 226 1.6 riastrad text of the definition of time. The above definition is what we get 227 1.6 riastrad effectively by substituting int32_t for the type time_t.) 228 1.2 riastrad 229 1.2 riastrad Finally, alongside the definition in compat_time.c is 230 1.2 riastrad 231 1.2 riastrad __weak_alias(time,_time) 232 1.2 riastrad 233 1.5 riastrad to define `time' as an ELF weak symbol aliasing `_time'. 234 1.2 riastrad 235 1.2 riastrad The net effect is that NetBSD 6's libc provides the same definitions 236 1.2 riastrad as NetBSD 5's libc for the symbols `time' and `_time', so that old 237 1.2 riastrad programs that were compiled in NetBSD 5 will continue to work with 238 1.2 riastrad NetBSD 6's libc. But programs compiled in NetBSD 6 will have 64-bit 239 1.2 riastrad time_t. 240