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
next prev parent 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).