xref: /openbsd-src/lib/libc/include/namespace.h (revision 0b7734b3d77bb9b21afec6f4621cae6c805dbd45)
1 /*	$OpenBSD: namespace.h,v 1.10 2016/05/07 19:05:22 guenther Exp $	*/
2 
3 #ifndef _LIBC_NAMESPACE_H_
4 #define _LIBC_NAMESPACE_H_
5 
6 /*
7  * Copyright (c) 2015 Philip Guenther <guenther@openbsd.org>
8  *
9  * Permission to use, copy, modify, and distribute this software for any
10  * purpose with or without fee is hereby granted, provided that the above
11  * copyright notice and this permission notice appear in all copies.
12  *
13  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
14  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
15  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
16  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
17  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
18  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
19  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20  */
21 
22 /*
23  * The goal: calls from inside libc to other libc functions should be via
24  * identifiers that are of hidden visibility and--to avoid confusion--are
25  * in the reserved namespace.  By doing this these calls are protected
26  * from overriding by applications and on many platforms can avoid creation
27  * or use of GOT or PLT entries.  I've chosen a prefix of underbar-C-underbar
28  * ("_libc_") for this.  These will not be declared directly; instead, the
29  * gcc "asm labels" extension will be used rename the function.
30  *
31  * For syscalls which are cancellation points, such as wait4(), there
32  * are identifiers that do not provide cancellation:
33  *	_libc_wait4		hidden alias, for use internal to libc only
34  *	_thread_sys_wait4	global name, for use outside libc only
35  * ...and identifiers that do provide cancellation:
36  *	wait4			weak alias, for general use
37  *	_libc_wait4_cancel	hidden alias, for use internal to libc only
38  * Inside libc, the bare name ("wait4") binds to the version *without*
39  * cancellation; the few times where cancellation is desired it can be
40  * obtained by calling CANCEL(x) instead of just x.
41  *
42  * Some other calls need to be wrapped for reasons other than cancellation,
43  * such as to provide functionality beyond the underlying syscall (e.g.,
44  * sigaction).  For these, there are identifiers for the raw call, without
45  * the wrapping:
46  *	_libc_sigaction		hidden alias, for use internal to libc only
47  *	_thread_sys_sigaction	global name, for use outside libc only
48  * ...and identifiers that do provide the libc wrapping:
49  *	sigaction		weak alias, for general use
50  *	_libc_sigaction_wrap	hidden alias, for use internal to libc only
51  * Inside libc, the bare name ("sigaction") binds to the wrapper; when the
52  * raw version is necessary it can be obtained by calling HIDDEN(x) instead of
53  * just x.
54  *
55  * For syscalls which are not cancellation points, such as getpid(),
56  * the identifiers are just:
57  *	_libc_getpid		hidden alias, for use internal to libc only
58  *	_thread_sys_getpid	global name, for use outside libc only
59  *	getpid			weak alias, for use outside libc only
60  *
61  * By using gcc's "asm label" extension, we can usually avoid having
62  * to type those prefixes in the .h and .c files.  However, for those
63  * cases where a non-default binding is necessary we can use these macros
64  * to get the desired identifier:
65  *
66  *   CANCEL(x)
67  *	This expands to the internal, hidden name of a cancellation
68  *	wrapper: _libc_x_cancel.  ex: CANCEL(fsync)(fd)
69  *
70  *   WRAP(x)
71  *	This expands to the internal, hidden name of a non-cancellation
72  *	wrapper: _libc_x_wrap.  ex: WRAP(sigprocmask)(set)
73  *
74  *
75  * In order to actually set up the desired asm labels, we use these in
76  * the internal .h files:
77  *   PROTO_NORMAL(x)		Symbols used both internally and externally
78  *	This makes gcc convert use of x to use _libc_x instead
79  *	ex: PROTO_NORMAL(getpid)
80  *
81  *   PROTO_STD_DEPRECATED(x)	Standard C symbols that we don't want to use
82  * 	This just marks the symbol as deprecated, with no renaming.
83  *	ex: PROTO_STD_DEPRECATED(strcpy)
84  *
85  *   PROTO_DEPRECATED(x)	Symbols not in ISO C that we don't want to use
86  * 	This marks the symbol as both weak and deprecated, with no renaming
87  *	ex: PROTO_DEPRECATED(creat)
88  *
89  *   PROTO_CANCEL(x)		Functions that have cancellation wrappers
90  *	Like PROTO_NORMAL(x), but also declares _libc_x_cancel
91  *	ex: PROTO_CANCEL(wait4)
92  *
93  *   PROTO_WRAP(x)		Functions that have wrappers for other reasons
94  *	Like PROTO_NORMAL(x), but also declares _libc_x_wrap.  Internal
95  *	calls that want the wrapper's processing should invoke WRAP(x)(...)
96  *	ex: PROTO_WRAP(sigaction)
97  *
98  *
99  * Finally, to create the expected aliases, we use these in the .c files
100  * where the definitions are:
101  *   DEF_STRONG(x)		Symbols reserved to or specified by ISO C
102  *	This defines x as a strong alias for _libc_x; this must only
103  *	be used for symbols that are reserved by the C standard
104  *	(or reserved in the external identifier namespace).
105  *	Matches with PROTO_NORMAL()
106  *	ex: DEF_STRONG(fopen)
107  *
108  *   DEF_WEAK(x)		Symbols used internally and not in ISO C
109  *	This defines x as a weak alias for _libc_x
110  *	Matches with PROTO_NORMAL()
111  *	ex: DEF_WEAK(lseek)
112  *
113  *   DEF_CANCEL(x)		Symbols that have a cancellation wrapper
114  *	This defines x as a weak alias for _libc_x_cancel.
115  *	Matches with PROTO_CANCEL()
116  *	ex: DEF_CANCEL(read)
117  *
118  *   DEF_WRAP(x)
119  *	This defines x as a weak alias for _libc_x_wrap.
120  *	Matches with PROTO_WRAP()
121  *	ex: DEF_WRAP(sigaction)
122  *
123  *   DEF_SYS(x)
124  *	This defines _thread_sys_x as a strong alias for _libc_x.  This should
125  *	only be needed for syscalls that have C instead of asm stubs.
126  *	Matches with PROTO_NORMAL(), PROTO_CANCEL(), or PROTO_WRAP()
127  *	ex: DEF_SYS(pread)
128  *
129  *   MAKE_CLONE(dst, src)	Symbols that are exact clones of other symbols
130  *	This declares _libc_dst as being the same type as dst, and makes
131  *	_libc_dst a strong, hidden alias for _libc_src.  You still need to
132  *	DEF_STRONG(dst) or DEF_WEAK(dst) to alias dst itself
133  *	ex: MAKE_CLONE(SHA224Pad, SHA256Pad)
134  */
135 
136 #include <sys/cdefs.h>	/* for __dso_hidden and __{weak,strong}_alias */
137 
138 #define	HIDDEN(x)		_libc_##x
139 #define	CANCEL(x)		_libc_##x##_cancel
140 #define	WRAP(x)			_libc_##x##_wrap
141 #define	HIDDEN_STRING(x)	"_libc_" __STRING(x)
142 #define	CANCEL_STRING(x)	"_libc_" __STRING(x) "_cancel"
143 #define	WRAP_STRING(x)		"_libc_" __STRING(x) "_wrap"
144 
145 #define	PROTO_NORMAL(x)		__dso_hidden typeof(x) x asm(HIDDEN_STRING(x))
146 #define	PROTO_STD_DEPRECATED(x)	typeof(x) x __attribute__((deprecated))
147 #define	PROTO_DEPRECATED(x)	typeof(x) x __attribute__((deprecated, weak))
148 #define	PROTO_CANCEL(x)		__dso_hidden typeof(x) HIDDEN(x), \
149 					x asm(CANCEL_STRING(x))
150 #define	PROTO_WRAP(x)		PROTO_NORMAL(x), WRAP(x)
151 
152 #define	DEF_STRONG(x)		__strong_alias(x, HIDDEN(x))
153 #define	DEF_WEAK(x)		__weak_alias(x, HIDDEN(x))
154 #define	DEF_CANCEL(x)		__weak_alias(x, CANCEL(x))
155 #define	DEF_WRAP(x)		__weak_alias(x, WRAP(x))
156 #define	DEF_SYS(x)		__strong_alias(_thread_sys_##x, HIDDEN(x))
157 
158 #define	MAKE_CLONE(dst, src)	__dso_hidden typeof(dst) HIDDEN(dst) \
159 				__attribute__((alias (HIDDEN_STRING(src))))
160 
161 
162 /*
163  * gcc will generate calls to the functions below.
164  * Declare and redirect them here so we always go
165  * directly to our hidden aliases.
166  */
167 #include <sys/_types.h>
168 void	*memcpy(void *__restrict, const void *__restrict, __size_t);
169 void	*memset(void *, int, __size_t);
170 void	__stack_smash_handler(const char [], int __attribute__((__unused__)));
171 PROTO_NORMAL(memcpy);
172 PROTO_NORMAL(memset);
173 PROTO_NORMAL(__stack_smash_handler);
174 
175 #endif  /* _LIBC_NAMESPACE_H_ */
176 
177