]>
Commit | Line | Data |
---|---|---|
28f540f4 RM |
1 | /* Support macros for making weak and strong aliases for symbols, |
2 | and for using symbol sets and linker warnings with GNU ld. | |
e26dd47f | 3 | Copyright (C) 1995, 1996, 1997, 1998, 2000 Free Software Foundation, Inc. |
5290baf0 | 4 | This file is part of the GNU C Library. |
28f540f4 | 5 | |
5290baf0 UD |
6 | The GNU C Library is free software; you can redistribute it and/or |
7 | modify it under the terms of the GNU Library General Public License as | |
8 | published by the Free Software Foundation; either version 2 of the | |
9 | License, or (at your option) any later version. | |
28f540f4 | 10 | |
5290baf0 UD |
11 | The GNU C Library is distributed in the hope that it will be useful, |
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
14 | Library General Public License for more details. | |
28f540f4 | 15 | |
5290baf0 UD |
16 | You should have received a copy of the GNU Library General Public |
17 | License along with the GNU C Library; see the file COPYING.LIB. If not, | |
18 | write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, | |
19 | Boston, MA 02111-1307, USA. */ | |
28f540f4 RM |
20 | |
21 | #ifndef _LIBC_SYMBOLS_H | |
5290baf0 | 22 | #define _LIBC_SYMBOLS_H 1 |
28f540f4 RM |
23 | |
24 | /* This file's macros are included implicitly in the compilation of every | |
25 | file in the C library by -imacros. | |
26 | ||
27 | We include config.h which is generated by configure. | |
28 | It should define for us the following symbols: | |
29 | ||
c224a18a RM |
30 | * HAVE_ASM_SET_DIRECTIVE if we have `.set B, A' instead of `A = B'. |
31 | * ASM_GLOBAL_DIRECTIVE with `.globl' or `.global'. | |
28f540f4 RM |
32 | * HAVE_GNU_LD if using GNU ld, with support for weak symbols in a.out, |
33 | and for symbol set and warning messages extensions in a.out and ELF. | |
c224a18a RM |
34 | * HAVE_ELF if using ELF, which supports weak symbols using `.weak'. |
35 | * HAVE_ASM_WEAK_DIRECTIVE if we have weak symbols using `.weak'. | |
36 | * HAVE_ASM_WEAKEXT_DIRECTIVE if we have weak symbols using `.weakext'. | |
28f540f4 RM |
37 | |
38 | */ | |
28f540f4 | 39 | |
92777700 RM |
40 | /* This is defined for the compilation of all C library code. features.h |
41 | tests this to avoid inclusion of stubs.h while compiling the library, | |
42 | before stubs.h has been generated. Some library code that is shared | |
43 | with other packages also tests this symbol to see if it is being | |
44 | compiled as part of the C library. We must define this before including | |
45 | config.h, because it makes some definitions conditional on whether libc | |
46 | itself is being compiled, or just some generator program. */ | |
c709e372 | 47 | #define _LIBC 1 |
92777700 | 48 | |
d3669add RM |
49 | /* Enable declarations of GNU extensions, since we are compiling them. */ |
50 | #define _GNU_SOURCE 1 | |
ec4b0518 UD |
51 | /* And we also need the data for the reentrant functions. */ |
52 | #define _REENTRANT 1 | |
d3669add | 53 | |
92777700 | 54 | #include <config.h> |
28f540f4 | 55 | |
c224a18a RM |
56 | /* The symbols in all the user (non-_) macros are C symbols. |
57 | HAVE_GNU_LD without HAVE_ELF implies a.out. */ | |
28f540f4 | 58 | |
dfd2257a UD |
59 | #if defined HAVE_ASM_WEAK_DIRECTIVE || defined HAVE_ASM_WEAKEXT_DIRECTIVE |
60 | # define HAVE_WEAK_SYMBOLS | |
28f540f4 | 61 | #endif |
28f540f4 RM |
62 | |
63 | #ifndef __SYMBOL_PREFIX | |
dfd2257a UD |
64 | # ifdef NO_UNDERSCORES |
65 | # define __SYMBOL_PREFIX | |
66 | # else | |
67 | # define __SYMBOL_PREFIX "_" | |
68 | # endif | |
28f540f4 RM |
69 | #endif |
70 | ||
71 | #ifndef C_SYMBOL_NAME | |
dfd2257a UD |
72 | # ifdef NO_UNDERSCORES |
73 | # define C_SYMBOL_NAME(name) name | |
74 | # else | |
75 | # define C_SYMBOL_NAME(name) _##name | |
76 | # endif | |
28f540f4 RM |
77 | #endif |
78 | ||
b15cb495 UD |
79 | #ifndef ASM_LINE_SEP |
80 | # define ASM_LINE_SEP ; | |
81 | #endif | |
82 | ||
428383e8 UD |
83 | #ifndef __ASSEMBLER__ |
84 | /* GCC understands weak symbols and aliases; use its interface where | |
85 | possible, instead of embedded assembly language. */ | |
d02907df | 86 | |
428383e8 | 87 | /* Define ALIASNAME as a strong alias for NAME. */ |
c62f5cab GM |
88 | # define strong_alias(name, aliasname) _strong_alias(name, aliasname) |
89 | # define _strong_alias(name, aliasname) \ | |
428383e8 UD |
90 | extern __typeof (name) aliasname __attribute__ ((alias (#name))); |
91 | ||
92 | /* This comes between the return type and function name in | |
93 | a function definition to make that definition weak. */ | |
94 | # define weak_function __attribute__ ((weak)) | |
95 | # define weak_const_function __attribute__ ((weak, __const__)) | |
96 | ||
97 | # ifdef HAVE_WEAK_SYMBOLS | |
98 | ||
99 | /* Define ALIASNAME as a weak alias for NAME. | |
100 | If weak aliases are not available, this defines a strong alias. */ | |
c62f5cab GM |
101 | # define weak_alias(name, aliasname) _weak_alias (name, aliasname) |
102 | # define _weak_alias(name, aliasname) \ | |
428383e8 UD |
103 | extern __typeof (name) aliasname __attribute__ ((weak, alias (#name))); |
104 | ||
105 | /* Declare SYMBOL as weak undefined symbol (resolved to 0 if not defined). */ | |
ebdf53a7 | 106 | # define weak_extern(symbol) _weak_extern (symbol) |
428383e8 | 107 | # ifdef HAVE_ASM_WEAKEXT_DIRECTIVE |
ebdf53a7 | 108 | # define _weak_extern(symbol) asm (".weakext " __SYMBOL_PREFIX #symbol); |
428383e8 | 109 | # else |
ebdf53a7 | 110 | # define _weak_extern(symbol) asm (".weak " __SYMBOL_PREFIX #symbol); |
428383e8 UD |
111 | # endif |
112 | ||
113 | # else | |
114 | ||
115 | # define weak_alias(name, aliasname) strong_alias(name, aliasname) | |
116 | # define weak_extern(symbol) /* Nothing. */ | |
117 | ||
118 | # endif | |
119 | ||
120 | #else /* __ASSEMBLER__ */ | |
121 | ||
122 | # ifdef HAVE_ASM_SET_DIRECTIVE | |
123 | # define strong_alias(original, alias) \ | |
b15cb495 | 124 | ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME (alias) ASM_LINE_SEP \ |
28f540f4 | 125 | .set C_SYMBOL_NAME (alias),C_SYMBOL_NAME (original) |
dfd2257a | 126 | # else |
428383e8 | 127 | # define strong_alias(original, alias) \ |
b15cb495 | 128 | ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME (alias) ASM_LINE_SEP \ |
335aa320 | 129 | C_SYMBOL_NAME (alias) = C_SYMBOL_NAME (original) |
dfd2257a | 130 | # endif |
d02907df | 131 | |
428383e8 | 132 | # ifdef HAVE_WEAK_SYMBOLS |
dfd2257a | 133 | # ifdef HAVE_ASM_WEAKEXT_DIRECTIVE |
dfd2257a | 134 | # define weak_alias(original, alias) \ |
c224a18a | 135 | .weakext C_SYMBOL_NAME (alias), C_SYMBOL_NAME (original) |
dfd2257a | 136 | # define weak_extern(symbol) \ |
af5b3bc3 | 137 | .weakext C_SYMBOL_NAME (symbol) |
c224a18a | 138 | |
dfd2257a | 139 | # else /* ! HAVE_ASM_WEAKEXT_DIRECTIVE */ |
c224a18a | 140 | |
dfd2257a | 141 | # define weak_alias(original, alias) \ |
b15cb495 | 142 | .weak C_SYMBOL_NAME (alias) ASM_LINE_SEP \ |
28f540f4 | 143 | C_SYMBOL_NAME (alias) = C_SYMBOL_NAME (original) |
e6964dd4 | 144 | |
dfd2257a | 145 | # define weak_extern(symbol) \ |
af5b3bc3 | 146 | .weak C_SYMBOL_NAME (symbol) |
d02907df | 147 | |
dfd2257a | 148 | # endif /* ! HAVE_ASM_WEAKEXT_DIRECTIVE */ |
c224a18a | 149 | |
428383e8 | 150 | # else /* ! HAVE_WEAK_SYMBOLS */ |
af5b3bc3 | 151 | |
428383e8 UD |
152 | # define weak_alias(original, alias) strong_alias(original, alias) |
153 | # define weak_extern(symbol) /* Nothing */ | |
154 | # endif /* ! HAVE_WEAK_SYMBOLS */ | |
af5b3bc3 | 155 | |
428383e8 | 156 | #endif /* __ASSEMBLER__ */ |
958f803f | 157 | |
dfd2257a UD |
158 | /* On some platforms we can make internal function calls (i.e., calls of |
159 | functions not exported) a bit faster by using a different calling | |
160 | convention. */ | |
161 | #ifndef internal_function | |
162 | # define internal_function /* empty */ | |
163 | #endif | |
28f540f4 | 164 | |
a8eab8b1 UD |
165 | /* Prepare for the case that `__builtin_expect' is not available. */ |
166 | #ifndef HAVE_BUILTIN_EXPECT | |
167 | # define __builtin_expect(expr, val) (expr) | |
168 | #endif | |
169 | ||
e862aada UD |
170 | /* Determine the return address. */ |
171 | #define RETURN_ADDRESS(nr) \ | |
172 | __builtin_extract_return_addr (__builtin_return_address (nr)) | |
173 | ||
44c8d1a2 RM |
174 | /* When a reference to SYMBOL is encountered, the linker will emit a |
175 | warning message MSG. */ | |
28f540f4 | 176 | #ifdef HAVE_GNU_LD |
dfd2257a | 177 | # ifdef HAVE_ELF |
fd26970f UD |
178 | |
179 | /* We want the .gnu.warning.SYMBOL section to be unallocated. */ | |
dfd2257a UD |
180 | # ifdef HAVE_ASM_PREVIOUS_DIRECTIVE |
181 | # define __make_section_unallocated(section_string) \ | |
b15cb495 | 182 | asm (".section " section_string "\n\t.previous"); |
e26dd47f | 183 | # elif defined HAVE_ASM_POPSECTION_DIRECTIVE |
dfd2257a | 184 | # define __make_section_unallocated(section_string) \ |
b15cb495 | 185 | asm (".pushsection " section_string "\n\t.popsection"); |
dfd2257a UD |
186 | # else |
187 | # define __make_section_unallocated(section_string) | |
188 | # endif | |
fd26970f | 189 | |
b15cb495 UD |
190 | /* Tacking on "\n\t#" to the section name makes gcc put it's bogus |
191 | section attributes on what looks like a comment to the assembler. */ | |
e26dd47f UD |
192 | # ifdef HAVE_SECTION_QUOTES |
193 | # define link_warning(symbol, msg) \ | |
194 | __make_section_unallocated (".gnu.warning." #symbol) \ | |
195 | static const char __evoke_link_warning_##symbol[] \ | |
196 | __attribute__ ((section (".gnu.warning." #symbol "\"\n\t#\""))) = msg; | |
197 | # else | |
198 | # define link_warning(symbol, msg) \ | |
199 | __make_section_unallocated (".gnu.warning." #symbol) \ | |
44c8d1a2 | 200 | static const char __evoke_link_warning_##symbol[] \ |
37fb8add | 201 | __attribute__ ((section (".gnu.warning." #symbol "\n\t#"))) = msg; |
e26dd47f | 202 | # endif |
dfd2257a UD |
203 | # else |
204 | # define link_warning(symbol, msg) \ | |
b15cb495 UD |
205 | asm (".stabs \"" msg "\",30,0,0,0\n\t" \ |
206 | ".stabs \"" __SYMBOL_PREFIX #symbol "\",1,0,0,0\n"); | |
dfd2257a | 207 | # endif |
28f540f4 RM |
208 | #else |
209 | /* We will never be heard; they will all die horribly. */ | |
dfd2257a | 210 | # define link_warning(symbol, msg) |
28f540f4 RM |
211 | #endif |
212 | ||
213 | /* A canned warning for sysdeps/stub functions. */ | |
214 | #define stub_warning(name) \ | |
44c8d1a2 RM |
215 | link_warning (name, \ |
216 | "warning: " #name " is not implemented and will always fail") | |
5f9e57ba RM |
217 | |
218 | /* | |
28f540f4 | 219 | \f |
5f9e57ba RM |
220 | */ |
221 | ||
28f540f4 RM |
222 | #ifdef HAVE_GNU_LD |
223 | ||
224 | /* Symbol set support macros. */ | |
225 | ||
dfd2257a | 226 | # ifdef HAVE_ELF |
28f540f4 RM |
227 | |
228 | /* Make SYMBOL, which is in the text segment, an element of SET. */ | |
dfd2257a | 229 | # define text_set_element(set, symbol) _elf_set_element(set, symbol) |
28f540f4 | 230 | /* Make SYMBOL, which is in the data segment, an element of SET. */ |
dfd2257a | 231 | # define data_set_element(set, symbol) _elf_set_element(set, symbol) |
28f540f4 | 232 | /* Make SYMBOL, which is in the bss segment, an element of SET. */ |
dfd2257a | 233 | # define bss_set_element(set, symbol) _elf_set_element(set, symbol) |
28f540f4 RM |
234 | |
235 | /* These are all done the same way in ELF. | |
236 | There is a new section created for each set. */ | |
b5567b2a | 237 | # ifdef SHARED |
53afa8d9 RM |
238 | /* When building a shared library, make the set section writable, |
239 | because it will need to be relocated at run time anyway. */ | |
dfd2257a | 240 | # define _elf_set_element(set, symbol) \ |
53afa8d9 | 241 | static const void *__elf_set_##set##_element_##symbol##__ \ |
d6e2f671 | 242 | __attribute__ ((unused, section (#set))) = &(symbol) |
dfd2257a UD |
243 | # else |
244 | # define _elf_set_element(set, symbol) \ | |
28f540f4 | 245 | static const void *const __elf_set_##set##_element_##symbol##__ \ |
d6e2f671 | 246 | __attribute__ ((unused, section (#set))) = &(symbol) |
dfd2257a | 247 | # endif |
28f540f4 RM |
248 | |
249 | /* Define SET as a symbol set. This may be required (it is in a.out) to | |
250 | be able to use the set's contents. */ | |
dfd2257a | 251 | # define symbol_set_define(set) symbol_set_declare(set) |
28f540f4 RM |
252 | |
253 | /* Declare SET for use in this module, if defined in another module. */ | |
dfd2257a | 254 | # define symbol_set_declare(set) \ |
03df72bf GM |
255 | extern void *const __start_##set __attribute__ ((__weak__)); \ |
256 | extern void *const __stop_##set __attribute__ ((__weak__)); \ | |
af5b3bc3 | 257 | weak_extern (__start_##set) weak_extern (__stop_##set) |
28f540f4 RM |
258 | |
259 | /* Return a pointer (void *const *) to the first element of SET. */ | |
dfd2257a | 260 | # define symbol_set_first_element(set) (&__start_##set) |
28f540f4 RM |
261 | |
262 | /* Return true iff PTR (a void *const *) has been incremented | |
263 | past the last element in SET. */ | |
dfd2257a | 264 | # define symbol_set_end_p(set, ptr) ((ptr) >= &__stop_##set) |
28f540f4 | 265 | |
dfd2257a | 266 | # else /* Not ELF: a.out. */ |
28f540f4 | 267 | |
dfd2257a | 268 | # define text_set_element(set, symbol) \ |
b15cb495 | 269 | asm (".stabs \"" __SYMBOL_PREFIX #set "\",23,0,0," __SYMBOL_PREFIX #symbol) |
dfd2257a | 270 | # define data_set_element(set, symbol) \ |
b15cb495 | 271 | asm (".stabs \"" __SYMBOL_PREFIX #set "\",25,0,0," __SYMBOL_PREFIX #symbol) |
dfd2257a UD |
272 | # define bss_set_element(set, symbol) ?error Must use initialized data. |
273 | # define symbol_set_define(set) void *const (set)[1]; | |
03df72bf | 274 | # define symbol_set_declare(set) extern void *const (set)[1]; |
28f540f4 | 275 | |
dfd2257a UD |
276 | # define symbol_set_first_element(set) &(set)[1] |
277 | # define symbol_set_end_p(set, ptr) (*(ptr) == 0) | |
28f540f4 | 278 | |
dfd2257a | 279 | # endif /* ELF. */ |
28f540f4 RM |
280 | #endif /* Have GNU ld. */ |
281 | ||
1ea89a40 | 282 | #if DO_VERSIONING |
ebdf53a7 | 283 | # define symbol_version(real, name, version) \ |
8b943b4a | 284 | _symbol_version(real, name, version) |
ebdf53a7 GM |
285 | # define default_symbol_version(real, name, version) \ |
286 | _default_symbol_version(real, name, version) | |
287 | # ifdef __ASSEMBLER__ | |
8b943b4a | 288 | # define _symbol_version(real, name, version) \ |
da2d1bc5 | 289 | .symver real, name##@##version |
8b943b4a | 290 | # define _default_symbol_version(real, name, version) \ |
da2d1bc5 UD |
291 | .symver real, name##@##@##version |
292 | # else | |
8b943b4a | 293 | # define _symbol_version(real, name, version) \ |
1ea89a40 | 294 | __asm__ (".symver " #real "," #name "@" #version) |
8b943b4a | 295 | # define _default_symbol_version(real, name, version) \ |
f2ea0f5b | 296 | __asm__ (".symver " #real "," #name "@@" #version) |
da2d1bc5 | 297 | # endif |
1ea89a40 UD |
298 | #else |
299 | # define symbol_version(real, name, version) | |
da2d1bc5 UD |
300 | # define default_symbol_version(real, name, version) \ |
301 | strong_alias(real, name) | |
1ea89a40 UD |
302 | #endif |
303 | ||
28f540f4 | 304 | #endif /* libc-symbols.h */ |