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
|
/* $OpenBSD: namespace.h,v 1.1 2016/09/12 19:47:02 guenther Exp $ */
#ifndef _LIBM_NAMESPACE_H_
#define _LIBM_NAMESPACE_H_
/*
* 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 "_libm_" for this.
* These will not be declared directly; instead, the gcc "asm labels"
* extension will be used rename the function.
*
* 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 _libm_x instead. Use
* DEF_STD(x) or DEF_NONSTD(x) to create the external alias.
* ex: PROTO_NORMAL(ceil)
*
* PROTO_STD_DEPRECATED(x) Standard C symbols that are not used internally
* This just marks the symbol as deprecated, with no renaming.
* Do not use DEF_*(x) with this.
* ex: PROTO_STD_DEPRECATED(tgammal)
*
* PROTO_DEPRECATED(x) Symbols not in C that are not used internally
* This marks the symbol as deprecated and, in the static lib, weak.
* No renaming is done. Do not use DEF_*(x) with this.
* ex: PROTO_DEPRECATED(creat)
*
* Finally, to create the expected aliases, we use these in the .c files
* where the definitions are:
* DEF_STD(x) Symbols reserved to or specified by ISO C
* This defines x as a strong alias for _libm_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_STD(fopen)
*
* DEF_NONSTD(x) Symbols used internally and not in ISO C
* This defines x as a alias for _libm_x, weak in the static version
* Matches with PROTO_NORMAL()
* ex: DEF_NONSTD(lseek)
*
* LDBL_CLONE(x) long double aliases that are used
* This defines xl and _libm_xl as aliases for _libm_x.
* Matches with LDBL_PROTO_NORMAL()
*
* LDBL_UNUSED_CLONE(x) long double aliases that are unused
* This defines xl as an alias for _libm_x.
* Matches with LDBL_PROTO_STD_DEPRECATED()
*
* LDBL_MAYBE_CLONE(x)
* LDBL_MAYBE_UNUSED_CLONE(x)
* Like LDBL_CLONE() and LDBL_UNUSED_CLONE(), except they do nothing
* if LDBL_MANT_DIG != DBL_MANT_DIG
*
* MAKE_UNUSED_CLONE(dst, src) Unused symbols that are exact clones
* of other symbols
* This declares dst as being the same type as dst, and makes
* _libm_dst a strong, hidden alias for _libm_src. You still need to
* DEF_STD(dst) or DEF_NONSTD(dst) to alias dst itself
* ex: MAKE_UNUSED_CLONE(nexttoward, nextafter);
*/
#include <sys/cdefs.h> /* for __dso_hidden and __{weak,strong}_alias */
#ifndef PIC
# define WEAK_IN_STATIC_ALIAS(x,y) __weak_alias(x,y)
# define WEAK_IN_STATIC __attribute__((weak))
#else
# define WEAK_IN_STATIC_ALIAS(x,y) __strong_alias(x,y)
# define WEAK_IN_STATIC /* nothing */
#endif
#define HIDDEN(x) _libm_##x
#define HIDDEN_STRING(x) "_libm_" __STRING(x)
#define PROTO_NORMAL(x) __dso_hidden typeof(x) HIDDEN(x), x asm(HIDDEN_STRING(x))
#define PROTO_STD_DEPRECATED(x) typeof(x) HIDDEN(x), x __attribute__((deprecated))
#define PROTO_DEPRECATED(x) PROTO_STD_DEPRECATED(x) WEAK_IN_STATIC
#define DEF_STD(x) __strong_alias(x, HIDDEN(x))
#define DEF_NONSTD(x) WEAK_IN_STATIC_ALIAS(x, HIDDEN(x))
#define MAKE_UNUSED_CLONE(dst, src) __strong_alias(dst, src)
#define LDBL_UNUSED_CLONE(x) __strong_alias(x##l, HIDDEN(x))
#define LDBL_CLONE(x) LDBL_UNUSED_CLONE(x); \
__dso_hidden typeof(HIDDEN(x##l)) HIDDEN(x##l) \
__attribute__((alias (HIDDEN_STRING(x))))
#if __LDBL_MANT_DIG__ == __DBL_MANT_DIG__
# define LDBL_PROTO_NORMAL(x) typeof(x) HIDDEN(x)
# define LDBL_PROTO_STD_DEPRECATED(x) typeof(x) HIDDEN(x)
# define LDBL_MAYBE_CLONE(x) LDBL_CLONE(x)
# define LDBL_MAYBE_UNUSED_CLONE(x) LDBL_UNUSED_CLONE(x)
#else
# define LDBL_PROTO_NORMAL(x) PROTO_NORMAL(x)
# define LDBL_PROTO_STD_DEPRECATED(x) PROTO_STD_DEPRECATED(x)
# define LDBL_MAYBE_CLONE(x) __asm("")
# define LDBL_MAYBE_UNUSED_CLONE(x) __asm("")
#endif
#endif /* _LIBM_NAMESPACE_H_ */
|