1
0
mirror of https://sourceware.org/git/glibc.git synced 2025-07-29 11:41:21 +03:00

powerpc: Simplify vsyscall internal macros

This patch simplifies the powerpc internal macros for vDSO calls
by:

  - Removing INTERNAL_VSYSCALL_NO_SYSCALL_FALLBACK, used solely on
    get_timebase_freq.

  - Adjust INTERNAL_VSYSCALL_CALL_TYPE powerpc32 to follow powerpc64
    argument ordering.

  - Use HAVE_*_VSYSCALL instead of explicit strings.

  - Make powerpc libc-vdso.h include generic implementation.

No semantic change expected, checked on powerpc-linux-gnu-power4,
powerpc64-linux-gnu, and powerpc64le-linux-gnu.

	* sysdeps/unix/sysv/linux/libc-vdso.h (VDSO_IFUNC_RET): Define if not
	defined.
	* sysdeps/unix/sysv/linux/powerpc/get_timebase_freq.c
	(__get_timebase_freq): Remove use of
	INTERNAL_VSYSCALL_NO_SYSCALL_FALLBACK.
	(get_timebase_freq_fallback): New symbol.
	* sysdeps/unix/sysv/linux/powerpc/gettimeofday.c (time): Use
	HAVE_GETTIMEOFDAY_VSYSCALL.
	* sysdeps/unix/sysv/linux/powerpc/time.c (gettimeofday): Use
	HAVE_TIME_VSYSCALL.
	* sysdeps/unix/sysv/linux/powerpc/libc-vdso.h: Include generic
	implementation.
	* sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h
	(INTERNAL_VSYSCALL_CALL_TYPE): Make calling convention similar to
	powerpc64.
	(INTERNAL_VSYSCALL_NO_SYSCALL_FALLBACK): Remove macro.
	* .../sysv/linux/powerpc/powerpc64/sysdep.h
	(INTERNAL_VSYSCALL_NO_SYSCALL_FALLBACK): Likewise.
	* sysdeps/unix/sysv/linux/powerpc/sysdep.h
	(HAVE_GETTIMEOFDAY_VSYSCALL): Define.
This commit is contained in:
Adhemerval Zanella
2019-06-03 21:07:25 +00:00
parent b8a7c7da4e
commit 986a506481
6 changed files with 59 additions and 54 deletions

View File

@ -1,5 +1,26 @@
2019-09-17 Adhemerval Zanella <adhemerval.zanella@linaro.org> 2019-09-17 Adhemerval Zanella <adhemerval.zanella@linaro.org>
* sysdeps/unix/sysv/linux/libc-vdso.h (VDSO_IFUNC_RET): Define if not
defined.
* sysdeps/unix/sysv/linux/powerpc/get_timebase_freq.c
(__get_timebase_freq): Remove use of
INTERNAL_VSYSCALL_NO_SYSCALL_FALLBACK.
(get_timebase_freq_fallback): New symbol.
* sysdeps/unix/sysv/linux/powerpc/gettimeofday.c (time): Use
HAVE_GETTIMEOFDAY_VSYSCALL.
* sysdeps/unix/sysv/linux/powerpc/time.c (gettimeofday): Use
HAVE_TIME_VSYSCALL.
* sysdeps/unix/sysv/linux/powerpc/libc-vdso.h: Include generic
implementation.
* sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h
(INTERNAL_VSYSCALL_CALL_TYPE): Make calling convention similar to
powerpc64.
(INTERNAL_VSYSCALL_NO_SYSCALL_FALLBACK): Remove macro.
* .../sysv/linux/powerpc/powerpc64/sysdep.h
(INTERNAL_VSYSCALL_NO_SYSCALL_FALLBACK): Likewise.
* sysdeps/unix/sysv/linux/powerpc/sysdep.h
(HAVE_GETTIMEOFDAY_VSYSCALL): Define.
* sysdeps/powerpc/powerpc32/backtrace.c (is_sigtramp_address, * sysdeps/powerpc/powerpc32/backtrace.c (is_sigtramp_address,
is_sigtramp_address_rt): Use HAVE_SIGTRAMP_{RT}32 instead of SHARED. is_sigtramp_address_rt): Use HAVE_SIGTRAMP_{RT}32 instead of SHARED.
* sysdeps/powerpc/powerpc64/backtrace.c (is_sigtramp_address): * sysdeps/powerpc/powerpc64/backtrace.c (is_sigtramp_address):

View File

@ -21,6 +21,13 @@
#define VDSO_SYMBOL(__name) __vdso_##__name #define VDSO_SYMBOL(__name) __vdso_##__name
/* Adjust the return IFUNC value from a vDSO symbol accordingly required
by the ELFv1 ABI. It is used by the architecture to create an ODP
entry since the kernel vDSO does not provide it. */
#ifndef VDSO_IFUNC_RET
# define VDSO_IFUNC_RET(__value) (__value)
#endif
#ifdef HAVE_CLOCK_GETTIME_VSYSCALL #ifdef HAVE_CLOCK_GETTIME_VSYSCALL
extern int (*VDSO_SYMBOL(clock_gettime)) (clockid_t, struct timespec *) extern int (*VDSO_SYMBOL(clock_gettime)) (clockid_t, struct timespec *)
attribute_hidden; attribute_hidden;

View File

@ -23,17 +23,11 @@
#include <not-cancel.h> #include <not-cancel.h>
#include <libc-vdso.h> #include <libc-vdso.h>
uint64_t static uint64_t
__get_timebase_freq (void) get_timebase_freq_fallback (void)
{ {
hp_timing_t result = 0L; hp_timing_t result = 0L;
#ifdef SHARED
/* The vDSO does not return an error (it clear cr0.so on returning). */
INTERNAL_SYSCALL_DECL (err);
result =
INTERNAL_VSYSCALL_NO_SYSCALL_FALLBACK (get_tbfreq, err, uint64_t, 0);
#else
/* We read the information from the /proc filesystem. /proc/cpuinfo /* We read the information from the /proc filesystem. /proc/cpuinfo
contains at least one line like: contains at least one line like:
timebase : 33333333 timebase : 33333333
@ -99,8 +93,20 @@ __get_timebase_freq (void)
} }
} }
} }
#endif
return result; return result;
} }
uint64_t
__get_timebase_freq (void)
{
/* The vDSO does not have a fallback mechanism (such calling a syscall). */
__typeof (VDSO_SYMBOL (get_tbfreq)) vdsop = VDSO_SYMBOL (get_tbfreq);
PTR_DEMANGLE (vdsop);
if (vdsop == NULL)
return get_timebase_freq_fallback ();
INTERNAL_SYSCALL_DECL (err);
return INTERNAL_VSYSCALL_CALL_TYPE (vdsop, err, uint64_t, 0);
}
weak_alias (__get_timebase_freq, __ppc_get_timebase_freq) weak_alias (__get_timebase_freq, __ppc_get_timebase_freq)

View File

@ -22,17 +22,9 @@
#include <sysdep.h> #include <sysdep.h>
#include <sysdep-vdso.h> #include <sysdep-vdso.h>
#include_next <libc-vdso.h>
extern unsigned long long (*VDSO_SYMBOL(get_tbfreq)) (void);
#if defined(__PPC64__) || defined(__powerpc64__)
extern void *VDSO_SYMBOL(sigtramp_rt64);
#else
extern void *VDSO_SYMBOL(sigtramp32);
extern void *VDSO_SYMBOL(sigtramp_rt32);
#endif
#if (defined(__PPC64__) || defined(__powerpc64__)) && _CALL_ELF != 2 #if (defined(__PPC64__) || defined(__powerpc64__)) && _CALL_ELF != 2
# include <dl-machine.h>
/* The correct solution is for _dl_vdso_vsym to return the address of the OPD /* The correct solution is for _dl_vdso_vsym to return the address of the OPD
for the kernel VDSO function. That address would then be stored in the for the kernel VDSO function. That address would then be stored in the
__vdso_* variables and returned as the result of the IFUNC resolver function. __vdso_* variables and returned as the result of the IFUNC resolver function.
@ -51,7 +43,7 @@ extern void *VDSO_SYMBOL(sigtramp_rt32);
are processed immediately at startup the resolver functions and this code need are processed immediately at startup the resolver functions and this code need
not be thread-safe, but if the caller writes to a PLT slot it must do so in a not be thread-safe, but if the caller writes to a PLT slot it must do so in a
thread-safe manner with all the required barriers. */ thread-safe manner with all the required barriers. */
#define VDSO_IFUNC_RET(value) \ # define VDSO_IFUNC_RET(value) \
({ \ ({ \
static Elf64_FuncDesc vdso_opd = { .fd_toc = ~0x0 }; \ static Elf64_FuncDesc vdso_opd = { .fd_toc = ~0x0 }; \
vdso_opd.fd_func = (Elf64_Addr)value; \ vdso_opd.fd_func = (Elf64_Addr)value; \
@ -59,7 +51,17 @@ extern void *VDSO_SYMBOL(sigtramp_rt32);
}) })
#else #else
#define VDSO_IFUNC_RET(value) ((void *) (value)) # define VDSO_IFUNC_RET(value) ((void *) (value))
#endif
#include_next <libc-vdso.h>
extern unsigned long long (*VDSO_SYMBOL(get_tbfreq)) (void);
#if defined(__PPC64__) || defined(__powerpc64__)
extern void *VDSO_SYMBOL(sigtramp_rt64);
#else
extern void *VDSO_SYMBOL(sigtramp32);
extern void *VDSO_SYMBOL(sigtramp_rt32);
#endif #endif
#endif /* _LIBC_VDSO_H */ #endif /* _LIBC_VDSO_H */

View File

@ -41,7 +41,7 @@
function call, with the exception of LR (which is needed for the function call, with the exception of LR (which is needed for the
"sc; bnslr+" sequence) and CR (where only CR0.SO is clobbered to signal "sc; bnslr+" sequence) and CR (where only CR0.SO is clobbered to signal
an error return status). */ an error return status). */
# define INTERNAL_VSYSCALL_CALL_TYPE(funcptr, err, nr, type, args...) \ # define INTERNAL_VSYSCALL_CALL_TYPE(funcptr, err, type, nr, args...) \
({ \ ({ \
register void *r0 __asm__ ("r0"); \ register void *r0 __asm__ ("r0"); \
register long int r3 __asm__ ("r3"); \ register long int r3 __asm__ ("r3"); \
@ -69,7 +69,7 @@
}) })
#define INTERNAL_VSYSCALL_CALL(funcptr, err, nr, args...) \ #define INTERNAL_VSYSCALL_CALL(funcptr, err, nr, args...) \
INTERNAL_VSYSCALL_CALL_TYPE(funcptr, err, nr, long int, args) INTERNAL_VSYSCALL_CALL_TYPE(funcptr, err, long int, nr, args)
# undef INLINE_SYSCALL # undef INLINE_SYSCALL
# define INLINE_SYSCALL(name, nr, args...) \ # define INLINE_SYSCALL(name, nr, args...) \
@ -131,20 +131,6 @@
# undef INTERNAL_SYSCALL_ERRNO # undef INTERNAL_SYSCALL_ERRNO
# define INTERNAL_SYSCALL_ERRNO(val, err) (val) # define INTERNAL_SYSCALL_ERRNO(val, err) (val)
# define INTERNAL_VSYSCALL_NO_SYSCALL_FALLBACK(name, err, type, nr, args...) \
({ \
type sc_ret = ENOSYS; \
\
__typeof (__vdso_##name) vdsop = __vdso_##name; \
PTR_DEMANGLE (vdsop); \
if (vdsop != NULL) \
sc_ret = \
INTERNAL_VSYSCALL_CALL_TYPE (vdsop, err, nr, type, ##args); \
else \
err = 1 << 28; \
sc_ret; \
})
# define LOADARGS_0(name, dummy) \ # define LOADARGS_0(name, dummy) \
r0 = name r0 = name
# define LOADARGS_1(name, __arg1) \ # define LOADARGS_1(name, __arg1) \

View File

@ -45,22 +45,6 @@
#endif /* __ASSEMBLER__ */ #endif /* __ASSEMBLER__ */
/* This version is for internal uses when there is no desire
to set errno */
#define INTERNAL_VSYSCALL_NO_SYSCALL_FALLBACK(name, err, type, nr, args...) \
({ \
type sc_ret = ENOSYS; \
\
__typeof (__vdso_##name) vdsop = __vdso_##name; \
PTR_DEMANGLE (vdsop); \
if (vdsop != NULL) \
sc_ret = \
INTERNAL_VSYSCALL_CALL_TYPE (vdsop, err, type, nr, ##args); \
else \
err = 1 << 28; \
sc_ret; \
})
/* Define a macro which expands inline into the wrapper code for a system /* Define a macro which expands inline into the wrapper code for a system
call. This use is for internal calls that do not need to handle errors call. This use is for internal calls that do not need to handle errors
normally. It will never touch errno. This returns just what the kernel normally. It will never touch errno. This returns just what the kernel
@ -94,10 +78,9 @@
#define INTERNAL_VSYSCALL_CALL(funcptr, err, nr, args...) \ #define INTERNAL_VSYSCALL_CALL(funcptr, err, nr, args...) \
INTERNAL_VSYSCALL_CALL_TYPE(funcptr, err, long int, nr, args) INTERNAL_VSYSCALL_CALL_TYPE(funcptr, err, long int, nr, args)
#undef INLINE_SYSCALL
/* This version is for kernels that implement system calls that /* This version is for kernels that implement system calls that
behave like function calls as far as register saving. */ behave like function calls as far as register saving. */
#undef INLINE_SYSCALL
#define INLINE_SYSCALL(name, nr, args...) \ #define INLINE_SYSCALL(name, nr, args...) \
({ \ ({ \
INTERNAL_SYSCALL_DECL (sc_err); \ INTERNAL_SYSCALL_DECL (sc_err); \