1/* 2 * CDDL HEADER START 3 * 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. 7 * 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. 12 * 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] 18 * 19 * CDDL HEADER END 20 */ 21 22/* 23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27#pragma ident "%Z%%M% %I% %E% SMI" 28 29 .file "%M%" 30 31#include <SYS.h> 32#include <sys/regset.h> 33#include <../assym.h> 34 35 /* 36 * This is where execution resumes when a thread created with 37 * thr_create() or pthread_create() returns (see setup_context()). 38 * We pass the (void *) return value to _thrp_terminate(). 39 */ 40 ENTRY(_lwp_start) 41 movq %rax, %rdi 42 call _thrp_terminate 43 RET /* actually, never returns */ 44 SET_SIZE(_lwp_start) 45 46 /* All we need to do now is (carefully) call lwp_exit(). */ 47 ENTRY(_lwp_terminate) 48 SYSTRAP_RVAL1(lwp_exit) 49 RET /* if we return, it is very bad */ 50 SET_SIZE(_lwp_terminate) 51 52 ENTRY(set_curthread) 53 movq %rdi, %fs:0 54 ret 55 SET_SIZE(set_curthread) 56 57 ENTRY(__lwp_park) 58 movq %rsi, %rdx 59 movq %rdi, %rsi 60 movq $0, %rdi 61 SYSTRAP_RVAL1(lwp_park) 62 SYSLWPERR 63 RET 64 SET_SIZE(__lwp_park) 65 66 ENTRY(__lwp_unpark) 67 movq %rdi, %rsi 68 movq $1, %rdi 69 SYSTRAP_RVAL1(lwp_park) 70 SYSLWPERR 71 RET 72 SET_SIZE(__lwp_unpark) 73 74 ENTRY(__lwp_unpark_all) 75 movq %rsi, %rdx 76 movq %rdi, %rsi 77 movq $2, %rdi 78 SYSTRAP_RVAL1(lwp_park) 79 SYSLWPERR 80 RET 81 SET_SIZE(__lwp_unpark_all) 82 83/* 84 * __sighndlr(int sig, siginfo_t *si, ucontext_t *uc, void (*hndlr)()) 85 * 86 * This is called from sigacthandler() for the entire purpose of 87 * communicating the ucontext to java's stack tracing functions. 88 */ 89 ENTRY(__sighndlr) 90 .globl __sighndlrend 91 pushq %rbp 92 movq %rsp, %rbp 93 call *%rcx 94 leave 95 ret 96__sighndlrend: 97 SET_SIZE(__sighndlr) 98 99/* 100 * int _sigsetjmp(sigjmp_buf env, int savemask) 101 * 102 * This version is faster than the old non-threaded version because we 103 * don't normally have to call __getcontext() to get the signal mask. 104 * (We have a copy of it in the ulwp_t structure.) 105 */ 106 107#undef sigsetjmp 108 109#if SIZEOF_SIGJMP_BUF < SIZEOF_UCONTEXT_T 110 111#error "sigjmp_buf is too small to contain a ucontext_t" 112 113#else 114 115#if defined(__GNUC_AS__) 116#define REGOFF(reg) ( reg * CLONGSIZE ) 117#else 118#define REGOFF(reg) [ reg \* CLONGSIZE ] 119#endif 120 121 ENTRY2(sigsetjmp,_sigsetjmp) 122 pushq %rbp 123 movq %rsp, %rbp 124 125 /* construct a complete gregset_t for __csigsetjmp */ 126 subq $REGOFF(_NGREG), %rsp 127 movq %r15, REGOFF(REG_R15) (%rsp) 128 movq %r14, REGOFF(REG_R14) (%rsp) 129 movq %r13, REGOFF(REG_R13) (%rsp) 130 movq %r12, REGOFF(REG_R12) (%rsp) 131 movq %r11, REGOFF(REG_R11) (%rsp) 132 movq %r10, REGOFF(REG_R10) (%rsp) 133 movq %r9, REGOFF(REG_R9) (%rsp) 134 movq %r8, REGOFF(REG_R8) (%rsp) 135 movq %rdi, REGOFF(REG_RDI) (%rsp) 136 movq %rsi, REGOFF(REG_RSI) (%rsp) 137 movq %rbx, REGOFF(REG_RBX) (%rsp) 138 movq %rdx, REGOFF(REG_RDX) (%rsp) 139 movq %rcx, REGOFF(REG_RCX) (%rsp) 140 movq $0, REGOFF(REG_RAX) (%rsp) 141 movq $0, REGOFF(REG_TRAPNO) (%rsp) 142 movq $0, REGOFF(REG_ERR) (%rsp) 143 xorq %rax, %rax 144 movw %cs, %ax 145 movq %rax, REGOFF(REG_CS) (%rsp) 146 movq $0, REGOFF(REG_RFL) (%rsp) 147 movw %ss, %ax 148 movq %rax, REGOFF(REG_SS) (%rsp) 149 movw %fs, %ax 150 movq %rax, REGOFF(REG_FS) (%rsp) 151 movw %gs, %ax 152 movq %rax, REGOFF(REG_GS) (%rsp) 153 movw %es, %ax 154 movq %rax, REGOFF(REG_ES) (%rsp) 155 movw %ds, %ax 156 movq %rax, REGOFF(REG_DS) (%rsp) 157 movq %fs:0, %rax 158 movq %rax, REGOFF(REG_FSBASE) (%rsp) 159 movq $0, REGOFF(REG_GSBASE) (%rsp) 160 161 movq (%rbp), %rax /* previous %rbp */ 162 movq %rax, REGOFF(REG_RBP) (%rsp) 163 movq 8(%rbp), %rax /* previous %rip */ 164 movq %rax, REGOFF(REG_RIP) (%rsp) 165 leaq 16(%rbp), %rax /* previous %rsp */ 166 movq %rax, REGOFF(REG_RSP) (%rsp) 167 168 movq %rsp, %rdx /* pointer to gregset_t */ 169 call __csigsetjmp 170 xorq %rax, %rax 171 leave 172 ret 173 SET_SIZE(sigsetjmp) 174 SET_SIZE(_sigsetjmp) 175 176#endif /* SIZEOF_SIGJMP_BUF < SIZEOF_UCONTEXT_T */ 177