summaryrefslogtreecommitdiff
path: root/src/lib/libc/include/namespace.h
diff options
context:
space:
mode:
authorguenther <>2015-08-31 02:53:57 +0000
committerguenther <>2015-08-31 02:53:57 +0000
commit9bfe2450029c26d54ebb48f0d8c01d35b63865d3 (patch)
treebb414296df7d65acc4ba9b4159bf5979ae934d04 /src/lib/libc/include/namespace.h
parent4f937c61ae895d4e27690c1e2bb8bc911a3b4a12 (diff)
downloadopenbsd-9bfe2450029c26d54ebb48f0d8c01d35b63865d3.tar.gz
openbsd-9bfe2450029c26d54ebb48f0d8c01d35b63865d3.tar.bz2
openbsd-9bfe2450029c26d54ebb48f0d8c01d35b63865d3.zip
Add framework for resolving (pun intended) libc namespace issues, using
wrapper .h files and asm labels to let internal calls resolve directly and not be overridable or use the PLT. Then, apply that framework to most of the functions in stdio.h, string.h, err.h, and wchar.h. Delete the should-have-been-hidden-all-along _v?(err|warn)[cx]? symbols while here. tests clean on i386, amd64, sparc64, powerpc, and mips64 naming feedback from kettenis@ and millert@ ok kettenis@
Diffstat (limited to 'src/lib/libc/include/namespace.h')
-rw-r--r--src/lib/libc/include/namespace.h158
1 files changed, 149 insertions, 9 deletions
diff --git a/src/lib/libc/include/namespace.h b/src/lib/libc/include/namespace.h
index 4a51f15ddf..b0cad502a3 100644
--- a/src/lib/libc/include/namespace.h
+++ b/src/lib/libc/include/namespace.h
@@ -1,18 +1,158 @@
1/* $OpenBSD: namespace.h,v 1.2 1996/08/19 08:28:08 tholo Exp $ */ 1/* $OpenBSD: namespace.h,v 1.3 2015/08/31 02:53:56 guenther Exp $ */
2 2
3#ifndef _LIBC_NAMESPACE_H_
4#define _LIBC_NAMESPACE_H_
5
6/* These will be replaced with symbol renaming ala PROTO_NORMAL */
3#define catclose _catclose 7#define catclose _catclose
4#define catgets _catgets 8#define catgets _catgets
5#define catopen _catopen 9#define catopen _catopen
6#define err _err
7#define errx _errx
8#define strtoq _strtoq 10#define strtoq _strtoq
9#define strtouq _strtouq 11#define strtouq _strtouq
10#define sys_errlist _sys_errlist 12#define sys_errlist _sys_errlist
11#define sys_nerr _sys_nerr 13#define sys_nerr _sys_nerr
12#define sys_siglist _sys_siglist 14#define sys_siglist _sys_siglist
13#define verr _verr 15
14#define verrx _verrx 16/*
15#define vwarn _vwarn 17 * Copyright (c) 2015 Philip Guenther <guenther@openbsd.org>
16#define vwarnx _vwarnx 18 *
17#define warn _warn 19 * Permission to use, copy, modify, and distribute this software for any
18#define warnx _warnx 20 * purpose with or without fee is hereby granted, provided that the above
21 * copyright notice and this permission notice appear in all copies.
22 *
23 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
24 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
25 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
26 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
27 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
28 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
29 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
30 */
31
32/*
33 * The goal: calls from inside libc to other libc functions should be via
34 * identifiers that are of hidden visibility and--to avoid confusion--are
35 * in the reserved namespace. By doing this these calls are protected
36 * from overriding by applications and on many platforms can avoid creation
37 * or use of GOT or PLT entries. I've chosen a prefix of underbar-C-underbar
38 * ("_libc_") for this. These will not be declared directly; instead, the
39 * gcc "asm labels" extension will be used rename the function.
40 *
41 * For syscalls which are cancellation points, such as wait4(), there
42 * are identifiers that do not provide cancellation:
43 * _libc_wait4 hidden alias, for use internal to libc only
44 * _thread_sys_wait4 global name, for use outside libc only
45 * ...and identifiers that do provide cancellation:
46 * wait4 weak alias, for general use
47 * _libc_wait4_cancel hidden alias, for use internal to libc only
48 * Inside libc, the bare name ("wait4") binds to the version *without*
49 * cancellation; the few times where cancellation is desired it can be
50 * obtained by calling CANCEL(x) instead of just x.
51 *
52 * Some other calls need to be wrapped for reasons other than cancellation,
53 * such as to provide functionality beyond the underlying syscall (e.g.,
54 * setlogin). For these, there are identifiers for the raw call, without
55 * the wrapping:
56 * _libc_setlogin hidden alias, for use internal to libc only
57 * _thread_sys_setlogin global name, for use outside libc only
58 * ...and identifiers that do provide the libc wrapping:
59 * setlogin weak alias, for general use
60 * _libc_setlogin_wrap hidden alias, for use internal to libc only
61 * Inside libc, the bare name ("setlogin") binds to the wrapper; when the
62 * raw version is necessary it can be obtained by calling HIDDEN(x) instead of
63 * just x.
64 *
65 * For syscalls which are not cancellation points, such as getpid(),
66 * the identifiers are just:
67 * _libc_getpid hidden alias, for use internal to libc only
68 * _thread_sys_getpid global name, for use outside libc only
69 * getpid weak alias, for use outside libc only
70 *
71 * By using gcc's "asm label" extension, we can usually avoid having
72 * to type those prefixes in the .h and .c files. However, for those
73 * cases where a non-default binding is necessary we can use these macros
74 * to get the desired identifier:
75 *
76 * CANCEL(x)
77 * This expands to the internal, hidden name of a cancellation
78 * wrapper: _libc_x_cancel. ex: CANCEL(fsync)(fd)
79 *
80 * WRAP(x)
81 * This expands to the internal, hidden name of a non-cancellation
82 * wrapper: _libc_x_wrap. ex: WRAP(sigpending)(set)
83 *
84 *
85 * In order to actually set up the desired asm labels, we use these in
86 * the internal .h files:
87 * PROTO_NORMAL(x) Symbols used both internally and externally
88 * This makes gcc convert use of x to use _libc_x instead
89 * ex: PROTO_NORMAL(getpid)
90 *
91 * PROTO_STD_DEPRECATED(x) Standard C symbols that we don't want to use
92 * This just marks the symbol as deprecated, with no renaming.
93 * ex: PROTO_STD_DEPRECATED(strcpy)
94 *
95 * PROTO_DEPRECATED(x) Symbols not in ISO C that we don't want to use
96 * This marks the symbol as both weak and deprecated, with no renaming
97 * ex: PROTO_DEPRECATED(creat)
98 *
99 * PROTO_CANCEL(x) Functions that have cancellation wrappers
100 * Like PROTO_NORMAL(x), but also declares _libc_x_cancel
101 * ex: PROTO_CANCEL(wait4)
102 *
103 * PROTO_WRAP(x) Functions that have wrappers for other reasons
104 * This makes gcc convert use of x to use _libc_x_wrap instead.
105 * ex: PROTO_WRAP(setlogin)
106 *
107 *
108 * Finally, to create the expected aliases, we use these in the .c files
109 * where the definitions are:
110 * DEF_STRONG(x) Symbols reserved to or specified by ISO C
111 * This defines x as a strong alias for _libc_x; this must only
112 * be used for symbols that are reserved by the C standard
113 * (or reserved in the external identifier namespace).
114 * Matches with PROTO_NORMAL()
115 * ex: DEF_STRONG(fopen)
116 *
117 * DEF_WEAK(x) Symbols used internally and not in ISO C
118 * This defines x as a weak alias for _libc_x
119 * Matches with PROTO_NORMAL()
120 * ex: DEF_WEAK(lseek)
121 *
122 * DEF_CANCEL(x) Symbols that have a cancellation wrapper
123 * This defines x as a weak alias for _libc_x_cancel.
124 * Matches with PROTO_CANCEL()
125 * ex: DEF_CANCEL(read)
126 *
127 * DEF_WRAP(x)
128 * This defines x as a weak alias for _libc_x_wrap.
129 * Matches with PROTO_WRAP()
130 * ex: DEF_WRAP(setlogin)
131 *
132 * DEF_SYS(x)
133 * This defines _thread_sys_x as a strong alias for _libc_x. This should
134 * only be needed for syscalls that have C instead of asm stubs.
135 * Matches with PROTO_NORMAL(), PROTO_CANCEL(), or PROTO_WRAP()
136 * ex: DEF_SYS(pread)
137 */
138
139#define HIDDEN(x) _libc_##x
140#define CANCEL(x) _libc_##x##_cancel
141#define WRAP(x) _libc_##x##_wrap
142#define HIDDEN_STRING(x) "_libc_" __STRING(x)
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) PROTO_NORMAL(x), CANCEL(x)
149#define PROTO_WRAP(x) __dso_hidden typeof(x) x asm(WRAP_STRING(x))
150
151#define DEF_STRONG(x) __strong_alias(x, HIDDEN(x))
152#define DEF_WEAK(x) __weak_alias(x, HIDDEN(x))
153#define DEF_CANCEL(x) __weak_alias(x, CANCEL(x))
154#define DEF_WRAP(x) __weak_alias(x, WRAP(x))
155#define DEF_SYS(x) __strong_alias(_thread_sys_##x, HIDDEN(x))
156
157#endif /* _LIBC_NAMESPACE_H_ */
158