75 lines
1.5 KiB
ArmAsm
75 lines
1.5 KiB
ArmAsm
/*
|
|
* \brief Linux clone() binding
|
|
* \author Christian Prochaska
|
|
* \date 2009-07-14
|
|
*
|
|
* based on glibc-2.9/sysdeps/unix/sysv/linux/x86_64/clone.S
|
|
*/
|
|
|
|
#define L(name) name
|
|
|
|
#define SYS_clone 56
|
|
#define SYS_exit 60
|
|
|
|
.text
|
|
.globl lx_clone
|
|
.type lx_clone, @function
|
|
lx_clone:
|
|
.cfi_startproc
|
|
|
|
/* Align the new stack pointer to 16 bytes. */
|
|
andq $0xfffffffffffffff0, %rsi
|
|
|
|
/* Insert the argument onto the new stack. */
|
|
subq $16,%rsi
|
|
movq %rcx,8(%rsi)
|
|
|
|
/* Save the function pointer. It will be popped off in the
|
|
child in the ebx frobbing below. */
|
|
movq %rdi,0(%rsi)
|
|
|
|
/* Do the system call. */
|
|
movq %rdx, %rdi
|
|
movq %r8, %rdx
|
|
movq %r9, %r8
|
|
movq 8(%rsp), %r10
|
|
movl $SYS_clone,%eax
|
|
|
|
/* End FDE now, because in the child the unwind info will be
|
|
wrong. */
|
|
.cfi_endproc
|
|
syscall
|
|
|
|
testq %rax,%rax
|
|
jz L(thread_start)
|
|
|
|
L(pseudo_end):
|
|
/* parent returns */
|
|
ret
|
|
|
|
L(thread_start):
|
|
.cfi_startproc
|
|
/* Clearing frame pointer is insufficient, use CFI. */
|
|
.cfi_undefined %rip;
|
|
|
|
/* Clear the frame pointer. The ABI suggests this be done, to mark
|
|
the outermost frame obviously. */
|
|
xorq %rbp, %rbp
|
|
|
|
/* Set up arguments for the function call. */
|
|
popq %rax /* Function to call. */
|
|
popq %rdi /* Argument. */
|
|
call *%rax
|
|
/* Call exit with return value from function call. */
|
|
movq %rax, %rdi
|
|
movq $SYS_exit, %rax
|
|
syscall
|
|
.cfi_endproc
|
|
|
|
/*
|
|
* Allow stacks to be mapped executable (needed because Genode does not
|
|
* offer an API to handle non-executable mappings yet).
|
|
*/
|
|
.section .note.GNU-stack, "", @progbits
|
|
|