diff options
author | Richard Henderson <rth@twiddle.net> | 2016-02-09 12:53:17 +1100 |
---|---|---|
committer | Richard Henderson <rth@twiddle.net> | 2016-02-09 14:32:51 +1100 |
commit | 447f711575e70c09fd883f28d86e175993025277 (patch) | |
tree | 4f6f8c67553438d3b8b30d1b4aadeb76382f63c7 /sysdeps/unix/sysv | |
parent | f685eeedc6d7baf1bf822ef058e06bc1bcae4541 (diff) | |
download | glibc-447f711575e70c09fd883f28d86e175993025277.tar.gz glibc-447f711575e70c09fd883f28d86e175993025277.tar.xz glibc-447f711575e70c09fd883f28d86e175993025277.zip |
x86_64: Implement execl{,e,p} without double stack allocation
Diffstat (limited to 'sysdeps/unix/sysv')
-rw-r--r-- | sysdeps/unix/sysv/linux/x86_64/64/execl.S | 65 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/x86_64/64/execle.S | 66 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/x86_64/64/execlp.S | 52 |
3 files changed, 183 insertions, 0 deletions
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 0000000000..29b492393b --- /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 0000000000..c2fc5c93d5 --- /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 0000000000..caa08951e3 --- /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) |