public inbox for libc-alpha@sourceware.org
 help / color / mirror / Atom feed
From: Richard Henderson <rth@twiddle.net>
To: Rasmus Villemoes <rv@rasmusvillemoes.dk>, libc-alpha@sourceware.org
Subject: Re: [PATCH v2 1/3] posix: Remove dynamic memory allocation from execl{e,p}
Date: Tue, 09 Feb 2016 11:36:00 -0000	[thread overview]
Message-ID: <56B9CF1A.6020807@twiddle.net> (raw)
In-Reply-To: <878u2wfbwv.fsf@rasmusvillemoes.dk>

[-- Attachment #1: Type: text/plain, Size: 1918 bytes --]

On 02/08/2016 08:28 AM, Rasmus Villemoes wrote:
> On Tue, Feb 02 2016, Rich Felker <dalias@libc.org> wrote:
>
>> On Mon, Feb 01, 2016 at 04:52:15PM +0000, Joseph Myers wrote:
>>> On Mon, 1 Feb 2016, Adhemerval Zanella wrote:
>>>
>>>> +  char *argv[argc+1];
>>>> +  va_start (ap, arg);
>>>> +  argv[0] = (char*) arg;
>>>> +  for (i = 1; i < argc; i++)
>>>> +     argv[i] = va_arg (ap, char *);
>>>> +  argv[i] = NULL;
>>>
>>> I don't see how you're ensuring this stack allocation is safe (i.e. if
>>> it's too big, it doesn't corrupt memory that's in use by other threads).
>>
>> There's no obligation to. If you pass something like a million
>> arguments to a variadic function, the compiler will generate code in
>> the caller that overflows the stack before the callee is even reached.
>> The size of the vla used in execl is exactly the same size as the
>> argument block on the stack used for passing arguments to execl from
>> its caller, and it's nobody's fault but the programmer's if this is
>> way too big. It's not a runtime variable.
>
> This is true, and maybe it's not worth the extra complication, but if
> we're willing to make arch-specific versions of execl and execle we can
> avoid the double stack use and the time spent copying the argv
> array. That won't remove the possible stack overflow, of course, but
> then it'll in all likelihood happen in the user code and not glibc.

I like the idea.  It's a quality of implementation issue, wherein by re-using 
the data that's (mostly) on the stack already we don't need twice again the 
amount of stack space for any given call.

I think that Adhemerval's patch should go in as a default implementation, and 
various targets can implement the assembly as desired.

I've tested the following on x86_64 and i686.  I've compile-tested for x32 (but 
need a more complete x32 installation for testing), and alpha (testing is just 
slow).

Thoughts?


r~

[-- Attachment #2: 0001-Move-posix-execl-files-to-sysdeps.patch --]
[-- Type: text/x-patch, Size: 977 bytes --]

From f685eeedc6d7baf1bf822ef058e06bc1bcae4541 Mon Sep 17 00:00:00 2001
From: Richard Henderson <rth@twiddle.net>
Date: Tue, 9 Feb 2016 11:53:32 +1100
Subject: [PATCH 1/5] Move posix/execl files to sysdeps/

This will allow them to be overridable.
---
 {posix => sysdeps/posix}/execl.c  | 0
 {posix => sysdeps/posix}/execle.c | 0
 {posix => sysdeps/posix}/execlp.c | 0
 3 files changed, 0 insertions(+), 0 deletions(-)
 rename {posix => sysdeps/posix}/execl.c (100%)
 rename {posix => sysdeps/posix}/execle.c (100%)
 rename {posix => sysdeps/posix}/execlp.c (100%)

diff --git a/posix/execl.c b/sysdeps/posix/execl.c
similarity index 100%
rename from posix/execl.c
rename to sysdeps/posix/execl.c
diff --git a/posix/execle.c b/sysdeps/posix/execle.c
similarity index 100%
rename from posix/execle.c
rename to sysdeps/posix/execle.c
diff --git a/posix/execlp.c b/sysdeps/posix/execlp.c
similarity index 100%
rename from posix/execlp.c
rename to sysdeps/posix/execlp.c
-- 
2.5.0


[-- Attachment #3: 0002-x86_64-Implement-execl-e-p-without-double-stack-allo.patch --]
[-- Type: text/x-patch, Size: 7218 bytes --]

From 447f711575e70c09fd883f28d86e175993025277 Mon Sep 17 00:00:00 2001
From: Richard Henderson <rth@twiddle.net>
Date: Tue, 9 Feb 2016 12:53:17 +1100
Subject: [PATCH 2/5] x86_64: Implement execl{,e,p} without double stack
 allocation

---
 include/unistd.h                           |  1 +
 posix/execv.c                              |  1 +
 sysdeps/unix/sysv/linux/x86_64/64/execl.S  | 65 +++++++++++++++++++++++++++++
 sysdeps/unix/sysv/linux/x86_64/64/execle.S | 66 ++++++++++++++++++++++++++++++
 sysdeps/unix/sysv/linux/x86_64/64/execlp.S | 52 +++++++++++++++++++++++
 5 files changed, 185 insertions(+)
 create mode 100644 sysdeps/unix/sysv/linux/x86_64/64/execl.S
 create mode 100644 sysdeps/unix/sysv/linux/x86_64/64/execle.S
 create mode 100644 sysdeps/unix/sysv/linux/x86_64/64/execlp.S

diff --git a/include/unistd.h b/include/unistd.h
index 5152f64..21b8135 100644
--- a/include/unistd.h
+++ b/include/unistd.h
@@ -9,6 +9,7 @@ rtld_hidden_proto (_exit, __noreturn__)
 libc_hidden_proto (alarm)
 libc_hidden_proto (confstr)
 libc_hidden_proto (execl)
+libc_hidden_proto (execv)
 libc_hidden_proto (execle)
 libc_hidden_proto (execlp)
 libc_hidden_proto (execvp)
diff --git a/posix/execv.c b/posix/execv.c
index 16c0a02..faca14f 100644
--- a/posix/execv.c
+++ b/posix/execv.c
@@ -24,3 +24,4 @@ execv (const char *path, char *const argv[])
 {
   return __execve (path, argv, __environ);
 }
+libc_hidden_def (execv)
diff --git a/sysdeps/unix/sysv/linux/x86_64/64/execl.S b/sysdeps/unix/sysv/linux/x86_64/64/execl.S
new file mode 100644
index 0000000..29b4923
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/x86_64/64/execl.S
@@ -0,0 +1,65 @@
+/* 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 <sysdep.h>
+
+ENTRY(execl)
+	/* Move return address into a register.  */
+	pop	%rax
+	cfi_adjust_cfa_offset(-8)
+	cfi_register(%rip, %rax)
+
+	/* Save the portions of the argv argument list in registers.  */
+	push	%r9
+	cfi_adjust_cfa_offset(8)
+	push	%r8
+	cfi_adjust_cfa_offset(8)
+	push	%rcx
+	cfi_adjust_cfa_offset(8)
+	push	%rdx
+	cfi_adjust_cfa_offset(8)
+	push	%rsi
+	cfi_adjust_cfa_offset(8)
+
+	/* Load the address of the argv array.  */
+	mov	%rsp, %rsi
+
+	/* Restore return address to the stack.  */
+	push	%rax
+	cfi_adjust_cfa_offset(8)
+	cfi_rel_offset(%rip, 0)
+
+	/* Load __environ for the env parameter.  */
+#ifdef PIC
+	mov	__environ@GOTPCREL(%rip), %rdx
+	mov	(%rdx), %rdx
+#else
+	mov	__environ(%rip), %rdx
+#endif
+
+	DO_CALL (execve, 3)
+
+	/* All returns are errors.  */
+	SYSCALL_SET_ERRNO
+	or	$-1, %rax
+
+	/* Pop all of the extra stack space in one go.  */
+	ret	$40
+
+END(execl)
+
+libc_hidden_def (execl)
diff --git a/sysdeps/unix/sysv/linux/x86_64/64/execle.S b/sysdeps/unix/sysv/linux/x86_64/64/execle.S
new file mode 100644
index 0000000..c2fc5c9
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/x86_64/64/execle.S
@@ -0,0 +1,66 @@
+/* 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 <sysdep.h>
+
+ENTRY(execle)
+	/* Move return address into a register.  */
+	pop	%rax
+	cfi_adjust_cfa_offset(-8)
+	cfi_register(%rip, %rax)
+
+	/* Save the portions of the argv argument list in registers.  */
+	push	%r9
+	cfi_adjust_cfa_offset(8)
+	push	%r8
+	cfi_adjust_cfa_offset(8)
+	push	%rcx
+	cfi_adjust_cfa_offset(8)
+	push	%rdx
+	cfi_adjust_cfa_offset(8)
+	push	%rsi
+	cfi_adjust_cfa_offset(8)
+
+	/* Load the address of the argv array.  */
+	mov	%rsp, %rsi
+
+	/* Restore return address to the stack.  */
+	push	%rax
+	cfi_adjust_cfa_offset(8)
+	cfi_rel_offset(%rip, 0)
+
+	/* Find the env argument.  It is the array element after the argv
+	   NULL terminator, which cannot be located before argv[1].  */
+	lea	8(%rsi), %rax
+	mov	(%rax), %rdx
+1:	add	$8, %rax
+	test	%rdx, %rdx
+	mov	(%rax), %rdx
+	jnz	1b
+
+	DO_CALL (execve, 3)
+
+	/* All returns are errors.  */
+	SYSCALL_SET_ERRNO
+	or	$-1, %rax
+
+	/* Pop all of the extra stack space in one go.  */
+	ret	$40
+
+END(execle)
+
+libc_hidden_def (execle)
diff --git a/sysdeps/unix/sysv/linux/x86_64/64/execlp.S b/sysdeps/unix/sysv/linux/x86_64/64/execlp.S
new file mode 100644
index 0000000..caa0895
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/x86_64/64/execlp.S
@@ -0,0 +1,52 @@
+/* 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 <sysdep.h>
+
+ENTRY(execlp)
+	/* Move return address into a register.  */
+	pop	%rax
+	cfi_adjust_cfa_offset(-8)
+	cfi_register(%rip, %rax)
+
+	/* Save the portions of the argv argument list in registers.  */
+	push	%r9
+	cfi_adjust_cfa_offset(8)
+	push	%r8
+	cfi_adjust_cfa_offset(8)
+	push	%rcx
+	cfi_adjust_cfa_offset(8)
+	push	%rdx
+	cfi_adjust_cfa_offset(8)
+	push	%rsi
+	cfi_adjust_cfa_offset(8)
+
+	/* Load the address of the argv array.  */
+	mov	%rsp, %rsi
+
+	/* Restore return address to the stack.  */
+	push	%rax
+	cfi_adjust_cfa_offset(8)
+	cfi_rel_offset(%rip, 0)
+
+	call	HIDDEN_JUMPTARGET (execvp)
+
+	/* Pop all of the extra stack space in one go.  */
+	ret	$40
+END(execlp)
+
+libc_hidden_def (execlp)
-- 
2.5.0


[-- Attachment #4: 0003-i386-Implement-execl-e-p-without-double-stack-alloca.patch --]
[-- Type: text/x-patch, Size: 4113 bytes --]

From 072dce81771f971f49f2480630842a2874a2c860 Mon Sep 17 00:00:00 2001
From: Richard Henderson <rth@twiddle.net>
Date: Tue, 9 Feb 2016 13:12:33 +1100
Subject: [PATCH 3/5] i386: Implement execl{,e,p} without double stack
 allocation

---
 sysdeps/unix/sysv/linux/i386/execl.S  | 39 +++++++++++++++++++++++++++++
 sysdeps/unix/sysv/linux/i386/execle.S | 46 +++++++++++++++++++++++++++++++++++
 sysdeps/unix/sysv/linux/i386/execlp.S |  4 +++
 3 files changed, 89 insertions(+)
 create mode 100644 sysdeps/unix/sysv/linux/i386/execl.S
 create mode 100644 sysdeps/unix/sysv/linux/i386/execle.S
 create mode 100644 sysdeps/unix/sysv/linux/i386/execlp.S

diff --git a/sysdeps/unix/sysv/linux/i386/execl.S b/sysdeps/unix/sysv/linux/i386/execl.S
new file mode 100644
index 0000000..047ef48
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/i386/execl.S
@@ -0,0 +1,39 @@
+/* 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 <sysdep.h>
+
+ENTRY(execl)
+	mov	4(%esp), %edx
+	lea	8(%esp), %eax
+
+	push	%eax			/* alignment padding */
+	cfi_adjust_cfa_offset(4)
+	push	%eax			/* create argv argument */
+	cfi_adjust_cfa_offset(4)
+	push	%edx			/* create path argument */
+	cfi_adjust_cfa_offset(4)
+
+	/* Let execv deal with pic vs non-pic loading of __environ.  */
+	call	HIDDEN_JUMPTARGET (execv)
+
+	add	$12, %esp
+	cfi_adjust_cfa_offset(-12)
+	ret
+END(execl)
+
+libc_hidden_def (execl)
diff --git a/sysdeps/unix/sysv/linux/i386/execle.S b/sysdeps/unix/sysv/linux/i386/execle.S
new file mode 100644
index 0000000..34cc7bc
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/i386/execle.S
@@ -0,0 +1,46 @@
+/* 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 <sysdep.h>
+
+ENTRY(execle)
+	lea	8(%esp), %eax	/* find argv array */
+
+	/* Find the env argument.  It is the array element after the argv
+	   NULL terminator, which cannot be located before argv[1].  */
+	mov	4(%eax), %edx
+	xor	%ecx, %ecx
+1:	inc	%ecx
+	test	%edx, %edx
+	mov	4(%eax, %ecx, 4), %edx
+	jnz	1b
+
+	push	%edx		/* create env argument */
+	cfi_adjust_cfa_offset(4)
+	push	%eax		/* create argv argument */
+	cfi_adjust_cfa_offset(4)
+	push	12(%esp)	/* copy path argument */
+	cfi_adjust_cfa_offset(4)
+
+	call	HIDDEN_JUMPTARGET (execve)
+
+	add	$12, %esp
+	cfi_adjust_cfa_offset(-12)
+	ret
+END(execle)
+
+libc_hidden_def (execle)
diff --git a/sysdeps/unix/sysv/linux/i386/execlp.S b/sysdeps/unix/sysv/linux/i386/execlp.S
new file mode 100644
index 0000000..d1c8806
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/i386/execlp.S
@@ -0,0 +1,4 @@
+#define execl		execlp
+#define execv		execvp
+#define __GI_execv	__GI_execvp
+#include "execl.S"
-- 
2.5.0


[-- Attachment #5: 0004-x32-Implement-execl-e-p-without-double-stack-allocat.patch --]
[-- Type: text/x-patch, Size: 8124 bytes --]

From 4577d8457637adac28ed34bc3f9ce0a936dc786e Mon Sep 17 00:00:00 2001
From: Richard Henderson <rth@twiddle.net>
Date: Tue, 9 Feb 2016 15:19:32 +1100
Subject: [PATCH 4/5] x32: Implement execl{,e,p} without double stack
 allocation

---
 sysdeps/unix/sysv/linux/x86_64/x32/execl.S  | 88 +++++++++++++++++++++++++++++
 sysdeps/unix/sysv/linux/x86_64/x32/execle.S | 87 ++++++++++++++++++++++++++++
 sysdeps/unix/sysv/linux/x86_64/x32/execlp.S | 76 +++++++++++++++++++++++++
 3 files changed, 251 insertions(+)
 create mode 100644 sysdeps/unix/sysv/linux/x86_64/x32/execl.S
 create mode 100644 sysdeps/unix/sysv/linux/x86_64/x32/execle.S
 create mode 100644 sysdeps/unix/sysv/linux/x86_64/x32/execlp.S

diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/execl.S b/sysdeps/unix/sysv/linux/x86_64/x32/execl.S
new file mode 100644
index 0000000..9139bad
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/x86_64/x32/execl.S
@@ -0,0 +1,88 @@
+/* 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 <sysdep.h>
+
+ENTRY(execl)
+	/* Move return address into a register.  */
+	pop	%rax
+	cfi_adjust_cfa_offset(-8)
+	cfi_register(%rip, %rax)
+
+	/* Save the arguments in registers.  Stop as soon as we detect
+	   the NULL terminator, as if we find one, we do not want to fall
+	   into the on-stack conversion loop.  */
+	sub	$24, %esp
+	cfi_adjust_cfa_offset(24)
+
+	mov	%edi, 4(%rsp)	/* argv[0] must be non-null.  */
+
+	mov	%edx, 8(%rsp)
+	test	%edx, %edx
+	jz	9f
+
+	mov	%ecx, 12(%rsp)
+	test	%ecx, %ecx
+	jz	9f
+
+	mov	%r8d, 16(%rsp)
+	test	%r8d, %r8d
+	jz	9f
+
+	mov	%r9d, 20(%rsp)
+	test	%r9d, %r9d
+	jz	9f
+
+	/* Convert the on-stack pointer arguments to in-place
+	   from a 64-bit padded array into a 32-bit packed array.
+           Note that this is memory is callee owned.  */
+	xor	%ecx, %ecx
+1:	mov	24(%rsp, %rcx, 8), %edx
+	mov	%edx, 24(%rsp, %rcx, 4)
+	inc	%ecx
+	test	%edx, %edx
+	jnz	1b
+
+9:
+	/* Restore return address to the stack.  */
+	push	%rax
+	cfi_adjust_cfa_offset(8)
+	cfi_rel_offset(%rip, 0)
+
+	/* Load __environ for the env parameter.  */
+#ifdef PIC
+	mov	__environ@GOTPCREL(%rip), %edx
+	mov	(%rdx), %edx
+#else
+	mov	__environ(%rip), %edx
+#endif
+
+	/* Load argv parameter.  Note that path (esi) is already loaded.  */
+	lea	12(%rsp), %edi
+
+	DO_CALL (execve, 3)
+
+	/* All returns are errors.  */
+	SYSCALL_SET_ERRNO
+	or	$-1, %rax
+
+	/* Pop all of the extra stack space in one go.  */
+	ret	$24
+
+END(execl)
+
+libc_hidden_def (execl)
diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/execle.S b/sysdeps/unix/sysv/linux/x86_64/x32/execle.S
new file mode 100644
index 0000000..c7de7e0
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/x86_64/x32/execle.S
@@ -0,0 +1,87 @@
+/* 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 <sysdep.h>
+
+ENTRY(execle)
+	/* Move return address into a register.  */
+	pop	%rax
+	cfi_adjust_cfa_offset(-8)
+	cfi_register(%rip, %rax)
+
+	/* Save the arguments in registers.  Stop as soon as we detect
+	   the NULL terminator, as if we find one, we do not want to fall
+	   into the on-stack conversion loop.  Move the potential ENV
+	   parameter in place in EDX on each exit path.  */
+	sub	$24, %esp
+	cfi_adjust_cfa_offset(24)
+
+	mov	%edi, 4(%rsp)	/* argv[0] must be non-null.  */
+
+	mov	%edx, 8(%rsp)
+	test	%edx, %edx
+	mov	%ecx, %edx
+	jz	9f
+
+	mov	%ecx, 12(%rsp)
+	test	%ecx, %ecx
+	mov	%r8d, %edx
+	jz	9f
+
+	mov	%r8d, 16(%rsp)
+	test	%r8d, %r8d
+	mov	%r9d, %edx
+	jz	9f
+
+	mov	%r9d, 20(%rsp)
+	test	%r9d, %r9d
+	mov	24(%rsp), %edx
+	jz	9f
+
+	/* Convert the on-stack pointer arguments to in-place
+	   from a 64-bit padded array into a 32-bit packed array.
+           Note that this is memory is callee owned, and that this
+	   loop exits with the ENV parameter loaded in EDX.  */
+	xor	%ecx, %ecx
+	mov	24(%rsp, %rcx, 8), %edx
+1:	mov	%edx, 24(%rsp, %rcx, 4)
+	inc	%ecx
+	test	%edx, %edx
+	mov	24(%rsp, %rcx, 8), %edx
+	jnz	1b
+
+9:
+	/* Restore return address to the stack.  */
+	push	%rax
+	cfi_adjust_cfa_offset(8)
+	cfi_rel_offset(%rip, 0)
+
+	/* Load argv parameter.  Note that path (esi) is already loaded.  */
+	lea	12(%rsp), %edi
+
+	DO_CALL (execve, 3)
+
+	/* All returns are errors.  */
+	SYSCALL_SET_ERRNO
+	or	$-1, %rax
+
+	/* Pop all of the extra stack space in one go.  */
+	ret	$24
+
+END(execle)
+
+libc_hidden_def (execle)
diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/execlp.S b/sysdeps/unix/sysv/linux/x86_64/x32/execlp.S
new file mode 100644
index 0000000..cad65f5
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/x86_64/x32/execlp.S
@@ -0,0 +1,76 @@
+/* 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 <sysdep.h>
+
+ENTRY(execlp)
+	/* Move return address into a register.  */
+	pop	%rax
+	cfi_adjust_cfa_offset(-8)
+	cfi_register(%rip, %rax)
+
+	/* Save the arguments in registers.  Stop as soon as we detect
+	   the NULL terminator, as if we find one, we do not want to fall
+	   into the on-stack conversion loop.  */
+	sub	$24, %esp
+	cfi_adjust_cfa_offset(24)
+
+	mov	%edi, 4(%rsp)	/* argv[0] must be non-null.  */
+
+	mov	%edx, 8(%rsp)
+	test	%edx, %edx
+	jz	9f
+
+	mov	%ecx, 12(%rsp)
+	test	%ecx, %ecx
+	jz	9f
+
+	mov	%r8d, 16(%rsp)
+	test	%r8d, %r8d
+	jz	9f
+
+	mov	%r9d, 20(%rsp)
+	test	%r9d, %r9d
+	jz	9f
+
+	/* Convert the on-stack pointer arguments to in-place
+	   from a 64-bit padded array into a 32-bit packed array.
+           Note that this is memory is callee owned.  */
+	xor	%ecx, %ecx
+1:	mov	24(%rsp, %rcx, 8), %edx
+	mov	%edx, 24(%rsp, %rcx, 4)
+	inc	%ecx
+	test	%edx, %edx
+	jnz	1b
+
+9:
+	/* Restore return address to the stack.  */
+	push	%rax
+	cfi_adjust_cfa_offset(8)
+	cfi_rel_offset(%rip, 0)
+
+	/* Load argv parameter.  Note that path (esi) is already loaded.  */
+	lea	12(%rsp), %edi
+
+	call	HIDDEN_JUMPTARGET (execvp)
+
+	/* Pop all of the extra stack space in one go.  */
+	ret	$24
+
+END(execlp)
+
+libc_hidden_def (execlp)
-- 
2.5.0


[-- Attachment #6: 0005-alpha-Implement-execl-e-p-without-double-stack-alloc.patch --]
[-- Type: text/x-patch, Size: 5898 bytes --]

From 5b78856069a21550d4b67b4c0a269915f37fce0f Mon Sep 17 00:00:00 2001
From: Richard Henderson <rth@twiddle.net>
Date: Tue, 9 Feb 2016 13:43:08 +1100
Subject: [PATCH 5/5] alpha: Implement execl{,e,p} without double stack
 allocation

---
 sysdeps/unix/sysv/linux/alpha/execl.S  | 52 ++++++++++++++++++++++++++++++
 sysdeps/unix/sysv/linux/alpha/execle.S | 58 ++++++++++++++++++++++++++++++++++
 sysdeps/unix/sysv/linux/alpha/execlp.S | 53 +++++++++++++++++++++++++++++++
 3 files changed, 163 insertions(+)
 create mode 100644 sysdeps/unix/sysv/linux/alpha/execl.S
 create mode 100644 sysdeps/unix/sysv/linux/alpha/execle.S
 create mode 100644 sysdeps/unix/sysv/linux/alpha/execlp.S

diff --git a/sysdeps/unix/sysv/linux/alpha/execl.S b/sysdeps/unix/sysv/linux/alpha/execl.S
new file mode 100644
index 0000000..11f4307
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/alpha/execl.S
@@ -0,0 +1,52 @@
+/* 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 <sysdep.h>
+
+ENTRY(execl)
+	cfi_startproc
+	ldgp	gp, 0(pv)
+	lda	sp, -48(sp)
+	cfi_adjust_cfa_offset(48)
+	.frame	sp, 48, ra
+	.prologue 1
+
+	/* Save the portions of the argv argument list in registers.  */
+	stq	a5, 40(sp)
+	stq	a4, 32(sp)
+	stq	a3, 24(sp)
+	stq	a2, 16(sp)
+	stq	a1,  8(sp)
+
+	/* Load the argv and envp arguments; path is already in place.  */
+	lda	a1, 8(sp)
+	ldq	a2, __environ
+
+	lda	v0, SYS_ify(execve)
+	call_pal PAL_callsys
+
+	/* Discard the stack frame now.  */
+	lda	sp, 48(sp)
+	cfi_adjust_cfa_offset(-48)
+
+	/* All returns are errors.  */
+	br	SYSCALL_ERROR_LABEL
+
+PSEUDO_END (execle)
+	cfi_endproc
+
+libc_hidden_def (execl)
diff --git a/sysdeps/unix/sysv/linux/alpha/execle.S b/sysdeps/unix/sysv/linux/alpha/execle.S
new file mode 100644
index 0000000..ce75ce3
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/alpha/execle.S
@@ -0,0 +1,58 @@
+/* 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 <sysdep.h>
+
+ENTRY(execle)
+	cfi_startproc
+	lda	sp, -48(sp)
+	cfi_adjust_cfa_offset(48)
+	.frame  sp, 48, ra
+	.prologue 0
+
+	/* Save the portions of the argv argument list in registers.  */
+	stq	a5, 40(sp)
+	stq	a4, 32(sp)
+	stq	a3, 24(sp)
+	stq	a2, 16(sp)
+	stq	a1,  8(sp)
+
+	/* Find the env argument.  It is the array element after the argv
+	   NULL terminator, which cannot be located before argv[1].  */
+	lda	t0, 16(sp)
+1:	ldq	t1, 0(t0)
+	addq	t0, 8, t0
+	bne	t1, 1b
+
+	/* Load the argv and envp arguments; path is already in place.  */
+	lda	a1, 8(sp)
+	ldq	a2, 0(t0)
+
+	lda	v0, SYS_ify(execve)
+	call_pal PAL_callsys
+
+	/* Discard the stack frame now.  */
+	lda	sp, 48(sp)
+	cfi_adjust_cfa_offset(-48)
+
+	/* All returns are errors.  */
+	br	SYSCALL_ERROR_LABEL
+
+PSEUDO_END (execle)
+	cfi_endproc
+
+libc_hidden_def (execle)
diff --git a/sysdeps/unix/sysv/linux/alpha/execlp.S b/sysdeps/unix/sysv/linux/alpha/execlp.S
new file mode 100644
index 0000000..b0ef76d
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/alpha/execlp.S
@@ -0,0 +1,53 @@
+/* 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 <sysdep.h>
+
+ENTRY(execlp)
+	cfi_startproc
+	ldgp	gp, 0(pv)
+	lda	sp, -48(sp)
+	cfi_adjust_cfa_offset(48)
+	stq	ra, 0(sp)
+	cfi_rel_offset(ra, 0)
+	.prologue 1
+
+	/* Save the portions of the argv argument list in registers.  */
+	stq	a5, 40(sp)
+	stq	a4, 32(sp)
+	stq	a3, 24(sp)
+	stq	a2, 16(sp)
+	stq	a1,  8(sp)
+
+	/* Load the argv and envp arguments; path is already in place.  */
+	lda	a1, 8(sp)
+	ldq	a2, __environ
+#ifdef PIC
+	bsr	ra, __execvpe		!samegp
+#else
+	jsr	ra, __execvpe
+	ldgp	gp, 0(ra)
+#endif
+
+	lda	sp, 48(sp)
+	cfi_adjust_cfa_offset(-48)
+	ret
+
+END (execlp)
+	cfi_endproc
+
+libc_hidden_def (execlp)
-- 
2.5.0


  reply	other threads:[~2016-02-09 11:36 UTC|newest]

Thread overview: 45+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-02-01 16:21 [PATCH 0/3] posix: Execute file function fixes Adhemerval Zanella
2016-02-01 16:21 ` [PATCH v2 3/3] posix: New Linux posix_spawn{p} implementation Adhemerval Zanella
2016-02-02 13:06   ` Florian Weimer
2016-02-02 13:31     ` Adhemerval Zanella
2016-02-03 11:07       ` Torvald Riegel
2016-02-03 12:05         ` Adhemerval Zanella
2016-02-03 12:06           ` Torvald Riegel
2016-02-03 12:14             ` Adhemerval Zanella
2016-08-31 21:13   ` Rasmus Villemoes
2016-08-31 22:08     ` Joseph Myers
2016-09-01  9:28       ` Rasmus Villemoes
2016-09-14 13:13         ` Adhemerval Zanella
2016-09-14 18:58           ` Rasmus Villemoes
2016-09-14 19:59             ` Adhemerval Zanella
2016-09-20 20:25         ` Florian Weimer
2016-09-20 20:54           ` Rasmus Villemoes
2016-09-20 21:01           ` [PATCH] linux: spawni.c: simplify error reporting to parent Rasmus Villemoes
2016-09-22 20:54             ` Adhemerval Zanella
2016-09-23  5:21             ` Florian Weimer
2016-09-23 19:09               ` Rasmus Villemoes
2016-09-23 19:28                 ` Adhemerval Zanella
2016-09-23 20:37                   ` Florian Weimer
2016-09-27 20:26                     ` Rasmus Villemoes
2016-09-27 21:14                       ` Adhemerval Zanella
2016-09-28 14:14             ` Rich Felker
2016-09-28 15:03               ` Andreas Schwab
2016-09-28 15:22                 ` Rich Felker
2016-09-28 18:13                   ` Adhemerval Zanella
2016-10-06 12:52                     ` Florian Weimer
2016-09-06 20:43     ` [PATCH v2 3/3] posix: New Linux posix_spawn{p} implementation Rasmus Villemoes
2016-09-14 19:37     ` Adhemerval Zanella
2016-02-01 16:21 ` [PATCH v2 1/3] posix: Remove dynamic memory allocation from execl{e,p} Adhemerval Zanella
2016-02-01 16:52   ` Joseph Myers
2016-02-01 17:18     ` Adhemerval Zanella
2016-02-01 17:54       ` Joseph Myers
2016-02-01 18:09         ` Adhemerval Zanella
2016-02-02 11:24       ` Florian Weimer
2016-02-02 12:46         ` Szabolcs Nagy
2016-02-02 12:47         ` Adhemerval Zanella
2016-02-02 16:33     ` Rich Felker
2016-02-07 21:28       ` Rasmus Villemoes
2016-02-09 11:36         ` Richard Henderson [this message]
2016-02-09 13:30           ` Szabolcs Nagy
2016-02-10 16:36             ` Adhemerval Zanella
2016-02-01 16:21 ` [PATCH v4 2/3] posix: execvpe cleanup Adhemerval Zanella

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=56B9CF1A.6020807@twiddle.net \
    --to=rth@twiddle.net \
    --cc=libc-alpha@sourceware.org \
    --cc=rv@rasmusvillemoes.dk \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).