Home | History | Annotate | Line # | Download | only in libc
      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