about summary refs log tree commit diff
path: root/sysdeps/unix/sysv/linux/aarch64/clone.S
diff options
context:
space:
mode:
authorRichard Henderson <rth@redhat.com>2014-05-23 15:44:23 -0400
committerRichard Henderson <rth@redhat.com>2014-06-03 11:04:04 -0400
commit111cc714894d71fdc31c04e56b1bcd41b2680269 (patch)
tree5d69bd81441b97d5880c0e27c194dc1de7f37b01 /sysdeps/unix/sysv/linux/aarch64/clone.S
parentccc39911132db27b385b4dd196cf2bb82f2d03c2 (diff)
downloadglibc-111cc714894d71fdc31c04e56b1bcd41b2680269.tar.gz
glibc-111cc714894d71fdc31c04e56b1bcd41b2680269.tar.xz
glibc-111cc714894d71fdc31c04e56b1bcd41b2680269.zip
aarch64: Consolidate NPTL/non versions of clone
At the same time, rely on non-clobbered registers across syscall
so that we eliminate the stack frame that we previously ignored
in the unwind info.
Diffstat (limited to 'sysdeps/unix/sysv/linux/aarch64/clone.S')
-rw-r--r--sysdeps/unix/sysv/linux/aarch64/clone.S56
1 files changed, 24 insertions, 32 deletions
diff --git a/sysdeps/unix/sysv/linux/aarch64/clone.S b/sysdeps/unix/sysv/linux/aarch64/clone.S
index f2964f4871..a2b5a2bc24 100644
--- a/sysdeps/unix/sysv/linux/aarch64/clone.S
+++ b/sysdeps/unix/sysv/linux/aarch64/clone.S
@@ -39,47 +39,42 @@
  */
         .text
 ENTRY(__clone)
+	/* Save args for the child.  */
+	mov	x10, x0
+	mov	x11, x2
+	mov	x12, x3
+
 	/* Sanity check args.  */
-	cbz	x0, 1f
-	cbz	x1, 1f
-	/* Insert the args onto the new stack.  */
-	stp	x0, x3, [x1, #-16]!	/* Fn, arg.  */
+	mov	x0, #-EINVAL
+	cbz	x10, .Lsyscall_error
+	cbz	x1, .Lsyscall_error
 
 	/* Do the system call.  */
+	/* X0:flags, x1:newsp, x2:parenttidptr, x3:newtls, x4:childtid.  */
 	mov	x0, x2                  /* flags  */
-
 	/* New sp is already in x1.  */
 	mov	x2, x4			/* ptid  */
 	mov	x3, x5			/* tls  */
 	mov	x4, x6			/* ctid  */
-
-#ifdef RESET_PID
-	/* We rely on the kernel preserving the argument regsiters across a
-	   each system call so that we can inspect the flags against after
-	   the clone call.  */
-	mov	x5, x0
-#endif
-
 	mov	x8, #SYS_ify(clone)
-	/* X0:flags, x1:newsp, x2:parenttidptr, x3:newtls, x4:childtid.  */
 	svc	0x0
-	cfi_endproc
+
 	cmp	x0, #0
-	beq	2f
-	blt	3f
+	beq	thread_start
+	blt	.Lsyscall_error
 	RET
-1:	mov	x0, #-EINVAL
-3:
-	b	syscall_error
+PSEUDO_END (__clone)
 
-2:
+	.align 4
+	.type thread_start, %function
+thread_start:
 	cfi_startproc
 	cfi_undefined (x30)
 	mov	x29, 0
-#ifdef RESET_PID
-	tbnz	x5, #CLONE_THREAD_BIT, 3f
+
+	tbnz	x11, #CLONE_THREAD_BIT, 3f
 	mov	x0, #-1
-	tbnz	x5, #CLONE_VM_BIT, 2f
+	tbnz	x11, #CLONE_VM_BIT, 2f
 	mov	x8, #SYS_ify(getpid)
 	svc	0x0
 2:
@@ -87,18 +82,15 @@ ENTRY(__clone)
 	sub	x1, x1, #PTHREAD_SIZEOF
 	str	w0, [x1, #PTHREAD_PID_OFFSET]
 	str	w0, [x1, #PTHREAD_TID_OFFSET]
-
 3:
-#endif
-	/* Pick the function arg and call address from the stack and
-	   execute.  */
-	ldp	x1, x0, [sp], #16
-	blr	x1
+
+	/* Pick the function arg and execute.  */
+	mov	x0, x12
+	blr	x10
 
 	/* We are done, pass the return value through x0.  */
 	b	HIDDEN_JUMPTARGET(_exit)
 	cfi_endproc
-	cfi_startproc
-PSEUDO_END (__clone)
+	.size thread_start, .-thread_start
 
 weak_alias (__clone, clone)