RFC: New macros for bypassing PLT calls
Jakub Jelinek
jakub@redhat.com
Wed Jul 31 07:45:00 GMT 2002
Hi!
ATM glibc uses a couple of different methods for the hidden
function aliases.
Below is what I came up today, I wonder whether you agree with it
before changing it everywhere.
The usage is:
in include/ (ie. glibc private header) add something like:
libc_hidden (int, close, (int __fd));
if you want to all close (fd) calls to bypass PLT inside of libc.so.
Then the only other change is at the actual close function definition.
If the function is originally defined with some other name, say __close
and close used to be just weak or strong alias, then one needs to do:
int __close (int __fd)
{
... function definition
}
strong_alias (__close, close) // This is what the code already contained
libc_hidden_def (close) // If the close is supposed to
// be strong, otherwise libc_hidden_weak (close)
If there were no aliases (or just INTDEF etc.), then only:
int close (int __fd)
{
... function definition
}
libc_hidden_def (close)
One alternative would be to get rid of the prototypes in include/ headers,
ie. just say:
libc_hidden (close);
in include/foo.h.
libc_hidden definition would then have to change slightly:
# define libc_hidden(name) __libc_hidden(name, __GI_##name)
# define __libc_hidden(name, internal) \
__typeof(name) internal; \
__typeof(name) __REDIRECT (name, , internal) attribute_hidden
Are there any common cases which should be solved I've missed?
Jakub
-------------- next part --------------
#include "libc-symbols.h"
#if !defined NOT_IN_libc && defined SHARED \
&& defined DO_VERSIONING && defined __REDIRECT
# define libc_hidden(type, name, proto) __libc_hidden(type, name, proto, __GI_##name)
# define __libc_hidden(type, name, proto, internal) \
type internal proto; \
type __REDIRECT (name, proto, internal) attribute_hidden
# ifdef HAVE_ASM_SET_DIRECTIVE
# define __libc_hidden_def_1(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 __libc_hidden_def_1(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 __libc_hidden_def_1(original, alias) \
ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME (alias) ASM_LINE_SEP \
C_SYMBOL_NAME (alias) = C_SYMBOL_NAME (original)
# endif
# endif
# define __libc_hidden_def_2(...) #__VA_ARGS__
# define __libc_hidden_def_3(...) __libc_hidden_def_2(__VA_ARGS__)
# define libc_hidden_def(name) \
__asm__ (__libc_hidden_def_3 (__libc_hidden_def_1 (__GI_##name, name)));
# ifdef HAVE_WEAK_SYMBOLS
# ifdef HAVE_ASM_WEAKEXT_DIRECTIVE
# define __libc_hidden_weak_1(original, alias) \
.weakext C_SYMBOL_NAME (alias), C_SYMBOL_NAME (original)
# else /* ! HAVE_ASM_WEAKEXT_DIRECTIVE */
# ifdef HAVE_ASM_GLOBAL_DOT_NAME
# define __libc_hidden_weak_1(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 __libc_hidden_weak_1(original, alias) \
.weak C_SYMBOL_NAME (alias) ASM_LINE_SEP \
C_SYMBOL_NAME (alias) = C_SYMBOL_NAME (original)
# endif
# endif
# define libc_hidden_weak(name) \
__asm__ (__libc_hidden_def_3 (__libc_hidden_weak_1 (__GI_##name, name)));
# else
# define libc_hidden_weak(name) libc_hidden_def(name)
# endif
#else
# define libc_hidden(type, name, proto) type name proto
# define libc_hidden_def(name)
# define libc_hidden_weak(name)
#endif
-------------- next part --------------
#define SHARED
#define DO_VERSIONING
#define NO_UNDERSCORES 1
#define HAVE_ASM_WEAK_DIRECTIVE 1
#define HAVE_ASM_SET_DIRECTIVE 1
#define ASM_GLOBAL_DIRECTIVE .globl
#ifndef ASM_LINE_SEP
# define ASM_LINE_SEP ;
#endif
#ifndef C_SYMBOL_NAME
# ifdef NO_UNDERSCORES
# define C_SYMBOL_NAME(name) name
# else
# define C_SYMBOL_NAME(name) _##name
# endif
#endif
#define attribute_hidden __attribute__ ((visibility ("hidden")))
#include <features.h>
#ifndef __ASSEMBLER__
/* GCC understands weak symbols and aliases; use its interface where
possible, instead of embedded assembly language. */
/* Define ALIASNAME as a strong alias for NAME. */
# define strong_alias(name, aliasname) _strong_alias(name, aliasname)
# define _strong_alias(name, aliasname) \
extern __typeof (name) aliasname __attribute__ ((alias (#name)));
/* This comes between the return type and function name in
a function definition to make that definition weak. */
# define weak_function __attribute__ ((weak))
# define weak_const_function __attribute__ ((weak, __const__))
# ifdef HAVE_WEAK_SYMBOLS
/* Define ALIASNAME as a weak alias for NAME.
If weak aliases are not available, this defines a strong alias. */
# define weak_alias(name, aliasname) _weak_alias (name, aliasname)
# define _weak_alias(name, aliasname) \
extern __typeof (name) aliasname __attribute__ ((weak, alias (#name)));
/* Declare SYMBOL as weak undefined symbol (resolved to 0 if not defined). */
# define weak_extern(symbol) _weak_extern (symbol)
# ifdef HAVE_ASM_WEAKEXT_DIRECTIVE
# define _weak_extern(symbol) asm (".weakext " __SYMBOL_PREFIX #symbol);
# else
# define _weak_extern(symbol) asm (".weak " __SYMBOL_PREFIX #symbol);
# endif
# else
# define weak_alias(name, aliasname) strong_alias(name, aliasname)
# define weak_extern(symbol) /* Nothing. */
# endif
#else /* __ASSEMBLER__ */
# ifdef HAVE_ASM_SET_DIRECTIVE
# define strong_alias(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 strong_alias(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 strong_alias(original, alias) \
ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME (alias) ASM_LINE_SEP \
C_SYMBOL_NAME (alias) = C_SYMBOL_NAME (original)
# endif
# endif
# ifdef HAVE_WEAK_SYMBOLS
# ifdef HAVE_ASM_WEAKEXT_DIRECTIVE
# define weak_alias(original, alias) \
.weakext C_SYMBOL_NAME (alias), C_SYMBOL_NAME (original)
# define weak_extern(symbol) \
.weakext C_SYMBOL_NAME (symbol)
# else /* ! HAVE_ASM_WEAKEXT_DIRECTIVE */
# ifdef HAVE_ASM_GLOBAL_DOT_NAME
# define weak_alias(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 weak_alias(original, alias) \
.weak C_SYMBOL_NAME (alias) ASM_LINE_SEP \
C_SYMBOL_NAME (alias) = C_SYMBOL_NAME (original)
# endif
# define weak_extern(symbol) \
.weak C_SYMBOL_NAME (symbol)
# endif /* ! HAVE_ASM_WEAKEXT_DIRECTIVE */
# else /* ! HAVE_WEAK_SYMBOLS */
# define weak_alias(original, alias) strong_alias(original, alias)
# define weak_extern(symbol) /* Nothing */
# endif /* ! HAVE_WEAK_SYMBOLS */
#endif /* __ASSEMBLER__ */
-------------- next part --------------
#include "libc-hidden.h"
libc_hidden (int, h1, (int __fd));
libc_hidden (int, h2, (int __fd));
-------------- next part --------------
#include "x.h"
void foo (void)
{
h1 (26);
}
int __h2 (int __fd)
{
return __fd;
}
strong_alias (__h2, h2)
libc_hidden_weak (h2)
-------------- next part --------------
#include "x.h"
void bar (void)
{
h1 (26);
}
int h1 (int __fd)
{
return __fd;
}
libc_hidden_def(h1)
void baz (void)
{
h1 (26);
}
More information about the Libc-hacker
mailing list