1 /*        $NetBSD: cdefs_elf.h,v 1.59 2024/05/29 02:06:46 riastradh Exp $       */
2 
3 /*
4  * Copyright (c) 1995, 1996 Carnegie-Mellon University.
5  * All rights reserved.
6  *
7  * Author: Chris G. Demetriou
8  *
9  * Permission to use, copy, modify and distribute this software and
10  * its documentation is hereby granted, provided that both the copyright
11  * notice and this permission notice appear in all copies of the
12  * software, derivative works or modified versions, and any portions
13  * thereof, and that both notices appear in supporting documentation.
14  *
15  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
16  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
17  * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
18  *
19  * Carnegie Mellon requests users of this software to return to
20  *
21  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
22  *  School of Computer Science
23  *  Carnegie Mellon University
24  *  Pittsburgh PA 15213-3890
25  *
26  * any improvements or extensions that they make and grant Carnegie the
27  * rights to redistribute these changes.
28  */
29 
30 #ifndef _SYS_CDEFS_ELF_H_
31 #define   _SYS_CDEFS_ELF_H_
32 
33 #ifdef __LEADING_UNDERSCORE
34 #define   _C_LABEL(x)                   __CONCAT(_,x)
35 #define _C_LABEL_STRING(x)    "_"x
36 #else
37 #define   _C_LABEL(x)                   x
38 #define _C_LABEL_STRING(x)    x
39 #endif
40 
41 #if __STDC__
42 #define   ___RENAME(x)        __asm(___STRING(_C_LABEL(x)))
43 #else
44 #ifdef __LEADING_UNDERSCORE
45 #define   ___RENAME(x)        ____RENAME(_/**/x)
46 #define   ____RENAME(x)       __asm(___STRING(x))
47 #else
48 #define   ___RENAME(x)        __asm(___STRING(x))
49 #endif
50 #endif
51 
52 #define   __indr_reference(sym,alias)   /* nada, since we do weak refs */
53 
54 #if __STDC__
55 #define   __strong_alias(alias,sym)                                             \
56     __asm(".global " _C_LABEL_STRING(#alias) "\n"                     \
57               _C_LABEL_STRING(#alias) " = " _C_LABEL_STRING(#sym));
58 
59 #define   __weak_alias(alias,sym)                                                         \
60     __asm(".weak " _C_LABEL_STRING(#alias) "\n"                                 \
61               _C_LABEL_STRING(#alias) " = " _C_LABEL_STRING(#sym));
62 
63 /* Do not use __weak_extern, use __weak_reference instead */
64 #define   __weak_extern(sym)                                                    \
65     __asm(".weak " _C_LABEL_STRING(#sym));
66 
67 #if __GNUC_PREREQ__(4, 0)
68 #define   __weak    __attribute__((__weak__))
69 #else
70 #define   __weak
71 #endif
72 
73 #if __GNUC_PREREQ__(4, 0)
74 #define   __weak_reference(sym)         __attribute__((__weakref__(#sym)))
75 #else
76 #define   __weak_reference(sym)         ; __asm(".weak " _C_LABEL_STRING(#sym))
77 #endif
78 
79 #if __GNUC_PREREQ__(4, 2)
80 #define   __weakref_visible   static
81 #else
82 #define   __weakref_visible   extern
83 #endif
84 
85 #define   __warn_references(sym,msg)                                            \
86     __asm(".pushsection .gnu.warning." #sym "\n"                      \
87             ".ascii \"" msg "\"\n"                                              \
88             ".popsection");
89 
90 #else /* !__STDC__ */
91 
92 #ifdef __LEADING_UNDERSCORE
93 #define __weak_alias(alias,sym) ___weak_alias(_/**/alias,_/**/sym)
94 #define   ___weak_alias(alias,sym)                                              \
95     __asm(".weak alias\nalias = sym");
96 #else
97 #define   __weak_alias(alias,sym)                                                         \
98     __asm(".weak alias\nalias = sym");
99 #endif
100 #ifdef __LEADING_UNDERSCORE
101 #define __weak_extern(sym) ___weak_extern(_/**/sym)
102 #define   ___weak_extern(sym)                                                   \
103     __asm(".weak sym");
104 #else
105 #define   __weak_extern(sym)                                                    \
106     __asm(".weak sym");
107 #endif
108 #define   __warn_references(sym,msg)                                            \
109     __asm(".pushsection .gnu.warning.sym\n"                                     \
110             ".ascii \"" msg "\"\n"                                              \
111             ".popsection");
112 
113 #endif /* !__STDC__ */
114 
115 #if __arm__
116 #define __ifunc(name, resolver) \
117           __asm(".globl       " _C_LABEL_STRING(#name) "\n" \
118                 ".type        " _C_LABEL_STRING(#name) ", %gnu_indirect_function\n" \
119                  _C_LABEL_STRING(#name) " = " _C_LABEL_STRING(#resolver))
120 #define __hidden_ifunc(name, resolver) \
121           __asm(".globl       " _C_LABEL_STRING(#name) "\n" \
122                 ".hidden      " _C_LABEL_STRING(#name) "\n" \
123                 ".type        " _C_LABEL_STRING(#name) ", %gnu_indirect_function\n" \
124                  _C_LABEL_STRING(#name) " = " _C_LABEL_STRING(#resolver))
125 #else
126 #define __ifunc(name, resolver) \
127           __asm(".globl       " _C_LABEL_STRING(#name) "\n" \
128                 ".type        " _C_LABEL_STRING(#name) ", @gnu_indirect_function\n" \
129                 _C_LABEL_STRING(#name) " = " _C_LABEL_STRING(#resolver))
130 #define __hidden_ifunc(name, resolver) \
131           __asm(".globl       " _C_LABEL_STRING(#name) "\n" \
132                 ".hidden      " _C_LABEL_STRING(#name) "\n" \
133                 ".type        " _C_LABEL_STRING(#name) ", @gnu_indirect_function\n" \
134                 _C_LABEL_STRING(#name) " = " _C_LABEL_STRING(#resolver))
135 #endif
136 
137 #ifdef __arm__
138 #if __STDC__
139 #  define __SECTIONSTRING(_sec, _str)                                 \
140           __asm(".pushsection " #_sec ",\"MS\",%progbits,1\n"                   \
141                 ".asciz \"" _str "\"\n"                                         \
142                 ".popsection")
143 #else
144 #  define __SECTIONSTRING(_sec, _str)                                 \
145           __asm(".pushsection " _sec ",\"MS\",%progbits,1\n"                    \
146                 ".asciz \"" _str "\"\n"                                         \
147                 ".popsection")
148 #  endif
149 #else
150 #  if __STDC__
151 #  define __SECTIONSTRING(_sec, _str)                                           \
152           __asm(".pushsection " #_sec ",\"MS\",@progbits,1\n"                   \
153                 ".asciz \"" _str "\"\n"                                         \
154                 ".popsection")
155 #  else
156 #  define __SECTIONSTRING(_sec, _str)                                           \
157           __asm(".pushsection " _sec ",\"MS\",@progbits,1\n"                    \
158                 ".asciz \"" _str "\"\n"                                         \
159                 ".popsection")
160 #  endif
161 #endif
162 
163 #define   __IDSTRING(_n,_s)             __SECTIONSTRING(.ident,_s)
164 
165 #ifdef _NETBSD_REVISIONID
166 #define   __RCSID(_s)                                                                           \
167           __IDSTRING(rcsid,_s);                                                                 \
168           __IDSTRING(revisionid,                                                                \
169               "$" "NetBSD: " __FILE__ " " _NETBSD_REVISIONID " $")
170 #else
171 #define   __RCSID(_s)         __IDSTRING(rcsid,_s)
172 #endif
173 #define   __SCCSID(_s)
174 #define __SCCSID2(_s)
175 #define   __COPYRIGHT(_s)                         __SECTIONSTRING(.copyright,_s)
176 
177 #define   __KERNEL_RCSID(_n, _s)                  __RCSID(_s)
178 #define   __KERNEL_SCCSID(_n, _s)
179 #define   __KERNEL_COPYRIGHT(_n, _s)    __COPYRIGHT(_s)
180 
181 #ifndef __lint__
182 #define   __link_set_make_entry(set, sym)                                                 \
183           static void const * const __link_set_##set##_sym_##sym                \
184               __section("link_set_" #set) __used = (const void *)&sym
185 #define   __link_set_make_entry2(set, sym, n)                                   \
186           static void const * const __link_set_##set##_sym_##sym##_##n          \
187               __section("link_set_" #set) __used = (const void *)&sym[n]
188 #else
189 #define   __link_set_make_entry(set, sym)                                                 \
190           extern void const * const __link_set_##set##_sym_##sym
191 #define   __link_set_make_entry2(set, sym, n)                                   \
192           extern void const * const __link_set_##set##_sym_##sym##_##n
193 #endif /* __lint__ */
194 
195 #define   __link_set_add_text(set, sym) __link_set_make_entry(set, sym)
196 #define   __link_set_add_rodata(set, sym)         __link_set_make_entry(set, sym)
197 #define   __link_set_add_data(set, sym) __link_set_make_entry(set, sym)
198 #define   __link_set_add_bss(set, sym)  __link_set_make_entry(set, sym)
199 #define   __link_set_add_text2(set, sym, n)   __link_set_make_entry2(set, sym, n)
200 #define   __link_set_add_rodata2(set, sym, n) __link_set_make_entry2(set, sym, n)
201 #define   __link_set_add_data2(set, sym, n)   __link_set_make_entry2(set, sym, n)
202 #define   __link_set_add_bss2(set, sym, n)    __link_set_make_entry2(set, sym, n)
203 
204 #define   __link_set_start(set)         (__start_link_set_##set)
205 #define   __link_set_end(set) (__stop_link_set_##set)
206 
207 #define   __link_set_decl(set, ptype)                                           \
208           extern ptype * const __link_set_start(set)[] __dso_hidden;  \
209           __asm__(".hidden " __STRING(__stop_link_set_##set)); \
210           extern ptype * const __link_set_end(set)[] __weak __dso_hidden
211 
212 #define   __link_set_count(set)                                                           \
213           (__link_set_end(set) - __link_set_start(set))
214 
215 
216 #ifdef _KERNEL
217 
218 /*
219  * On multiprocessor systems we can gain an improvement in performance
220  * by being mindful of which cachelines data is placed in.
221  *
222  * __read_mostly:
223  *
224  *        It makes sense to ensure that rarely modified data is not
225  *        placed in the same cacheline as frequently modified data.
226  *        To mitigate the phenomenon known as "false-sharing" we
227  *        can annotate rarely modified variables with __read_mostly.
228  *        All such variables are placed into the .data.read_mostly
229  *        section in the kernel ELF.
230  *
231  *        Prime candidates for __read_mostly annotation are variables
232  *        which are hardly ever modified and which are used in code
233  *        hot-paths, e.g. pmap_initialized.
234  *
235  * __cacheline_aligned:
236  *
237  *        Some data structures (mainly locks) benefit from being aligned
238  *        on a cacheline boundary, and having a cacheline to themselves.
239  *        This way, the modification of other data items cannot adversely
240  *        affect the lock and vice versa.
241  *
242  *        Any variables annotated with __cacheline_aligned will be
243  *        placed into the .data.cacheline_aligned ELF section.
244  */
245 #define   __read_mostly                                                         \
246     __attribute__((__section__(".data.read_mostly")))
247 
248 #define   __cacheline_aligned                                         \
249     __attribute__((__aligned__(COHERENCY_UNIT),                       \
250                      __section__(".data.cacheline_aligned")))
251 
252 #endif /* _KERNEL */
253 
254 #endif /* !_SYS_CDEFS_ELF_H_ */
255