x86-64: Add p{read,write}[v]64 to syscalls.list [BZ #20348]

Message ID 20160712132628.GA7361@intel.com
State New, archived
Headers

Commit Message

Lu, Hongjiu July 12, 2016, 1:26 p.m. UTC
  64-bit off_t in pread64, preadv, pwrite64 and pwritev syscalls is pased
in one 64-bit register for both x32 and x86-64.  Since the inline
asm statement only passes long, which is 32-bit for x32, in registers,
64-bit off_t is truncated to 32-bit on x32.  Since __ASSUME_PREADV and
__ASSUME_PWRITEV are defined unconditionally, these syscalls can be
implemented in syscalls.list to pass 64-bit off_t in one 64-bit register.

Tested on x86-64 and x32 with off_t > 4GB on pread64/pwrite64 and
preadv64/pwritev64.

OK for master?

H.J.
---
	[BZ #20348]
	* sysdeps/unix/sysv/linux/x86_64/syscalls.list: Add pread64,
	preadv64, pwrite64 and pwritev64.
---
 sysdeps/unix/sysv/linux/x86_64/syscalls.list | 4 ++++
 1 file changed, 4 insertions(+)
  

Comments

Adhemerval Zanella Netto July 12, 2016, 2:04 p.m. UTC | #1
On 12/07/2016 14:26, H.J. Lu wrote:
> 64-bit off_t in pread64, preadv, pwrite64 and pwritev syscalls is pased
> in one 64-bit register for both x32 and x86-64.  Since the inline
> asm statement only passes long, which is 32-bit for x32, in registers,
> 64-bit off_t is truncated to 32-bit on x32.  Since __ASSUME_PREADV and
> __ASSUME_PWRITEV are defined unconditionally, these syscalls can be
> implemented in syscalls.list to pass 64-bit off_t in one 64-bit register.
> 
> Tested on x86-64 and x32 with off_t > 4GB on pread64/pwrite64 and
> preadv64/pwritev64.
> 
> OK for master?
> 
> H.J.
> ---
> 	[BZ #20348]
> 	* sysdeps/unix/sysv/linux/x86_64/syscalls.list: Add pread64,
> 	preadv64, pwrite64 and pwritev64.
> ---
>  sysdeps/unix/sysv/linux/x86_64/syscalls.list | 4 ++++
>  1 file changed, 4 insertions(+)
> 
> diff --git a/sysdeps/unix/sysv/linux/x86_64/syscalls.list b/sysdeps/unix/sysv/linux/x86_64/syscalls.list
> index d09d101..bcf6370 100644
> --- a/sysdeps/unix/sysv/linux/x86_64/syscalls.list
> +++ b/sysdeps/unix/sysv/linux/x86_64/syscalls.list
> @@ -6,6 +6,10 @@ msgctl		-	msgctl		i:iip	__msgctl	msgctl
>  msgget		-	msgget		i:ii	__msgget	msgget
>  msgrcv		-	msgrcv		Ci:ibnii __msgrcv	msgrcv
>  msgsnd		-	msgsnd		Ci:ibni	__msgsnd	msgsnd
> +pread64		-	pread64		Ci:ipii	__libc_pread	__libc_pread64 __pread64 pread64 __pread pread
> +preadv64	-	preadv		Ci:ipii	preadv64	preadv
> +pwrite64	-	pwrite64	Ci:ipii	__libc_pwrite	__pwrite64 pwrite64 __pwrite pwrite
> +pwritev64	-	pwritev		Ci:ipii	pwritev64	pwritev
>  shmat		-	shmat		i:ipi	__shmat		shmat
>  shmctl		-	shmctl		i:iip	__shmctl	shmctl
>  shmdt		-	shmdt		i:s	__shmdt		shmdt
> 

This is pretty much what I suggested [1] with the difference that my
idea is to re-add the auto-generated wrappers just for x32.  I would
prefer to keep x86_64 continue to use default implementation and
work on fix {INLINE,INTERNAL}_SYSCALL to work with 64-bit arguments
in x32.

Also, I think we should remove the first try to fix LO_HI_LONG [2],
since 64 bits argument does not work correct in x32 anyway.

[1] https://sourceware.org/ml/libc-alpha/2016-07/msg00318.html
[2] https://sourceware.org/git/?p=glibc.git;a=commit;h=cf1ad5b3add36790cbf58a3972c492a8f1632929
  
H.J. Lu July 12, 2016, 3:03 p.m. UTC | #2
On Tue, Jul 12, 2016 at 7:04 AM, Adhemerval Zanella
<adhemerval.zanella@linaro.org> wrote:
>
>
> On 12/07/2016 14:26, H.J. Lu wrote:
>> 64-bit off_t in pread64, preadv, pwrite64 and pwritev syscalls is pased
>> in one 64-bit register for both x32 and x86-64.  Since the inline
>> asm statement only passes long, which is 32-bit for x32, in registers,
>> 64-bit off_t is truncated to 32-bit on x32.  Since __ASSUME_PREADV and
>> __ASSUME_PWRITEV are defined unconditionally, these syscalls can be
>> implemented in syscalls.list to pass 64-bit off_t in one 64-bit register.
>>
>> Tested on x86-64 and x32 with off_t > 4GB on pread64/pwrite64 and
>> preadv64/pwritev64.
>>
>> OK for master?
>>
>> H.J.
>> ---
>>       [BZ #20348]
>>       * sysdeps/unix/sysv/linux/x86_64/syscalls.list: Add pread64,
>>       preadv64, pwrite64 and pwritev64.
>> ---
>>  sysdeps/unix/sysv/linux/x86_64/syscalls.list | 4 ++++
>>  1 file changed, 4 insertions(+)
>>
>> diff --git a/sysdeps/unix/sysv/linux/x86_64/syscalls.list b/sysdeps/unix/sysv/linux/x86_64/syscalls.list
>> index d09d101..bcf6370 100644
>> --- a/sysdeps/unix/sysv/linux/x86_64/syscalls.list
>> +++ b/sysdeps/unix/sysv/linux/x86_64/syscalls.list
>> @@ -6,6 +6,10 @@ msgctl               -       msgctl          i:iip   __msgctl        msgctl
>>  msgget               -       msgget          i:ii    __msgget        msgget
>>  msgrcv               -       msgrcv          Ci:ibnii __msgrcv       msgrcv
>>  msgsnd               -       msgsnd          Ci:ibni __msgsnd        msgsnd
>> +pread64              -       pread64         Ci:ipii __libc_pread    __libc_pread64 __pread64 pread64 __pread pread
>> +preadv64     -       preadv          Ci:ipii preadv64        preadv
>> +pwrite64     -       pwrite64        Ci:ipii __libc_pwrite   __pwrite64 pwrite64 __pwrite pwrite
>> +pwritev64    -       pwritev         Ci:ipii pwritev64       pwritev
>>  shmat                -       shmat           i:ipi   __shmat         shmat
>>  shmctl               -       shmctl          i:iip   __shmctl        shmctl
>>  shmdt                -       shmdt           i:s     __shmdt         shmdt
>>
>
> This is pretty much what I suggested [1] with the difference that my
> idea is to re-add the auto-generated wrappers just for x32.  I would
> prefer to keep x86_64 continue to use default implementation and
> work on fix {INLINE,INTERNAL}_SYSCALL to work with 64-bit arguments
> in x32.

syscalls.list is the preferred way to implement a system call, not
{INLINE,INTERNAL}_SYSCALL.  There is no reason only to do it
for x32.  As for {INLINE,INTERNAL}_SYSCALL with 64-bit argument,
they are only used in p{read,write}[v]64 and it is incorrect to pass long
as 64-bit integer to x32 syscall if the argument is long or pointer.

> Also, I think we should remove the first try to fix LO_HI_LONG [2],
> since 64 bits argument does not work correct in x32 anyway.

I think LO_HI_LONG should be defined only if __WORDSIZE != 64
and p{read,write}[v]64 should be added to wordsize-64/syscalls.list.

> [1] https://sourceware.org/ml/libc-alpha/2016-07/msg00318.html
> [2] https://sourceware.org/git/?p=glibc.git;a=commit;h=cf1ad5b3add36790cbf58a3972c492a8f1632929
  

Patch

diff --git a/sysdeps/unix/sysv/linux/x86_64/syscalls.list b/sysdeps/unix/sysv/linux/x86_64/syscalls.list
index d09d101..bcf6370 100644
--- a/sysdeps/unix/sysv/linux/x86_64/syscalls.list
+++ b/sysdeps/unix/sysv/linux/x86_64/syscalls.list
@@ -6,6 +6,10 @@  msgctl		-	msgctl		i:iip	__msgctl	msgctl
 msgget		-	msgget		i:ii	__msgget	msgget
 msgrcv		-	msgrcv		Ci:ibnii __msgrcv	msgrcv
 msgsnd		-	msgsnd		Ci:ibni	__msgsnd	msgsnd
+pread64		-	pread64		Ci:ipii	__libc_pread	__libc_pread64 __pread64 pread64 __pread pread
+preadv64	-	preadv		Ci:ipii	preadv64	preadv
+pwrite64	-	pwrite64	Ci:ipii	__libc_pwrite	__pwrite64 pwrite64 __pwrite pwrite
+pwritev64	-	pwritev		Ci:ipii	pwritev64	pwritev
 shmat		-	shmat		i:ipi	__shmat		shmat
 shmctl		-	shmctl		i:iip	__shmctl	shmctl
 shmdt		-	shmdt		i:s	__shmdt		shmdt