4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 #pragma ident "%Z%%M% %I% %E% SMI"
29 #include "thr_uberdata.h"
30 #include <sys/stack.h>
33 * Initialization of the main stack is performed in libc_init().
34 * Initialization of thread stacks is performed in _thrp_setup().
37 #pragma weak _stack_getbounds = stack_getbounds
39 stack_getbounds(stack_t
*sp
)
41 *sp
= curthread
->ul_ustack
;
45 #pragma weak _stack_setbounds = stack_setbounds
47 stack_setbounds(const stack_t
*sp
)
49 ulwp_t
*self
= curthread
;
51 if (sp
== NULL
|| sp
->ss_sp
== NULL
||
52 (uintptr_t)sp
->ss_sp
!= SA((uintptr_t)sp
->ss_sp
) ||
53 sp
->ss_flags
!= 0 || sp
->ss_size
< MINSIGSTKSZ
||
54 (uintptr_t)sp
->ss_size
!= SA((uintptr_t)sp
->ss_size
)) {
60 self
->ul_ustack
= *sp
;
67 * Returns a boolean value:
68 * 1 addr is within the bounds of the current stack
69 * 0 addr is outside of the bounds of the current stack
70 * Note that addr is an unbiased value.
72 #pragma weak _stack_inbounds = stack_inbounds
74 stack_inbounds(void *addr
)
76 stack_t
*ustackp
= &curthread
->ul_ustack
;
77 uintptr_t base
= (uintptr_t)ustackp
->ss_sp
;
78 size_t size
= ustackp
->ss_size
;
80 return ((uintptr_t)addr
>= base
&& (uintptr_t)addr
< base
+ size
);
83 #pragma weak _stack_violation = stack_violation
85 stack_violation(int sig
, const siginfo_t
*sip
, const ucontext_t
*ucp
)
91 if ((sig
!= SIGSEGV
&& sig
!= SIGBUS
) ||
92 sip
== NULL
|| ucp
== NULL
|| SI_FROMUSER(sip
))
96 * ucp has the correct view of the stack when the signal was raised.
98 base
= (uintptr_t)ucp
->uc_stack
.ss_sp
;
99 size
= ucp
->uc_stack
.ss_size
;
101 addr
= ucp
->uc_mcontext
.gregs
[REG_SP
] + STACK_BIAS
;
102 #elif defined(__amd64) || defined(__i386)
103 addr
= ucp
->uc_mcontext
.gregs
[REG_SP
];
105 * If the faulted address is just below the stack pointer we
106 * might be looking at a push instruction that caused the fault
107 * (the largest amount a push instruction can decrement the
108 * stack pointer by is 32). In that case, use the faulted
109 * address in our computation rather than the stack pointer.
111 if (addr
- (uintptr_t)sip
->si_addr
< 32)
112 addr
= (uintptr_t)sip
->si_addr
;
114 #error "none of __sparc, __amd64, __i386 is defined"
116 return (!(addr
>= base
&& addr
< base
+ size
));