17c478bd9Sstevel@tonic-gate/* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 57257d1b4Sraf * Common Development and Distribution License (the "License"). 67257d1b4Sraf * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 217c478bd9Sstevel@tonic-gate 227c478bd9Sstevel@tonic-gate/* 23*3de0cfbbSRoger A. Faulkner * Copyright 2010 Sun Microsystems, Inc. All rights reserved. 247c478bd9Sstevel@tonic-gate * Use is subject to license terms. 257c478bd9Sstevel@tonic-gate */ 267c478bd9Sstevel@tonic-gate 277257d1b4Sraf/* Copyright (c) 1988 AT&T */ 287257d1b4Sraf/* All Rights Reserved */ 297c478bd9Sstevel@tonic-gate 309a70fc3bSMark J. Nelson .file "setjmp.s" 317c478bd9Sstevel@tonic-gate 327c478bd9Sstevel@tonic-gate#include <sys/asm_linkage.h> 337c478bd9Sstevel@tonic-gate 347c478bd9Sstevel@tonic-gate ANSI_PRAGMA_WEAK(setjmp,function) 357c478bd9Sstevel@tonic-gate ANSI_PRAGMA_WEAK(longjmp,function) 367c478bd9Sstevel@tonic-gate 37*3de0cfbbSRoger A. Faulkner#include <../assym.h> 387c478bd9Sstevel@tonic-gate#include <sys/trap.h> 397c478bd9Sstevel@tonic-gate 407c478bd9Sstevel@tonic-gateJB_FLAGS = (0*8) ! offsets in jmpbuf (see siglongjmp.c) 417c478bd9Sstevel@tonic-gateJB_SP = (1*8) ! words 5 through 11 are unused! 427c478bd9Sstevel@tonic-gateJB_PC = (2*8) 437c478bd9Sstevel@tonic-gateJB_FP = (3*8) 447c478bd9Sstevel@tonic-gateJB_I7 = (4*8) 457c478bd9Sstevel@tonic-gate 467c478bd9Sstevel@tonic-gate/* 47*3de0cfbbSRoger A. Faulkner * Flag telling longjmp to set curthread->ul_siglink to NULL. 48*3de0cfbbSRoger A. Faulkner */ 49*3de0cfbbSRoger A. FaulknerJB_CLEARLINK = 0x10 50*3de0cfbbSRoger A. Faulkner 51*3de0cfbbSRoger A. Faulkner/* 527c478bd9Sstevel@tonic-gate * setjmp(buf_ptr) 537c478bd9Sstevel@tonic-gate * buf_ptr points to a twelve word array (jmp_buf) 547c478bd9Sstevel@tonic-gate */ 557c478bd9Sstevel@tonic-gate ENTRY(setjmp) 56*3de0cfbbSRoger A. Faulkner clr %o2 57*3de0cfbbSRoger A. Faulkner ldx [%g7 + UL_SIGLINK], %o1 ! are we in a signal context? 58*3de0cfbbSRoger A. Faulkner tst %o1 59*3de0cfbbSRoger A. Faulkner be,a,pt %xcc, 1f 60*3de0cfbbSRoger A. Faulkner mov JB_CLEARLINK, %o2 ! no, tell longjmp to clear ul_siglink 61*3de0cfbbSRoger A. Faulkner1: stx %o2, [%o0 + JB_FLAGS] 627c478bd9Sstevel@tonic-gate stx %sp, [%o0 + JB_SP] ! save caller's sp 637c478bd9Sstevel@tonic-gate add %o7, 8, %o1 ! compute return pc 647c478bd9Sstevel@tonic-gate stx %o1, [%o0 + JB_PC] ! save pc 657c478bd9Sstevel@tonic-gate stx %fp, [%o0 + JB_FP] ! save fp 667c478bd9Sstevel@tonic-gate stx %i7, [%o0 + JB_I7] ! save %i7 677c478bd9Sstevel@tonic-gate retl 687c478bd9Sstevel@tonic-gate clr %o0 ! return (0) 697c478bd9Sstevel@tonic-gate 707c478bd9Sstevel@tonic-gate SET_SIZE(setjmp) 717c478bd9Sstevel@tonic-gate 727c478bd9Sstevel@tonic-gate/* 737c478bd9Sstevel@tonic-gate * longjmp(buf_ptr, val) 747c478bd9Sstevel@tonic-gate * buf_ptr points to a jmpbuf which has been initialized by setjmp. 757c478bd9Sstevel@tonic-gate * val is the value we wish to return to setjmp's caller 767c478bd9Sstevel@tonic-gate * 777c478bd9Sstevel@tonic-gate * We flush the register file to the stack by doing a kernel call. 787c478bd9Sstevel@tonic-gate * This is necessary to ensure that the registers we want to 797c478bd9Sstevel@tonic-gate * pick up are stored on the stack, and that subsequent restores 807c478bd9Sstevel@tonic-gate * will function correctly. 817c478bd9Sstevel@tonic-gate * 827c478bd9Sstevel@tonic-gate * sp, fp, and %i7, the caller's return address, are all restored 837c478bd9Sstevel@tonic-gate * to the values they had at the time of the call to setjmp(). All 847c478bd9Sstevel@tonic-gate * other locals, ins and outs are set to potentially random values 857c478bd9Sstevel@tonic-gate * (as per the man page). This is sufficient to permit the correct 867c478bd9Sstevel@tonic-gate * operation of normal code. 877c478bd9Sstevel@tonic-gate * 887c478bd9Sstevel@tonic-gate * Actually, the above description is not quite correct. If the routine 897c478bd9Sstevel@tonic-gate * that called setjmp() has not altered the sp value of their frame we 907c478bd9Sstevel@tonic-gate * will restore the remaining locals and ins to the values these 917c478bd9Sstevel@tonic-gate * registers had in the this frame at the time of the call to longjmp() 927c478bd9Sstevel@tonic-gate * (not setjmp()!). This is intended to help compilers, typically not 937c478bd9Sstevel@tonic-gate * C compilers, that have some registers assigned to fixed purposes, 947c478bd9Sstevel@tonic-gate * and that only alter the values of these registers on function entry 957c478bd9Sstevel@tonic-gate * and exit. 967c478bd9Sstevel@tonic-gate * 977c478bd9Sstevel@tonic-gate * Since a C routine could call setjmp() followed by alloca() and thus 987c478bd9Sstevel@tonic-gate * alter the sp this feature will typically not be helpful for a C 997c478bd9Sstevel@tonic-gate * compiler. 1007c478bd9Sstevel@tonic-gate * 1017c478bd9Sstevel@tonic-gate * Note also that because the caller of a routine compiled "flat" (without 1027c478bd9Sstevel@tonic-gate * register windows) assumes that their ins and locals are preserved, 1037c478bd9Sstevel@tonic-gate * routines that call setjmp() must not be flat. 1047c478bd9Sstevel@tonic-gate */ 1057c478bd9Sstevel@tonic-gate ENTRY(longjmp) 1067c478bd9Sstevel@tonic-gate ta ST_FLUSH_WINDOWS ! flush all reg windows to the stack. 1077c478bd9Sstevel@tonic-gate ldx [%o0 + JB_SP], %o2 ! sp in %o2 until safe to puke there 1087c478bd9Sstevel@tonic-gate ldx [%o2 + STACK_BIAS], %l0 ! restore locals and ins if we can 1097c478bd9Sstevel@tonic-gate ldx [%o2 + (1*8) + STACK_BIAS], %l1 1107c478bd9Sstevel@tonic-gate ldx [%o2 + (2*8) + STACK_BIAS], %l2 1117c478bd9Sstevel@tonic-gate ldx [%o2 + (3*8) + STACK_BIAS], %l3 1127c478bd9Sstevel@tonic-gate ldx [%o2 + (4*8) + STACK_BIAS], %l4 1137c478bd9Sstevel@tonic-gate ldx [%o2 + (5*8) + STACK_BIAS], %l5 1147c478bd9Sstevel@tonic-gate ldx [%o2 + (6*8) + STACK_BIAS], %l6 1157c478bd9Sstevel@tonic-gate ldx [%o2 + (7*8) + STACK_BIAS], %l7 1167c478bd9Sstevel@tonic-gate ldx [%o2 + (8*8) + STACK_BIAS], %i0 1177c478bd9Sstevel@tonic-gate ldx [%o2 + (9*8) + STACK_BIAS], %i1 1187c478bd9Sstevel@tonic-gate ldx [%o2 + (10*8) + STACK_BIAS], %i2 1197c478bd9Sstevel@tonic-gate ldx [%o2 + (11*8) + STACK_BIAS], %i3 1207c478bd9Sstevel@tonic-gate ldx [%o2 + (12*8) + STACK_BIAS], %i4 1217c478bd9Sstevel@tonic-gate ldx [%o2 + (13*8) + STACK_BIAS], %i5 1227c478bd9Sstevel@tonic-gate ldx [%o0 + JB_FP], %fp ! restore fp 1237c478bd9Sstevel@tonic-gate mov %o2, %sp ! restore sp 124*3de0cfbbSRoger A. Faulkner ldx [%o0 + JB_FLAGS], %o2 125*3de0cfbbSRoger A. Faulkner btst JB_CLEARLINK, %o2 ! test JB_CLEARLINK flag 126*3de0cfbbSRoger A. Faulkner bne,a,pt %xcc, 1f 127*3de0cfbbSRoger A. Faulkner clrx [%g7 + UL_SIGLINK] ! if set, clear ul_siglink 128*3de0cfbbSRoger A. Faulkner1: 1297c478bd9Sstevel@tonic-gate ldx [%o0 + JB_I7], %i7 ! restore %i7 1307c478bd9Sstevel@tonic-gate ldx [%o0 + JB_PC], %o3 ! get new return pc 1317c478bd9Sstevel@tonic-gate tst %o1 ! is return value 0? 1327c478bd9Sstevel@tonic-gate bnz 1f ! no - leave it alone 1337c478bd9Sstevel@tonic-gate sub %o3, 8, %o7 ! normalize return (for adb) (dly slot) 1347c478bd9Sstevel@tonic-gate mov 1, %o1 ! yes - set it to one 1357c478bd9Sstevel@tonic-gate1: 1367c478bd9Sstevel@tonic-gate retl 1377c478bd9Sstevel@tonic-gate mov %o1, %o0 ! return (val) 1387c478bd9Sstevel@tonic-gate 1397c478bd9Sstevel@tonic-gate SET_SIZE(longjmp) 140