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