summaryrefslogtreecommitdiff
path: root/lib/libc/include/namespace.h
blob: b0cad502a310ade209571db9364079af8340625e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
/*	$OpenBSD: namespace.h,v 1.3 2015/08/31 02:53:56 guenther Exp $	*/

#ifndef _LIBC_NAMESPACE_H_
#define _LIBC_NAMESPACE_H_

/* These will be replaced with symbol renaming ala PROTO_NORMAL */
#define catclose	_catclose
#define catgets		_catgets
#define catopen		_catopen
#define strtoq		_strtoq
#define strtouq		_strtouq
#define sys_errlist	_sys_errlist
#define sys_nerr	_sys_nerr
#define sys_siglist	_sys_siglist

/*
 * Copyright (c) 2015 Philip Guenther <guenther@openbsd.org>
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

/*
 * The goal: calls from inside libc to other libc functions should be via
 * identifiers that are of hidden visibility and--to avoid confusion--are
 * in the reserved namespace.  By doing this these calls are protected
 * from overriding by applications and on many platforms can avoid creation
 * or use of GOT or PLT entries.  I've chosen a prefix of underbar-C-underbar
 * ("_libc_") for this.  These will not be declared directly; instead, the
 * gcc "asm labels" extension will be used rename the function.
 *
 * For syscalls which are cancellation points, such as wait4(), there
 * are identifiers that do not provide cancellation:
 *	_libc_wait4		hidden alias, for use internal to libc only
 *	_thread_sys_wait4	global name, for use outside libc only
 * ...and identifiers that do provide cancellation:
 *	wait4			weak alias, for general use
 *	_libc_wait4_cancel	hidden alias, for use internal to libc only
 * Inside libc, the bare name ("wait4") binds to the version *without*
 * cancellation; the few times where cancellation is desired it can be
 * obtained by calling CANCEL(x) instead of just x.
 *
 * Some other calls need to be wrapped for reasons other than cancellation,
 * such as to provide functionality beyond the underlying syscall (e.g.,
 * setlogin).  For these, there are identifiers for the raw call, without
 * the wrapping:
 *	_libc_setlogin		hidden alias, for use internal to libc only
 *	_thread_sys_setlogin	global name, for use outside libc only
 * ...and identifiers that do provide the libc wrapping:
 *	setlogin		weak alias, for general use
 *	_libc_setlogin_wrap	hidden alias, for use internal to libc only
 * Inside libc, the bare name ("setlogin") binds to the wrapper; when the
 * raw version is necessary it can be obtained by calling HIDDEN(x) instead of
 * just x.
 *
 * For syscalls which are not cancellation points, such as getpid(),
 * the identifiers are just:
 *	_libc_getpid		hidden alias, for use internal to libc only
 *	_thread_sys_getpid	global name, for use outside libc only
 *	getpid			weak alias, for use outside libc only
 *
 * By using gcc's "asm label" extension, we can usually avoid having
 * to type those prefixes in the .h and .c files.  However, for those
 * cases where a non-default binding is necessary we can use these macros
 * to get the desired identifier:
 *
 *   CANCEL(x)
 *	This expands to the internal, hidden name of a cancellation
 *	wrapper: _libc_x_cancel.  ex: CANCEL(fsync)(fd)
 *
 *   WRAP(x)
 *	This expands to the internal, hidden name of a non-cancellation
 *	wrapper: _libc_x_wrap.  ex: WRAP(sigpending)(set)
 *
 *
 * In order to actually set up the desired asm labels, we use these in
 * the internal .h files:
 *   PROTO_NORMAL(x)		Symbols used both internally and externally
 *	This makes gcc convert use of x to use _libc_x instead
 *	ex: PROTO_NORMAL(getpid)
 *
 *   PROTO_STD_DEPRECATED(x)	Standard C symbols that we don't want to use
 * 	This just marks the symbol as deprecated, with no renaming.
 *	ex: PROTO_STD_DEPRECATED(strcpy)
 *
 *   PROTO_DEPRECATED(x)	Symbols not in ISO C that we don't want to use
 * 	This marks the symbol as both weak and deprecated, with no renaming
 *	ex: PROTO_DEPRECATED(creat)
 *
 *   PROTO_CANCEL(x)		Functions that have cancellation wrappers
 *	Like PROTO_NORMAL(x), but also declares _libc_x_cancel
 *	ex: PROTO_CANCEL(wait4)
 *
 *   PROTO_WRAP(x)		Functions that have wrappers for other reasons
 *	This makes gcc convert use of x to use _libc_x_wrap instead.
 *	ex: PROTO_WRAP(setlogin)
 *
 *
 * Finally, to create the expected aliases, we use these in the .c files
 * where the definitions are:
 *   DEF_STRONG(x)		Symbols reserved to or specified by ISO C
 *	This defines x as a strong alias for _libc_x; this must only
 *	be used for symbols that are reserved by the C standard
 *	(or reserved in the external identifier namespace).
 *	Matches with PROTO_NORMAL()
 *	ex: DEF_STRONG(fopen)
 *
 *   DEF_WEAK(x)		Symbols used internally and not in ISO C
 *	This defines x as a weak alias for _libc_x
 *	Matches with PROTO_NORMAL()
 *	ex: DEF_WEAK(lseek)
 *
 *   DEF_CANCEL(x)		Symbols that have a cancellation wrapper
 *	This defines x as a weak alias for _libc_x_cancel.
 *	Matches with PROTO_CANCEL()
 *	ex: DEF_CANCEL(read)
 *
 *   DEF_WRAP(x)
 *	This defines x as a weak alias for _libc_x_wrap.
 *	Matches with PROTO_WRAP()
 *	ex: DEF_WRAP(setlogin)
 *
 *   DEF_SYS(x)
 *	This defines _thread_sys_x as a strong alias for _libc_x.  This should
 *	only be needed for syscalls that have C instead of asm stubs.
 *	Matches with PROTO_NORMAL(), PROTO_CANCEL(), or PROTO_WRAP()
 *	ex: DEF_SYS(pread)
 */

#define	HIDDEN(x)		_libc_##x
#define	CANCEL(x)		_libc_##x##_cancel
#define	WRAP(x)			_libc_##x##_wrap
#define	HIDDEN_STRING(x)	"_libc_" __STRING(x)
#define	WRAP_STRING(x)		"_libc_" __STRING(x) "_wrap"

#define	PROTO_NORMAL(x)		__dso_hidden typeof(x) x asm(HIDDEN_STRING(x))
#define	PROTO_STD_DEPRECATED(x)	typeof(x) x __attribute__((deprecated))
#define	PROTO_DEPRECATED(x)	typeof(x) x __attribute__((deprecated, weak))
#define	PROTO_CANCEL(x)		PROTO_NORMAL(x), CANCEL(x)
#define	PROTO_WRAP(x)		__dso_hidden typeof(x) x asm(WRAP_STRING(x))

#define	DEF_STRONG(x)		__strong_alias(x, HIDDEN(x))
#define	DEF_WEAK(x)		__weak_alias(x, HIDDEN(x))
#define	DEF_CANCEL(x)		__weak_alias(x, CANCEL(x))
#define	DEF_WRAP(x)		__weak_alias(x, WRAP(x))
#define	DEF_SYS(x)		__strong_alias(_thread_sys_##x, HIDDEN(x))

#endif  /* _LIBC_NAMESPACE_H_ */