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