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