diff options
Diffstat (limited to 'include/libc-symbols.h')
-rw-r--r-- | include/libc-symbols.h | 182 |
1 files changed, 182 insertions, 0 deletions
diff --git a/include/libc-symbols.h b/include/libc-symbols.h index 901458a7b3..4734c50ed7 100644 --- a/include/libc-symbols.h +++ b/include/libc-symbols.h @@ -381,4 +381,186 @@ # define INTVARDEF2(name, newname) #endif +/* The following macros are used for PLT bypassing within libc.so + (and if needed other libraries similarly). + First of all, you need to have the function prototyped somewhere, + say in foo/foo.h: + + int foo (int __bar); + + If calls to foo within libc.so should always go to foo defined in libc.so, + then in include/foo.h you add: + + libc_hidden_proto (foo) + + line and after the foo function definition: + + int foo (int __bar) + { + return __bar; + } + libc_hidden_def (foo) + + or + + int foo (int __bar) + { + return __bar; + } + libc_hidden_weak (foo) + + If foo is normally just an alias (strong or weak) of some other function, + you should use the normal strong_alias first, then add libc_hidden_def + or libc_hidden_weak: + + int baz (int __bar) + { + return __bar; + } + strong_alias (baz, foo) + libc_hidden_weak (foo) + + If the function should be internal to multiple objects, say ld.so and + libc.so, the best way is to use: + + #if !defined NOT_IN_libc || defined IS_IN_rtld + hidden_proto (foo) + #endif + + in include/foo.h and the normal macros at all function definitions + depending on what DSO they belong to. + + If versioned_symbol macro is used to define foo, + libc_hidden_ver macro should be used, as in: + + int __real_foo (int __bar) + { + return __bar; + } + versioned_symbol (libc, __real_foo, foo, GLIBC_2_1); + libc_hidden_ver (__real_foo, foo) */ + +#if defined SHARED && defined DO_VERSIONING \ + && defined HAVE_BROKEN_ALIAS_ATTRIBUTE +# ifndef __ASSEMBLER__ +# ifdef HAVE_BROKEN_VISIBILITY_ATTRIBUTE +# define __hidden_proto_hiddenattr +# else +# define __hidden_proto_hiddenattr attribute_hidden +# endif +# ifndef HAVE_BROKEN_ALIAS_ATTRIBUTE +# define hidden_proto(name) __hidden_proto (name, __GI_##name) +# else +# define hidden_proto(name) +# endif +# define __hidden_proto(name, internal) \ + __typeof (name) internal; \ + __typeof (name) name __asm__ (__hidden_asmname (#internal)) \ + __hidden_proto_hiddenattr; +# define __hidden_asmname(name) \ + __hidden_asmname1 (__USER_LABEL_PREFIX__, name) +# define __hidden_asmname1(prefix, name) __hidden_asmname2(prefix, name) +# define __hidden_asmname2(prefix, name) #prefix name +# ifdef HAVE_ASM_SET_DIRECTIVE +# define __hidden_def1(original, alias) \ + ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME (alias) ASM_LINE_SEP \ + .set C_SYMBOL_NAME (alias), C_SYMBOL_NAME (original) +# else +# ifdef HAVE_ASM_GLOBAL_DOT_NAME +# define __hidden_def1(original, alias) \ + ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME (alias) ASM_LINE_SEP \ + C_SYMBOL_NAME (alias) = C_SYMBOL_NAME (original) ASM_LINE_SEP \ + ASM_GLOBAL_DIRECTIVE C_SYMBOL_DOT_NAME (alias) ASM_LINE_SEP \ + C_SYMBOL_DOT_NAME (alias) = C_SYMBOL_DOT_NAME (original) +# else +# define __hidden_def1(original, alias) \ + ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME (alias) ASM_LINE_SEP \ + C_SYMBOL_NAME (alias) = C_SYMBOL_NAME (original) +# endif +# endif +# define __hidden_def2(...) #__VA_ARGS__ +# define __hidden_def3(...) __hidden_def2 (__VA_ARGS__) +# define hidden_def(name) \ + __asm__ (__hidden_def3 (__hidden_def1 (__GI_##name, name))); +# define hidden_ver(local, name) \ + __asm__ (__hidden_def3 (__hidden_def1 (local, __GI_##name))); +# ifdef HAVE_WEAK_SYMBOLS +# ifdef HAVE_ASM_WEAKEXT_DIRECTIVE +# define __hidden_weak1(original, alias) \ + .weakext C_SYMBOL_NAME (alias), C_SYMBOL_NAME (original) +# else /* ! HAVE_ASM_WEAKEXT_DIRECTIVE */ +# ifdef HAVE_ASM_GLOBAL_DOT_NAME +# define __hidden_weak1(original, alias) \ + .weak C_SYMBOL_NAME (alias) ASM_LINE_SEP \ + C_SYMBOL_NAME (alias) = C_SYMBOL_NAME (original) ASM_LINE_SEP \ + ASM_GLOBAL_DIRECTIVE C_SYMBOL_DOT_NAME (alias) ASM_LINE_SEP \ + C_SYMBOL_DOT_NAME (alias) = C_SYMBOL_DOT_NAME (original) +# else +# define __hidden_weak1(original, alias) \ + .weak C_SYMBOL_NAME (alias) ASM_LINE_SEP \ + C_SYMBOL_NAME (alias) = C_SYMBOL_NAME (original) +# endif +# endif +# define hidden_weak(name) \ + __asm__ (__hidden_def3 (__hidden_weak1 (__GI_##name, name))); +# else +# define hidden_weak(name) hidden_def (name) +# endif +# else +/* For assembly, we need to do the opposite of what we do in C: + in assembly gcc __REDIRECT stuff is not in place, so functions + are defined by its normal name and we need to create the + __GI_* alias to it, in C __REDIRECT causes the function definition + to use __GI_* name and we need to add alias to the real name. + hidden_proto and hidden_weak don't make sense for assembly. */ +# define hidden_def(name) strong_alias (name, __GI_##name) +# define hidden_ver(local, name) strong_alias (local, __GI_##name) +# endif +#else +# ifndef __ASSEMBLY__ +# define hidden_proto(name) +# define hidden_weak(name) +# endif +# define hidden_def(name) +# define hidden_ver(local, name) +#endif + +#if !defined NOT_IN_libc && !defined HAVE_BROKEN_ALIAS_ATTRIBUTE +# define libc_hidden_proto(name) hidden_proto (name) +# define libc_hidden_def(name) hidden_def (name) +# define libc_hidden_weak(name) hidden_weak (name) +# define libc_hidden_ver(local, name) hidden_ver (local, name) +#else +# define libc_hidden_proto(name) +# define libc_hidden_def(name) +# define libc_hidden_weak(name) +# define libc_hidden_ver(local, name) +#endif + +#if defined NOT_IN_libc && defined IS_IN_rtld \ + && !defined HAVE_BROKEN_ALIAS_ATTRIBUTE +# define rtld_hidden_proto(name) hidden_proto (name) +# define rtld_hidden_def(name) hidden_def (name) +# define rtld_hidden_weak(name) hidden_weak (name) +# define rtld_hidden_ver(local, name) hidden_ver (local, name) +#else +# define rtld_hidden_proto(name) +# define rtld_hidden_def(name) +# define rtld_hidden_weak(name) +# define rtld_hidden_ver(local, name) +#endif + +#if defined NOT_IN_libc && defined IS_IN_libm \ + && !defined HAVE_BROKEN_ALIAS_ATTRIBUTE +# define libm_hidden_proto(name) hidden_proto (name) +# define libm_hidden_def(name) hidden_def (name) +# define libm_hidden_weak(name) hidden_weak (name) +# define libm_hidden_ver(local, name) hidden_ver (local, name) +#else +# define libm_hidden_proto(name) +# define libm_hidden_def(name) +# define libm_hidden_weak(name) +# define libm_hidden_ver(local, name) +#endif + #endif /* libc-symbols.h */ |