[PATCH v6] aarch64: Add split-stack support

Wilco Dijkstra Wilco.Dijkstra@arm.com
Tue Feb 13 16:40:00 GMT 2018


Hi Adhemerval,

A few comments on the assembly code:


+# This function is called with non-standard calling convention: on entry
+# x10 is the requested stack pointer, x11 is previous stack pointer (if
+# functions has stacked arguments which needs to be restored), and x12 is
+# the caller link register on function entry (which will be restored by
+# morestack when returning to caller).  The split-stack prologue is in
+# the form:
+#
+# function:
+#	mrs    x9, tpidr_el0
+#	ldur   x9, [x9, #-8]
+#	mov    x10, <required stack allocation>
+#	movk   x10, #0x0, lsl #16
+#	sub    x10, sp, x10
+#	mov    x11, sp   	# if function has stacked arguments

+#	mov    x12, x30

This should go...

+#	cmp    x9, x10
+#	bcc    .LX
+# main_fn_entry:
+#	[function body]
+# LX:

...here:

        mov    x12, x30

+#	bl      __morestack
+#	b	main_fn_entry

Note using a bl here rather than a branch means you'll kill the return stack.

+# The N bit is also restored to indicate that the function is called
+# (so the prologue addition can set up the argument pointer correctly).
+
+ENTRY(__morestack)
+.LFB1:
+	.cfi_startproc
+
+#ifdef __PIC__
+	.cfi_personality 0x9b,DW.ref.__gcc_personality_v0
+	.cfi_lsda 0x1b,.LLSDA1
+#else
+	.cfi_personality 0x3,__gcc_personality_v0
+	.cfi_lsda 0x3,.LLSDA1
+#endif
+	# Calculate requested stack size.
+	sub	x10, sp, x10
+
+	# Save parameters
+	stp	x29, x12, [sp, -MORESTACK_FRAMESIZE]!
+	.cfi_def_cfa_offset MORESTACK_FRAMESIZE
+	.cfi_offset 29, -MORESTACK_FRAMESIZE
+	.cfi_offset 30, -MORESTACK_FRAMESIZE+8
+	add	x29, sp, 0
+	.cfi_def_cfa_register 29
+	# Adjust the requested stack size for the frame pointer save.
+	stp	x0, x1, [x29, 16]
+	stp	x2, x3, [x29, 32]
+	add	x10, x10, BACKOFF
+	stp	x4, x5, [x29, 48]
+	stp	x6, x7, [x29, 64]
+	stp 	x8, x30, [x29, 80]
+	str	x10, [x29, 96]

Probably best to use NEWSTACK_SAVE here for clarity.

+	# void __morestack_block_signals (void)
+	bl	__morestack_block_signals
+
+	# void *__generic_morestack (size_t *pframe_size,
+	#			     void *old_stack,
+	#			     size_t param_size)
+	# pframe_size: is the size of the required stack frame (the function
+	#	       amount of space remaining on the allocated stack).
+	# old_stack: points at the parameters the old stack
+	# param_size: size in bytes of parameters to copy to the new stack.
+	add	x0, x29, NEWSTACK_SAVE
+	add	x1, x29, MORESTACK_FRAMESIZE
+	mov	x2, 0
+	bl	__generic_morestack
+
+	# Start using new stack
+	mov	sp, x0
+
+	# Set __private_ss stack guard for the new stack.
+	ldr	x9, [x29, NEWSTACK_SAVE]
+	add	x0, x0, BACKOFF
+	sub	x0, x0, x9
+.LEHB0:
+	mrs	x1, tpidr_el0
+	str	x0, [x1, SPLITSTACK_PTR_TP]

Is the label for unwinding exactly at the right place?

+	# void __morestack_unblock_signals (void)
+	bl	__morestack_unblock_signals
+
+	# Set up for a call to the target function.
+	ldp	x0, x1, [x29, 16]
+	ldp	x2, x3, [x29, 32]
+	ldp	x4, x5, [x29, 48]
+	ldp	x6, x7, [x29, 64]
+	ldp	x8, x12, [x29, 80]
+	add	x11, x29, MORESTACK_FRAMESIZE

+	ldr	x30, [x29, 8]
+	# Indicate __morestack was called.
+	cmp	x12, 0

No idea what this is for but the ldr/cmp are completely redundant.

+	blr	x12
+
+	stp	x0, x1, [x29, 16]

+	stp	x2, x3, [x29, 32]
+	stp	x4, x5, [x29, 48]
+	stp	x6, x7, [x29, 64]

These 3 STPs are dead.

+	bl	__morestack_block_signals
+
+	# void *__generic_releasestack (size_t *pavailable)
+	add	x0, x29, NEWSTACK_SAVE
+	bl	__generic_releasestack
+
+	# Reset __private_ss stack guard to value for old stack
+	ldr	x9, [x29, NEWSTACK_SAVE]
+	add	x0, x0, BACKOFF
+	sub	x0, x0, x9
+
+	# Update TCB split stack field
+.LEHE0:
+	mrs	x1, tpidr_el0
+	str	x0, [x1, SPLITSTACK_PTR_TP]
+
+	bl __morestack_unblock_signals
+
+	# Use old stack again.
+	add	sp, x29, MORESTACK_FRAMESIZE
+
+	ldp	x0, x1, [x29, 16]

+	ldp	x2, x3, [x29, 32]
+	ldp	x4, x5, [x29, 48]
+	ldp	x6, x7, [x29, 64]

These 3 LDPs are dead.

+	ldp	x29, x30, [x29]
+
+	.cfi_remember_state
+	.cfi_restore 30
+	.cfi_restore 29
+	.cfi_def_cfa 31, 0
+
+	ret


More information about the Gcc-patches mailing list