xref: /openbsd-src/lib/libc/include/DETAILS (revision cfc1d11d2d2b66cc2b843a6a8140179f5ad89413)
1*cfc1d11dSguentherThe goal: calls from inside libc to other libc functions should
2*cfc1d11dSguenther * not be overridable (except for the malloc family), and
3*cfc1d11dSguenther * not have pointless inefficiencies.
4*cfc1d11dSguenther
5*cfc1d11dSguentherTo achieve this, we arrange that all these internal call be via
6*cfc1d11dSguentheridentifiers that are of hidden visibility and--to avoid confusion
7*cfc1d11dSguentherand work correctly in static executables--are in the reserved
8*cfc1d11dSguenthernamespace.
9*cfc1d11dSguenther
10*cfc1d11dSguentherThis document describes the details of the naming scheme and how
11*cfc1d11dSguentherit is implemented.
12*cfc1d11dSguenther
13*cfc1d11dSguentherI've chosen a prefix of underbar-libc-underbar ("_libc_") for this.
14*cfc1d11dSguentherThese are not declared directly; instead, the gcc "asm labels"
15*cfc1d11dSguentherextension is used to rename the function.
16*cfc1d11dSguenther
17*cfc1d11dSguentherWe need many of the symbols to be weak in *static* builds, but they
18*cfc1d11dSguenthercan be strong in the dynamic library, as there's a natural precedence
19*cfc1d11dSguentherfrom the search order there.  When the descriptions below say a
20*cfc1d11dSguenthername is "weak", that is only necessary for the static library and
21*cfc1d11dSguenthernot for the shared library.  Note: use defined(PIC) to recognize
22*cfc1d11dSguentherwhen compiling the shared objects: some archs define __PIC__ *all*
23*cfc1d11dSguentherthe time.
24*cfc1d11dSguenther
25*cfc1d11dSguenther---------
26*cfc1d11dSguenther
27*cfc1d11dSguentherFor syscalls which are not cancellation points, such as getpid(),
28*cfc1d11dSguentherthe identifiers are just:
29*cfc1d11dSguenther	_libc_getpid		hidden alias, for use internal to libc only
30*cfc1d11dSguenther	_thread_sys_getpid	global name, for use outside libc only
31*cfc1d11dSguenther	getpid			weak alias, for use outside libc only
32*cfc1d11dSguenther
33*cfc1d11dSguentherFor syscalls which are cancellation points, such as wait4(), there
34*cfc1d11dSguentherare identifiers that do not provide cancellation:
35*cfc1d11dSguenther	_libc_wait4		hidden alias, for use internal to libc only
36*cfc1d11dSguenther	_thread_sys_wait4	global name, for use outside libc only
37*cfc1d11dSguenther...and identifiers that do provide cancellation:
38*cfc1d11dSguenther	wait4			weak alias, for general use
39*cfc1d11dSguenther	_libc_wait4_cancel	hidden name, for use internal to libc only
40*cfc1d11dSguentherInside libc, the bare name ("wait4") binds to the version *with*
41*cfc1d11dSguenthercancellation.  If it's necessary to use the syscall without doing
42*cfc1d11dSguenthercancellation it can be obtained by calling HIDDEN(x) instead of
43*cfc1d11dSguentherjust x.
44*cfc1d11dSguenther
45*cfc1d11dSguentherSome other calls need to be wrapped for reasons other than cancellation,
46*cfc1d11dSguenthersuch as to provide functionality beyond the underlying syscall (e.g.,
47*cfc1d11dSguentherptrace).  For these, there are identifiers for the raw call, without
48*cfc1d11dSguentherthe wrapping:
49*cfc1d11dSguenther	_libc_ptrace		hidden alias, for use internal to libc only
50*cfc1d11dSguenther	_thread_sys_ptrace	global name, for use outside libc only
51*cfc1d11dSguenther...and identifiers that do provide the libc wrapping:
52*cfc1d11dSguenther	ptrace			weak alias, for general use
53*cfc1d11dSguenther	_libc_ptrace_wrap	hidden name, for use internal to libc only
54*cfc1d11dSguentherInside libc, the bare name ("ptrace") binds to the wrapper; if
55*cfc1d11dSguentherthe raw version is necessary it can be obtained by calling HIDDEN(x)
56*cfc1d11dSguentherinstead of just x.
57*cfc1d11dSguenther
58*cfc1d11dSguentherFor syscalls implemented in ASM, the aliases of the raw syscall stub
59*cfc1d11dSguentherare provided by the ASM macros.  Of the macros used by sys/Makefile.inc:
60*cfc1d11dSguentherRSYSCALL(), PSEUDO(), and PSEUDO_NOERROR() generate all three names
61*cfc1d11dSguenther(ala getpid() above), while RSYSCALL_HIDDEN() generates just the
62*cfc1d11dSguenther_thread_sys_x and _libc_x names.
63*cfc1d11dSguenther
64*cfc1d11dSguenther
65*cfc1d11dSguenther
66*cfc1d11dSguentherBy using gcc's "asm label" extension, we can usually avoid having
67*cfc1d11dSguentherto type those prefixes in the .h and .c files.  However, for those
68*cfc1d11dSguenthercases where a non-default binding is necessary we can use these macros
69*cfc1d11dSguentherto get the desired identifier:
70*cfc1d11dSguenther
71*cfc1d11dSguenther  CANCEL(x)
72*cfc1d11dSguenther	This expands to the internal, hidden name of a cancellation
73*cfc1d11dSguenther	wrapper: _libc_x_cancel.  ex: CANCEL(fsync)(fd)
74*cfc1d11dSguenther
75*cfc1d11dSguenther  WRAP(x)
76*cfc1d11dSguenther	This expands to the internal, hidden name of a non-cancellation
77*cfc1d11dSguenther	wrapper: _libc_x_wrap.  ex: WRAP(sigprocmask)(set)
78*cfc1d11dSguenther
79*cfc1d11dSguenther
80*cfc1d11dSguentherIn order to actually set up the desired asm labels, we use these in
81*cfc1d11dSguentherthe internal .h files:
82*cfc1d11dSguenther  PROTO_NORMAL(x)		Symbols used both internally and externally
83*cfc1d11dSguenther	This makes gcc convert use of x to use _libc_x instead
84*cfc1d11dSguenther	ex: PROTO_NORMAL(getpid)
85*cfc1d11dSguenther
86*cfc1d11dSguenther  PROTO_STD_DEPRECATED(x)	Standard C symbols that we don't want to use
87*cfc1d11dSguenther	This just marks the symbol as deprecated, with no renaming.
88*cfc1d11dSguenther	ex: PROTO_STD_DEPRECATED(strcpy)
89*cfc1d11dSguenther
90*cfc1d11dSguenther  PROTO_DEPRECATED(x)	Symbols not in ISO C that we don't want to use
91*cfc1d11dSguenther	This marks the symbol as both weak and deprecated, with no renaming
92*cfc1d11dSguenther	ex: PROTO_DEPRECATED(creat)
93*cfc1d11dSguenther
94*cfc1d11dSguenther  PROTO_CANCEL(x)		Functions that have cancellation wrappers
95*cfc1d11dSguenther	Like PROTO_NORMAL(x), but also declares _libc_x_cancel
96*cfc1d11dSguenther	ex: PROTO_CANCEL(wait4)
97*cfc1d11dSguenther
98*cfc1d11dSguenther  PROTO_WRAP(x)		Functions that have wrappers for other reasons
99*cfc1d11dSguenther	Like PROTO_NORMAL(x), but also declares _libc_x_wrap.  Internal
100*cfc1d11dSguenther	calls that want the wrapper's processing should invoke WRAP(x)(...)
101*cfc1d11dSguenther	ex: PROTO_WRAP(sigaction)
102*cfc1d11dSguenther
103*cfc1d11dSguenther
104*cfc1d11dSguentherFinally, to create the expected aliases, we use these in the .c files
105*cfc1d11dSguentherwhere the definitions are:
106*cfc1d11dSguenther  DEF_STRONG(x)		Symbols reserved to or specified by ISO C
107*cfc1d11dSguenther	This defines x as a strong alias for _libc_x; this must only
108*cfc1d11dSguenther	be used for symbols that are reserved by the C standard
109*cfc1d11dSguenther	(or reserved in the external identifier namespace).
110*cfc1d11dSguenther	Matches with PROTO_NORMAL()
111*cfc1d11dSguenther	ex: DEF_STRONG(fopen)
112*cfc1d11dSguenther
113*cfc1d11dSguenther  DEF_WEAK(x)		Symbols used internally and not in ISO C
114*cfc1d11dSguenther	This defines x as a weak alias for _libc_x
115*cfc1d11dSguenther	Matches with PROTO_NORMAL()
116*cfc1d11dSguenther	ex: DEF_WEAK(lseek)
117*cfc1d11dSguenther
118*cfc1d11dSguenther  DEF_CANCEL(x)		Symbols that have a cancellation wrapper
119*cfc1d11dSguenther	This defines x as a weak alias for _libc_x_cancel.
120*cfc1d11dSguenther	Matches with PROTO_CANCEL()
121*cfc1d11dSguenther	ex: DEF_CANCEL(read)
122*cfc1d11dSguenther
123*cfc1d11dSguenther  DEF_WRAP(x)
124*cfc1d11dSguenther	This defines x as a weak alias for _libc_x_wrap.
125*cfc1d11dSguenther	Matches with PROTO_WRAP()
126*cfc1d11dSguenther	ex: DEF_WRAP(ptrace)
127*cfc1d11dSguenther
128*cfc1d11dSguenther  MAKE_CLONE(dst, src)	Symbols that are exact clones of other symbols
129*cfc1d11dSguenther	This declares _libc_dst as being the same type as dst, and makes
130*cfc1d11dSguenther	_libc_dst a strong, hidden alias for _libc_src.  You still need to
131*cfc1d11dSguenther	DEF_STRONG(dst) or DEF_WEAK(dst) to alias dst itself
132*cfc1d11dSguenther	ex: MAKE_CLONE(SHA224Pad, SHA256Pad)
133*cfc1d11dSguenther
134