aboutsummaryrefslogtreecommitdiff
path: root/lib/libc/include/generic-netbsd/sys/cdefs_elf.h
blob: 0f2c5d5e051676ca488c116ce2a213abbd6a7003 (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
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
/*	$NetBSD: cdefs_elf.h,v 1.58 2021/06/04 01:58:02 thorpej Exp $	*/

/*
 * Copyright (c) 1995, 1996 Carnegie-Mellon University.
 * All rights reserved.
 *
 * Author: Chris G. Demetriou
 *
 * Permission to use, copy, modify and distribute this software and
 * its documentation is hereby granted, provided that both the copyright
 * notice and this permission notice appear in all copies of the
 * software, derivative works or modified versions, and any portions
 * thereof, and that both notices appear in supporting documentation.
 *
 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
 * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
 * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
 *
 * Carnegie Mellon requests users of this software to return to
 *
 *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
 *  School of Computer Science
 *  Carnegie Mellon University
 *  Pittsburgh PA 15213-3890
 *
 * any improvements or extensions that they make and grant Carnegie the
 * rights to redistribute these changes.
 */

#ifndef _SYS_CDEFS_ELF_H_
#define	_SYS_CDEFS_ELF_H_

#ifdef __LEADING_UNDERSCORE
#define	_C_LABEL(x)		__CONCAT(_,x)
#define _C_LABEL_STRING(x)	"_"x
#else
#define	_C_LABEL(x)		x
#define _C_LABEL_STRING(x)	x
#endif

#if __STDC__
#define	___RENAME(x)	__asm(___STRING(_C_LABEL(x)))
#else
#ifdef __LEADING_UNDERSCORE
#define	___RENAME(x)	____RENAME(_/**/x)
#define	____RENAME(x)	__asm(___STRING(x))
#else
#define	___RENAME(x)	__asm(___STRING(x))
#endif
#endif

#define	__indr_reference(sym,alias)	/* nada, since we do weak refs */

#if __STDC__
#define	__strong_alias(alias,sym)	       				\
    __asm(".global " _C_LABEL_STRING(#alias) "\n"			\
	    _C_LABEL_STRING(#alias) " = " _C_LABEL_STRING(#sym));

#define	__weak_alias(alias,sym)						\
    __asm(".weak " _C_LABEL_STRING(#alias) "\n"				\
	    _C_LABEL_STRING(#alias) " = " _C_LABEL_STRING(#sym));

/* Do not use __weak_extern, use __weak_reference instead */
#define	__weak_extern(sym)						\
    __asm(".weak " _C_LABEL_STRING(#sym));

#if __GNUC_PREREQ__(4, 0)
#define	__weak	__attribute__((__weak__))
#else
#define	__weak
#endif

#if __GNUC_PREREQ__(4, 0)
#define	__weak_reference(sym)	__attribute__((__weakref__(#sym)))
#else
#define	__weak_reference(sym)	; __asm(".weak " _C_LABEL_STRING(#sym))
#endif

#if __GNUC_PREREQ__(4, 2)
#define	__weakref_visible	static
#else
#define	__weakref_visible	extern
#endif

#define	__warn_references(sym,msg)					\
    __asm(".pushsection .gnu.warning." #sym "\n"			\
	  ".ascii \"" msg "\"\n"					\
	  ".popsection");

#else /* !__STDC__ */

#ifdef __LEADING_UNDERSCORE
#define __weak_alias(alias,sym) ___weak_alias(_/**/alias,_/**/sym)
#define	___weak_alias(alias,sym)					\
    __asm(".weak alias\nalias = sym");
#else
#define	__weak_alias(alias,sym)						\
    __asm(".weak alias\nalias = sym");
#endif
#ifdef __LEADING_UNDERSCORE
#define __weak_extern(sym) ___weak_extern(_/**/sym)
#define	___weak_extern(sym)						\
    __asm(".weak sym");
#else
#define	__weak_extern(sym)						\
    __asm(".weak sym");
#endif
#define	__warn_references(sym,msg)					\
    __asm(".pushsection .gnu.warning.sym\n"				\
	  ".ascii \"" msg "\"\n"					\
	  ".popsection");

#endif /* !__STDC__ */

#if __arm__
#define __ifunc(name, resolver) \
	__asm(".globl	" _C_LABEL_STRING(#name) "\n" \
	      ".type	" _C_LABEL_STRING(#name) ", %gnu_indirect_function\n" \
	       _C_LABEL_STRING(#name) " = " _C_LABEL_STRING(#resolver))
#define __hidden_ifunc(name, resolver) \
	__asm(".globl	" _C_LABEL_STRING(#name) "\n" \
	      ".hidden	" _C_LABEL_STRING(#name) "\n" \
	      ".type	" _C_LABEL_STRING(#name) ", %gnu_indirect_function\n" \
	       _C_LABEL_STRING(#name) " = " _C_LABEL_STRING(#resolver))
#else
#define __ifunc(name, resolver) \
	__asm(".globl	" _C_LABEL_STRING(#name) "\n" \
	      ".type	" _C_LABEL_STRING(#name) ", @gnu_indirect_function\n" \
	      _C_LABEL_STRING(#name) " = " _C_LABEL_STRING(#resolver))
#define __hidden_ifunc(name, resolver) \
	__asm(".globl	" _C_LABEL_STRING(#name) "\n" \
	      ".hidden	" _C_LABEL_STRING(#name) "\n" \
	      ".type	" _C_LABEL_STRING(#name) ", @gnu_indirect_function\n" \
	      _C_LABEL_STRING(#name) " = " _C_LABEL_STRING(#resolver))
#endif

#ifdef __arm__
#if __STDC__
#  define	__SECTIONSTRING(_sec, _str)				\
	__asm(".pushsection " #_sec ",\"MS\",%progbits,1\n"		\
	      ".asciz \"" _str "\"\n"					\
	      ".popsection")
#else
#  define	__SECTIONSTRING(_sec, _str)				\
	__asm(".pushsection " _sec ",\"MS\",%progbits,1\n"		\
	      ".asciz \"" _str "\"\n"					\
	      ".popsection")
#  endif
#else
#  if __STDC__
#  define	__SECTIONSTRING(_sec, _str)					\
	__asm(".pushsection " #_sec ",\"MS\",@progbits,1\n"		\
	      ".asciz \"" _str "\"\n"					\
	      ".popsection")
#  else
#  define	__SECTIONSTRING(_sec, _str)					\
	__asm(".pushsection " _sec ",\"MS\",@progbits,1\n"		\
	      ".asciz \"" _str "\"\n"					\
	      ".popsection")
#  endif
#endif

#define	__IDSTRING(_n,_s)		__SECTIONSTRING(.ident,_s)

#define	__RCSID(_s)			__IDSTRING(rcsid,_s)
#define	__SCCSID(_s)
#define __SCCSID2(_s)
#define	__COPYRIGHT(_s)			__SECTIONSTRING(.copyright,_s)

#define	__KERNEL_RCSID(_n, _s)		__RCSID(_s)
#define	__KERNEL_SCCSID(_n, _s)
#define	__KERNEL_COPYRIGHT(_n, _s)	__COPYRIGHT(_s)

#ifndef __lint__
#define	__link_set_make_entry(set, sym)					\
	static void const * const __link_set_##set##_sym_##sym		\
	    __section("link_set_" #set) __used = (const void *)&sym
#define	__link_set_make_entry2(set, sym, n)				\
	static void const * const __link_set_##set##_sym_##sym##_##n	\
	    __section("link_set_" #set) __used = (const void *)&sym[n]
#else
#define	__link_set_make_entry(set, sym)					\
	extern void const * const __link_set_##set##_sym_##sym
#define	__link_set_make_entry2(set, sym, n)				\
	extern void const * const __link_set_##set##_sym_##sym##_##n
#endif /* __lint__ */

#define	__link_set_add_text(set, sym)	__link_set_make_entry(set, sym)
#define	__link_set_add_rodata(set, sym)	__link_set_make_entry(set, sym)
#define	__link_set_add_data(set, sym)	__link_set_make_entry(set, sym)
#define	__link_set_add_bss(set, sym)	__link_set_make_entry(set, sym)
#define	__link_set_add_text2(set, sym, n)   __link_set_make_entry2(set, sym, n)
#define	__link_set_add_rodata2(set, sym, n) __link_set_make_entry2(set, sym, n)
#define	__link_set_add_data2(set, sym, n)   __link_set_make_entry2(set, sym, n)
#define	__link_set_add_bss2(set, sym, n)    __link_set_make_entry2(set, sym, n)

#define	__link_set_start(set)	(__start_link_set_##set)
#define	__link_set_end(set)	(__stop_link_set_##set)

#define	__link_set_decl(set, ptype)					\
	extern ptype * const __link_set_start(set)[] __dso_hidden;	\
	__asm__(".hidden " __STRING(__stop_link_set_##set)); \
	extern ptype * const __link_set_end(set)[] __weak __dso_hidden

#define	__link_set_count(set)						\
	(__link_set_end(set) - __link_set_start(set))


#ifdef _KERNEL

/*
 * On multiprocessor systems we can gain an improvement in performance
 * by being mindful of which cachelines data is placed in.
 *
 * __read_mostly:
 *
 *	It makes sense to ensure that rarely modified data is not
 *	placed in the same cacheline as frequently modified data.
 *	To mitigate the phenomenon known as "false-sharing" we
 *	can annotate rarely modified variables with __read_mostly.
 *	All such variables are placed into the .data.read_mostly
 *	section in the kernel ELF.
 *
 *	Prime candidates for __read_mostly annotation are variables
 *	which are hardly ever modified and which are used in code
 *	hot-paths, e.g. pmap_initialized.
 *
 * __cacheline_aligned:
 *
 *	Some data structures (mainly locks) benefit from being aligned
 *	on a cacheline boundary, and having a cacheline to themselves.
 *	This way, the modification of other data items cannot adversely
 *	affect the lock and vice versa.
 *
 *	Any variables annotated with __cacheline_aligned will be
 *	placed into the .data.cacheline_aligned ELF section.
 */
#define	__read_mostly						\
    __attribute__((__section__(".data.read_mostly")))

#define	__cacheline_aligned					\
    __attribute__((__aligned__(COHERENCY_UNIT),			\
		 __section__(".data.cacheline_aligned")))

#endif /* _KERNEL */

#endif /* !_SYS_CDEFS_ELF_H_ */