|
|
|
@ -1,6 +1,6 @@ |
|
|
|
/* Support macros for making weak and strong aliases for symbols,
|
|
|
|
and for using symbol sets and linker warnings with GNU ld. |
|
|
|
Copyright (C) 1995-1998,2000-2006,2008,2009,2011 |
|
|
|
Copyright (C) 1995-1998,2000-2006,2008,2009,2011,2012 |
|
|
|
Free Software Foundation, Inc. |
|
|
|
This file is part of the GNU C Library. |
|
|
|
|
|
|
|
@ -32,7 +32,6 @@ |
|
|
|
* ASM_GLOBAL_DIRECTIVE with `.globl' or `.global'. |
|
|
|
* ASM_TYPE_DIRECTIVE_PREFIX with `@' or `#' or whatever for .type, |
|
|
|
or leave it undefined if there is no .type directive. |
|
|
|
* HAVE_ELF if using ELF, which supports weak symbols using `.weak'. |
|
|
|
* HAVE_ASM_WEAK_DIRECTIVE if we have weak symbols using `.weak'. |
|
|
|
* HAVE_ASM_WEAKEXT_DIRECTIVE if we have weak symbols using `.weakext'. |
|
|
|
|
|
|
|
@ -54,8 +53,7 @@ |
|
|
|
|
|
|
|
#include <config.h> |
|
|
|
|
|
|
|
/* The symbols in all the user (non-_) macros are C symbols.
|
|
|
|
NO HAVE_ELF implies a.out. */ |
|
|
|
/* The symbols in all the user (non-_) macros are C symbols. */ |
|
|
|
|
|
|
|
#if defined HAVE_ASM_WEAK_DIRECTIVE || defined HAVE_ASM_WEAKEXT_DIRECTIVE |
|
|
|
# define HAVE_WEAK_SYMBOLS |
|
|
|
@ -222,51 +220,35 @@ |
|
|
|
|
|
|
|
/* When a reference to SYMBOL is encountered, the linker will emit a
|
|
|
|
warning message MSG. */ |
|
|
|
#ifdef HAVE_ELF |
|
|
|
|
|
|
|
/* We want the .gnu.warning.SYMBOL section to be unallocated. */ |
|
|
|
# ifdef HAVE_ASM_PREVIOUS_DIRECTIVE |
|
|
|
# define __make_section_unallocated(section_string) \ |
|
|
|
#ifdef HAVE_ASM_PREVIOUS_DIRECTIVE |
|
|
|
# define __make_section_unallocated(section_string) \ |
|
|
|
asm (".section " section_string "\n\t.previous"); |
|
|
|
# elif defined HAVE_ASM_POPSECTION_DIRECTIVE |
|
|
|
# define __make_section_unallocated(section_string) \ |
|
|
|
#elif defined HAVE_ASM_POPSECTION_DIRECTIVE |
|
|
|
# define __make_section_unallocated(section_string) \ |
|
|
|
asm (".pushsection " section_string "\n\t.popsection"); |
|
|
|
# else |
|
|
|
# define __make_section_unallocated(section_string) |
|
|
|
# endif |
|
|
|
#else |
|
|
|
# define __make_section_unallocated(section_string) |
|
|
|
#endif |
|
|
|
|
|
|
|
/* Tacking on "\n\t#" to the section name makes gcc put it's bogus
|
|
|
|
section attributes on what looks like a comment to the assembler. */ |
|
|
|
# ifdef HAVE_SECTION_QUOTES |
|
|
|
# define __sec_comment "\"\n\t#\"" |
|
|
|
# else |
|
|
|
# define __sec_comment "\n\t#" |
|
|
|
# endif |
|
|
|
# define link_warning(symbol, msg) \ |
|
|
|
#ifdef HAVE_SECTION_QUOTES |
|
|
|
# define __sec_comment "\"\n\t#\"" |
|
|
|
#else |
|
|
|
# define __sec_comment "\n\t#" |
|
|
|
#endif |
|
|
|
#define link_warning(symbol, msg) \ |
|
|
|
__make_section_unallocated (".gnu.warning." #symbol) \ |
|
|
|
static const char __evoke_link_warning_##symbol[] \ |
|
|
|
__attribute__ ((used, section (".gnu.warning." #symbol __sec_comment))) \ |
|
|
|
= msg; |
|
|
|
# define libc_freeres_ptr(decl) \ |
|
|
|
#define libc_freeres_ptr(decl) \ |
|
|
|
__make_section_unallocated ("__libc_freeres_ptrs, \"aw\", %nobits") \ |
|
|
|
decl __attribute__ ((section ("__libc_freeres_ptrs" __sec_comment))) |
|
|
|
# define __libc_freeres_fn_section \ |
|
|
|
#define __libc_freeres_fn_section \ |
|
|
|
__attribute__ ((section ("__libc_freeres_fn"))) |
|
|
|
#else /* Not ELF: a.out */ |
|
|
|
# ifdef HAVE_XCOFF |
|
|
|
/* XCOFF does not support .stabs.
|
|
|
|
The native aix linker will remove the .stab and .stabstr sections |
|
|
|
The gnu linker will have a fatal error if there is a relocation for |
|
|
|
symbol in the .stab section. Silently disable this macro. */ |
|
|
|
# define link_warning(symbol, msg) |
|
|
|
# else |
|
|
|
# define link_warning(symbol, msg) \ |
|
|
|
asm (".stabs \"" msg "\",30,0,0,0\n\t" \ |
|
|
|
".stabs \"" __SYMBOL_PREFIX #symbol "\",1,0,0,0\n"); |
|
|
|
# endif /* XCOFF */ |
|
|
|
# define libc_freeres_ptr(decl) decl |
|
|
|
# define __libc_freeres_fn_section |
|
|
|
#endif |
|
|
|
|
|
|
|
#define libc_freeres_fn(name) \ |
|
|
|
static void name (void) __attribute_used__ __libc_freeres_fn_section; \ |
|
|
|
text_set_element (__libc_subfreeres, name); \ |
|
|
|
@ -337,77 +319,50 @@ for linking") |
|
|
|
|
|
|
|
/* Symbol set support macros. */ |
|
|
|
|
|
|
|
#ifdef HAVE_ELF |
|
|
|
|
|
|
|
/* Make SYMBOL, which is in the text segment, an element of SET. */ |
|
|
|
# define text_set_element(set, symbol) _elf_set_element(set, symbol) |
|
|
|
#define text_set_element(set, symbol) _elf_set_element(set, symbol) |
|
|
|
/* Make SYMBOL, which is in the data segment, an element of SET. */ |
|
|
|
# define data_set_element(set, symbol) _elf_set_element(set, symbol) |
|
|
|
#define data_set_element(set, symbol) _elf_set_element(set, symbol) |
|
|
|
/* Make SYMBOL, which is in the bss segment, an element of SET. */ |
|
|
|
# define bss_set_element(set, symbol) _elf_set_element(set, symbol) |
|
|
|
#define bss_set_element(set, symbol) _elf_set_element(set, symbol) |
|
|
|
|
|
|
|
/* These are all done the same way in ELF.
|
|
|
|
There is a new section created for each set. */ |
|
|
|
# ifdef SHARED |
|
|
|
#ifdef SHARED |
|
|
|
/* When building a shared library, make the set section writable,
|
|
|
|
because it will need to be relocated at run time anyway. */ |
|
|
|
# define _elf_set_element(set, symbol) \ |
|
|
|
# define _elf_set_element(set, symbol) \ |
|
|
|
static const void *__elf_set_##set##_element_##symbol##__ \ |
|
|
|
__attribute__ ((used, section (#set))) = &(symbol) |
|
|
|
# else |
|
|
|
# define _elf_set_element(set, symbol) \ |
|
|
|
#else |
|
|
|
# define _elf_set_element(set, symbol) \ |
|
|
|
static const void *const __elf_set_##set##_element_##symbol##__ \ |
|
|
|
__attribute__ ((used, section (#set))) = &(symbol) |
|
|
|
# endif |
|
|
|
#endif |
|
|
|
|
|
|
|
/* Define SET as a symbol set. This may be required (it is in a.out) to
|
|
|
|
be able to use the set's contents. */ |
|
|
|
# define symbol_set_define(set) symbol_set_declare(set) |
|
|
|
#define symbol_set_define(set) symbol_set_declare(set) |
|
|
|
|
|
|
|
/* Declare SET for use in this module, if defined in another module.
|
|
|
|
In a shared library, this is always local to that shared object. |
|
|
|
For static linking, the set might be wholly absent and so we use |
|
|
|
weak references. */ |
|
|
|
# define symbol_set_declare(set) \ |
|
|
|
#define symbol_set_declare(set) \ |
|
|
|
extern char const __start_##set[] __symbol_set_attribute; \ |
|
|
|
extern char const __stop_##set[] __symbol_set_attribute; |
|
|
|
# ifdef SHARED |
|
|
|
# define __symbol_set_attribute attribute_hidden |
|
|
|
# else |
|
|
|
# define __symbol_set_attribute __attribute__ ((weak)) |
|
|
|
# endif |
|
|
|
#ifdef SHARED |
|
|
|
# define __symbol_set_attribute attribute_hidden |
|
|
|
#else |
|
|
|
# define __symbol_set_attribute __attribute__ ((weak)) |
|
|
|
#endif |
|
|
|
|
|
|
|
/* Return a pointer (void *const *) to the first element of SET. */ |
|
|
|
# define symbol_set_first_element(set) ((void *const *) (&__start_##set)) |
|
|
|
#define symbol_set_first_element(set) ((void *const *) (&__start_##set)) |
|
|
|
|
|
|
|
/* Return true iff PTR (a void *const *) has been incremented
|
|
|
|
past the last element in SET. */ |
|
|
|
# define symbol_set_end_p(set, ptr) ((ptr) >= (void *const *) &__stop_##set) |
|
|
|
|
|
|
|
#else /* Not ELF: a.out. */ |
|
|
|
|
|
|
|
# ifdef HAVE_XCOFF |
|
|
|
/* XCOFF does not support .stabs.
|
|
|
|
The native aix linker will remove the .stab and .stabstr sections |
|
|
|
The gnu linker will have a fatal error if there is a relocation for |
|
|
|
symbol in the .stab section. Silently disable these macros. */ |
|
|
|
# define text_set_element(set, symbol) |
|
|
|
# define data_set_element(set, symbol) |
|
|
|
# define bss_set_element(set, symbol) |
|
|
|
# else |
|
|
|
# define text_set_element(set, symbol) \ |
|
|
|
asm (".stabs \"" __SYMBOL_PREFIX #set "\",23,0,0," __SYMBOL_PREFIX #symbol) |
|
|
|
# define data_set_element(set, symbol) \ |
|
|
|
asm (".stabs \"" __SYMBOL_PREFIX #set "\",25,0,0," __SYMBOL_PREFIX #symbol) |
|
|
|
# define bss_set_element(set, symbol) ?error Must use initialized data. |
|
|
|
# endif /* XCOFF */ |
|
|
|
# define symbol_set_define(set) void *const (set)[1]; |
|
|
|
# define symbol_set_declare(set) extern void *const (set)[1]; |
|
|
|
|
|
|
|
# define symbol_set_first_element(set) &(set)[1] |
|
|
|
# define symbol_set_end_p(set, ptr) (*(ptr) == 0) |
|
|
|
|
|
|
|
#endif /* ELF. */ |
|
|
|
#define symbol_set_end_p(set, ptr) ((ptr) >= (void *const *) &__stop_##set) |
|
|
|
|
|
|
|
#if DO_VERSIONING |
|
|
|
# define symbol_version(real, name, version) \ |
|
|
|
|