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