README revision 1.6 1 1.6 riastrad $NetBSD: README,v 1.6 2017/01/12 00:38:25 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.5 riastrad __LIBC12_SOURCE__. Instead, <compat/include/time.h>
213 1.5 riastrad (src/lib/libc/compat/include/time.h) declares `time' with the
214 1.5 riastrad effective old signature:
215 1.5 riastrad
216 1.5 riastrad int32_t time(int32_t *);
217 1.5 riastrad
218 1.5 riastrad Then compat_time.c defines `time' normally:
219 1.5 riastrad
220 1.6 riastrad int32_t
221 1.6 riastrad time(int32_t *t)
222 1.5 riastrad {
223 1.5 riastrad ...
224 1.5 riastrad
225 1.5 riastrad Again, macro expansion replaces `time' by `_time', but since there
226 1.5 riastrad is no __RENAME directive in <compat/include/time.h>, the resulting
227 1.6 riastrad ELF global symbol is `_time'. (Actually, compat_time.c just has
228 1.6 riastrad `#define time_t int32_t' and `#include "gen/time.c"' to get the same
229 1.6 riastrad text of the definition of time. The above definition is what we get
230 1.6 riastrad effectively by substituting int32_t for the type time_t.)
231 1.2 riastrad
232 1.2 riastrad Finally, alongside the definition in compat_time.c is
233 1.2 riastrad
234 1.2 riastrad __weak_alias(time,_time)
235 1.2 riastrad
236 1.5 riastrad to define `time' as an ELF weak symbol aliasing `_time'.
237 1.2 riastrad
238 1.2 riastrad The net effect is that NetBSD 6's libc provides the same definitions
239 1.2 riastrad as NetBSD 5's libc for the symbols `time' and `_time', so that old
240 1.2 riastrad programs that were compiled in NetBSD 5 will continue to work with
241 1.2 riastrad NetBSD 6's libc. But programs compiled in NetBSD 6 will have 64-bit
242 1.2 riastrad time_t.
243