[3/6] linux: Implement mremap in C

Message ID 20211122185437.1934590-4-adhemerval.zanella@linaro.org
State Committed
Headers
Series linux: Some syscall refactors |

Checks

Context Check Description
dj/TryBot-apply_patch success Patch applied to master at the time it was sent

Commit Message

Adhemerval Zanella Netto Nov. 22, 2021, 6:54 p.m. UTC
  Variadic function calls in syscalls.list does not work for all ABIs
(for instance where the argument are passed on the stack instead of
registers) and might have underlying issues depending of the variadic
type (for instance if a 64-bit argument is used).

Checked on x86_64-linux-gnu.
---
 sysdeps/unix/sysv/linux/Makefile      |  1 +
 sysdeps/unix/sysv/linux/mremap.c      | 41 +++++++++++++++++++++++++++
 sysdeps/unix/sysv/linux/syscalls.list |  1 -
 3 files changed, 42 insertions(+), 1 deletion(-)
 create mode 100644 sysdeps/unix/sysv/linux/mremap.c
  

Comments

Stafford Horne Nov. 26, 2021, 12:26 a.m. UTC | #1
On Mon, Nov 22, 2021 at 03:54:34PM -0300, Adhemerval Zanella wrote:
> Variadic function calls in syscalls.list does not work for all ABIs
> (for instance where the argument are passed on the stack instead of
> registers) and might have underlying issues depending of the variadic
> type (for instance if a 64-bit argument is used).
> 
> Checked on x86_64-linux-gnu.
> ---
>  sysdeps/unix/sysv/linux/Makefile      |  1 +
>  sysdeps/unix/sysv/linux/mremap.c      | 41 +++++++++++++++++++++++++++
>  sysdeps/unix/sysv/linux/syscalls.list |  1 -
>  3 files changed, 42 insertions(+), 1 deletion(-)
>  create mode 100644 sysdeps/unix/sysv/linux/mremap.c
> 
> diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
> index aa10754b98..1dd6ec9ef9 100644
> --- a/sysdeps/unix/sysv/linux/Makefile
> +++ b/sysdeps/unix/sysv/linux/Makefile
> @@ -68,6 +68,7 @@ sysdep_routines += adjtimex clone umount umount2 readahead sysctl \
>  		   closefrom_fallback \
>  		   clone3 clone-internal \
>  		   fanotify_mark \
> +		   mremap \
>  
>  CFLAGS-gethostid.c = -fexceptions
>  CFLAGS-tee.c = -fexceptions -fasynchronous-unwind-tables
> diff --git a/sysdeps/unix/sysv/linux/mremap.c b/sysdeps/unix/sysv/linux/mremap.c
> new file mode 100644
> index 0000000000..83b4e95338
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/mremap.c
> @@ -0,0 +1,41 @@
> +/* Remap a virtual memory address.  Linux specific syscall.
> +   Copyright (C) 2020 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.

2021

> +
> +   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
> +   <https://www.gnu.org/licenses/>.  */
> +
> +#include <sys/mman.h>
> +#include <sysdep.h>
> +#include <stdarg.h>
> +#include <stddef.h>
> +
> +void *
> +__mremap (void *addr, size_t old_len, size_t new_len, int flags, ...)
> +{
> +  va_list va;
> +  void *new_addr = NULL;
> +
> +  if (flags & MREMAP_FIXED)
> +    {
> +      va_start (va, flags);
> +      new_addr = va_arg (va, void *);
> +      va_end (va);
> +    }
> +
> +  return (void *) INLINE_SYSCALL_CALL (mremap, addr, old_len, new_len, flags,
> +				       new_addr);
> +}
> +libc_hidden_def (__mremap)
> +weak_alias (__mremap, mremap)
> diff --git a/sysdeps/unix/sysv/linux/syscalls.list b/sysdeps/unix/sysv/linux/syscalls.list
> index 29899eb264..2acd7551d3 100644
> --- a/sysdeps/unix/sysv/linux/syscalls.list
> +++ b/sysdeps/unix/sysv/linux/syscalls.list
> @@ -35,7 +35,6 @@ mincore		-	mincore		i:aUV	mincore
>  mlock		-	mlock		i:bU	mlock
>  mlockall	-	mlockall	i:i	mlockall
>  mount		EXTRA	mount		i:sssUp	__mount	mount
> -mremap		EXTRA	mremap		b:aUUip	__mremap	mremap
>  munlock		-	munlock		i:aU	munlock
>  munlockall	-	munlockall	i:	munlockall
>  nfsservctl	EXTRA	nfsservctl	i:ipp	__compat_nfsservctl	nfsservctl@GLIBC_2.0:GLIBC_2.28
> -- 
> 2.32.0
>

This looks OK to me.

Note, I guess this syscall would be broken in or1k at the moment as it passes
variadic args on the stack.  However,  I didn't see any test failures due to
this.

-Stafford
  
Adhemerval Zanella Netto Nov. 30, 2021, 11:55 a.m. UTC | #2
On 25/11/2021 21:26, Stafford Horne wrote:
> On Mon, Nov 22, 2021 at 03:54:34PM -0300, Adhemerval Zanella wrote:
>> Variadic function calls in syscalls.list does not work for all ABIs
>> (for instance where the argument are passed on the stack instead of
>> registers) and might have underlying issues depending of the variadic
>> type (for instance if a 64-bit argument is used).
>>
>> Checked on x86_64-linux-gnu.
>> ---
>>  sysdeps/unix/sysv/linux/Makefile      |  1 +
>>  sysdeps/unix/sysv/linux/mremap.c      | 41 +++++++++++++++++++++++++++
>>  sysdeps/unix/sysv/linux/syscalls.list |  1 -
>>  3 files changed, 42 insertions(+), 1 deletion(-)
>>  create mode 100644 sysdeps/unix/sysv/linux/mremap.c
>>
>> diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
>> index aa10754b98..1dd6ec9ef9 100644
>> --- a/sysdeps/unix/sysv/linux/Makefile
>> +++ b/sysdeps/unix/sysv/linux/Makefile
>> @@ -68,6 +68,7 @@ sysdep_routines += adjtimex clone umount umount2 readahead sysctl \
>>  		   closefrom_fallback \
>>  		   clone3 clone-internal \
>>  		   fanotify_mark \
>> +		   mremap \
>>  
>>  CFLAGS-gethostid.c = -fexceptions
>>  CFLAGS-tee.c = -fexceptions -fasynchronous-unwind-tables
>> diff --git a/sysdeps/unix/sysv/linux/mremap.c b/sysdeps/unix/sysv/linux/mremap.c
>> new file mode 100644
>> index 0000000000..83b4e95338
>> --- /dev/null
>> +++ b/sysdeps/unix/sysv/linux/mremap.c
>> @@ -0,0 +1,41 @@
>> +/* Remap a virtual memory address.  Linux specific syscall.
>> +   Copyright (C) 2020 Free Software Foundation, Inc.
>> +   This file is part of the GNU C Library.
> 
> 2021

Ack.

> 
>> +
>> +   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
>> +   <https://www.gnu.org/licenses/>.  */
>> +
>> +#include <sys/mman.h>
>> +#include <sysdep.h>
>> +#include <stdarg.h>
>> +#include <stddef.h>
>> +
>> +void *
>> +__mremap (void *addr, size_t old_len, size_t new_len, int flags, ...)
>> +{
>> +  va_list va;
>> +  void *new_addr = NULL;
>> +
>> +  if (flags & MREMAP_FIXED)
>> +    {
>> +      va_start (va, flags);
>> +      new_addr = va_arg (va, void *);
>> +      va_end (va);
>> +    }
>> +
>> +  return (void *) INLINE_SYSCALL_CALL (mremap, addr, old_len, new_len, flags,
>> +				       new_addr);
>> +}
>> +libc_hidden_def (__mremap)
>> +weak_alias (__mremap, mremap)
>> diff --git a/sysdeps/unix/sysv/linux/syscalls.list b/sysdeps/unix/sysv/linux/syscalls.list
>> index 29899eb264..2acd7551d3 100644
>> --- a/sysdeps/unix/sysv/linux/syscalls.list
>> +++ b/sysdeps/unix/sysv/linux/syscalls.list
>> @@ -35,7 +35,6 @@ mincore		-	mincore		i:aUV	mincore
>>  mlock		-	mlock		i:bU	mlock
>>  mlockall	-	mlockall	i:i	mlockall
>>  mount		EXTRA	mount		i:sssUp	__mount	mount
>> -mremap		EXTRA	mremap		b:aUUip	__mremap	mremap
>>  munlock		-	munlock		i:aU	munlock
>>  munlockall	-	munlockall	i:	munlockall
>>  nfsservctl	EXTRA	nfsservctl	i:ipp	__compat_nfsservctl	nfsservctl@GLIBC_2.0:GLIBC_2.28
>> -- 
>> 2.32.0
>>
> 
> This looks OK to me.
> 
> Note, I guess this syscall would be broken in or1k at the moment as it passes
> variadic args on the stack.  However,  I didn't see any test failures due to
> this.

I think it would be for MREMAP_FIXED and the there is no failures because we
don't use the flag neither internally nor on any test.
  

Patch

diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
index aa10754b98..1dd6ec9ef9 100644
--- a/sysdeps/unix/sysv/linux/Makefile
+++ b/sysdeps/unix/sysv/linux/Makefile
@@ -68,6 +68,7 @@  sysdep_routines += adjtimex clone umount umount2 readahead sysctl \
 		   closefrom_fallback \
 		   clone3 clone-internal \
 		   fanotify_mark \
+		   mremap \
 
 CFLAGS-gethostid.c = -fexceptions
 CFLAGS-tee.c = -fexceptions -fasynchronous-unwind-tables
diff --git a/sysdeps/unix/sysv/linux/mremap.c b/sysdeps/unix/sysv/linux/mremap.c
new file mode 100644
index 0000000000..83b4e95338
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/mremap.c
@@ -0,0 +1,41 @@ 
+/* Remap a virtual memory address.  Linux specific syscall.
+   Copyright (C) 2020 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
+   <https://www.gnu.org/licenses/>.  */
+
+#include <sys/mman.h>
+#include <sysdep.h>
+#include <stdarg.h>
+#include <stddef.h>
+
+void *
+__mremap (void *addr, size_t old_len, size_t new_len, int flags, ...)
+{
+  va_list va;
+  void *new_addr = NULL;
+
+  if (flags & MREMAP_FIXED)
+    {
+      va_start (va, flags);
+      new_addr = va_arg (va, void *);
+      va_end (va);
+    }
+
+  return (void *) INLINE_SYSCALL_CALL (mremap, addr, old_len, new_len, flags,
+				       new_addr);
+}
+libc_hidden_def (__mremap)
+weak_alias (__mremap, mremap)
diff --git a/sysdeps/unix/sysv/linux/syscalls.list b/sysdeps/unix/sysv/linux/syscalls.list
index 29899eb264..2acd7551d3 100644
--- a/sysdeps/unix/sysv/linux/syscalls.list
+++ b/sysdeps/unix/sysv/linux/syscalls.list
@@ -35,7 +35,6 @@  mincore		-	mincore		i:aUV	mincore
 mlock		-	mlock		i:bU	mlock
 mlockall	-	mlockall	i:i	mlockall
 mount		EXTRA	mount		i:sssUp	__mount	mount
-mremap		EXTRA	mremap		b:aUUip	__mremap	mremap
 munlock		-	munlock		i:aU	munlock
 munlockall	-	munlockall	i:	munlockall
 nfsservctl	EXTRA	nfsservctl	i:ipp	__compat_nfsservctl	nfsservctl@GLIBC_2.0:GLIBC_2.28