[OE-core] [PATCH v2] [Dora] eglibc 2.18: powerpc: Fix time related syscalls

Richard Purdie richard.purdie at linuxfoundation.org
Fri Mar 28 17:25:51 UTC 2014


On Fri, 2014-03-28 at 14:41 +0000, Mats Kärrman wrote:
> Concatenated fix of PowerPC time related system calls in eglibc 2.18 taken
> from upstream glibc. See credits in patch header.
> 
> The effect is that some time related system calls returns nothing or garbage.
> Fix tested on PowerPC e300c3.
> 
> Eglibc 2.17 does not have this issue and the patches are already part of 2.19.
> 
> Upstream-Status: Backport

This needs to be in the header of the patch, not the commit message (so
that when reading the patch later, someone can understand its status
quickly). When I see people removing patches during package upgrades, I
can also be happier when I see its a backport.

Cheers,

Richard

> Signed-off-by: Mats Karrman <mats.karrman at tritech.se>
> ---
>  .../ppc-fix-time-related-syscalls.patch            |  225 ++++++++++++++++++++
>  meta/recipes-core/eglibc/eglibc_2.18.bb            |    1 +
>  2 files changed, 226 insertions(+)
>  create mode 100644 meta/recipes-core/eglibc/eglibc-2.18/ppc-fix-time-related-syscalls.patch
> 
> V2: Added upstream status.
> 
> diff --git a/meta/recipes-core/eglibc/eglibc-2.18/ppc-fix-time-related-syscalls.patch b/meta/recipes-core/eglibc/eglibc-2.18/ppc-fix-time-related-syscalls.patch
> new file mode 100644
> index 0000000..fa1072b
> --- /dev/null
> +++ b/meta/recipes-core/eglibc/eglibc-2.18/ppc-fix-time-related-syscalls.patch
> @@ -0,0 +1,225 @@
> +Concatenated fix of PowerPC time related system calls in eglibc 2.18 taken
> +from upstream glibc. Eglibc 2.17 does not have this issue and the patches are
> +already part of 2.19.
> +This compilation includes the following committs:
> +
> +
> +PowerPC: Fix vDSO missing ODP entries
> +
> +author	Adhemerval Zanella <azanella at linux.vnet.ibm.com>	
> +	Thu, 7 Nov 2013 11:34:22 +0000 (05:34 -0600)
> +
> +This patch fixes the vDSO symbol used directed in IFUNC resolver where
> +they do not have an associated ODP entry leading to undefined behavior
> +in some cases. It adds an artificial OPD static entry to such cases
> +and set its TOC to non 0 to avoid triggering lazy resolutions.
> +
> +
> +Update copyright notices with scripts/update-copyrights
> +
> +author	Allan McRae <allan at archlinux.org>	
> +	Wed, 1 Jan 2014 11:03:15 +0000 (21:03 +1000)
> +
> +((Only for files otherwise touched by this patch))
> +
> +
> +PowerPC: Fix ftime gettimeofday internal call returning bogus data
> +
> +author	Adhemerval Zanella <azanella at linux.vnet.ibm.com>	
> +	Thu, 16 Jan 2014 12:53:18 +0000 (06:53 -0600)
> +
> +This patches fixes BZ#16430 by setting a different symbol for internal
> +GLIBC calls that points to ifunc resolvers. For PPC32, if the symbol
> +is defined as hidden (which is the case for gettimeofday and time) the
> +compiler will create local branches (symbol at local) and linker will not
> +create PLT calls (required for IFUNC). This will leads to internal symbol
> +calling the IFUNC resolver instead of the resolved symbol.
> +For PPC64 this behavior does not occur because a call to a function in
> +another translation unit might use a different toc pointer thus requiring
> +a PLT call.
> +
> +
> +PowerPC: Fix gettimeofday ifunc selection
> +
> +author	Adhemerval Zanella <azanella at linux.vnet.ibm.com>	
> +	Mon, 20 Jan 2014 18:29:51 +0000 (12:29 -0600)
> +
> +The IFUNC selector for gettimeofday runs before _libc_vdso_platform_setup where
> +__vdso_gettimeofday is set. The selector then sets __gettimeofday (the internal
> +version used within GLIBC) to use the system call version instead of the vDSO one.
> +This patch changes the check if vDSO is available to get its value directly
> +instead of rely on __vdso_gettimeofday.
> +
> +This patch changes it by getting the vDSO value directly.
> +
> +It fixes BZ#16431.
> +
> +
> +---
> +diff -pruN libc.orig/sysdeps/unix/sysv/linux/powerpc/bits/libc-vdso.h libc/sysdeps/unix/sysv/linux/powerpc/bits/libc-vdso.h
> +--- libc.orig/sysdeps/unix/sysv/linux/powerpc/bits/libc-vdso.h
> ++++ libc/sysdeps/unix/sysv/linux/powerpc/bits/libc-vdso.h
> +@@ -1,5 +1,5 @@
> + /* Resolve function pointers to VDSO functions.
> +-   Copyright (C) 2005-2013 Free Software Foundation, Inc.
> ++   Copyright (C) 2005-2014 Free Software Foundation, Inc.
> +    This file is part of the GNU C Library.
> + 
> +    The GNU C Library is free software; you can redistribute it and/or
> +@@ -34,12 +34,32 @@ extern void *__vdso_getcpu;
> + 
> + extern void *__vdso_time;
> + 
> +-/* This macro is needed for PPC64 to return a skeleton OPD entry of a vDSO
> +-   symbol.  This works because _dl_vdso_vsym always return the function
> +-   address, and no vDSO symbols use the TOC or chain pointers from the OPD
> +-   so we can allow them to be garbage.  */
> + #if defined(__PPC64__) || defined(__powerpc64__)
> +-#define VDSO_IFUNC_RET(value)  ((void *) &(value))
> ++/* 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
> ++   __vdso_* variables and returned as the result of the IFUNC resolver function.
> ++   Yet, the kernel does not contain any OPD entries for the VDSO functions
> ++   (incomplete implementation).  However, PLT relocations for IFUNCs still expect
> ++   the address of an OPD to be returned from the IFUNC resolver function (since
> ++   PLT entries on PPC64 are just copies of OPDs).  The solution for now is to
> ++   create an artificial static OPD for each VDSO function returned by a resolver
> ++   function.  The TOC value is set to a non-zero value to avoid triggering lazy
> ++   symbol resolution via .glink0/.plt0 for a zero TOC (requires thread-safe PLT
> ++   sequences) when the dynamic linker isn't prepared for it e.g. RTLD_NOW.  None
> ++   of the kernel VDSO routines use the TOC or AUX values so any non-zero value
> ++   will work.  Note that function pointer comparisons will not use this artificial
> ++   static OPD since those are resolved via ADDR64 relocations and will point at
> ++   the non-IFUNC default OPD for the symbol.  Lastly, because the IFUNC relocations
> ++   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
> ++   thread-safe manner with all the required barriers.  */
> ++#define VDSO_IFUNC_RET(value)                            \
> ++  ({                                                     \
> ++    static Elf64_FuncDesc vdso_opd = { .fd_toc = ~0x0 }; \
> ++    vdso_opd.fd_func = (Elf64_Addr)value;                \
> ++    &vdso_opd;                                           \
> ++  })
> ++
> + #else
> + #define VDSO_IFUNC_RET(value)  ((void *) (value))
> + #endif
> +diff -pruN libc.orig/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c libc/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c
> +--- libc.orig/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c
> ++++ libc/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c
> +@@ -1,4 +1,4 @@
> +-/* Copyright (C) 2005-2013 Free Software Foundation, Inc.
> ++/* Copyright (C) 2005-2014 Free Software Foundation, Inc.
> +    This file is part of the GNU C Library.
> + 
> +    The GNU C Library is free software; you can redistribute it and/or
> +@@ -22,6 +22,7 @@
> + 
> + # include <dl-vdso.h>
> + # include <bits/libc-vdso.h>
> ++# include <dl-machine.h>
> + 
> + void *gettimeofday_ifunc (void) __asm__ ("__gettimeofday");
> + 
> +@@ -34,17 +35,36 @@ __gettimeofday_syscall (struct timeval *
> + void *
> + gettimeofday_ifunc (void)
> + {
> ++  PREPARE_VERSION (linux2615, "LINUX_2.6.15", 123718565);
> ++
> +   /* If the vDSO is not available we fall back syscall.  */
> +-  return (__vdso_gettimeofday ? VDSO_IFUNC_RET (__vdso_gettimeofday)
> +-	  : __gettimeofday_syscall);
> ++  void *vdso_gettimeofday = _dl_vdso_vsym ("__kernel_gettimeofday", &linux2615);
> ++  return (vdso_gettimeofday ? VDSO_IFUNC_RET (vdso_gettimeofday)
> ++         : (void*)__gettimeofday_syscall);
> + }
> + asm (".type __gettimeofday, %gnu_indirect_function");
> + 
> + /* This is doing "libc_hidden_def (__gettimeofday)" but the compiler won't
> +    let us do it in C because it doesn't know we're defining __gettimeofday
> +    here in this file.  */
> +-asm (".globl __GI___gettimeofday\n"
> +-     "__GI___gettimeofday = __gettimeofday");
> ++asm (".globl __GI___gettimeofday");
> ++
> ++/* __GI___gettimeofday is defined as hidden and for ppc32 it enables the
> ++   compiler make a local call (symbol at local) for internal GLIBC usage. It
> ++   means the PLT won't be used and the ifunc resolver will be called directly.
> ++   For ppc64 a call to a function in another translation unit might use a
> ++   different toc pointer thus disallowing direct branchess and making internal
> ++   ifuncs calls safe.  */
> ++#ifdef __powerpc64__
> ++asm ("__GI___gettimeofday = __gettimeofday");
> ++#else
> ++int
> ++__gettimeofday_vsyscall (struct timeval *tv, struct timezone *tz)
> ++{
> ++  return INLINE_VSYSCALL (gettimeofday, 2, tv, tz);
> ++}
> ++asm ("__GI___gettimeofday = __gettimeofday_vsyscall");
> ++#endif
> + 
> + #else
> + 
> +diff -pruN libc.orig/sysdeps/unix/sysv/linux/powerpc/time.c libc/sysdeps/unix/sysv/linux/powerpc/time.c
> +--- libc.orig/sysdeps/unix/sysv/linux/powerpc/time.c
> ++++ libc/sysdeps/unix/sysv/linux/powerpc/time.c
> +@@ -1,5 +1,5 @@
> + /* time system call for Linux/PowerPC.
> +-   Copyright (C) 2013 Free Software Foundation, Inc.
> ++   Copyright (C) 2013-2014 Free Software Foundation, Inc.
> +    This file is part of the GNU C Library.
> + 
> +    The GNU C Library is free software; you can redistribute it and/or
> +@@ -20,7 +20,9 @@
> + 
> + # include <time.h>
> + # include <sysdep.h>
> ++# include <dl-vdso.h>
> + # include <bits/libc-vdso.h>
> ++# include <dl-machine.h>
> + 
> + void *time_ifunc (void) asm ("time");
> + 
> +@@ -43,17 +45,36 @@ time_syscall (time_t *t)
> + void *
> + time_ifunc (void)
> + {
> ++  PREPARE_VERSION (linux2615, "LINUX_2.6.15", 123718565);
> ++
> +   /* If the vDSO is not available we fall back to the syscall.  */
> +-  return (__vdso_time ? VDSO_IFUNC_RET (__vdso_time)
> +-	  : time_syscall);
> ++  void *vdso_time = _dl_vdso_vsym ("__kernel_time", &linux2615);
> ++  return (vdso_time ? VDSO_IFUNC_RET (vdso_time)
> ++         : (void*)time_syscall);
> + }
> + asm (".type time, %gnu_indirect_function");
> + 
> + /* This is doing "libc_hidden_def (time)" but the compiler won't
> +  * let us do it in C because it doesn't know we're defining time
> +  * here in this file.  */
> +-asm (".globl __GI_time\n"
> +-     "__GI_time = time");
> ++asm (".globl __GI_time");
> ++
> ++/* __GI_time is defined as hidden and for ppc32 it enables the
> ++   compiler make a local call (symbol at local) for internal GLIBC usage. It
> ++   means the PLT won't be used and the ifunc resolver will be called directly.
> ++   For ppc64 a call to a function in another translation unit might use a
> ++   different toc pointer thus disallowing direct branchess and making internal
> ++   ifuncs calls safe.  */
> ++#ifdef __powerpc64__
> ++asm ("__GI_time = time");
> ++#else
> ++time_t
> ++__time_vsyscall (time_t *t)
> ++{
> ++  return INLINE_VSYSCALL (time, 1, t);
> ++}
> ++asm ("__GI_time = __time_vsyscall");
> ++#endif
> + 
> + #else
> + 
> diff --git a/meta/recipes-core/eglibc/eglibc_2.18.bb b/meta/recipes-core/eglibc/eglibc_2.18.bb
> index 15e5eed..43f43ae 100644
> --- a/meta/recipes-core/eglibc/eglibc_2.18.bb
> +++ b/meta/recipes-core/eglibc/eglibc_2.18.bb
> @@ -28,6 +28,7 @@ SRC_URI = "http://downloads.yoctoproject.org/releases/eglibc/eglibc-${PV}-svnr23
>             file://fix-tibetian-locales.patch \
>             file://0001-ARM-Pass-dl_hwcap-to-IFUNC-resolver.patch \
>             file://make-4.patch \
> +           file://ppc-fix-time-related-syscalls.patch \
>            "
>  SRC_URI[md5sum] = "b395b021422a027d89884992e91734fc"
>  SRC_URI[sha256sum] = "15f564b45dc5dd65faf0875579e3447961ae61e876933384ae05d19328539ad4"
> -- 
> 1.7.10.4





More information about the Openembedded-core mailing list