]>
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. | |
da2d1bc5 | 3 | Copyright (C) 1995, 1996, 1997, 1998 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> |
cb2f05ed RM |
55 | /* |
56 | \f | |
b3a59f40 | 57 | */ |
28f540f4 | 58 | |
b3a59f40 | 59 | #ifndef ASSEMBLER |
f45e34fc RM |
60 | |
61 | /* Define the macros `_' and `N_' for conveniently marking translatable | |
62 | strings in the libc source code. */ | |
63 | ||
dfd2257a | 64 | # define N_(msgid) msgid |
f45e34fc | 65 | |
dfd2257a | 66 | # include <libintl.h> |
cb2f05ed | 67 | extern const char _libc_intl_domainname[]; |
f45e34fc | 68 | |
dfd2257a | 69 | # ifdef dgettext |
cb2f05ed | 70 | /* This is defined as an optimizing macro, so use it. */ |
dfd2257a UD |
71 | # define _(msgid) dgettext (_libc_intl_domainname, (msgid)) |
72 | # else | |
cb2f05ed RM |
73 | /* Be sure to use only the __ name when `dgettext' is a plain function |
74 | instead of an optimizing macro. */ | |
dfd2257a UD |
75 | # define _(msgid) __dgettext (_libc_intl_domainname, (msgid)) |
76 | # endif | |
f45e34fc | 77 | |
b3a59f40 | 78 | #endif |
cb2f05ed RM |
79 | |
80 | /* | |
81 | \f | |
82 | */ | |
c224a18a RM |
83 | /* The symbols in all the user (non-_) macros are C symbols. |
84 | HAVE_GNU_LD without HAVE_ELF implies a.out. */ | |
28f540f4 | 85 | |
dfd2257a UD |
86 | #if defined HAVE_ASM_WEAK_DIRECTIVE || defined HAVE_ASM_WEAKEXT_DIRECTIVE |
87 | # define HAVE_WEAK_SYMBOLS | |
28f540f4 | 88 | #endif |
28f540f4 RM |
89 | |
90 | #ifndef __SYMBOL_PREFIX | |
dfd2257a UD |
91 | # ifdef NO_UNDERSCORES |
92 | # define __SYMBOL_PREFIX | |
93 | # else | |
94 | # define __SYMBOL_PREFIX "_" | |
95 | # endif | |
28f540f4 RM |
96 | #endif |
97 | ||
98 | #ifndef C_SYMBOL_NAME | |
dfd2257a UD |
99 | # ifdef NO_UNDERSCORES |
100 | # define C_SYMBOL_NAME(name) name | |
101 | # else | |
102 | # define C_SYMBOL_NAME(name) _##name | |
103 | # endif | |
28f540f4 RM |
104 | #endif |
105 | ||
d02907df | 106 | |
28f540f4 | 107 | /* Define ALIAS as a strong alias for ORIGINAL. */ |
335aa320 | 108 | #ifdef HAVE_ASM_SET_DIRECTIVE |
dfd2257a | 109 | # define strong_alias_asm(original, alias) \ |
d02907df | 110 | ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME (alias); \ |
28f540f4 | 111 | .set C_SYMBOL_NAME (alias),C_SYMBOL_NAME (original) |
dfd2257a UD |
112 | # ifdef ASSEMBLER |
113 | # define strong_alias(original, alias) strong_alias_asm (original, alias) | |
114 | # else | |
115 | # define strong_alias(original, alias) \ | |
d02907df RM |
116 | asm (__string_1 (ASM_GLOBAL_DIRECTIVE) " " __SYMBOL_PREFIX #alias "\n" \ |
117 | ".set " __SYMBOL_PREFIX #alias "," __SYMBOL_PREFIX #original); | |
dfd2257a | 118 | # endif |
335aa320 | 119 | #else |
dfd2257a | 120 | # define strong_alias_asm(original, alias) \ |
d02907df | 121 | ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME (alias); \ |
335aa320 | 122 | C_SYMBOL_NAME (alias) = C_SYMBOL_NAME (original) |
dfd2257a UD |
123 | # ifdef ASSEMBLER |
124 | # define strong_alias(original, alias) strong_alias_asm (original, alias) | |
125 | # else | |
126 | # define strong_alias(original, alias) \ | |
d02907df RM |
127 | asm (__string_1 (ASM_GLOBAL_DIRECTIVE) " " __SYMBOL_PREFIX #alias "\n" \ |
128 | __SYMBOL_PREFIX #alias " = " __SYMBOL_PREFIX #original); | |
dfd2257a | 129 | # endif |
335aa320 | 130 | #endif |
28f540f4 | 131 | |
d02907df RM |
132 | /* Helper macros used above. */ |
133 | #define __string_1(x) __string_0(x) | |
134 | #define __string_0(x) #x | |
135 | ||
136 | ||
28f540f4 | 137 | #ifdef HAVE_WEAK_SYMBOLS |
c224a18a | 138 | |
dfd2257a | 139 | # ifdef ASSEMBLER |
d02907df | 140 | |
dfd2257a | 141 | # ifdef HAVE_ASM_WEAKEXT_DIRECTIVE |
c224a18a RM |
142 | |
143 | /* Define ALIAS as a weak alias for ORIGINAL. | |
144 | If weak aliases are not available, this defines a strong alias. */ | |
dfd2257a | 145 | # define weak_alias(original, alias) \ |
c224a18a RM |
146 | .weakext C_SYMBOL_NAME (alias), C_SYMBOL_NAME (original) |
147 | ||
af5b3bc3 | 148 | /* Declare SYMBOL as weak undefined symbol (resolved to 0 if not defined). */ |
dfd2257a | 149 | # define weak_extern(symbol) \ |
af5b3bc3 | 150 | .weakext C_SYMBOL_NAME (symbol) |
c224a18a | 151 | |
dfd2257a | 152 | # else /* ! HAVE_ASM_WEAKEXT_DIRECTIVE */ |
c224a18a | 153 | |
d02907df RM |
154 | /* Define ALIAS as a weak alias for ORIGINAL. |
155 | If weak aliases are not available, this defines a strong alias. */ | |
dfd2257a | 156 | # define weak_alias(original, alias) \ |
28f540f4 RM |
157 | .weak C_SYMBOL_NAME (alias); \ |
158 | C_SYMBOL_NAME (alias) = C_SYMBOL_NAME (original) | |
e6964dd4 | 159 | |
af5b3bc3 RM |
160 | |
161 | /* Declare SYMBOL as weak undefined symbol (resolved to 0 if not defined). */ | |
dfd2257a | 162 | # define weak_extern(symbol) \ |
af5b3bc3 | 163 | .weak C_SYMBOL_NAME (symbol) |
d02907df | 164 | |
dfd2257a | 165 | # endif /* ! HAVE_ASM_WEAKEXT_DIRECTIVE */ |
c224a18a | 166 | |
dfd2257a | 167 | # else /* ! ASSEMBLER */ |
c224a18a | 168 | |
dfd2257a UD |
169 | # ifdef HAVE_ASM_WEAKEXT_DIRECTIVE |
170 | # define weak_extern_asm(symbol) asm (".weakext " __SYMBOL_PREFIX #symbol); | |
171 | # define weak_alias_asm(original, alias) \ | |
c224a18a | 172 | asm (".weakext " __SYMBOL_PREFIX #alias ", " __SYMBOL_PREFIX #original); |
dfd2257a UD |
173 | # else /* ! HAVE_ASM_WEAKEXT_DIRECTIVE */ |
174 | # define weak_extern_asm(symbol) asm (".weak " __SYMBOL_PREFIX #symbol); | |
175 | # define weak_alias_asm(original, alias) \ | |
28f540f4 RM |
176 | asm (".weak " __SYMBOL_PREFIX #alias "\n" \ |
177 | __SYMBOL_PREFIX #alias " = " __SYMBOL_PREFIX #original); | |
dfd2257a | 178 | # endif /* ! HAVE_ASM_WEAKEXT_DIRECTIVE */ |
af5b3bc3 | 179 | |
dfd2257a UD |
180 | # define weak_alias(o, a) weak_alias_asm (o, a) |
181 | # define weak_extern(symbol) weak_extern_asm (symbol) | |
af5b3bc3 | 182 | |
dfd2257a | 183 | # endif /* ! ASSEMBLER */ |
28f540f4 | 184 | #else |
dfd2257a UD |
185 | # define weak_alias(original, alias) strong_alias(original, alias) |
186 | # define weak_extern(symbol) /* Do nothing; the ref will be strong. */ | |
28f540f4 RM |
187 | #endif |
188 | ||
189 | ||
dfd2257a | 190 | #if (!defined ASSEMBLER && \ |
af5b3bc3 RM |
191 | (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 7))) |
192 | /* GCC 2.7 and later has special syntax for weak symbols and aliases. | |
958f803f RM |
193 | Using that is better when possible, because the compiler and assembler |
194 | are better clued in to what we are doing. */ | |
dfd2257a UD |
195 | # undef strong_alias |
196 | # define strong_alias(name, aliasname) \ | |
af5b3bc3 | 197 | extern __typeof (name) aliasname __attribute__ ((alias (#name))); |
958f803f | 198 | |
dfd2257a UD |
199 | # ifdef HAVE_WEAK_SYMBOLS |
200 | # undef weak_alias | |
201 | # define weak_alias(name, aliasname) \ | |
af5b3bc3 RM |
202 | extern __typeof (name) aliasname __attribute__ ((weak, alias (#name))); |
203 | ||
204 | /* This comes between the return type and function name in | |
205 | a function definition to make that definition weak. */ | |
dfd2257a UD |
206 | # define weak_function __attribute__ ((weak)) |
207 | # define weak_const_function __attribute__ ((weak, __const__)) | |
af5b3bc3 | 208 | |
dfd2257a | 209 | # endif /* HAVE_WEAK_SYMBOLS. */ |
af5b3bc3 RM |
210 | #endif /* Not ASSEMBLER, and GCC 2.7 or later. */ |
211 | ||
958f803f | 212 | |
af5b3bc3 RM |
213 | #ifndef weak_function |
214 | /* If we do not have the __attribute__ ((weak)) syntax, there is no way we | |
215 | can define functions as weak symbols. The compiler will emit a `.globl' | |
216 | directive for the function symbol, and a `.weak' directive in addition | |
217 | will produce an error from the assembler. */ | |
dfd2257a UD |
218 | # define weak_function /* empty */ |
219 | # define weak_const_function /* empty */ | |
af5b3bc3 | 220 | #endif |
958f803f | 221 | |
dfd2257a UD |
222 | /* On some platforms we can make internal function calls (i.e., calls of |
223 | functions not exported) a bit faster by using a different calling | |
224 | convention. */ | |
225 | #ifndef internal_function | |
226 | # define internal_function /* empty */ | |
227 | #endif | |
28f540f4 | 228 | |
44c8d1a2 RM |
229 | /* When a reference to SYMBOL is encountered, the linker will emit a |
230 | warning message MSG. */ | |
28f540f4 | 231 | #ifdef HAVE_GNU_LD |
dfd2257a | 232 | # ifdef HAVE_ELF |
fd26970f UD |
233 | |
234 | /* We want the .gnu.warning.SYMBOL section to be unallocated. */ | |
dfd2257a UD |
235 | # ifdef HAVE_ASM_PREVIOUS_DIRECTIVE |
236 | # define __make_section_unallocated(section_string) \ | |
fd26970f | 237 | asm(".section " section_string "; .previous"); |
dfd2257a UD |
238 | # elif defined (HAVE_ASM_POPSECTION_DIRECTIVE) |
239 | # define __make_section_unallocated(section_string) \ | |
fd26970f | 240 | asm(".pushsection " section_string "; .popsection"); |
dfd2257a UD |
241 | # else |
242 | # define __make_section_unallocated(section_string) | |
243 | # endif | |
fd26970f | 244 | |
dfd2257a | 245 | # define link_warning(symbol, msg) \ |
fd26970f | 246 | __make_section_unallocated (".gnu.warning." #symbol) \ |
44c8d1a2 RM |
247 | static const char __evoke_link_warning_##symbol[] \ |
248 | __attribute__ ((section (".gnu.warning." #symbol))) = msg; | |
dfd2257a UD |
249 | # else |
250 | # define link_warning(symbol, msg) \ | |
28f540f4 | 251 | asm(".stabs \"" msg "\",30,0,0,0\n" \ |
44c8d1a2 | 252 | ".stabs \"" __SYMBOL_PREFIX #symbol "\",1,0,0,0\n"); |
dfd2257a | 253 | # endif |
28f540f4 RM |
254 | #else |
255 | /* We will never be heard; they will all die horribly. */ | |
dfd2257a | 256 | # define link_warning(symbol, msg) |
28f540f4 RM |
257 | #endif |
258 | ||
259 | /* A canned warning for sysdeps/stub functions. */ | |
260 | #define stub_warning(name) \ | |
44c8d1a2 RM |
261 | link_warning (name, \ |
262 | "warning: " #name " is not implemented and will always fail") | |
5f9e57ba RM |
263 | |
264 | /* | |
28f540f4 | 265 | \f |
5f9e57ba RM |
266 | */ |
267 | ||
28f540f4 RM |
268 | #ifdef HAVE_GNU_LD |
269 | ||
270 | /* Symbol set support macros. */ | |
271 | ||
dfd2257a | 272 | # ifdef HAVE_ELF |
28f540f4 RM |
273 | |
274 | /* Make SYMBOL, which is in the text segment, an element of SET. */ | |
dfd2257a | 275 | # define text_set_element(set, symbol) _elf_set_element(set, symbol) |
28f540f4 | 276 | /* Make SYMBOL, which is in the data segment, an element of SET. */ |
dfd2257a | 277 | # define data_set_element(set, symbol) _elf_set_element(set, symbol) |
28f540f4 | 278 | /* Make SYMBOL, which is in the bss segment, an element of SET. */ |
dfd2257a | 279 | # define bss_set_element(set, symbol) _elf_set_element(set, symbol) |
28f540f4 RM |
280 | |
281 | /* These are all done the same way in ELF. | |
282 | There is a new section created for each set. */ | |
dfd2257a | 283 | # ifdef PIC |
53afa8d9 RM |
284 | /* When building a shared library, make the set section writable, |
285 | because it will need to be relocated at run time anyway. */ | |
dfd2257a | 286 | # define _elf_set_element(set, symbol) \ |
53afa8d9 | 287 | static const void *__elf_set_##set##_element_##symbol##__ \ |
d6e2f671 | 288 | __attribute__ ((unused, section (#set))) = &(symbol) |
dfd2257a UD |
289 | # else |
290 | # define _elf_set_element(set, symbol) \ | |
28f540f4 | 291 | static const void *const __elf_set_##set##_element_##symbol##__ \ |
d6e2f671 | 292 | __attribute__ ((unused, section (#set))) = &(symbol) |
dfd2257a | 293 | # endif |
28f540f4 RM |
294 | |
295 | /* Define SET as a symbol set. This may be required (it is in a.out) to | |
296 | be able to use the set's contents. */ | |
dfd2257a | 297 | # define symbol_set_define(set) symbol_set_declare(set) |
28f540f4 RM |
298 | |
299 | /* Declare SET for use in this module, if defined in another module. */ | |
dfd2257a | 300 | # define symbol_set_declare(set) \ |
ec967c06 RM |
301 | extern void *const __start_##set __attribute__ ((__weak__)); \ |
302 | extern void *const __stop_##set __attribute__ ((__weak__)); \ | |
af5b3bc3 | 303 | weak_extern (__start_##set) weak_extern (__stop_##set) |
28f540f4 RM |
304 | |
305 | /* Return a pointer (void *const *) to the first element of SET. */ | |
dfd2257a | 306 | # define symbol_set_first_element(set) (&__start_##set) |
28f540f4 RM |
307 | |
308 | /* Return true iff PTR (a void *const *) has been incremented | |
309 | past the last element in SET. */ | |
dfd2257a | 310 | # define symbol_set_end_p(set, ptr) ((ptr) >= &__stop_##set) |
28f540f4 | 311 | |
dfd2257a | 312 | # else /* Not ELF: a.out. */ |
28f540f4 | 313 | |
dfd2257a | 314 | # define text_set_element(set, symbol) \ |
28f540f4 | 315 | asm(".stabs \"" __SYMBOL_PREFIX #set "\",23,0,0," __SYMBOL_PREFIX #symbol) |
dfd2257a | 316 | # define data_set_element(set, symbol) \ |
28f540f4 | 317 | asm(".stabs \"" __SYMBOL_PREFIX #set "\",25,0,0," __SYMBOL_PREFIX #symbol) |
dfd2257a UD |
318 | # define bss_set_element(set, symbol) ?error Must use initialized data. |
319 | # define symbol_set_define(set) void *const (set)[1]; | |
320 | # define symbol_set_declare(set) extern void *const (set)[1]; | |
28f540f4 | 321 | |
dfd2257a UD |
322 | # define symbol_set_first_element(set) &(set)[1] |
323 | # define symbol_set_end_p(set, ptr) (*(ptr) == 0) | |
28f540f4 | 324 | |
dfd2257a | 325 | # endif /* ELF. */ |
28f540f4 RM |
326 | #endif /* Have GNU ld. */ |
327 | ||
1ea89a40 | 328 | #if DO_VERSIONING |
da2d1bc5 UD |
329 | # ifdef ASSEMBLER |
330 | # define symbol_version(real, name, version) \ | |
331 | .symver real, name##@##version | |
332 | # define default_symbol_version(real, name, version) \ | |
333 | .symver real, name##@##@##version | |
334 | # else | |
335 | # define symbol_version(real, name, version) \ | |
1ea89a40 | 336 | __asm__ (".symver " #real "," #name "@" #version) |
da2d1bc5 | 337 | # define default_symbol_version(real, name, version) \ |
f2ea0f5b | 338 | __asm__ (".symver " #real "," #name "@@" #version) |
da2d1bc5 | 339 | # endif |
1ea89a40 UD |
340 | #else |
341 | # define symbol_version(real, name, version) | |
da2d1bc5 UD |
342 | # define default_symbol_version(real, name, version) \ |
343 | strong_alias(real, name) | |
1ea89a40 UD |
344 | #endif |
345 | ||
28f540f4 | 346 | #endif /* libc-symbols.h */ |