xref: /titanic_50/usr/src/cmd/mdb/sparc/v9/libstand/setjmp.s (revision 7c478bd95313f5f23a4c958a745db2134aa03244)
1*7c478bd9Sstevel@tonic-gate/*
2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START
3*7c478bd9Sstevel@tonic-gate *
4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the
5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only
6*7c478bd9Sstevel@tonic-gate * (the "License").  You may not use this file except in compliance
7*7c478bd9Sstevel@tonic-gate * with the License.
8*7c478bd9Sstevel@tonic-gate *
9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions
12*7c478bd9Sstevel@tonic-gate * and limitations under the License.
13*7c478bd9Sstevel@tonic-gate *
14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
19*7c478bd9Sstevel@tonic-gate *
20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END
21*7c478bd9Sstevel@tonic-gate */
22*7c478bd9Sstevel@tonic-gate/*
23*7c478bd9Sstevel@tonic-gate * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
24*7c478bd9Sstevel@tonic-gate * Use is subject to license terms.
25*7c478bd9Sstevel@tonic-gate */
26*7c478bd9Sstevel@tonic-gate
27*7c478bd9Sstevel@tonic-gate#pragma ident	"%Z%%M%	%I%	%E% SMI"
28*7c478bd9Sstevel@tonic-gate
29*7c478bd9Sstevel@tonic-gate#if defined(__lint)
30*7c478bd9Sstevel@tonic-gate#include <setjmp.h>
31*7c478bd9Sstevel@tonic-gate#endif
32*7c478bd9Sstevel@tonic-gate
33*7c478bd9Sstevel@tonic-gate#include <sys/asm_linkage.h>
34*7c478bd9Sstevel@tonic-gate
35*7c478bd9Sstevel@tonic-gate/*
36*7c478bd9Sstevel@tonic-gate * This is a copy of the setjmp (and longjmp) code used in libc.  Note that
37*7c478bd9Sstevel@tonic-gate * we use sigsetjmp as an alias for setjmp, with a corresponding alias between
38*7c478bd9Sstevel@tonic-gate * siglongjmp and longjmp.  We can do this because there aren't any signals
39*7c478bd9Sstevel@tonic-gate * in kmdb (with the possible exception of the smoke signals the machine will
40*7c478bd9Sstevel@tonic-gate * emit when we break something).  We can also use a sigjmp_buf as a jmp_buf,
41*7c478bd9Sstevel@tonic-gate * since the latter is smaller than the former.
42*7c478bd9Sstevel@tonic-gate */
43*7c478bd9Sstevel@tonic-gate
44*7c478bd9Sstevel@tonic-gate#if !defined(__lint)
45*7c478bd9Sstevel@tonic-gateJB_FLAGS	= (0*8)	! offsets in jmpbuf (see sigsetjmp.c)
46*7c478bd9Sstevel@tonic-gateJB_SP		= (1*8)	! words 5 through 11 are unused!
47*7c478bd9Sstevel@tonic-gateJB_PC		= (2*8)
48*7c478bd9Sstevel@tonic-gateJB_FP		= (3*8)
49*7c478bd9Sstevel@tonic-gateJB_I7		= (4*8)
50*7c478bd9Sstevel@tonic-gate#endif
51*7c478bd9Sstevel@tonic-gate
52*7c478bd9Sstevel@tonic-gate/*
53*7c478bd9Sstevel@tonic-gate * setjmp(buf_ptr)
54*7c478bd9Sstevel@tonic-gate * buf_ptr points to a twelve word array (jmp_buf)
55*7c478bd9Sstevel@tonic-gate */
56*7c478bd9Sstevel@tonic-gate
57*7c478bd9Sstevel@tonic-gate#if defined(__lint)
58*7c478bd9Sstevel@tonic-gate/* ARGSUSED */
59*7c478bd9Sstevel@tonic-gateint
60*7c478bd9Sstevel@tonic-gatesetjmp(jmp_buf env)
61*7c478bd9Sstevel@tonic-gate{
62*7c478bd9Sstevel@tonic-gate	return (0);
63*7c478bd9Sstevel@tonic-gate}
64*7c478bd9Sstevel@tonic-gate
65*7c478bd9Sstevel@tonic-gate/* ARGSUSED */
66*7c478bd9Sstevel@tonic-gateint
67*7c478bd9Sstevel@tonic-gatesigsetjmp(sigjmp_buf env, int savemask)
68*7c478bd9Sstevel@tonic-gate{
69*7c478bd9Sstevel@tonic-gate	return (0);
70*7c478bd9Sstevel@tonic-gate}
71*7c478bd9Sstevel@tonic-gate#else	/* __lint */
72*7c478bd9Sstevel@tonic-gate
73*7c478bd9Sstevel@tonic-gate	ENTRY(setjmp)
74*7c478bd9Sstevel@tonic-gate	ALTENTRY(sigsetjmp)
75*7c478bd9Sstevel@tonic-gate	clr	[%o0 + JB_FLAGS]	! clear flags (used by sigsetjmp)
76*7c478bd9Sstevel@tonic-gate	stx	%sp, [%o0 + JB_SP]	! save caller's sp
77*7c478bd9Sstevel@tonic-gate	add	%o7, 8, %o1		! compute return pc
78*7c478bd9Sstevel@tonic-gate	stx	%o1, [%o0 + JB_PC]	! save pc
79*7c478bd9Sstevel@tonic-gate	stx	%fp, [%o0 + JB_FP]	! save fp
80*7c478bd9Sstevel@tonic-gate	stx	%i7, [%o0 + JB_I7]	! save %i7
81*7c478bd9Sstevel@tonic-gate	flushw
82*7c478bd9Sstevel@tonic-gate	retl
83*7c478bd9Sstevel@tonic-gate	clr	%o0			! return (0)
84*7c478bd9Sstevel@tonic-gate
85*7c478bd9Sstevel@tonic-gate	SET_SIZE(setjmp)
86*7c478bd9Sstevel@tonic-gate#endif	/* __lint */
87*7c478bd9Sstevel@tonic-gate
88*7c478bd9Sstevel@tonic-gate/*
89*7c478bd9Sstevel@tonic-gate * longjmp(buf_ptr, val)
90*7c478bd9Sstevel@tonic-gate * buf_ptr points to a jmpbuf which has been initialized by setjmp.
91*7c478bd9Sstevel@tonic-gate * val is the value we wish to return to setjmp's caller
92*7c478bd9Sstevel@tonic-gate *
93*7c478bd9Sstevel@tonic-gate * We flush the register file to the stack by doing a kernel call.
94*7c478bd9Sstevel@tonic-gate * This is necessary to ensure that the registers we want to
95*7c478bd9Sstevel@tonic-gate * pick up are stored on the stack, and that subsequent restores
96*7c478bd9Sstevel@tonic-gate * will function correctly.
97*7c478bd9Sstevel@tonic-gate *
98*7c478bd9Sstevel@tonic-gate * sp, fp, and %i7, the caller's return address, are all restored
99*7c478bd9Sstevel@tonic-gate * to the values they had at the time of the call to setjmp().  All
100*7c478bd9Sstevel@tonic-gate * other locals, ins and outs are set to potentially random values
101*7c478bd9Sstevel@tonic-gate * (as per the man page).  This is sufficient to permit the correct
102*7c478bd9Sstevel@tonic-gate * operation of normal code.
103*7c478bd9Sstevel@tonic-gate *
104*7c478bd9Sstevel@tonic-gate * Actually, the above description is not quite correct.  If the routine
105*7c478bd9Sstevel@tonic-gate * that called setjmp() has not altered the sp value of their frame we
106*7c478bd9Sstevel@tonic-gate * will restore the remaining locals and ins to the values these
107*7c478bd9Sstevel@tonic-gate * registers had in the this frame at the time of the call to longjmp()
108*7c478bd9Sstevel@tonic-gate * (not setjmp()!).  This is intended to help compilers, typically not
109*7c478bd9Sstevel@tonic-gate * C compilers, that have some registers assigned to fixed purposes,
110*7c478bd9Sstevel@tonic-gate * and that only alter the values of these registers on function entry
111*7c478bd9Sstevel@tonic-gate * and exit.
112*7c478bd9Sstevel@tonic-gate *
113*7c478bd9Sstevel@tonic-gate * Since a C routine could call setjmp() followed by alloca() and thus
114*7c478bd9Sstevel@tonic-gate * alter the sp this feature will typically not be helpful for a C
115*7c478bd9Sstevel@tonic-gate * compiler.
116*7c478bd9Sstevel@tonic-gate *
117*7c478bd9Sstevel@tonic-gate * Note also that because the caller of a routine compiled "flat" (without
118*7c478bd9Sstevel@tonic-gate * register windows) assumes that their ins and locals are preserved,
119*7c478bd9Sstevel@tonic-gate * routines that call setjmp() must not be flat.
120*7c478bd9Sstevel@tonic-gate */
121*7c478bd9Sstevel@tonic-gate
122*7c478bd9Sstevel@tonic-gate#if defined(__lint)
123*7c478bd9Sstevel@tonic-gate/* ARGSUSED */
124*7c478bd9Sstevel@tonic-gatevoid
125*7c478bd9Sstevel@tonic-gatelongjmp(jmp_buf env, int val)
126*7c478bd9Sstevel@tonic-gate{
127*7c478bd9Sstevel@tonic-gate}
128*7c478bd9Sstevel@tonic-gate
129*7c478bd9Sstevel@tonic-gate/* ARGSUSED */
130*7c478bd9Sstevel@tonic-gatevoid
131*7c478bd9Sstevel@tonic-gatesiglongjmp(sigjmp_buf env, int val)
132*7c478bd9Sstevel@tonic-gate{
133*7c478bd9Sstevel@tonic-gate}
134*7c478bd9Sstevel@tonic-gate#else	/* __lint */
135*7c478bd9Sstevel@tonic-gate
136*7c478bd9Sstevel@tonic-gate	ENTRY(longjmp)
137*7c478bd9Sstevel@tonic-gate	ALTENTRY(siglongjmp)
138*7c478bd9Sstevel@tonic-gate
139*7c478bd9Sstevel@tonic-gate	/* flush all reg windows to the stack. */
140*7c478bd9Sstevel@tonic-gate	save
141*7c478bd9Sstevel@tonic-gate	flushw
142*7c478bd9Sstevel@tonic-gate	restore
143*7c478bd9Sstevel@tonic-gate	nop
144*7c478bd9Sstevel@tonic-gate
145*7c478bd9Sstevel@tonic-gate	ldx	[%o0 + JB_SP], %o2	! sp in %o2 until safe to puke there
146*7c478bd9Sstevel@tonic-gate	ldx	[%o2 + STACK_BIAS], %l0	! restore locals and ins if we can
147*7c478bd9Sstevel@tonic-gate	ldx	[%o2 + (1*8) + STACK_BIAS], %l1
148*7c478bd9Sstevel@tonic-gate	ldx	[%o2 + (2*8) + STACK_BIAS], %l2
149*7c478bd9Sstevel@tonic-gate	ldx	[%o2 + (3*8) + STACK_BIAS], %l3
150*7c478bd9Sstevel@tonic-gate	ldx	[%o2 + (4*8) + STACK_BIAS], %l4
151*7c478bd9Sstevel@tonic-gate	ldx	[%o2 + (5*8) + STACK_BIAS], %l5
152*7c478bd9Sstevel@tonic-gate	ldx	[%o2 + (6*8) + STACK_BIAS], %l6
153*7c478bd9Sstevel@tonic-gate	ldx	[%o2 + (7*8) + STACK_BIAS], %l7
154*7c478bd9Sstevel@tonic-gate	ldx	[%o2 + (8*8) + STACK_BIAS], %i0
155*7c478bd9Sstevel@tonic-gate	ldx	[%o2 + (9*8) + STACK_BIAS], %i1
156*7c478bd9Sstevel@tonic-gate	ldx	[%o2 + (10*8) + STACK_BIAS], %i2
157*7c478bd9Sstevel@tonic-gate	ldx	[%o2 + (11*8) + STACK_BIAS], %i3
158*7c478bd9Sstevel@tonic-gate	ldx	[%o2 + (12*8) + STACK_BIAS], %i4
159*7c478bd9Sstevel@tonic-gate	ldx	[%o2 + (13*8) + STACK_BIAS], %i5
160*7c478bd9Sstevel@tonic-gate	ldx	[%o0 + JB_FP], %fp	! restore fp
161*7c478bd9Sstevel@tonic-gate	mov	%o2, %sp		! restore sp
162*7c478bd9Sstevel@tonic-gate	ldx	[%o0 + JB_I7], %i7	! restore %i7
163*7c478bd9Sstevel@tonic-gate	ldx	[%o0 + JB_PC], %o3	! get new return pc
164*7c478bd9Sstevel@tonic-gate	tst	%o1			! is return value 0?
165*7c478bd9Sstevel@tonic-gate	bnz	1f			! no - leave it alone
166*7c478bd9Sstevel@tonic-gate	sub	%o3, 8, %o7		! normalize return (for adb) (dly slot)
167*7c478bd9Sstevel@tonic-gate	mov	1, %o1			! yes - set it to one
168*7c478bd9Sstevel@tonic-gate1:
169*7c478bd9Sstevel@tonic-gate	retl
170*7c478bd9Sstevel@tonic-gate	mov	%o1, %o0		! return (val)
171*7c478bd9Sstevel@tonic-gate
172*7c478bd9Sstevel@tonic-gate	SET_SIZE(longjmp)
173*7c478bd9Sstevel@tonic-gate#endif	/* __lint */
174