Consolidate lseek/lseek64/llseek implementations

Message ID 1472167053-28899-1-git-send-email-adhemerval.zanella@linaro.org
State Dropped
Headers

Commit Message

Adhemerval Zanella Netto Aug. 25, 2016, 11:17 p.m. UTC
  This patch consolidates all Linux lseek/lseek64/llseek implementation
in on on sysdeps/unix/sysv/linux/lseek{64}.c.  It also removes the llseek
file and instead consolidate the LFS lseek implementation on lseek64.c
as for other LFS symbols implementations.

The general idea is:

  - lseek: ABIs without __OFF_T_MATCHES_OFF64_T  will preferable use
  __NR__llseek if kernel supports it, otherwise they will use __NR_lseek.
  ABIs with __OFF_T_MATCHES_OFF64_T won't produce any symbol.

  - lseek64: ABIs with __OFF_T_MATCHES_OFF64_T will use __NR_lseek since
  it will use 64-bit arguments without low/high splitting as for __NR__lseek.
  ABIs without __OFF_T_MATCHES_OFF64_T will use __NR_llseek instead.

  - llseek: files will be removed and symbols will be aliased ot lseek64.

ABI without __OFF_T_MATCHES_OFF64_T and without __NR_llseek (basically MIPS64n32
so far) are covered by building lseek with off_t as expected and lseek64
using __NR_lseek (as expected for off64_t being passed using 64-bit registers).

For this consolidation I mantained the x32 assembly specific implementation
because to correctly fix this it would required both the x32 fix for
{INLINE,INTERNAL}_SYSCALL [1] and a wrapper to correctly subscribe it to
return 64 bits instead of default 32 bits (as for times).  It could a future
cleanup.

It is based on my previous {INTERNAL,INLINE}_SYSCALL_CALL macro [2],
although it is mainly for simplification.

Tested on x86_64, i686, aarch64, armhf, and powerpc64le.

	* nptl/Makefile (libpthread-routines): Remove ptw-llseek and add
	ptw-lseek64.
	* sysdeps/unix/sysv/linux/Makefile (sysdeps_routines): Remove llseek.
	* sysdeps/unix/sysv/linux/alpha/Makefile  (sysdeps_routines):
	Likewise.
	* sysdeps/unix/sysv/linux/generic/wordsize-32/llseek.c: Remove file.
	* sysdeps/unix/sysv/linux/generic/wordsize-32/lseek.c: Remove file.
	* sysdeps/unix/sysv/linux/mips/mips64/llseek.c: Likewise.
	* sysdeps/unix/sysv/linux/llseek.c: Remove file.
	* sysdeps/unix/sysv/linux/lseek.c: New file.
	* sysdeps/unix/sysv/linux/lseek64.c: Add default Linux implementation.
	* sysdeps/unix/sysv/linux/mips/mips64/syscalls.list: Remove lseek and
	__libc_lseek64 from auto-generation.
	* sysdeps/unix/sysv/linux/wordsize-64/syscalls.list: Likewise.
	* sysdeps/unix/sysv/linux/x86_64/x32/lseek64.S: New file.

[1] https://sourceware.org/ml/libc-alpha/2016-08/msg00443.html
[2] https://sourceware.org/ml/libc-alpha/2016-08/msg00646.html
---
 nptl/Makefile                                      |  2 +-
 sysdeps/unix/sysv/linux/Makefile                   |  2 +-
 sysdeps/unix/sysv/linux/alpha/Makefile             |  2 +-
 .../unix/sysv/linux/generic/wordsize-32/llseek.c   | 46 ------------------
 .../unix/sysv/linux/generic/wordsize-32/lseek.c    | 38 ---------------
 sysdeps/unix/sysv/linux/llseek.c                   | 46 ------------------
 sysdeps/unix/sysv/linux/lseek.c                    | 54 ++++++++++++++++++++++
 sysdeps/unix/sysv/linux/lseek64.c                  | 52 ++++++++++++++++++++-
 sysdeps/unix/sysv/linux/mips/mips64/llseek.c       |  1 -
 sysdeps/unix/sysv/linux/mips/mips64/syscalls.list  |  2 -
 sysdeps/unix/sysv/linux/wordsize-64/syscalls.list  |  3 --
 sysdeps/unix/sysv/linux/x86_64/x32/lseek64.S       |  1 +
 13 files changed, 125 insertions(+), 140 deletions(-)
 delete mode 100644 sysdeps/unix/sysv/linux/generic/wordsize-32/llseek.c
 delete mode 100644 sysdeps/unix/sysv/linux/generic/wordsize-32/lseek.c
 delete mode 100644 sysdeps/unix/sysv/linux/llseek.c
 create mode 100644 sysdeps/unix/sysv/linux/lseek.c
 delete mode 100644 sysdeps/unix/sysv/linux/mips/mips64/llseek.c
 create mode 100644 sysdeps/unix/sysv/linux/x86_64/x32/lseek64.S
  

Comments

Yury Norov Aug. 29, 2016, 8:40 a.m. UTC | #1
Hi Adhemerval,

On Thu, Aug 25, 2016 at 08:17:33PM -0300, Adhemerval Zanella wrote:
> This patch consolidates all Linux lseek/lseek64/llseek implementation
> in on on sysdeps/unix/sysv/linux/lseek{64}.c.  It also removes the llseek
> file and instead consolidate the LFS lseek implementation on lseek64.c
> as for other LFS symbols implementations.
> 
> The general idea is:
> 
>   - lseek: ABIs without __OFF_T_MATCHES_OFF64_T  will preferable use
>   __NR__llseek if kernel supports it, otherwise they will use __NR_lseek.
>   ABIs with __OFF_T_MATCHES_OFF64_T won't produce any symbol.
> 
>   - lseek64: ABIs with __OFF_T_MATCHES_OFF64_T will use __NR_lseek since
>   it will use 64-bit arguments without low/high splitting as for __NR__lseek.
>   ABIs without __OFF_T_MATCHES_OFF64_T will use __NR_llseek instead.
> 
>   - llseek: files will be removed and symbols will be aliased ot lseek64.
> 
> ABI without __OFF_T_MATCHES_OFF64_T and without __NR_llseek (basically MIPS64n32
> so far) are covered by building lseek with off_t as expected and lseek64
> using __NR_lseek (as expected for off64_t being passed using 64-bit registers).
> 
> For this consolidation I mantained the x32 assembly specific implementation
> because to correctly fix this it would required both the x32 fix for
> {INLINE,INTERNAL}_SYSCALL [1] and a wrapper to correctly subscribe it to
> return 64 bits instead of default 32 bits (as for times).  It could a future
> cleanup.
> 
> It is based on my previous {INTERNAL,INLINE}_SYSCALL_CALL macro [2],
> although it is mainly for simplification.
> 
> Tested on x86_64, i686, aarch64, armhf, and powerpc64le.
> 
> 	* nptl/Makefile (libpthread-routines): Remove ptw-llseek and add
> 	ptw-lseek64.
> 	* sysdeps/unix/sysv/linux/Makefile (sysdeps_routines): Remove llseek.
> 	* sysdeps/unix/sysv/linux/alpha/Makefile  (sysdeps_routines):
> 	Likewise.
> 	* sysdeps/unix/sysv/linux/generic/wordsize-32/llseek.c: Remove file.
> 	* sysdeps/unix/sysv/linux/generic/wordsize-32/lseek.c: Remove file.
> 	* sysdeps/unix/sysv/linux/mips/mips64/llseek.c: Likewise.
> 	* sysdeps/unix/sysv/linux/llseek.c: Remove file.
> 	* sysdeps/unix/sysv/linux/lseek.c: New file.
> 	* sysdeps/unix/sysv/linux/lseek64.c: Add default Linux implementation.
> 	* sysdeps/unix/sysv/linux/mips/mips64/syscalls.list: Remove lseek and
> 	__libc_lseek64 from auto-generation.
> 	* sysdeps/unix/sysv/linux/wordsize-64/syscalls.list: Likewise.
> 	* sysdeps/unix/sysv/linux/x86_64/x32/lseek64.S: New file.
> 
> [1] https://sourceware.org/ml/libc-alpha/2016-08/msg00443.html
> [2] https://sourceware.org/ml/libc-alpha/2016-08/msg00646.html
> ---
>  nptl/Makefile                                      |  2 +-
>  sysdeps/unix/sysv/linux/Makefile                   |  2 +-
>  sysdeps/unix/sysv/linux/alpha/Makefile             |  2 +-
>  .../unix/sysv/linux/generic/wordsize-32/llseek.c   | 46 ------------------
>  .../unix/sysv/linux/generic/wordsize-32/lseek.c    | 38 ---------------
>  sysdeps/unix/sysv/linux/llseek.c                   | 46 ------------------
>  sysdeps/unix/sysv/linux/lseek.c                    | 54 ++++++++++++++++++++++
>  sysdeps/unix/sysv/linux/lseek64.c                  | 52 ++++++++++++++++++++-
>  sysdeps/unix/sysv/linux/mips/mips64/llseek.c       |  1 -
>  sysdeps/unix/sysv/linux/mips/mips64/syscalls.list  |  2 -
>  sysdeps/unix/sysv/linux/wordsize-64/syscalls.list  |  3 --
>  sysdeps/unix/sysv/linux/x86_64/x32/lseek64.S       |  1 +
>  13 files changed, 125 insertions(+), 140 deletions(-)
>  delete mode 100644 sysdeps/unix/sysv/linux/generic/wordsize-32/llseek.c
>  delete mode 100644 sysdeps/unix/sysv/linux/generic/wordsize-32/lseek.c
>  delete mode 100644 sysdeps/unix/sysv/linux/llseek.c
>  create mode 100644 sysdeps/unix/sysv/linux/lseek.c
>  delete mode 100644 sysdeps/unix/sysv/linux/mips/mips64/llseek.c
>  create mode 100644 sysdeps/unix/sysv/linux/x86_64/x32/lseek64.S
> 
> diff --git a/nptl/Makefile b/nptl/Makefile
> index 2ddcd2b..31abb0e 100644
> --- a/nptl/Makefile
> +++ b/nptl/Makefile
> @@ -110,7 +110,7 @@ libpthread-routines = nptl-init vars events version pt-interp \
>  		      pt-fork pt-vfork \
>  		      ptw-write ptw-read ptw-close ptw-fcntl ptw-accept \
>  		      ptw-connect ptw-recv ptw-recvfrom ptw-send \
> -		      ptw-sendto ptw-fsync ptw-lseek ptw-llseek \
> +		      ptw-sendto ptw-fsync ptw-lseek ptw-lseek64 \
>  		      ptw-msync ptw-nanosleep ptw-open ptw-open64 ptw-pause \
>  		      ptw-pread ptw-pread64 ptw-pwrite ptw-pwrite64 \
>  		      ptw-tcdrain ptw-wait ptw-waitpid ptw-msgrcv ptw-msgsnd \
> diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
> index 4ece07c..0d5db81 100644
> --- a/sysdeps/unix/sysv/linux/Makefile
> +++ b/sysdeps/unix/sysv/linux/Makefile
> @@ -14,7 +14,7 @@ endif
>  ifeq ($(subdir),misc)
>  include $(firstword $(wildcard $(sysdirs:=/sysctl.mk)))
>  
> -sysdep_routines += clone llseek umount umount2 readahead \
> +sysdep_routines += clone umount umount2 readahead \
>  		   setfsuid setfsgid epoll_pwait signalfd \
>  		   eventfd eventfd_read eventfd_write prlimit \
>  		   personality
> diff --git a/sysdeps/unix/sysv/linux/alpha/Makefile b/sysdeps/unix/sysv/linux/alpha/Makefile
> index 3b523b7..60e294e 100644
> --- a/sysdeps/unix/sysv/linux/alpha/Makefile
> +++ b/sysdeps/unix/sysv/linux/alpha/Makefile
> @@ -10,7 +10,7 @@ ifeq ($(subdir),misc)
>  sysdep_headers += alpha/ptrace.h alpha/regdef.h sys/io.h
>  
>  sysdep_routines += ieee_get_fp_control ieee_set_fp_control \
> -		   ioperm llseek
> +		   ioperm

You can join lines now, right?

>  # Support old timeval32 entry points
>  sysdep_routines += osf_select osf_gettimeofday osf_settimeofday \
> diff --git a/sysdeps/unix/sysv/linux/generic/wordsize-32/llseek.c b/sysdeps/unix/sysv/linux/generic/wordsize-32/llseek.c
> deleted file mode 100644
> index 458964c..0000000
> --- a/sysdeps/unix/sysv/linux/generic/wordsize-32/llseek.c
> +++ /dev/null
> @@ -1,46 +0,0 @@
> -/* Copyright (C) 2011-2016 Free Software Foundation, Inc.
> -   This file is part of the GNU C Library.
> -   Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
> -
> -   The GNU C Library is free software; you can redistribute it and/or
> -   modify it under the terms of the GNU Lesser General Public
> -   License as published by the Free Software Foundation; either
> -   version 2.1 of the License, or (at your option) any later version.
> -
> -   The GNU C Library is distributed in the hope that it will be useful,
> -   but WITHOUT ANY WARRANTY; without even the implied warranty of
> -   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> -   Lesser General Public License for more details.
> -
> -   You should have received a copy of the GNU Lesser General Public
> -   License along with the GNU C Library.  If not, see
> -   <http://www.gnu.org/licenses/>.  */
> -
> -#include <errno.h>
> -#include <sys/types.h>
> -
> -#include <sysdep.h>
> -#include <sys/syscall.h>
> -
> -/* Seek to OFFSET on FD, starting from WHENCE.  */
> -extern loff_t __llseek (int fd, loff_t offset, int whence);
> -
> -loff_t
> -__llseek (int fd, loff_t offset, int whence)
> -{
> -  loff_t retval;
> -
> -  return (loff_t) (INLINE_SYSCALL (_llseek, 5, fd, (off_t) (offset >> 32),
> -				   (off_t) (offset & 0xffffffff),
> -				   &retval, whence) ?: retval);
> -}
> -weak_alias (__llseek, llseek)
> -strong_alias (__llseek, __libc_lseek64)
> -strong_alias (__llseek, __lseek64)
> -weak_alias (__llseek, lseek64)
> -
> -/* llseek doesn't have a prototype.  Since the second parameter is a
> -   64bit type, this results in wrong behaviour if no prototype is
> -   provided.  */
> -link_warning (llseek, "\
> -the `llseek' function may be dangerous; use `lseek64' instead.")
> diff --git a/sysdeps/unix/sysv/linux/generic/wordsize-32/lseek.c b/sysdeps/unix/sysv/linux/generic/wordsize-32/lseek.c
> deleted file mode 100644
> index dbf0b26..0000000
> --- a/sysdeps/unix/sysv/linux/generic/wordsize-32/lseek.c
> +++ /dev/null
> @@ -1,38 +0,0 @@
> -/* Copyright (C) 2011-2016 Free Software Foundation, Inc.
> -   This file is part of the GNU C Library.
> -   Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
> -
> -   The GNU C Library is free software; you can redistribute it and/or
> -   modify it under the terms of the GNU Lesser General Public
> -   License as published by the Free Software Foundation; either
> -   version 2.1 of the License, or (at your option) any later version.
> -
> -   The GNU C Library is distributed in the hope that it will be useful,
> -   but WITHOUT ANY WARRANTY; without even the implied warranty of
> -   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> -   Lesser General Public License for more details.
> -
> -   You should have received a copy of the GNU Lesser General Public
> -   License along with the GNU C Library.  If not, see
> -   <http://www.gnu.org/licenses/>.  */
> -
> -#include <errno.h>
> -#include <unistd.h>
> -#include <sys/types.h>
> -
> -#include <sysdep.h>
> -#include <sys/syscall.h>
> -
> -#include "overflow.h"
> -
> -off_t
> -__lseek (int fd, off_t offset, int whence)
> -{
> -  loff_t res;
> -  int rc = INLINE_SYSCALL (_llseek, 5, fd, (off_t) (offset >> 31),
> -                           (off_t) offset, &res, whence);
> -  return rc ?: lseek_overflow (res);
> -}
> -libc_hidden_def (__lseek)
> -weak_alias (__lseek, lseek)
> -strong_alias (__lseek, __libc_lseek)
> diff --git a/sysdeps/unix/sysv/linux/llseek.c b/sysdeps/unix/sysv/linux/llseek.c
> deleted file mode 100644
> index b6f3ea5..0000000
> --- a/sysdeps/unix/sysv/linux/llseek.c
> +++ /dev/null
> @@ -1,46 +0,0 @@
> -/* Long-long seek operation.
> -   Copyright (C) 1996-2016 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
> -   modify it under the terms of the GNU Lesser General Public
> -   License as published by the Free Software Foundation; either
> -   version 2.1 of the License, or (at your option) any later version.
> -
> -   The GNU C Library is distributed in the hope that it will be useful,
> -   but WITHOUT ANY WARRANTY; without even the implied warranty of
> -   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> -   Lesser General Public License for more details.
> -
> -   You should have received a copy of the GNU Lesser General Public
> -   License along with the GNU C Library; if not, see
> -   <http://www.gnu.org/licenses/>.  */
> -
> -#include <errno.h>
> -#include <sys/types.h>
> -
> -#include <sysdep.h>
> -#include <sys/syscall.h>
> -
> -/* Seek to OFFSET on FD, starting from WHENCE.  */
> -extern loff_t __llseek (int fd, loff_t offset, int whence);
> -
> -loff_t
> -__llseek (int fd, loff_t offset, int whence)
> -{
> -  loff_t retval;
> -
> -  return (loff_t) (INLINE_SYSCALL (_llseek, 5, fd, (off_t) (offset >> 32),
> -				   (off_t) (offset & 0xffffffff),
> -				   &retval, whence) ?: retval);
> -}
> -weak_alias (__llseek, llseek)
> -strong_alias (__llseek, __libc_lseek64)
> -strong_alias (__llseek, __lseek64)
> -weak_alias (__llseek, lseek64)
> -
> -/* llseek doesn't have a prototype.  Since the second parameter is a
> -   64bit type, this results in wrong behaviour if no prototype is
> -   provided.  */
> -link_warning (llseek, "\
> -the `llseek' function may be dangerous; use `lseek64' instead.")
> diff --git a/sysdeps/unix/sysv/linux/lseek.c b/sysdeps/unix/sysv/linux/lseek.c
> new file mode 100644
> index 0000000..15bee74
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/lseek.c
> @@ -0,0 +1,54 @@
> +/* Copyright (C) 2016 Free Software Foundation, Inc.

Missed "short one-line description"

> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library.  If not, see
> +   <http://www.gnu.org/licenses/>.  */
> +
> +#include <unistd.h>
> +#include <sys/types.h>
> +#include <sysdep.h>
> +#include <errno.h>
> +
> +#ifndef __OFF_T_MATCHES_OFF64_T
> +
> +/* Test for overflows of structures where we ask the kernel to fill them
> +   in with standard 64-bit syscalls but return them through APIs that
> +   only expose the low 32 bits of some fields.  */
> +
> +static inline off_t lseek_overflow (loff_t res)
> +{
> +  off_t retval = (off_t) res;
> +  if (retval == res)
> +    return retval;
> +
> +  __set_errno (EOVERFLOW);
> +  return (off_t) -1;
> +}
> +
> +off_t
> +__lseek (int fd, off_t offset, int whence)
> +{
> +# ifdef __NR__llseek
> +  loff_t res;
> +  int rc = INLINE_SYSCALL_CALL (_llseek, fd, (off_t)(offset >> 31),
> +				(off_t) offset, &res, whence);

Why you not use SYSCALL_LL()?

> +  return rc ?: lseek_overflow (res);
> +# else
> +  return INLINE_SYSCALL_CALL (lseek, fd, offset, whence);
> +# endif
> +}
> +libc_hidden_def (__lseek)
> +weak_alias (__lseek, lseek)
> +strong_alias (__lseek, __libc_lseek)
> +#endif /* __OFF_T_MATCHES_OFF64_T  */
> diff --git a/sysdeps/unix/sysv/linux/lseek64.c b/sysdeps/unix/sysv/linux/lseek64.c
> index d81e98f..704d5b3 100644
> --- a/sysdeps/unix/sysv/linux/lseek64.c
> +++ b/sysdeps/unix/sysv/linux/lseek64.c
> @@ -1 +1,51 @@
> -/* We don't need a definition since the llseek function is what we need.  */
> +/* Copyright (C) 2016 Free Software Foundation, Inc.

Single-line comment?

> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library.  If not, see
> +   <http://www.gnu.org/licenses/>.  */
> +
> +#include <unistd.h>
> +#include <sys/types.h>
> +#include <sysdep.h>
> +#include <errno.h>
> +
> +off64_t
> +__lseek64 (int fd, off64_t offset, int whence)
> +{
> +#if defined(__OFF_T_MATCHES_OFF64_T) || !defined(__NR__llseek)

This will not work for aarch64/ilp32, as __OFF_T_MATCHES_OFF64_T
is defined there, but offset is passed in a pair.

> +  return INLINE_SYSCALL_CALL (lseek, fd, offset, whence);
> +#else
> +  loff_t res;
> +  int rc = INLINE_SYSCALL_CALL (_llseek, fd, (off_t) (offset >> 31),
> +				(off_t) offset, &res, whence);

Why are you not using your SYSCALL_LL() macro?

> +  return rc ?: res;
> +#endif
> +}
> +
> +#ifdef  __OFF_T_MATCHES_OFF64_T
> +weak_alias (__lseek64, lseek)
> +weak_alias (__lseek64, __lseek)
> +strong_alias (__lseek64, __libc_lseek)
> +libc_hidden_def (__lseek)
> +#endif
> +
> +strong_alias (__lseek64, __libc_lseek64)
> +weak_alias (__lseek64, lseek64)

Can someone give me more detailed explanation about using strong_alias
vs weak_alias? What's the rule to choose between them?

> +/* llseek doesn't have a prototype.  Since the second parameter is a
> +   64bit type, this results in wrong behaviour if no prototype is
> +   provided.  */
> +weak_alias (__lseek64, llseek)
> +link_warning (llseek, "\
> +the `llseek' function may be dangerous; use `lseek64' instead.")
> diff --git a/sysdeps/unix/sysv/linux/mips/mips64/llseek.c b/sysdeps/unix/sysv/linux/mips/mips64/llseek.c
> deleted file mode 100644
> index 24013a8..0000000
> --- a/sysdeps/unix/sysv/linux/mips/mips64/llseek.c
> +++ /dev/null
> @@ -1 +0,0 @@
> -/* lseek() is 64-bit capable already.  */
> diff --git a/sysdeps/unix/sysv/linux/mips/mips64/syscalls.list b/sysdeps/unix/sysv/linux/mips/mips64/syscalls.list
> index 66cc687..d2d851e 100644
> --- a/sysdeps/unix/sysv/linux/mips/mips64/syscalls.list
> +++ b/sysdeps/unix/sysv/linux/mips/mips64/syscalls.list
> @@ -1,7 +1,5 @@
>  # File name	Caller	Syscall name	Args	Strong name	Weak names
>  
> -lseek		-	lseek		i:iii	__libc_lseek	__lseek lseek __llseek llseek __libc_lseek64 __lseek64 lseek64
> -
>  ftruncate	-	ftruncate	i:ii	__ftruncate	ftruncate ftruncate64 __ftruncate64
>  truncate	-	truncate	i:si	truncate	truncate64
>  
> diff --git a/sysdeps/unix/sysv/linux/wordsize-64/syscalls.list b/sysdeps/unix/sysv/linux/wordsize-64/syscalls.list
> index 2eb9419..3f3569f 100644
> --- a/sysdeps/unix/sysv/linux/wordsize-64/syscalls.list
> +++ b/sysdeps/unix/sysv/linux/wordsize-64/syscalls.list
> @@ -1,8 +1,5 @@
>  # File name	Caller	Syscall name	# args	Strong name	Weak names
>  
> -# Whee! 64-bit systems naturally implement llseek.
> -llseek		EXTRA	lseek		i:iii	__libc_lseek	__lseek lseek __libc_lseek64 __llseek llseek __lseek64 lseek64
> -lseek		llseek	-
>  fstatfs		-	fstatfs		i:ip	__fstatfs	fstatfs fstatfs64 __fstatfs64
>  statfs		-	statfs		i:sp	__statfs	statfs statfs64
>  mmap		-	mmap		b:aniiii __mmap		mmap __mmap64 mmap64
> diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/lseek64.S b/sysdeps/unix/sysv/linux/x86_64/x32/lseek64.S
> new file mode 100644
> index 0000000..d81e98f
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/x86_64/x32/lseek64.S
> @@ -0,0 +1 @@
> +/* We don't need a definition since the llseek function is what we need.  */
> -- 
> 2.7.4
  
Adhemerval Zanella Netto Aug. 29, 2016, 7:24 p.m. UTC | #2
On 29/08/2016 05:40, Yury Norov wrote:

>> diff --git a/sysdeps/unix/sysv/linux/alpha/Makefile b/sysdeps/unix/sysv/linux/alpha/Makefile
>> index 3b523b7..60e294e 100644
>> --- a/sysdeps/unix/sysv/linux/alpha/Makefile
>> +++ b/sysdeps/unix/sysv/linux/alpha/Makefile
>> @@ -10,7 +10,7 @@ ifeq ($(subdir),misc)
>>  sysdep_headers += alpha/ptrace.h alpha/regdef.h sys/io.h
>>  
>>  sysdep_routines += ieee_get_fp_control ieee_set_fp_control \
>> -		   ioperm llseek
>> +		   ioperm
> 
> You can join lines now, right?

I think so, although I do not have any preference here.  I will
wrap the lines.

>> diff --git a/sysdeps/unix/sysv/linux/lseek.c b/sysdeps/unix/sysv/linux/lseek.c
>> new file mode 100644
>> index 0000000..15bee74
>> --- /dev/null
>> +++ b/sysdeps/unix/sysv/linux/lseek.c
>> @@ -0,0 +1,54 @@
>> +/* Copyright (C) 2016 Free Software Foundation, Inc.
> 
> Missed "short one-line description"

Ack, I will add it.

> 
>> +   This file is part of the GNU C Library.
>> +
>> +   The GNU C Library is free software; you can redistribute it and/or
>> +   modify it under the terms of the GNU Lesser General Public
>> +   License as published by the Free Software Foundation; either
>> +   version 2.1 of the License, or (at your option) any later version.
>> +
>> +   The GNU C Library is distributed in the hope that it will be useful,
>> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
>> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
>> +   Lesser General Public License for more details.
>> +
>> +   You should have received a copy of the GNU Lesser General Public
>> +   License along with the GNU C Library.  If not, see
>> +   <http://www.gnu.org/licenses/>.  */
>> +
>> +#include <unistd.h>
>> +#include <sys/types.h>
>> +#include <sysdep.h>
>> +#include <errno.h>
>> +
>> +#ifndef __OFF_T_MATCHES_OFF64_T
>> +
>> +/* Test for overflows of structures where we ask the kernel to fill them
>> +   in with standard 64-bit syscalls but return them through APIs that
>> +   only expose the low 32 bits of some fields.  */
>> +
>> +static inline off_t lseek_overflow (loff_t res)
>> +{
>> +  off_t retval = (off_t) res;
>> +  if (retval == res)
>> +    return retval;
>> +
>> +  __set_errno (EOVERFLOW);
>> +  return (off_t) -1;
>> +}
>> +
>> +off_t
>> +__lseek (int fd, off_t offset, int whence)
>> +{
>> +# ifdef __NR__llseek
>> +  loff_t res;
>> +  int rc = INLINE_SYSCALL_CALL (_llseek, fd, (off_t)(offset >> 31),
>> +				(off_t) offset, &res, whence);
> 
> Why you not use SYSCALL_LL()?

Because Linux define __NR__llseek interface as:

fs/read_write.c:
 330 #ifdef __ARCH_WANT_SYS_LLSEEK
 331 SYSCALL_DEFINE5(llseek, unsigned int, fd, unsigned long, offset_high,
 332                 unsigned long, offset_low, loff_t __user *, result,
 333                 unsigned int, whence)

And SYSCALL_LL{64} uses __LONG_LONG_PAIR which will set the (high,low)
call to (low,high) in little-endian mode (as expected in pread/pwrite
calls).

I think we could add another macro, but I do not think it is worth
adding for this specific case.


> 
>> +  return rc ?: lseek_overflow (res);
>> +# else
>> +  return INLINE_SYSCALL_CALL (lseek, fd, offset, whence);
>> +# endif
>> +}
>> +libc_hidden_def (__lseek)
>> +weak_alias (__lseek, lseek)
>> +strong_alias (__lseek, __libc_lseek)
>> +#endif /* __OFF_T_MATCHES_OFF64_T  */
>> diff --git a/sysdeps/unix/sysv/linux/lseek64.c b/sysdeps/unix/sysv/linux/lseek64.c
>> index d81e98f..704d5b3 100644
>> --- a/sysdeps/unix/sysv/linux/lseek64.c
>> +++ b/sysdeps/unix/sysv/linux/lseek64.c
>> @@ -1 +1,51 @@
>> -/* We don't need a definition since the llseek function is what we need.  */
>> +/* Copyright (C) 2016 Free Software Foundation, Inc.
> 
> Single-line comment?
> 

Ack, I will add it.

>> +   This file is part of the GNU C Library.
>> +
>> +   The GNU C Library is free software; you can redistribute it and/or
>> +   modify it under the terms of the GNU Lesser General Public
>> +   License as published by the Free Software Foundation; either
>> +   version 2.1 of the License, or (at your option) any later version.
>> +
>> +   The GNU C Library is distributed in the hope that it will be useful,
>> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
>> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
>> +   Lesser General Public License for more details.
>> +
>> +   You should have received a copy of the GNU Lesser General Public
>> +   License along with the GNU C Library.  If not, see
>> +   <http://www.gnu.org/licenses/>.  */
>> +
>> +#include <unistd.h>
>> +#include <sys/types.h>
>> +#include <sysdep.h>
>> +#include <errno.h>
>> +
>> +off64_t
>> +__lseek64 (int fd, off64_t offset, int whence)
>> +{
>> +#if defined(__OFF_T_MATCHES_OFF64_T) || !defined(__NR__llseek)
> 
> This will not work for aarch64/ilp32, as __OFF_T_MATCHES_OFF64_T
> is defined there, but offset is passed in a pair.

This code make the assumption that:

1. __OFF_T_MATCHES_OFF64_T arch will use __NR_lseek that (as for
   all 64-bit ABI) will pass 64-bit arguments

2. if __OFF_T_MATCHES_OFF64_T is not defined then it will use
   __NR__llseek that splits the off64_t in (high, low)

So if I understand correctly aarch64/ilp32 uses __NR_lseek with
__NR__lseek signature? Why wire up __NR_lseek different?

> 
>> +  return INLINE_SYSCALL_CALL (lseek, fd, offset, whence);
>> +#else
>> +  loff_t res;
>> +  int rc = INLINE_SYSCALL_CALL (_llseek, fd, (off_t) (offset >> 31),
>> +				(off_t) offset, &res, whence);
> 
> Why are you not using your SYSCALL_LL() macro?
> 
>> +  return rc ?: res;
>> +#endif
>> +}
>> +
>> +#ifdef  __OFF_T_MATCHES_OFF64_T
>> +weak_alias (__lseek64, lseek)
>> +weak_alias (__lseek64, __lseek)
>> +strong_alias (__lseek64, __libc_lseek)
>> +libc_hidden_def (__lseek)
>> +#endif
>> +
>> +strong_alias (__lseek64, __libc_lseek64)
>> +weak_alias (__lseek64, lseek64)
> 
> Can someone give me more detailed explanation about using strong_alias
> vs weak_alias? What's the rule to choose between them?

The idea here is to avoid namespace pollution in static linking.  Basically
strong_alias do not allow symbol override, so for __libc_lseek64 since it
on a glibc specific namespace (due '__' prefix) we can use a strong alias
and assume user programs won't be able/require to use the name.  This is
not true for lseek64, since it is a platform specific name program might
use.

> 
>> +/* llseek doesn't have a prototype.  Since the second parameter is a
>> +   64bit type, this results in wrong behaviour if no prototype is
>> +   provided.  */
>> +weak_alias (__lseek64, llseek)
>> +link_warning (llseek, "\
>> +the `llseek' function may be dangerous; use `lseek64' instead.")
>> diff --git a/sysdeps/unix/sysv/linux/mips/mips64/llseek.c b/sysdeps/unix/sysv/linux/mips/mips64/llseek.c
>> deleted file mode 100644
>> index 24013a8..0000000
>> --- a/sysdeps/unix/sysv/linux/mips/mips64/llseek.c
>> +++ /dev/null
>> @@ -1 +0,0 @@
>> -/* lseek() is 64-bit capable already.  */
>> diff --git a/sysdeps/unix/sysv/linux/mips/mips64/syscalls.list b/sysdeps/unix/sysv/linux/mips/mips64/syscalls.list
>> index 66cc687..d2d851e 100644
>> --- a/sysdeps/unix/sysv/linux/mips/mips64/syscalls.list
>> +++ b/sysdeps/unix/sysv/linux/mips/mips64/syscalls.list
>> @@ -1,7 +1,5 @@
>>  # File name	Caller	Syscall name	Args	Strong name	Weak names
>>  
>> -lseek		-	lseek		i:iii	__libc_lseek	__lseek lseek __llseek llseek __libc_lseek64 __lseek64 lseek64
>> -
>>  ftruncate	-	ftruncate	i:ii	__ftruncate	ftruncate ftruncate64 __ftruncate64
>>  truncate	-	truncate	i:si	truncate	truncate64
>>  
>> diff --git a/sysdeps/unix/sysv/linux/wordsize-64/syscalls.list b/sysdeps/unix/sysv/linux/wordsize-64/syscalls.list
>> index 2eb9419..3f3569f 100644
>> --- a/sysdeps/unix/sysv/linux/wordsize-64/syscalls.list
>> +++ b/sysdeps/unix/sysv/linux/wordsize-64/syscalls.list
>> @@ -1,8 +1,5 @@
>>  # File name	Caller	Syscall name	# args	Strong name	Weak names
>>  
>> -# Whee! 64-bit systems naturally implement llseek.
>> -llseek		EXTRA	lseek		i:iii	__libc_lseek	__lseek lseek __libc_lseek64 __llseek llseek __lseek64 lseek64
>> -lseek		llseek	-
>>  fstatfs		-	fstatfs		i:ip	__fstatfs	fstatfs fstatfs64 __fstatfs64
>>  statfs		-	statfs		i:sp	__statfs	statfs statfs64
>>  mmap		-	mmap		b:aniiii __mmap		mmap __mmap64 mmap64
>> diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/lseek64.S b/sysdeps/unix/sysv/linux/x86_64/x32/lseek64.S
>> new file mode 100644
>> index 0000000..d81e98f
>> --- /dev/null
>> +++ b/sysdeps/unix/sysv/linux/x86_64/x32/lseek64.S
>> @@ -0,0 +1 @@
>> +/* We don't need a definition since the llseek function is what we need.  */
>> -- 
>> 2.7.4
  
Andreas Schwab Aug. 29, 2016, 8:15 p.m. UTC | #3
On Aug 25 2016, Adhemerval Zanella <adhemerval.zanella@linaro.org> wrote:

> diff --git a/sysdeps/unix/sysv/linux/lseek.c b/sysdeps/unix/sysv/linux/lseek.c
> new file mode 100644
> index 0000000..15bee74
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/lseek.c
> @@ -0,0 +1,54 @@
> +/* Copyright (C) 2016 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
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library.  If not, see
> +   <http://www.gnu.org/licenses/>.  */
> +
> +#include <unistd.h>
> +#include <sys/types.h>
> +#include <sysdep.h>
> +#include <errno.h>
> +
> +#ifndef __OFF_T_MATCHES_OFF64_T
> +
> +/* Test for overflows of structures where we ask the kernel to fill them
> +   in with standard 64-bit syscalls but return them through APIs that
> +   only expose the low 32 bits of some fields.  */
> +
> +static inline off_t lseek_overflow (loff_t res)
> +{
> +  off_t retval = (off_t) res;
> +  if (retval == res)
> +    return retval;
> +
> +  __set_errno (EOVERFLOW);
> +  return (off_t) -1;
> +}
> +
> +off_t
> +__lseek (int fd, off_t offset, int whence)
> +{
> +# ifdef __NR__llseek
> +  loff_t res;
> +  int rc = INLINE_SYSCALL_CALL (_llseek, fd, (off_t)(offset >> 31),
> +				(off_t) offset, &res, whence);

The casts are no-ops.

Andreas.
  
Yury Norov Aug. 29, 2016, 10:21 p.m. UTC | #4
On Mon, Aug 29, 2016 at 04:24:35PM -0300, Adhemerval Zanella wrote:
> tatus: O
> Content-Length: 8675
> Lines: 240
> 
> 
> 
> On 29/08/2016 05:40, Yury Norov wrote:
> 
> >> diff --git a/sysdeps/unix/sysv/linux/alpha/Makefile b/sysdeps/unix/sysv/linux/alpha/Makefile
> >> index 3b523b7..60e294e 100644
> >> --- a/sysdeps/unix/sysv/linux/alpha/Makefile
> >> +++ b/sysdeps/unix/sysv/linux/alpha/Makefile
> >> @@ -10,7 +10,7 @@ ifeq ($(subdir),misc)
> >>  sysdep_headers += alpha/ptrace.h alpha/regdef.h sys/io.h
> >>  
> >>  sysdep_routines += ieee_get_fp_control ieee_set_fp_control \
> >> -		   ioperm llseek
> >> +		   ioperm
> > 
> > You can join lines now, right?
> 
> I think so, although I do not have any preference here.  I will
> wrap the lines.
> 
> >> diff --git a/sysdeps/unix/sysv/linux/lseek.c b/sysdeps/unix/sysv/linux/lseek.c
> >> new file mode 100644
> >> index 0000000..15bee74
> >> --- /dev/null
> >> +++ b/sysdeps/unix/sysv/linux/lseek.c
> >> @@ -0,0 +1,54 @@
> >> +/* Copyright (C) 2016 Free Software Foundation, Inc.
> > 
> > Missed "short one-line description"
> 
> Ack, I will add it.
> 
> > 
> >> +   This file is part of the GNU C Library.
> >> +
> >> +   The GNU C Library is free software; you can redistribute it and/or
> >> +   modify it under the terms of the GNU Lesser General Public
> >> +   License as published by the Free Software Foundation; either
> >> +   version 2.1 of the License, or (at your option) any later version.
> >> +
> >> +   The GNU C Library is distributed in the hope that it will be useful,
> >> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> >> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> >> +   Lesser General Public License for more details.
> >> +
> >> +   You should have received a copy of the GNU Lesser General Public
> >> +   License along with the GNU C Library.  If not, see
> >> +   <http://www.gnu.org/licenses/>.  */
> >> +
> >> +#include <unistd.h>
> >> +#include <sys/types.h>
> >> +#include <sysdep.h>
> >> +#include <errno.h>
> >> +
> >> +#ifndef __OFF_T_MATCHES_OFF64_T
> >> +
> >> +/* Test for overflows of structures where we ask the kernel to fill them
> >> +   in with standard 64-bit syscalls but return them through APIs that
> >> +   only expose the low 32 bits of some fields.  */
> >> +
> >> +static inline off_t lseek_overflow (loff_t res)
> >> +{
> >> +  off_t retval = (off_t) res;
> >> +  if (retval == res)
> >> +    return retval;
> >> +
> >> +  __set_errno (EOVERFLOW);
> >> +  return (off_t) -1;
> >> +}
> >> +
> >> +off_t
> >> +__lseek (int fd, off_t offset, int whence)
> >> +{
> >> +# ifdef __NR__llseek
> >> +  loff_t res;
> >> +  int rc = INLINE_SYSCALL_CALL (_llseek, fd, (off_t)(offset >> 31),
> >> +				(off_t) offset, &res, whence);
> > 
> > Why you not use SYSCALL_LL()?
> 
> Because Linux define __NR__llseek interface as:
> 
> fs/read_write.c:
>  330 #ifdef __ARCH_WANT_SYS_LLSEEK
>  331 SYSCALL_DEFINE5(llseek, unsigned int, fd, unsigned long, offset_high,
>  332                 unsigned long, offset_low, loff_t __user *, result,
>  333                 unsigned int, whence)
> 
> And SYSCALL_LL{64} uses __LONG_LONG_PAIR which will set the (high,low)
> call to (low,high) in little-endian mode (as expected in pread/pwrite
> calls).
> 
> I think we could add another macro, but I do not think it is worth
> adding for this specific case.

oops... That's why it wasn't working in my patch. Sorry for spamming.

> 
> > 
> >> +  return rc ?: lseek_overflow (res);
> >> +# else
> >> +  return INLINE_SYSCALL_CALL (lseek, fd, offset, whence);
> >> +# endif
> >> +}
> >> +libc_hidden_def (__lseek)
> >> +weak_alias (__lseek, lseek)
> >> +strong_alias (__lseek, __libc_lseek)
> >> +#endif /* __OFF_T_MATCHES_OFF64_T  */
> >> diff --git a/sysdeps/unix/sysv/linux/lseek64.c b/sysdeps/unix/sysv/linux/lseek64.c
> >> index d81e98f..704d5b3 100644
> >> --- a/sysdeps/unix/sysv/linux/lseek64.c
> >> +++ b/sysdeps/unix/sysv/linux/lseek64.c
> >> @@ -1 +1,51 @@
> >> -/* We don't need a definition since the llseek function is what we need.  */
> >> +/* Copyright (C) 2016 Free Software Foundation, Inc.
> > 
> > Single-line comment?
> > 
> 
> Ack, I will add it.
> 
> >> +   This file is part of the GNU C Library.
> >> +
> >> +   The GNU C Library is free software; you can redistribute it and/or
> >> +   modify it under the terms of the GNU Lesser General Public
> >> +   License as published by the Free Software Foundation; either
> >> +   version 2.1 of the License, or (at your option) any later version.
> >> +
> >> +   The GNU C Library is distributed in the hope that it will be useful,
> >> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> >> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> >> +   Lesser General Public License for more details.
> >> +
> >> +   You should have received a copy of the GNU Lesser General Public
> >> +   License along with the GNU C Library.  If not, see
> >> +   <http://www.gnu.org/licenses/>.  */
> >> +
> >> +#include <unistd.h>
> >> +#include <sys/types.h>
> >> +#include <sysdep.h>
> >> +#include <errno.h>
> >> +
> >> +off64_t
> >> +__lseek64 (int fd, off64_t offset, int whence)
> >> +{
> >> +#if defined(__OFF_T_MATCHES_OFF64_T) || !defined(__NR__llseek)
> > 
> > This will not work for aarch64/ilp32, as __OFF_T_MATCHES_OFF64_T
> > is defined there, but offset is passed in a pair.
> 
> This code make the assumption that:
> 
> 1. __OFF_T_MATCHES_OFF64_T arch will use __NR_lseek that (as for
>    all 64-bit ABI) will pass 64-bit arguments
> 
> 2. if __OFF_T_MATCHES_OFF64_T is not defined then it will use
>    __NR__llseek that splits the off64_t in (high, low)
> 
> So if I understand correctly aarch64/ilp32 uses __NR_lseek with
> __NR__lseek signature? Why wire up __NR_lseek different?

aarch64/ilp32 uses __NR__llseek as all compat arches.  __OFF_T_MATCHES_OFF64_T
means (at least I think so) that off_t is 64-bit, and it doesn't make
assumptions how glibc passes it to kernel. ILP32 passes it as pair because
kernel clears top halves of registers.

I'm not sure how it will affect other ports, but this code will work if you
remove the check against __OFF_T_MATCHES_OFF64_T and just have:

#if !defined(__NR__llseek)


> >> +  return INLINE_SYSCALL_CALL (lseek, fd, offset, whence);
> >> +#else
> >> +  loff_t res;
> >> +  int rc = INLINE_SYSCALL_CALL (_llseek, fd, (off_t) (offset >> 31),
> >> +				(off_t) offset, &res, whence);
> > 

Except this. (off_t) (offset >> 31) doesn't work if off_t is 64-bit.

So, I see 3 options:
 - apply proposed fixes.
 - if not possible, introduce new option (you have to add it for all ports).
 - leave things as is and handle lseek() in arch code for aarch64/ilp32
   (as now).

> > Why are you not using your SYSCALL_LL() macro?
> > 
> >> +  return rc ?: res;
> >> +#endif
> >> +}
> >> +
> >> +#ifdef  __OFF_T_MATCHES_OFF64_T
> >> +weak_alias (__lseek64, lseek)
> >> +weak_alias (__lseek64, __lseek)
> >> +strong_alias (__lseek64, __libc_lseek)
> >> +libc_hidden_def (__lseek)
> >> +#endif
> >> +
> >> +strong_alias (__lseek64, __libc_lseek64)
> >> +weak_alias (__lseek64, lseek64)
> > 
> > Can someone give me more detailed explanation about using strong_alias
> > vs weak_alias? What's the rule to choose between them?
> 
> The idea here is to avoid namespace pollution in static linking.  Basically
> strong_alias do not allow symbol override, so for __libc_lseek64 since it
> on a glibc specific namespace (due '__' prefix) we can use a strong alias
> and assume user programs won't be able/require to use the name.  This is
> not true for lseek64, since it is a platform specific name program might
> use.
 
Thanks.

> > 
> >> +/* llseek doesn't have a prototype.  Since the second parameter is a
> >> +   64bit type, this results in wrong behaviour if no prototype is
> >> +   provided.  */
> >> +weak_alias (__lseek64, llseek)
> >> +link_warning (llseek, "\
> >> +the `llseek' function may be dangerous; use `lseek64' instead.")
> >> diff --git a/sysdeps/unix/sysv/linux/mips/mips64/llseek.c b/sysdeps/unix/sysv/linux/mips/mips64/llseek.c
> >> deleted file mode 100644
> >> index 24013a8..0000000
> >> --- a/sysdeps/unix/sysv/linux/mips/mips64/llseek.c
> >> +++ /dev/null
> >> @@ -1 +0,0 @@
> >> -/* lseek() is 64-bit capable already.  */
> >> diff --git a/sysdeps/unix/sysv/linux/mips/mips64/syscalls.list b/sysdeps/unix/sysv/linux/mips/mips64/syscalls.list
> >> index 66cc687..d2d851e 100644
> >> --- a/sysdeps/unix/sysv/linux/mips/mips64/syscalls.list
> >> +++ b/sysdeps/unix/sysv/linux/mips/mips64/syscalls.list
> >> @@ -1,7 +1,5 @@
> >>  # File name	Caller	Syscall name	Args	Strong name	Weak names
> >>  
> >> -lseek		-	lseek		i:iii	__libc_lseek	__lseek lseek __llseek llseek __libc_lseek64 __lseek64 lseek64
> >> -
> >>  ftruncate	-	ftruncate	i:ii	__ftruncate	ftruncate ftruncate64 __ftruncate64
> >>  truncate	-	truncate	i:si	truncate	truncate64
> >>  
> >> diff --git a/sysdeps/unix/sysv/linux/wordsize-64/syscalls.list b/sysdeps/unix/sysv/linux/wordsize-64/syscalls.list
> >> index 2eb9419..3f3569f 100644
> >> --- a/sysdeps/unix/sysv/linux/wordsize-64/syscalls.list
> >> +++ b/sysdeps/unix/sysv/linux/wordsize-64/syscalls.list
> >> @@ -1,8 +1,5 @@
> >>  # File name	Caller	Syscall name	# args	Strong name	Weak names
> >>  
> >> -# Whee! 64-bit systems naturally implement llseek.
> >> -llseek		EXTRA	lseek		i:iii	__libc_lseek	__lseek lseek __libc_lseek64 __llseek llseek __lseek64 lseek64
> >> -lseek		llseek	-
> >>  fstatfs		-	fstatfs		i:ip	__fstatfs	fstatfs fstatfs64 __fstatfs64
> >>  statfs		-	statfs		i:sp	__statfs	statfs statfs64
> >>  mmap		-	mmap		b:aniiii __mmap		mmap __mmap64 mmap64
> >> diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/lseek64.S b/sysdeps/unix/sysv/linux/x86_64/x32/lseek64.S
> >> new file mode 100644
> >> index 0000000..d81e98f
> >> --- /dev/null
> >> +++ b/sysdeps/unix/sysv/linux/x86_64/x32/lseek64.S
> >> @@ -0,0 +1 @@
> >> +/* We don't need a definition since the llseek func
  

Patch

diff --git a/nptl/Makefile b/nptl/Makefile
index 2ddcd2b..31abb0e 100644
--- a/nptl/Makefile
+++ b/nptl/Makefile
@@ -110,7 +110,7 @@  libpthread-routines = nptl-init vars events version pt-interp \
 		      pt-fork pt-vfork \
 		      ptw-write ptw-read ptw-close ptw-fcntl ptw-accept \
 		      ptw-connect ptw-recv ptw-recvfrom ptw-send \
-		      ptw-sendto ptw-fsync ptw-lseek ptw-llseek \
+		      ptw-sendto ptw-fsync ptw-lseek ptw-lseek64 \
 		      ptw-msync ptw-nanosleep ptw-open ptw-open64 ptw-pause \
 		      ptw-pread ptw-pread64 ptw-pwrite ptw-pwrite64 \
 		      ptw-tcdrain ptw-wait ptw-waitpid ptw-msgrcv ptw-msgsnd \
diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
index 4ece07c..0d5db81 100644
--- a/sysdeps/unix/sysv/linux/Makefile
+++ b/sysdeps/unix/sysv/linux/Makefile
@@ -14,7 +14,7 @@  endif
 ifeq ($(subdir),misc)
 include $(firstword $(wildcard $(sysdirs:=/sysctl.mk)))
 
-sysdep_routines += clone llseek umount umount2 readahead \
+sysdep_routines += clone umount umount2 readahead \
 		   setfsuid setfsgid epoll_pwait signalfd \
 		   eventfd eventfd_read eventfd_write prlimit \
 		   personality
diff --git a/sysdeps/unix/sysv/linux/alpha/Makefile b/sysdeps/unix/sysv/linux/alpha/Makefile
index 3b523b7..60e294e 100644
--- a/sysdeps/unix/sysv/linux/alpha/Makefile
+++ b/sysdeps/unix/sysv/linux/alpha/Makefile
@@ -10,7 +10,7 @@  ifeq ($(subdir),misc)
 sysdep_headers += alpha/ptrace.h alpha/regdef.h sys/io.h
 
 sysdep_routines += ieee_get_fp_control ieee_set_fp_control \
-		   ioperm llseek
+		   ioperm
 
 # Support old timeval32 entry points
 sysdep_routines += osf_select osf_gettimeofday osf_settimeofday \
diff --git a/sysdeps/unix/sysv/linux/generic/wordsize-32/llseek.c b/sysdeps/unix/sysv/linux/generic/wordsize-32/llseek.c
deleted file mode 100644
index 458964c..0000000
--- a/sysdeps/unix/sysv/linux/generic/wordsize-32/llseek.c
+++ /dev/null
@@ -1,46 +0,0 @@ 
-/* Copyright (C) 2011-2016 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-   Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library.  If not, see
-   <http://www.gnu.org/licenses/>.  */
-
-#include <errno.h>
-#include <sys/types.h>
-
-#include <sysdep.h>
-#include <sys/syscall.h>
-
-/* Seek to OFFSET on FD, starting from WHENCE.  */
-extern loff_t __llseek (int fd, loff_t offset, int whence);
-
-loff_t
-__llseek (int fd, loff_t offset, int whence)
-{
-  loff_t retval;
-
-  return (loff_t) (INLINE_SYSCALL (_llseek, 5, fd, (off_t) (offset >> 32),
-				   (off_t) (offset & 0xffffffff),
-				   &retval, whence) ?: retval);
-}
-weak_alias (__llseek, llseek)
-strong_alias (__llseek, __libc_lseek64)
-strong_alias (__llseek, __lseek64)
-weak_alias (__llseek, lseek64)
-
-/* llseek doesn't have a prototype.  Since the second parameter is a
-   64bit type, this results in wrong behaviour if no prototype is
-   provided.  */
-link_warning (llseek, "\
-the `llseek' function may be dangerous; use `lseek64' instead.")
diff --git a/sysdeps/unix/sysv/linux/generic/wordsize-32/lseek.c b/sysdeps/unix/sysv/linux/generic/wordsize-32/lseek.c
deleted file mode 100644
index dbf0b26..0000000
--- a/sysdeps/unix/sysv/linux/generic/wordsize-32/lseek.c
+++ /dev/null
@@ -1,38 +0,0 @@ 
-/* Copyright (C) 2011-2016 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-   Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library.  If not, see
-   <http://www.gnu.org/licenses/>.  */
-
-#include <errno.h>
-#include <unistd.h>
-#include <sys/types.h>
-
-#include <sysdep.h>
-#include <sys/syscall.h>
-
-#include "overflow.h"
-
-off_t
-__lseek (int fd, off_t offset, int whence)
-{
-  loff_t res;
-  int rc = INLINE_SYSCALL (_llseek, 5, fd, (off_t) (offset >> 31),
-                           (off_t) offset, &res, whence);
-  return rc ?: lseek_overflow (res);
-}
-libc_hidden_def (__lseek)
-weak_alias (__lseek, lseek)
-strong_alias (__lseek, __libc_lseek)
diff --git a/sysdeps/unix/sysv/linux/llseek.c b/sysdeps/unix/sysv/linux/llseek.c
deleted file mode 100644
index b6f3ea5..0000000
--- a/sysdeps/unix/sysv/linux/llseek.c
+++ /dev/null
@@ -1,46 +0,0 @@ 
-/* Long-long seek operation.
-   Copyright (C) 1996-2016 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
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, see
-   <http://www.gnu.org/licenses/>.  */
-
-#include <errno.h>
-#include <sys/types.h>
-
-#include <sysdep.h>
-#include <sys/syscall.h>
-
-/* Seek to OFFSET on FD, starting from WHENCE.  */
-extern loff_t __llseek (int fd, loff_t offset, int whence);
-
-loff_t
-__llseek (int fd, loff_t offset, int whence)
-{
-  loff_t retval;
-
-  return (loff_t) (INLINE_SYSCALL (_llseek, 5, fd, (off_t) (offset >> 32),
-				   (off_t) (offset & 0xffffffff),
-				   &retval, whence) ?: retval);
-}
-weak_alias (__llseek, llseek)
-strong_alias (__llseek, __libc_lseek64)
-strong_alias (__llseek, __lseek64)
-weak_alias (__llseek, lseek64)
-
-/* llseek doesn't have a prototype.  Since the second parameter is a
-   64bit type, this results in wrong behaviour if no prototype is
-   provided.  */
-link_warning (llseek, "\
-the `llseek' function may be dangerous; use `lseek64' instead.")
diff --git a/sysdeps/unix/sysv/linux/lseek.c b/sysdeps/unix/sysv/linux/lseek.c
new file mode 100644
index 0000000..15bee74
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/lseek.c
@@ -0,0 +1,54 @@ 
+/* Copyright (C) 2016 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
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <unistd.h>
+#include <sys/types.h>
+#include <sysdep.h>
+#include <errno.h>
+
+#ifndef __OFF_T_MATCHES_OFF64_T
+
+/* Test for overflows of structures where we ask the kernel to fill them
+   in with standard 64-bit syscalls but return them through APIs that
+   only expose the low 32 bits of some fields.  */
+
+static inline off_t lseek_overflow (loff_t res)
+{
+  off_t retval = (off_t) res;
+  if (retval == res)
+    return retval;
+
+  __set_errno (EOVERFLOW);
+  return (off_t) -1;
+}
+
+off_t
+__lseek (int fd, off_t offset, int whence)
+{
+# ifdef __NR__llseek
+  loff_t res;
+  int rc = INLINE_SYSCALL_CALL (_llseek, fd, (off_t)(offset >> 31),
+				(off_t) offset, &res, whence);
+  return rc ?: lseek_overflow (res);
+# else
+  return INLINE_SYSCALL_CALL (lseek, fd, offset, whence);
+# endif
+}
+libc_hidden_def (__lseek)
+weak_alias (__lseek, lseek)
+strong_alias (__lseek, __libc_lseek)
+#endif /* __OFF_T_MATCHES_OFF64_T  */
diff --git a/sysdeps/unix/sysv/linux/lseek64.c b/sysdeps/unix/sysv/linux/lseek64.c
index d81e98f..704d5b3 100644
--- a/sysdeps/unix/sysv/linux/lseek64.c
+++ b/sysdeps/unix/sysv/linux/lseek64.c
@@ -1 +1,51 @@ 
-/* We don't need a definition since the llseek function is what we need.  */
+/* Copyright (C) 2016 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
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <unistd.h>
+#include <sys/types.h>
+#include <sysdep.h>
+#include <errno.h>
+
+off64_t
+__lseek64 (int fd, off64_t offset, int whence)
+{
+#if defined(__OFF_T_MATCHES_OFF64_T) || !defined(__NR__llseek)
+  return INLINE_SYSCALL_CALL (lseek, fd, offset, whence);
+#else
+  loff_t res;
+  int rc = INLINE_SYSCALL_CALL (_llseek, fd, (off_t) (offset >> 31),
+				(off_t) offset, &res, whence);
+  return rc ?: res;
+#endif
+}
+
+#ifdef  __OFF_T_MATCHES_OFF64_T
+weak_alias (__lseek64, lseek)
+weak_alias (__lseek64, __lseek)
+strong_alias (__lseek64, __libc_lseek)
+libc_hidden_def (__lseek)
+#endif
+
+strong_alias (__lseek64, __libc_lseek64)
+weak_alias (__lseek64, lseek64)
+
+/* llseek doesn't have a prototype.  Since the second parameter is a
+   64bit type, this results in wrong behaviour if no prototype is
+   provided.  */
+weak_alias (__lseek64, llseek)
+link_warning (llseek, "\
+the `llseek' function may be dangerous; use `lseek64' instead.")
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/llseek.c b/sysdeps/unix/sysv/linux/mips/mips64/llseek.c
deleted file mode 100644
index 24013a8..0000000
--- a/sysdeps/unix/sysv/linux/mips/mips64/llseek.c
+++ /dev/null
@@ -1 +0,0 @@ 
-/* lseek() is 64-bit capable already.  */
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/syscalls.list b/sysdeps/unix/sysv/linux/mips/mips64/syscalls.list
index 66cc687..d2d851e 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/syscalls.list
+++ b/sysdeps/unix/sysv/linux/mips/mips64/syscalls.list
@@ -1,7 +1,5 @@ 
 # File name	Caller	Syscall name	Args	Strong name	Weak names
 
-lseek		-	lseek		i:iii	__libc_lseek	__lseek lseek __llseek llseek __libc_lseek64 __lseek64 lseek64
-
 ftruncate	-	ftruncate	i:ii	__ftruncate	ftruncate ftruncate64 __ftruncate64
 truncate	-	truncate	i:si	truncate	truncate64
 
diff --git a/sysdeps/unix/sysv/linux/wordsize-64/syscalls.list b/sysdeps/unix/sysv/linux/wordsize-64/syscalls.list
index 2eb9419..3f3569f 100644
--- a/sysdeps/unix/sysv/linux/wordsize-64/syscalls.list
+++ b/sysdeps/unix/sysv/linux/wordsize-64/syscalls.list
@@ -1,8 +1,5 @@ 
 # File name	Caller	Syscall name	# args	Strong name	Weak names
 
-# Whee! 64-bit systems naturally implement llseek.
-llseek		EXTRA	lseek		i:iii	__libc_lseek	__lseek lseek __libc_lseek64 __llseek llseek __lseek64 lseek64
-lseek		llseek	-
 fstatfs		-	fstatfs		i:ip	__fstatfs	fstatfs fstatfs64 __fstatfs64
 statfs		-	statfs		i:sp	__statfs	statfs statfs64
 mmap		-	mmap		b:aniiii __mmap		mmap __mmap64 mmap64
diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/lseek64.S b/sysdeps/unix/sysv/linux/x86_64/x32/lseek64.S
new file mode 100644
index 0000000..d81e98f
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/x86_64/x32/lseek64.S
@@ -0,0 +1 @@ 
+/* We don't need a definition since the llseek function is what we need.  */