syscalls.list support for vDSO IFUNCs, use it for x32 gettimeofday and time.
This commit is contained in:
parent
d6c33fda03
commit
c14874927b
13
ChangeLog
13
ChangeLog
|
@ -1,5 +1,18 @@
|
||||||
2012-05-24 Roland McGrath <roland@hack.frob.com>
|
2012-05-24 Roland McGrath <roland@hack.frob.com>
|
||||||
|
|
||||||
|
* sysdeps/unix/sysv/linux/x86_64/x32/syscalls.list: New file.
|
||||||
|
|
||||||
|
* sysdeps/unix/make-syscalls.sh: Support "syscall:vdso_name@VDSOVER"
|
||||||
|
in the third column, to generate for the shared library an IFUNC
|
||||||
|
that uses _dl_vdso_vsym.
|
||||||
|
* Makerules (COMPILE.c, compile-stdin.c): New variables.
|
||||||
|
* Makeconfig (object-suffixes-noshared): New variable.
|
||||||
|
|
||||||
|
* sysdeps/unix/sysv/linux/dl-vdso.h (PREPARE_VERSION_KNOWN): New macro.
|
||||||
|
(VDSO_NAME_LINUX_2_6, VDSO_HASH_LINUX_2_6): New macros.
|
||||||
|
(VDSO_NAME_LINUX_2_6_15, VDSO_HASH_LINUX_2_6_15): New macros.
|
||||||
|
(VDSO_NAME_LINUX_2_6_29, VDSO_HASH_LINUX_2_6_29): New macros.
|
||||||
|
|
||||||
[BZ #14132]
|
[BZ #14132]
|
||||||
* include/sys/time.h (__gettimeofday): Remove macro.
|
* include/sys/time.h (__gettimeofday): Remove macro.
|
||||||
(__gettimeofday, gettimeofday): Add libc_hidden_proto.
|
(__gettimeofday, gettimeofday): Add libc_hidden_proto.
|
||||||
|
|
|
@ -720,6 +720,10 @@ CFLAGS-.op = -pg
|
||||||
libtype.op = lib%_p.a
|
libtype.op = lib%_p.a
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
# Convenience variable for when we want to treat shared-library cases
|
||||||
|
# differently from the rest.
|
||||||
|
object-suffixes-noshared := $(filter-out .os,$(object-suffixes))
|
||||||
|
|
||||||
bppfx = BP-
|
bppfx = BP-
|
||||||
ifeq (yes,$(build-bounded))
|
ifeq (yes,$(build-bounded))
|
||||||
# Under --enable-bounded, we build the library with `-fbounded-pointers -g'
|
# Under --enable-bounded, we build the library with `-fbounded-pointers -g'
|
||||||
|
|
|
@ -366,6 +366,7 @@ compile.c = $(CC) $< -c $(CFLAGS) $(CPPFLAGS)
|
||||||
compile.cc = $(CXX) $< -c $(CXXFLAGS) $(CPPFLAGS)
|
compile.cc = $(CXX) $< -c $(CXXFLAGS) $(CPPFLAGS)
|
||||||
compile.S = $(CC) $< -c $(CPPFLAGS) $(S-CPPFLAGS) \
|
compile.S = $(CC) $< -c $(CPPFLAGS) $(S-CPPFLAGS) \
|
||||||
$(ASFLAGS) $(ASFLAGS-$(suffix $@))
|
$(ASFLAGS) $(ASFLAGS-$(suffix $@))
|
||||||
|
COMPILE.c = $(CC) -c $(CFLAGS) $(CPPFLAGS)
|
||||||
COMPILE.S = $(CC) -c $(CPPFLAGS) $(S-CPPFLAGS) \
|
COMPILE.S = $(CC) -c $(CPPFLAGS) $(S-CPPFLAGS) \
|
||||||
$(ASFLAGS) $(ASFLAGS-$(suffix $@))
|
$(ASFLAGS) $(ASFLAGS-$(suffix $@))
|
||||||
|
|
||||||
|
@ -374,6 +375,9 @@ COMPILE.S = $(CC) -c $(CPPFLAGS) $(S-CPPFLAGS) \
|
||||||
# together. You can't compile the C library with such a compiler.
|
# together. You can't compile the C library with such a compiler.
|
||||||
OUTPUT_OPTION = -o $@
|
OUTPUT_OPTION = -o $@
|
||||||
|
|
||||||
|
# This is the end of the pipeline for compiling generated C code.
|
||||||
|
compile-stdin.c = $(COMPILE.c) -o $@ -x c - $(compile-mkdep-flags)
|
||||||
|
|
||||||
# We need the $(CFLAGS) to be in there to have the right predefines during
|
# We need the $(CFLAGS) to be in there to have the right predefines during
|
||||||
# the dependency run for C sources. But having it for assembly sources can
|
# the dependency run for C sources. But having it for assembly sources can
|
||||||
# get the wrong predefines.
|
# get the wrong predefines.
|
||||||
|
|
|
@ -64,10 +64,67 @@ done`
|
||||||
# Any calls left?
|
# Any calls left?
|
||||||
test -n "$calls" || exit 0
|
test -n "$calls" || exit 0
|
||||||
|
|
||||||
|
# This uses variables $weak and $strong.
|
||||||
|
emit_weak_aliases()
|
||||||
|
{
|
||||||
|
# A shortcoming in the current gas is that it will only allow one
|
||||||
|
# version-alias per symbol. So we create new strong aliases as needed.
|
||||||
|
vcount=""
|
||||||
|
|
||||||
|
for name in $weak; do
|
||||||
|
case $name in
|
||||||
|
*@@*)
|
||||||
|
base=`echo $name | sed 's/@@.*//'`
|
||||||
|
ver=`echo $name | sed 's/.*@@//'`
|
||||||
|
if test -z "$vcount" ; then
|
||||||
|
source=$strong
|
||||||
|
vcount=1
|
||||||
|
else
|
||||||
|
source="${strong}_${vcount}"
|
||||||
|
vcount=`expr $vcount + 1`
|
||||||
|
echo " echo 'strong_alias ($strong, $source)'; \\"
|
||||||
|
fi
|
||||||
|
echo " echo 'default_symbol_version($source, $base, $ver)'; \\"
|
||||||
|
;;
|
||||||
|
*@*)
|
||||||
|
base=`echo $name | sed 's/@.*//'`
|
||||||
|
ver=`echo $name | sed 's/.*@//'`
|
||||||
|
if test -z "$vcount" ; then
|
||||||
|
source=$strong
|
||||||
|
vcount=1
|
||||||
|
else
|
||||||
|
source="${strong}_${vcount}"
|
||||||
|
vcount=`expr $vcount + 1`
|
||||||
|
echo " echo 'strong_alias ($strong, $source)'; \\"
|
||||||
|
fi
|
||||||
|
echo " echo 'symbol_version ($source, $base, $ver)'; \\"
|
||||||
|
;;
|
||||||
|
!*)
|
||||||
|
name=`echo $name | sed 's/.//'`
|
||||||
|
echo " echo 'strong_alias ($strong, $name)'; \\"
|
||||||
|
echo " echo 'libc_hidden_def ($name)'; \\"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo " echo 'weak_alias ($strong, $name)'; \\"
|
||||||
|
echo " echo 'libc_hidden_weak ($name)'; \\"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
# Emit rules to compile the syscalls remaining in $calls.
|
# Emit rules to compile the syscalls remaining in $calls.
|
||||||
echo "$calls" |
|
echo "$calls" |
|
||||||
while read file srcfile caller syscall args strong weak; do
|
while read file srcfile caller syscall args strong weak; do
|
||||||
|
|
||||||
|
vdso_syscall=
|
||||||
|
case x"$syscall" in
|
||||||
|
*:*@*)
|
||||||
|
vdso_syscall="${syscall#*:}"
|
||||||
|
syscall="${syscall%:*}"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
case x"$syscall" in
|
case x"$syscall" in
|
||||||
x-) callnum=_ ;;
|
x-) callnum=_ ;;
|
||||||
*)
|
*)
|
||||||
|
@ -144,13 +201,14 @@ while read file srcfile caller syscall args strong weak; do
|
||||||
# Emit a compilation rule for this syscall.
|
# Emit a compilation rule for this syscall.
|
||||||
if test $shared_only = t; then
|
if test $shared_only = t; then
|
||||||
# The versioned symbols are only in the shared library.
|
# The versioned symbols are only in the shared library.
|
||||||
echo "\
|
echo "shared-only-routines += $file"
|
||||||
shared-only-routines += $file
|
test -n "$vdso_syscall" || echo "\$(objpfx)${file}.os: \\"
|
||||||
\$(objpfx)${file}.os: \\"
|
|
||||||
else
|
else
|
||||||
|
object_suffixes='$(object-suffixes)'
|
||||||
|
test -z "$vdso_syscall" || object_suffixes='$(object-suffixes-noshared)'
|
||||||
echo "\
|
echo "\
|
||||||
\$(foreach p,\$(sysd-rules-targets),\
|
\$(foreach p,\$(sysd-rules-targets),\
|
||||||
\$(foreach o,\$(object-suffixes),\$(objpfx)\$(patsubst %,\$p,$file)\$o)): \\"
|
\$(foreach o,${object_suffixes},\$(objpfx)\$(patsubst %,\$p,$file)\$o)): \\"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo " \$(..)sysdeps/unix/make-syscalls.sh"
|
echo " \$(..)sysdeps/unix/make-syscalls.sh"
|
||||||
|
@ -178,55 +236,43 @@ shared-only-routines += $file
|
||||||
esac
|
esac
|
||||||
|
|
||||||
# Append any weak aliases or versions defined for this syscall function.
|
# Append any weak aliases or versions defined for this syscall function.
|
||||||
|
emit_weak_aliases
|
||||||
# A shortcoming in the current gas is that it will only allow one
|
|
||||||
# version-alias per symbol. So we create new strong aliases as needed.
|
|
||||||
vcount=""
|
|
||||||
|
|
||||||
for name in $weak; do
|
|
||||||
case $name in
|
|
||||||
*@@*)
|
|
||||||
base=`echo $name | sed 's/@@.*//'`
|
|
||||||
ver=`echo $name | sed 's/.*@@//'`
|
|
||||||
if test -z "$vcount" ; then
|
|
||||||
source=$strong
|
|
||||||
vcount=1
|
|
||||||
else
|
|
||||||
source="${strong}_${vcount}"
|
|
||||||
vcount=`expr $vcount + 1`
|
|
||||||
echo " echo 'strong_alias ($strong, $source)'; \\"
|
|
||||||
fi
|
|
||||||
echo " echo 'default_symbol_version($source, $base, $ver)'; \\"
|
|
||||||
;;
|
|
||||||
*@*)
|
|
||||||
base=`echo $name | sed 's/@.*//'`
|
|
||||||
ver=`echo $name | sed 's/.*@//'`
|
|
||||||
if test -z "$vcount" ; then
|
|
||||||
source=$strong
|
|
||||||
vcount=1
|
|
||||||
else
|
|
||||||
source="${strong}_${vcount}"
|
|
||||||
vcount=`expr $vcount + 1`
|
|
||||||
echo " echo 'strong_alias ($strong, $source)'; \\"
|
|
||||||
fi
|
|
||||||
echo " echo 'symbol_version ($source, $base, $ver)'; \\"
|
|
||||||
;;
|
|
||||||
!*)
|
|
||||||
name=`echo $name | sed 's/.//'`
|
|
||||||
echo " echo 'strong_alias ($strong, $name)'; \\"
|
|
||||||
echo " echo 'libc_hidden_def ($name)'; \\"
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
echo " echo 'weak_alias ($strong, $name)'; \\"
|
|
||||||
echo " echo 'libc_hidden_weak ($name)'; \\"
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
|
|
||||||
# And finally, pipe this all into the compiler.
|
# And finally, pipe this all into the compiler.
|
||||||
echo ' ) | $(compile-syscall) '"\
|
echo ' ) | $(compile-syscall) '"\
|
||||||
\$(foreach p,\$(patsubst %$file,%,\$(basename \$(@F))),\$(\$(p)CPPFLAGS))"
|
\$(foreach p,\$(patsubst %$file,%,\$(basename \$(@F))),\$(\$(p)CPPFLAGS))"
|
||||||
|
|
||||||
|
if test -n "$vdso_syscall"; then
|
||||||
|
# In the shared library, we're going to emit an IFUNC using a vDSO function.
|
||||||
|
# $vdso_syscall looks like "name@KERNEL_X.Y" where "name" is the symbol
|
||||||
|
# name in the vDSO and KERNEL_X.Y is its symbol version.
|
||||||
|
vdso_symbol="${vdso_syscall%@*}"
|
||||||
|
vdso_symver="${vdso_syscall#*@}"
|
||||||
|
vdso_symver="${vdso_symver//./_}"
|
||||||
|
echo "\
|
||||||
|
\$(foreach p,\$(sysd-rules-targets),\$(objpfx)\$(patsubst %,\$p,$file).os): \\
|
||||||
|
\$(..)sysdeps/unix/make-syscalls.sh\
|
||||||
|
\$(make-target-directory)
|
||||||
|
(echo '#include <dl-vdso.h>'; \\
|
||||||
|
echo 'extern void *${strong}_ifunc (void) __asm (\"${strong}\");'; \\
|
||||||
|
echo 'void *'; \\
|
||||||
|
echo '${strong}_ifunc (void)'; \\
|
||||||
|
echo '{'; \\
|
||||||
|
echo ' PREPARE_VERSION_KNOWN (symver, ${vdso_symver});'; \\
|
||||||
|
echo ' return _dl_vdso_vsym (\"${vdso_symbol}\", &symver);'; \\
|
||||||
|
echo '}'; \\
|
||||||
|
echo 'asm (\".type ${strong}, %gnu_indirect_function\");'; \\"
|
||||||
|
# This is doing "libc_hidden_def (${strong})", but the compiler
|
||||||
|
# doesn't know that we've defined ${strong} in the same file, so
|
||||||
|
# we can't do it the normal way.
|
||||||
|
echo "\
|
||||||
|
echo 'asm (\".globl __GI_${strong}\\n\"'; \\
|
||||||
|
echo ' \"__GI_${strong} = ${strong}\");'; \\"
|
||||||
|
emit_weak_aliases
|
||||||
|
echo ' ) | $(compile-stdin.c) '"\
|
||||||
|
\$(foreach p,\$(patsubst %$file,%,\$(basename \$(@F))),\$(\$(p)CPPFLAGS))"
|
||||||
|
fi
|
||||||
|
|
||||||
if test $shared_only = t; then
|
if test $shared_only = t; then
|
||||||
# The versioned symbols are only in the shared library.
|
# The versioned symbols are only in the shared library.
|
||||||
echo endif
|
echo endif
|
||||||
|
|
|
@ -33,6 +33,17 @@
|
||||||
/* We don't have a specific file where the symbol can be found. */ \
|
/* We don't have a specific file where the symbol can be found. */ \
|
||||||
var.filename = NULL
|
var.filename = NULL
|
||||||
|
|
||||||
|
/* Use this for the known version sets defined below, where we
|
||||||
|
record their precomputed hash values only once, in this file. */
|
||||||
|
#define PREPARE_VERSION_KNOWN(var, vname) \
|
||||||
|
PREPARE_VERSION (var, VDSO_NAME_##vname, VDSO_HASH_##vname)
|
||||||
|
|
||||||
|
#define VDSO_NAME_LINUX_2_6 "LINUX_2.6"
|
||||||
|
#define VDSO_HASH_LINUX_2_6 61765110
|
||||||
|
#define VDSO_NAME_LINUX_2_6_15 "LINUX_2.6.15"
|
||||||
|
#define VDSO_HASH_LINUX_2_6_15 123718565
|
||||||
|
#define VDSO_NAME_LINUX_2_6_29 "LINUX_2.6.29"
|
||||||
|
#define VDSO_HASH_LINUX_2_6_29 123718585
|
||||||
|
|
||||||
/* Functions for resolving symbols in the VDSO link map. */
|
/* Functions for resolving symbols in the VDSO link map. */
|
||||||
extern void *_dl_vdso_vsym (const char *name,
|
extern void *_dl_vdso_vsym (const char *name,
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
# File name Caller Syscall name # args Strong name Weak names
|
# File name Caller Syscall name # args Strong name Weak names
|
||||||
|
|
||||||
fallocate - fallocate Ci:iiii fallocate fallocate64
|
fallocate - fallocate Ci:iiii fallocate fallocate64
|
||||||
|
gettimeofday - gettimeofday:__vdso_gettimeofday@LINUX_2.6 i:pP __gettimeofday gettimeofday
|
||||||
posix_fadvise - fadvise64 Vi:iiii posix_fadvise posix_fadvise64
|
posix_fadvise - fadvise64 Vi:iiii posix_fadvise posix_fadvise64
|
||||||
preadv - preadv Ci:ipii preadv preadv64
|
preadv - preadv Ci:ipii preadv preadv64
|
||||||
pwritev - pwritev Ci:ipii pwritev pwritev64
|
pwritev - pwritev Ci:ipii pwritev pwritev64
|
||||||
|
time - time:__vdso_time@LINUX_2.6 Ei:P time
|
||||||
|
|
Loading…
Reference in a new issue