xref: /openbsd-src/lib/libm/hidden/namespace.h (revision c9ad05d3055dda7d02ab88ed4f078c7f44e6d442)
1 /*	$OpenBSD: namespace.h,v 1.3 2018/03/12 06:19:19 guenther Exp $	*/
2 
3 #ifndef _LIBM_NAMESPACE_H_
4 #define _LIBM_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 "_libm_" for this.
28  * These will not be declared directly; instead, the gcc "asm labels"
29  * extension will be used rename the function.
30  *
31  * In order to actually set up the desired asm labels, we use these in
32  * the internal .h files:
33  *   PROTO_NORMAL(x)		Symbols used both internally and externally
34  *	This makes gcc convert use of x to use _libm_x instead.  Use
35  *	DEF_STD(x) or DEF_NONSTD(x) to create the external alias.
36  *	ex: PROTO_NORMAL(ceil)
37  *
38  *   PROTO_STD_DEPRECATED(x)	Standard C symbols that are not used internally
39  * 	This just marks the symbol as deprecated, with no renaming.
40  *	Do not use DEF_*(x) with this.
41  *	ex: PROTO_STD_DEPRECATED(tgammal)
42  *
43  *   PROTO_DEPRECATED(x)	Symbols not in C that are not used internally
44  * 	This marks the symbol as deprecated and, in the static lib, weak.
45  *	No renaming is done.  Do not use DEF_*(x) with this.
46  *	ex: PROTO_DEPRECATED(creat)
47  *
48  * Finally, to create the expected aliases, we use these in the .c files
49  * where the definitions are:
50  *   DEF_STD(x)		Symbols reserved to or specified by ISO C
51  *	This defines x as a strong alias for _libm_x; this must only
52  *	be used for symbols that are reserved by the C standard
53  *	(or reserved in the external identifier namespace).
54  *	Matches with PROTO_NORMAL()
55  *	ex: DEF_STD(fopen)
56  *
57  *   DEF_NONSTD(x)		Symbols used internally and not in ISO C
58  *	This defines x as a alias for _libm_x, weak in the static version
59  *	Matches with PROTO_NORMAL()
60  *	ex: DEF_NONSTD(lseek)
61  *
62  *   LDBL_CLONE(x)		long double aliases that are used
63  *	This defines xl and _libm_xl as aliases for _libm_x.
64  *	Matches with LDBL_PROTO_NORMAL()
65  *
66  *   LDBL_UNUSED_CLONE(x)	long double aliases that are unused
67  *	This defines xl as an alias for _libm_x.
68  *	Matches with LDBL_PROTO_STD_DEPRECATED()
69  *
70  *   LDBL_MAYBE_CLONE(x)
71  *   LDBL_MAYBE_UNUSED_CLONE(x)
72  *	Like LDBL_CLONE() and LDBL_UNUSED_CLONE(), except they do nothing
73  *	if LDBL_MANT_DIG != DBL_MANT_DIG
74  *
75  *   MAKE_UNUSED_CLONE(dst, src)	Unused symbols that are exact clones
76  *					of other symbols
77  *	This declares dst as being the same type as dst, and makes
78  *	_libm_dst a strong, hidden alias for _libm_src.  You still need to
79  *	DEF_STD(dst) or DEF_NONSTD(dst) to alias dst itself
80  *	ex: MAKE_UNUSED_CLONE(nexttoward, nextafter);
81  */
82 
83 #include <sys/cdefs.h>	/* for __dso_hidden and __{weak,strong}_alias */
84 
85 #ifndef PIC
86 # define WEAK_IN_STATIC_ALIAS(x,y)	__weak_alias(x,y)
87 # define WEAK_IN_STATIC			__attribute__((weak))
88 #else
89 # define WEAK_IN_STATIC_ALIAS(x,y)	__strong_alias(x,y)
90 # define WEAK_IN_STATIC			/* nothing */
91 #endif
92 
93 #define	HIDDEN(x)		_libm_##x
94 #define	HIDDEN_STRING(x)	"_libm_" __STRING(x)
95 
96 #define	PROTO_NORMAL(x)		__dso_hidden typeof(x) HIDDEN(x), x asm(HIDDEN_STRING(x))
97 #define	PROTO_STD_DEPRECATED(x)	typeof(x) HIDDEN(x), x __attribute__((deprecated))
98 #define PROTO_DEPRECATED(x)	PROTO_STD_DEPRECATED(x) WEAK_IN_STATIC
99 
100 #define	DEF_STD(x)		__strong_alias(x, HIDDEN(x))
101 #define DEF_NONSTD(x)		WEAK_IN_STATIC_ALIAS(x, HIDDEN(x))
102 
103 #define	MAKE_UNUSED_CLONE(dst, src)	__strong_alias(dst, src)
104 #define LDBL_UNUSED_CLONE(x)		__strong_alias(x##l, HIDDEN(x))
105 #define LDBL_NONSTD_UNUSED_CLONE(x)	WEAK_IN_STATIC_ALIAS(x##l, HIDDEN(x))
106 #define LDBL_CLONE(x)		LDBL_UNUSED_CLONE(x); \
107 				__dso_hidden typeof(HIDDEN(x##l)) HIDDEN(x##l) \
108 				__attribute__((alias (HIDDEN_STRING(x))))
109 #define LDBL_NONSTD_CLONE(x)	LDBL_NONSTD_UNUSED_CLONE(x); \
110 				__dso_hidden typeof(HIDDEN(x##l)) HIDDEN(x##l) \
111 				__attribute__((alias (HIDDEN_STRING(x))))
112 
113 #if __LDBL_MANT_DIG__ == __DBL_MANT_DIG__
114 # define LDBL_PROTO_NORMAL(x)		typeof(x) HIDDEN(x)
115 # define LDBL_PROTO_STD_DEPRECATED(x)	typeof(x) HIDDEN(x)
116 # define LDBL_MAYBE_CLONE(x)		LDBL_CLONE(x)
117 # define LDBL_MAYBE_UNUSED_CLONE(x)	LDBL_UNUSED_CLONE(x)
118 # define LDBL_MAYBE_NONSTD_UNUSED_CLONE(x)	LDBL_NONSTD_UNUSED_CLONE(x)
119 # define LDBL_MAYBE_NONSTD_CLONE(x)	LDBL_NONSTD_CLONE(x)
120 #else
121 # define LDBL_PROTO_NORMAL(x)		PROTO_NORMAL(x)
122 # define LDBL_PROTO_STD_DEPRECATED(x)	PROTO_STD_DEPRECATED(x)
123 # define LDBL_MAYBE_CLONE(x)		__asm("")
124 # define LDBL_MAYBE_UNUSED_CLONE(x)	__asm("")
125 # define LDBL_MAYBE_NONSTD_UNUSED_CLONE(x)	__asm("")
126 # define LDBL_MAYBE_NONSTD_CLONE(x)	__asm("")
127 #endif
128 
129 #endif	/* _LIBM_NAMESPACE_H_ */
130