xref: /onnv-gate/usr/src/lib/libc/sparc/gen/_stack_grow.s (revision 7298:b69e27387f74)
10Sstevel@tonic-gate/*
20Sstevel@tonic-gate * CDDL HEADER START
30Sstevel@tonic-gate *
40Sstevel@tonic-gate * The contents of this file are subject to the terms of the
56812Sraf * Common Development and Distribution License (the "License").
66812Sraf * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate *
80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate * See the License for the specific language governing permissions
110Sstevel@tonic-gate * and limitations under the License.
120Sstevel@tonic-gate *
130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate *
190Sstevel@tonic-gate * CDDL HEADER END
200Sstevel@tonic-gate */
216812Sraf
220Sstevel@tonic-gate/*
236812Sraf * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
240Sstevel@tonic-gate * Use is subject to license terms.
250Sstevel@tonic-gate */
260Sstevel@tonic-gate
27*7298SMark.J.Nelson@Sun.COM	.file	"_stack_grow.s"
280Sstevel@tonic-gate
290Sstevel@tonic-gate#include "SYS.h"
300Sstevel@tonic-gate#include <../assym.h>
310Sstevel@tonic-gate
320Sstevel@tonic-gate/*
330Sstevel@tonic-gate * void *
340Sstevel@tonic-gate * _stack_grow(void *addr)
350Sstevel@tonic-gate * {
360Sstevel@tonic-gate *	uintptr_t base = (uintptr_t)curthread->ul_ustack.ss_sp;
370Sstevel@tonic-gate *	size_t size = curthread->ul_ustack.ss_size;
380Sstevel@tonic-gate *
390Sstevel@tonic-gate *	if (size > (uintptr_t)addr - (base - STACK_BIAS))
400Sstevel@tonic-gate *		return (addr);
410Sstevel@tonic-gate *
420Sstevel@tonic-gate *	if (size == 0)
430Sstevel@tonic-gate *		return (addr);
440Sstevel@tonic-gate *
450Sstevel@tonic-gate *	if (size > %sp - (base - STACK_BIAS))
460Sstevel@tonic-gate *		%sp = base - STACK_BIAS - STACK_ALIGN;
470Sstevel@tonic-gate *
480Sstevel@tonic-gate *	*((char *)(base - 1));
490Sstevel@tonic-gate *
500Sstevel@tonic-gate *	_lwp_kill(_lwp_self(), SIGSEGV);
510Sstevel@tonic-gate * }
520Sstevel@tonic-gate */
530Sstevel@tonic-gate
540Sstevel@tonic-gate#if defined(__sparcv9)
550Sstevel@tonic-gate#define	PN	,pn %xcc,
560Sstevel@tonic-gate#else
570Sstevel@tonic-gate#define	PN
580Sstevel@tonic-gate#endif
590Sstevel@tonic-gate
600Sstevel@tonic-gate	/*
610Sstevel@tonic-gate	 * o0: address to which the stack will be grown (biased)
620Sstevel@tonic-gate	 */
630Sstevel@tonic-gate	ENTRY(_stack_grow)
640Sstevel@tonic-gate	ldn	[%g7 + UL_USTACK + SS_SP], %o1
650Sstevel@tonic-gate	ldn	[%g7 + UL_USTACK + SS_SIZE], %o2
660Sstevel@tonic-gate	sub	%o1, STACK_BIAS, %o3
670Sstevel@tonic-gate
680Sstevel@tonic-gate	sub	%o0, %o3, %o4
690Sstevel@tonic-gate	cmp	%o2, %o4
700Sstevel@tonic-gate	bleu PN	1f
710Sstevel@tonic-gate	tst	%o2
720Sstevel@tonic-gate
730Sstevel@tonic-gate	retl
740Sstevel@tonic-gate	nop
750Sstevel@tonic-gate1:
760Sstevel@tonic-gate	/*
770Sstevel@tonic-gate	 * If the stack size is 0, stack checking is disabled.
780Sstevel@tonic-gate	 */
790Sstevel@tonic-gate	bnz PN	2f
800Sstevel@tonic-gate	nop
810Sstevel@tonic-gate	retl
820Sstevel@tonic-gate	nop
830Sstevel@tonic-gate2:
840Sstevel@tonic-gate	/*
850Sstevel@tonic-gate	 * Move the stack pointer outside the stack bounds if it isn't already.
860Sstevel@tonic-gate	 */
870Sstevel@tonic-gate	sub	%sp, %o3, %o4
880Sstevel@tonic-gate	cmp	%o2, %o4
890Sstevel@tonic-gate	bleu PN	3f
900Sstevel@tonic-gate	nop
910Sstevel@tonic-gate	sub	%o3, STACK_ALIGN, %sp
920Sstevel@tonic-gate3:
930Sstevel@tonic-gate	/*
940Sstevel@tonic-gate	 * Dereference an address in the guard page.
950Sstevel@tonic-gate	 */
960Sstevel@tonic-gate	ldub	[%o1 - 1], %g0
970Sstevel@tonic-gate
980Sstevel@tonic-gate	/*
990Sstevel@tonic-gate	 * If the above load doesn't raise a SIGSEGV then do it ourselves.
1000Sstevel@tonic-gate	 */
1010Sstevel@tonic-gate	SYSTRAP_RVAL1(lwp_self)
1020Sstevel@tonic-gate	mov	SIGSEGV, %o1
1030Sstevel@tonic-gate	SYSTRAP_RVAL1(lwp_kill)
1040Sstevel@tonic-gate
1050Sstevel@tonic-gate	/*
1060Sstevel@tonic-gate	 * We should never get here; explode if we do.
1070Sstevel@tonic-gate	 */
1080Sstevel@tonic-gate	illtrap
1090Sstevel@tonic-gate	SET_SIZE(_stack_grow)
110