diff options
author | Adhemerval Zanella Netto <adhemerval.zanella@linaro.org> | 2023-08-24 13:42:14 -0300 |
---|---|---|
committer | Adhemerval Zanella <adhemerval.zanella@linaro.org> | 2023-09-05 10:15:48 -0300 |
commit | b56f7fe79e66387fd66009ab335ec61cab71d2ed (patch) | |
tree | a516c62d0ef1c23315869ad9522aadcf5079cbdd /sysdeps/unix/sysv/linux/arm/clone3.S | |
parent | 4be913652ca115160bae1daf560170ef8b112ccb (diff) | |
download | glibc-b56f7fe79e66387fd66009ab335ec61cab71d2ed.zip glibc-b56f7fe79e66387fd66009ab335ec61cab71d2ed.tar.gz glibc-b56f7fe79e66387fd66009ab335ec61cab71d2ed.tar.bz2 |
arm: Add the clone3 wrapper
It follows the internal signature:
extern int clone3 (struct clone_args *__cl_args, size_t __size,
int (*__func) (void *__arg), void *__arg);
Checked on arm-linux-gnueabihf.
Diffstat (limited to 'sysdeps/unix/sysv/linux/arm/clone3.S')
-rw-r--r-- | sysdeps/unix/sysv/linux/arm/clone3.S | 80 |
1 files changed, 80 insertions, 0 deletions
diff --git a/sysdeps/unix/sysv/linux/arm/clone3.S b/sysdeps/unix/sysv/linux/arm/clone3.S new file mode 100644 index 0000000..f236d18 --- /dev/null +++ b/sysdeps/unix/sysv/linux/arm/clone3.S @@ -0,0 +1,80 @@ +/* The clone3 syscall wrapper. Linux/arm version. + Copyright (C) 2023 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 <sysdep.h> +#define _ERRNO_H 1 +#include <bits/errno.h> + +/* The userland implementation is: + int clone3 (struct clone_args *cl_args, size_t size, + int (*func)(void *arg), void *arg); + + the kernel entry is: + int clone3 (struct clone_args *cl_args, size_t size); + + The parameters are passed in registers from userland: + r0: cl_args + r1: size + r2: func + r3: arg */ + + .text +ENTRY(__clone3) + /* Sanity check args. */ + cmp r0, #0 + ite ne + cmpne r1, #0 + moveq r0, #-EINVAL + beq PLTJMP(syscall_error) + + /* Do the syscall, the kernel expects: + r7: system call number: + r0: cl_args + r1: size */ + push { r7 } + cfi_adjust_cfa_offset (4) + cfi_rel_offset (r7, 0) + ldr r7, =SYS_ify(clone3) + swi 0x0 + cfi_endproc + + cmp r0, #0 + beq 1f + pop {r7} + blt PLTJMP(C_SYMBOL_NAME(__syscall_error)) + RETINSTR(, lr) + + cfi_startproc +PSEUDO_END (__clone3) + +1: + .fnstart + .cantunwind + mov r0, r3 + mov ip, r2 + BLX (ip) + + /* And we are done, passing the return value through r0. */ + ldr r7, =SYS_ify(exit) + swi 0x0 + + .fnend + +libc_hidden_def (__clone3) +weak_alias (__clone3, clone3) |