1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp Sat Dec 01 00:00:00 2007 +0000 1.3 @@ -0,0 +1,878 @@ 1.4 +/* 1.5 + * Copyright 1999-2007 Sun Microsystems, Inc. All Rights Reserved. 1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 + * 1.8 + * This code is free software; you can redistribute it and/or modify it 1.9 + * under the terms of the GNU General Public License version 2 only, as 1.10 + * published by the Free Software Foundation. 1.11 + * 1.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.15 + * version 2 for more details (a copy is included in the LICENSE file that 1.16 + * accompanied this code). 1.17 + * 1.18 + * You should have received a copy of the GNU General Public License version 1.19 + * 2 along with this work; if not, write to the Free Software Foundation, 1.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.21 + * 1.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 1.23 + * CA 95054 USA or visit www.sun.com if you need additional information or 1.24 + * have any questions. 1.25 + * 1.26 + */ 1.27 + 1.28 +// do not include precompiled header file 1.29 +# include "incls/_os_solaris_x86.cpp.incl" 1.30 + 1.31 +// put OS-includes here 1.32 +# include <sys/types.h> 1.33 +# include <sys/mman.h> 1.34 +# include <pthread.h> 1.35 +# include <signal.h> 1.36 +# include <setjmp.h> 1.37 +# include <errno.h> 1.38 +# include <dlfcn.h> 1.39 +# include <stdio.h> 1.40 +# include <unistd.h> 1.41 +# include <sys/resource.h> 1.42 +# include <thread.h> 1.43 +# include <sys/stat.h> 1.44 +# include <sys/time.h> 1.45 +# include <sys/filio.h> 1.46 +# include <sys/utsname.h> 1.47 +# include <sys/systeminfo.h> 1.48 +# include <sys/socket.h> 1.49 +# include <sys/trap.h> 1.50 +# include <sys/lwp.h> 1.51 +# include <pwd.h> 1.52 +# include <poll.h> 1.53 +# include <sys/lwp.h> 1.54 +# include <procfs.h> // see comment in <sys/procfs.h> 1.55 + 1.56 +#ifndef AMD64 1.57 +// QQQ seems useless at this point 1.58 +# define _STRUCTURED_PROC 1 // this gets us the new structured proc interfaces of 5.6 & later 1.59 +#endif // AMD64 1.60 +# include <sys/procfs.h> // see comment in <sys/procfs.h> 1.61 + 1.62 + 1.63 +#define MAX_PATH (2 * K) 1.64 + 1.65 +// Minimum stack size for the VM. It's easier to document a constant value 1.66 +// but it's different for x86 and sparc because the page sizes are different. 1.67 +#ifdef AMD64 1.68 +size_t os::Solaris::min_stack_allowed = 224*K; 1.69 +#define REG_SP REG_RSP 1.70 +#define REG_PC REG_RIP 1.71 +#define REG_FP REG_RBP 1.72 +#else 1.73 +size_t os::Solaris::min_stack_allowed = 64*K; 1.74 +#define REG_SP UESP 1.75 +#define REG_PC EIP 1.76 +#define REG_FP EBP 1.77 +// 4900493 counter to prevent runaway LDTR refresh attempt 1.78 + 1.79 +static volatile int ldtr_refresh = 0; 1.80 +// the libthread instruction that faults because of the stale LDTR 1.81 + 1.82 +static const unsigned char movlfs[] = { 0x8e, 0xe0 // movl %eax,%fs 1.83 + }; 1.84 +#endif // AMD64 1.85 + 1.86 +char* os::non_memory_address_word() { 1.87 + // Must never look like an address returned by reserve_memory, 1.88 + // even in its subfields (as defined by the CPU immediate fields, 1.89 + // if the CPU splits constants across multiple instructions). 1.90 + return (char*) -1; 1.91 +} 1.92 + 1.93 +// 1.94 +// Validate a ucontext retrieved from walking a uc_link of a ucontext. 1.95 +// There are issues with libthread giving out uc_links for different threads 1.96 +// on the same uc_link chain and bad or circular links. 1.97 +// 1.98 +bool os::Solaris::valid_ucontext(Thread* thread, ucontext_t* valid, ucontext_t* suspect) { 1.99 + if (valid >= suspect || 1.100 + valid->uc_stack.ss_flags != suspect->uc_stack.ss_flags || 1.101 + valid->uc_stack.ss_sp != suspect->uc_stack.ss_sp || 1.102 + valid->uc_stack.ss_size != suspect->uc_stack.ss_size) { 1.103 + DEBUG_ONLY(tty->print_cr("valid_ucontext: failed test 1");) 1.104 + return false; 1.105 + } 1.106 + 1.107 + if (thread->is_Java_thread()) { 1.108 + if (!valid_stack_address(thread, (address)suspect)) { 1.109 + DEBUG_ONLY(tty->print_cr("valid_ucontext: uc_link not in thread stack");) 1.110 + return false; 1.111 + } 1.112 + if (!valid_stack_address(thread, (address) suspect->uc_mcontext.gregs[REG_SP])) { 1.113 + DEBUG_ONLY(tty->print_cr("valid_ucontext: stackpointer not in thread stack");) 1.114 + return false; 1.115 + } 1.116 + } 1.117 + return true; 1.118 +} 1.119 + 1.120 +// We will only follow one level of uc_link since there are libthread 1.121 +// issues with ucontext linking and it is better to be safe and just 1.122 +// let caller retry later. 1.123 +ucontext_t* os::Solaris::get_valid_uc_in_signal_handler(Thread *thread, 1.124 + ucontext_t *uc) { 1.125 + 1.126 + ucontext_t *retuc = NULL; 1.127 + 1.128 + if (uc != NULL) { 1.129 + if (uc->uc_link == NULL) { 1.130 + // cannot validate without uc_link so accept current ucontext 1.131 + retuc = uc; 1.132 + } else if (os::Solaris::valid_ucontext(thread, uc, uc->uc_link)) { 1.133 + // first ucontext is valid so try the next one 1.134 + uc = uc->uc_link; 1.135 + if (uc->uc_link == NULL) { 1.136 + // cannot validate without uc_link so accept current ucontext 1.137 + retuc = uc; 1.138 + } else if (os::Solaris::valid_ucontext(thread, uc, uc->uc_link)) { 1.139 + // the ucontext one level down is also valid so return it 1.140 + retuc = uc; 1.141 + } 1.142 + } 1.143 + } 1.144 + return retuc; 1.145 +} 1.146 + 1.147 +// Assumes ucontext is valid 1.148 +ExtendedPC os::Solaris::ucontext_get_ExtendedPC(ucontext_t *uc) { 1.149 + return ExtendedPC((address)uc->uc_mcontext.gregs[REG_PC]); 1.150 +} 1.151 + 1.152 +// Assumes ucontext is valid 1.153 +intptr_t* os::Solaris::ucontext_get_sp(ucontext_t *uc) { 1.154 + return (intptr_t*)uc->uc_mcontext.gregs[REG_SP]; 1.155 +} 1.156 + 1.157 +// Assumes ucontext is valid 1.158 +intptr_t* os::Solaris::ucontext_get_fp(ucontext_t *uc) { 1.159 + return (intptr_t*)uc->uc_mcontext.gregs[REG_FP]; 1.160 +} 1.161 + 1.162 +// For Forte Analyzer AsyncGetCallTrace profiling support - thread 1.163 +// is currently interrupted by SIGPROF. 1.164 +// 1.165 +// The difference between this and os::fetch_frame_from_context() is that 1.166 +// here we try to skip nested signal frames. 1.167 +ExtendedPC os::Solaris::fetch_frame_from_ucontext(Thread* thread, 1.168 + ucontext_t* uc, intptr_t** ret_sp, intptr_t** ret_fp) { 1.169 + 1.170 + assert(thread != NULL, "just checking"); 1.171 + assert(ret_sp != NULL, "just checking"); 1.172 + assert(ret_fp != NULL, "just checking"); 1.173 + 1.174 + ucontext_t *luc = os::Solaris::get_valid_uc_in_signal_handler(thread, uc); 1.175 + return os::fetch_frame_from_context(luc, ret_sp, ret_fp); 1.176 +} 1.177 + 1.178 +ExtendedPC os::fetch_frame_from_context(void* ucVoid, 1.179 + intptr_t** ret_sp, intptr_t** ret_fp) { 1.180 + 1.181 + ExtendedPC epc; 1.182 + ucontext_t *uc = (ucontext_t*)ucVoid; 1.183 + 1.184 + if (uc != NULL) { 1.185 + epc = os::Solaris::ucontext_get_ExtendedPC(uc); 1.186 + if (ret_sp) *ret_sp = os::Solaris::ucontext_get_sp(uc); 1.187 + if (ret_fp) *ret_fp = os::Solaris::ucontext_get_fp(uc); 1.188 + } else { 1.189 + // construct empty ExtendedPC for return value checking 1.190 + epc = ExtendedPC(NULL); 1.191 + if (ret_sp) *ret_sp = (intptr_t *)NULL; 1.192 + if (ret_fp) *ret_fp = (intptr_t *)NULL; 1.193 + } 1.194 + 1.195 + return epc; 1.196 +} 1.197 + 1.198 +frame os::fetch_frame_from_context(void* ucVoid) { 1.199 + intptr_t* sp; 1.200 + intptr_t* fp; 1.201 + ExtendedPC epc = fetch_frame_from_context(ucVoid, &sp, &fp); 1.202 + return frame(sp, fp, epc.pc()); 1.203 +} 1.204 + 1.205 +frame os::get_sender_for_C_frame(frame* fr) { 1.206 + return frame(fr->sender_sp(), fr->link(), fr->sender_pc()); 1.207 +} 1.208 + 1.209 +extern "C" intptr_t *_get_previous_fp(); // in .il file. 1.210 + 1.211 +frame os::current_frame() { 1.212 + intptr_t* fp = _get_previous_fp(); 1.213 + frame myframe((intptr_t*)os::current_stack_pointer(), 1.214 + (intptr_t*)fp, 1.215 + CAST_FROM_FN_PTR(address, os::current_frame)); 1.216 + if (os::is_first_C_frame(&myframe)) { 1.217 + // stack is not walkable 1.218 + return frame(NULL, NULL, NULL); 1.219 + } else { 1.220 + return os::get_sender_for_C_frame(&myframe); 1.221 + } 1.222 +} 1.223 + 1.224 +// This is a simple callback that just fetches a PC for an interrupted thread. 1.225 +// The thread need not be suspended and the fetched PC is just a hint. 1.226 +// This one is currently used for profiling the VMThread ONLY! 1.227 + 1.228 +// Must be synchronous 1.229 +void GetThreadPC_Callback::execute(OSThread::InterruptArguments *args) { 1.230 + Thread* thread = args->thread(); 1.231 + ucontext_t* uc = args->ucontext(); 1.232 + intptr_t* sp; 1.233 + 1.234 + assert(ProfileVM && thread->is_VM_thread(), "just checking"); 1.235 + 1.236 + ExtendedPC new_addr((address)uc->uc_mcontext.gregs[REG_PC]); 1.237 + _addr = new_addr; 1.238 +} 1.239 + 1.240 +static int threadgetstate(thread_t tid, int *flags, lwpid_t *lwp, stack_t *ss, gregset_t rs, lwpstatus_t *lwpstatus) { 1.241 + char lwpstatusfile[PROCFILE_LENGTH]; 1.242 + int lwpfd, err; 1.243 + 1.244 + if (err = os::Solaris::thr_getstate(tid, flags, lwp, ss, rs)) 1.245 + return (err); 1.246 + if (*flags == TRS_LWPID) { 1.247 + sprintf(lwpstatusfile, "/proc/%d/lwp/%d/lwpstatus", getpid(), 1.248 + *lwp); 1.249 + if ((lwpfd = open(lwpstatusfile, O_RDONLY)) < 0) { 1.250 + perror("thr_mutator_status: open lwpstatus"); 1.251 + return (EINVAL); 1.252 + } 1.253 + if (pread(lwpfd, lwpstatus, sizeof (lwpstatus_t), (off_t)0) != 1.254 + sizeof (lwpstatus_t)) { 1.255 + perror("thr_mutator_status: read lwpstatus"); 1.256 + (void) close(lwpfd); 1.257 + return (EINVAL); 1.258 + } 1.259 + (void) close(lwpfd); 1.260 + } 1.261 + return (0); 1.262 +} 1.263 + 1.264 +#ifndef AMD64 1.265 + 1.266 +// Detecting SSE support by OS 1.267 +// From solaris_i486.s 1.268 +extern "C" bool sse_check(); 1.269 +extern "C" bool sse_unavailable(); 1.270 + 1.271 +enum { SSE_UNKNOWN, SSE_NOT_SUPPORTED, SSE_SUPPORTED}; 1.272 +static int sse_status = SSE_UNKNOWN; 1.273 + 1.274 + 1.275 +static void check_for_sse_support() { 1.276 + if (!VM_Version::supports_sse()) { 1.277 + sse_status = SSE_NOT_SUPPORTED; 1.278 + return; 1.279 + } 1.280 + // looking for _sse_hw in libc.so, if it does not exist or 1.281 + // the value (int) is 0, OS has no support for SSE 1.282 + int *sse_hwp; 1.283 + void *h; 1.284 + 1.285 + if ((h=dlopen("/usr/lib/libc.so", RTLD_LAZY)) == NULL) { 1.286 + //open failed, presume no support for SSE 1.287 + sse_status = SSE_NOT_SUPPORTED; 1.288 + return; 1.289 + } 1.290 + if ((sse_hwp = (int *)dlsym(h, "_sse_hw")) == NULL) { 1.291 + sse_status = SSE_NOT_SUPPORTED; 1.292 + } else if (*sse_hwp == 0) { 1.293 + sse_status = SSE_NOT_SUPPORTED; 1.294 + } 1.295 + dlclose(h); 1.296 + 1.297 + if (sse_status == SSE_UNKNOWN) { 1.298 + bool (*try_sse)() = (bool (*)())sse_check; 1.299 + sse_status = (*try_sse)() ? SSE_SUPPORTED : SSE_NOT_SUPPORTED; 1.300 + } 1.301 + 1.302 +} 1.303 + 1.304 +bool os::supports_sse() { 1.305 + if (sse_status == SSE_UNKNOWN) 1.306 + check_for_sse_support(); 1.307 + return sse_status == SSE_SUPPORTED; 1.308 +} 1.309 + 1.310 +#endif // AMD64 1.311 + 1.312 +bool os::is_allocatable(size_t bytes) { 1.313 +#ifdef AMD64 1.314 + return true; 1.315 +#else 1.316 + 1.317 + if (bytes < 2 * G) { 1.318 + return true; 1.319 + } 1.320 + 1.321 + char* addr = reserve_memory(bytes, NULL); 1.322 + 1.323 + if (addr != NULL) { 1.324 + release_memory(addr, bytes); 1.325 + } 1.326 + 1.327 + return addr != NULL; 1.328 +#endif // AMD64 1.329 + 1.330 +} 1.331 + 1.332 +extern "C" int JVM_handle_solaris_signal(int signo, siginfo_t* siginfo, void* ucontext, int abort_if_unrecognized); 1.333 + 1.334 +extern "C" void Fetch32PFI () ; 1.335 +extern "C" void Fetch32Resume () ; 1.336 +#ifdef AMD64 1.337 +extern "C" void FetchNPFI () ; 1.338 +extern "C" void FetchNResume () ; 1.339 +#endif // AMD64 1.340 + 1.341 +int JVM_handle_solaris_signal(int sig, siginfo_t* info, void* ucVoid, int abort_if_unrecognized) { 1.342 + ucontext_t* uc = (ucontext_t*) ucVoid; 1.343 + 1.344 +#ifndef AMD64 1.345 + if (sig == SIGILL && info->si_addr == (caddr_t)sse_check) { 1.346 + // the SSE instruction faulted. supports_sse() need return false. 1.347 + uc->uc_mcontext.gregs[EIP] = (greg_t)sse_unavailable; 1.348 + return true; 1.349 + } 1.350 +#endif // !AMD64 1.351 + 1.352 + Thread* t = ThreadLocalStorage::get_thread_slow(); // slow & steady 1.353 + 1.354 + SignalHandlerMark shm(t); 1.355 + 1.356 + if(sig == SIGPIPE || sig == SIGXFSZ) { 1.357 + if (os::Solaris::chained_handler(sig, info, ucVoid)) { 1.358 + return true; 1.359 + } else { 1.360 + if (PrintMiscellaneous && (WizardMode || Verbose)) { 1.361 + char buf[64]; 1.362 + warning("Ignoring %s - see 4229104 or 6499219", 1.363 + os::exception_name(sig, buf, sizeof(buf))); 1.364 + 1.365 + } 1.366 + return true; 1.367 + } 1.368 + } 1.369 + 1.370 + JavaThread* thread = NULL; 1.371 + VMThread* vmthread = NULL; 1.372 + 1.373 + if (os::Solaris::signal_handlers_are_installed) { 1.374 + if (t != NULL ){ 1.375 + if(t->is_Java_thread()) { 1.376 + thread = (JavaThread*)t; 1.377 + } 1.378 + else if(t->is_VM_thread()){ 1.379 + vmthread = (VMThread *)t; 1.380 + } 1.381 + } 1.382 + } 1.383 + 1.384 + guarantee(sig != os::Solaris::SIGinterrupt(), "Can not chain VM interrupt signal, try -XX:+UseAltSigs"); 1.385 + 1.386 + if (sig == os::Solaris::SIGasync()) { 1.387 + if(thread){ 1.388 + OSThread::InterruptArguments args(thread, uc); 1.389 + thread->osthread()->do_interrupt_callbacks_at_interrupt(&args); 1.390 + return true; 1.391 + } 1.392 + else if(vmthread){ 1.393 + OSThread::InterruptArguments args(vmthread, uc); 1.394 + vmthread->osthread()->do_interrupt_callbacks_at_interrupt(&args); 1.395 + return true; 1.396 + } else if (os::Solaris::chained_handler(sig, info, ucVoid)) { 1.397 + return true; 1.398 + } else { 1.399 + // If os::Solaris::SIGasync not chained, and this is a non-vm and 1.400 + // non-java thread 1.401 + return true; 1.402 + } 1.403 + } 1.404 + 1.405 + if (info == NULL || info->si_code <= 0 || info->si_code == SI_NOINFO) { 1.406 + // can't decode this kind of signal 1.407 + info = NULL; 1.408 + } else { 1.409 + assert(sig == info->si_signo, "bad siginfo"); 1.410 + } 1.411 + 1.412 + // decide if this trap can be handled by a stub 1.413 + address stub = NULL; 1.414 + 1.415 + address pc = NULL; 1.416 + 1.417 + //%note os_trap_1 1.418 + if (info != NULL && uc != NULL && thread != NULL) { 1.419 + // factor me: getPCfromContext 1.420 + pc = (address) uc->uc_mcontext.gregs[REG_PC]; 1.421 + 1.422 + // SafeFetch32() support 1.423 + if (pc == (address) Fetch32PFI) { 1.424 + uc->uc_mcontext.gregs[REG_PC] = intptr_t(Fetch32Resume) ; 1.425 + return true ; 1.426 + } 1.427 +#ifdef AMD64 1.428 + if (pc == (address) FetchNPFI) { 1.429 + uc->uc_mcontext.gregs [REG_PC] = intptr_t(FetchNResume) ; 1.430 + return true ; 1.431 + } 1.432 +#endif // AMD64 1.433 + 1.434 + // Handle ALL stack overflow variations here 1.435 + if (sig == SIGSEGV && info->si_code == SEGV_ACCERR) { 1.436 + address addr = (address) info->si_addr; 1.437 + if (thread->in_stack_yellow_zone(addr)) { 1.438 + thread->disable_stack_yellow_zone(); 1.439 + if (thread->thread_state() == _thread_in_Java) { 1.440 + // Throw a stack overflow exception. Guard pages will be reenabled 1.441 + // while unwinding the stack. 1.442 + stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::STACK_OVERFLOW); 1.443 + } else { 1.444 + // Thread was in the vm or native code. Return and try to finish. 1.445 + return true; 1.446 + } 1.447 + } else if (thread->in_stack_red_zone(addr)) { 1.448 + // Fatal red zone violation. Disable the guard pages and fall through 1.449 + // to handle_unexpected_exception way down below. 1.450 + thread->disable_stack_red_zone(); 1.451 + tty->print_raw_cr("An irrecoverable stack overflow has occurred."); 1.452 + } 1.453 + } 1.454 + 1.455 + if (thread->thread_state() == _thread_in_vm) { 1.456 + if (sig == SIGBUS && info->si_code == BUS_OBJERR && thread->doing_unsafe_access()) { 1.457 + stub = StubRoutines::handler_for_unsafe_access(); 1.458 + } 1.459 + } 1.460 + 1.461 + if (thread->thread_state() == _thread_in_Java) { 1.462 + // Support Safepoint Polling 1.463 + if ( sig == SIGSEGV && os::is_poll_address((address)info->si_addr)) { 1.464 + stub = SharedRuntime::get_poll_stub(pc); 1.465 + } 1.466 + else if (sig == SIGBUS && info->si_code == BUS_OBJERR) { 1.467 + // BugId 4454115: A read from a MappedByteBuffer can fault 1.468 + // here if the underlying file has been truncated. 1.469 + // Do not crash the VM in such a case. 1.470 + CodeBlob* cb = CodeCache::find_blob_unsafe(pc); 1.471 + nmethod* nm = cb->is_nmethod() ? (nmethod*)cb : NULL; 1.472 + if (nm != NULL && nm->has_unsafe_access()) { 1.473 + stub = StubRoutines::handler_for_unsafe_access(); 1.474 + } 1.475 + } 1.476 + else 1.477 + if (sig == SIGFPE && info->si_code == FPE_INTDIV) { 1.478 + // integer divide by zero 1.479 + stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::IMPLICIT_DIVIDE_BY_ZERO); 1.480 + } 1.481 +#ifndef AMD64 1.482 + else if (sig == SIGFPE && info->si_code == FPE_FLTDIV) { 1.483 + // floating-point divide by zero 1.484 + stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::IMPLICIT_DIVIDE_BY_ZERO); 1.485 + } 1.486 + else if (sig == SIGFPE && info->si_code == FPE_FLTINV) { 1.487 + // The encoding of D2I in i486.ad can cause an exception prior 1.488 + // to the fist instruction if there was an invalid operation 1.489 + // pending. We want to dismiss that exception. From the win_32 1.490 + // side it also seems that if it really was the fist causing 1.491 + // the exception that we do the d2i by hand with different 1.492 + // rounding. Seems kind of weird. QQQ TODO 1.493 + // Note that we take the exception at the NEXT floating point instruction. 1.494 + if (pc[0] == 0xDB) { 1.495 + assert(pc[0] == 0xDB, "not a FIST opcode"); 1.496 + assert(pc[1] == 0x14, "not a FIST opcode"); 1.497 + assert(pc[2] == 0x24, "not a FIST opcode"); 1.498 + return true; 1.499 + } else { 1.500 + assert(pc[-3] == 0xDB, "not an flt invalid opcode"); 1.501 + assert(pc[-2] == 0x14, "not an flt invalid opcode"); 1.502 + assert(pc[-1] == 0x24, "not an flt invalid opcode"); 1.503 + } 1.504 + } 1.505 + else if (sig == SIGFPE ) { 1.506 + tty->print_cr("caught SIGFPE, info 0x%x.", info->si_code); 1.507 + } 1.508 +#endif // !AMD64 1.509 + 1.510 + // QQQ It doesn't seem that we need to do this on x86 because we should be able 1.511 + // to return properly from the handler without this extra stuff on the back side. 1.512 + 1.513 + else if (sig == SIGSEGV && info->si_code > 0 && !MacroAssembler::needs_explicit_null_check((intptr_t)info->si_addr)) { 1.514 + // Determination of interpreter/vtable stub/compiled code null exception 1.515 + stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::IMPLICIT_NULL); 1.516 + } 1.517 + } 1.518 + 1.519 + // jni_fast_Get<Primitive>Field can trap at certain pc's if a GC kicks in 1.520 + // and the heap gets shrunk before the field access. 1.521 + if ((sig == SIGSEGV) || (sig == SIGBUS)) { 1.522 + address addr = JNI_FastGetField::find_slowcase_pc(pc); 1.523 + if (addr != (address)-1) { 1.524 + stub = addr; 1.525 + } 1.526 + } 1.527 + 1.528 + // Check to see if we caught the safepoint code in the 1.529 + // process of write protecting the memory serialization page. 1.530 + // It write enables the page immediately after protecting it 1.531 + // so we can just return to retry the write. 1.532 + if ((sig == SIGSEGV) && 1.533 + os::is_memory_serialize_page(thread, (address)info->si_addr)) { 1.534 + // Block current thread until the memory serialize page permission restored. 1.535 + os::block_on_serialize_page_trap(); 1.536 + return true; 1.537 + } 1.538 + } 1.539 + 1.540 + // Execution protection violation 1.541 + // 1.542 + // Preventative code for future versions of Solaris which may 1.543 + // enable execution protection when running the 32-bit VM on AMD64. 1.544 + // 1.545 + // This should be kept as the last step in the triage. We don't 1.546 + // have a dedicated trap number for a no-execute fault, so be 1.547 + // conservative and allow other handlers the first shot. 1.548 + // 1.549 + // Note: We don't test that info->si_code == SEGV_ACCERR here. 1.550 + // this si_code is so generic that it is almost meaningless; and 1.551 + // the si_code for this condition may change in the future. 1.552 + // Furthermore, a false-positive should be harmless. 1.553 + if (UnguardOnExecutionViolation > 0 && 1.554 + (sig == SIGSEGV || sig == SIGBUS) && 1.555 + uc->uc_mcontext.gregs[TRAPNO] == T_PGFLT) { // page fault 1.556 + int page_size = os::vm_page_size(); 1.557 + address addr = (address) info->si_addr; 1.558 + address pc = (address) uc->uc_mcontext.gregs[REG_PC]; 1.559 + // Make sure the pc and the faulting address are sane. 1.560 + // 1.561 + // If an instruction spans a page boundary, and the page containing 1.562 + // the beginning of the instruction is executable but the following 1.563 + // page is not, the pc and the faulting address might be slightly 1.564 + // different - we still want to unguard the 2nd page in this case. 1.565 + // 1.566 + // 15 bytes seems to be a (very) safe value for max instruction size. 1.567 + bool pc_is_near_addr = 1.568 + (pointer_delta((void*) addr, (void*) pc, sizeof(char)) < 15); 1.569 + bool instr_spans_page_boundary = 1.570 + (align_size_down((intptr_t) pc ^ (intptr_t) addr, 1.571 + (intptr_t) page_size) > 0); 1.572 + 1.573 + if (pc == addr || (pc_is_near_addr && instr_spans_page_boundary)) { 1.574 + static volatile address last_addr = 1.575 + (address) os::non_memory_address_word(); 1.576 + 1.577 + // In conservative mode, don't unguard unless the address is in the VM 1.578 + if (addr != last_addr && 1.579 + (UnguardOnExecutionViolation > 1 || os::address_is_in_vm(addr))) { 1.580 + 1.581 + // Unguard and retry 1.582 + address page_start = 1.583 + (address) align_size_down((intptr_t) addr, (intptr_t) page_size); 1.584 + bool res = os::unguard_memory((char*) page_start, page_size); 1.585 + 1.586 + if (PrintMiscellaneous && Verbose) { 1.587 + char buf[256]; 1.588 + jio_snprintf(buf, sizeof(buf), "Execution protection violation " 1.589 + "at " INTPTR_FORMAT 1.590 + ", unguarding " INTPTR_FORMAT ": %s, errno=%d", addr, 1.591 + page_start, (res ? "success" : "failed"), errno); 1.592 + tty->print_raw_cr(buf); 1.593 + } 1.594 + stub = pc; 1.595 + 1.596 + // Set last_addr so if we fault again at the same address, we don't end 1.597 + // up in an endless loop. 1.598 + // 1.599 + // There are two potential complications here. Two threads trapping at 1.600 + // the same address at the same time could cause one of the threads to 1.601 + // think it already unguarded, and abort the VM. Likely very rare. 1.602 + // 1.603 + // The other race involves two threads alternately trapping at 1.604 + // different addresses and failing to unguard the page, resulting in 1.605 + // an endless loop. This condition is probably even more unlikely than 1.606 + // the first. 1.607 + // 1.608 + // Although both cases could be avoided by using locks or thread local 1.609 + // last_addr, these solutions are unnecessary complication: this 1.610 + // handler is a best-effort safety net, not a complete solution. It is 1.611 + // disabled by default and should only be used as a workaround in case 1.612 + // we missed any no-execute-unsafe VM code. 1.613 + 1.614 + last_addr = addr; 1.615 + } 1.616 + } 1.617 + } 1.618 + 1.619 + if (stub != NULL) { 1.620 + // save all thread context in case we need to restore it 1.621 + 1.622 + if (thread != NULL) thread->set_saved_exception_pc(pc); 1.623 + // 12/02/99: On Sparc it appears that the full context is also saved 1.624 + // but as yet, no one looks at or restores that saved context 1.625 + // factor me: setPC 1.626 + uc->uc_mcontext.gregs[REG_PC] = (greg_t)stub; 1.627 + return true; 1.628 + } 1.629 + 1.630 + // signal-chaining 1.631 + if (os::Solaris::chained_handler(sig, info, ucVoid)) { 1.632 + return true; 1.633 + } 1.634 + 1.635 +#ifndef AMD64 1.636 + // Workaround (bug 4900493) for Solaris kernel bug 4966651. 1.637 + // Handle an undefined selector caused by an attempt to assign 1.638 + // fs in libthread getipriptr(). With the current libthread design every 512 1.639 + // thread creations the LDT for a private thread data structure is extended 1.640 + // and thre is a hazard that and another thread attempting a thread creation 1.641 + // will use a stale LDTR that doesn't reflect the structure's growth, 1.642 + // causing a GP fault. 1.643 + // Enforce the probable limit of passes through here to guard against an 1.644 + // infinite loop if some other move to fs caused the GP fault. Note that 1.645 + // this loop counter is ultimately a heuristic as it is possible for 1.646 + // more than one thread to generate this fault at a time in an MP system. 1.647 + // In the case of the loop count being exceeded or if the poll fails 1.648 + // just fall through to a fatal error. 1.649 + // If there is some other source of T_GPFLT traps and the text at EIP is 1.650 + // unreadable this code will loop infinitely until the stack is exausted. 1.651 + // The key to diagnosis in this case is to look for the bottom signal handler 1.652 + // frame. 1.653 + 1.654 + if(! IgnoreLibthreadGPFault) { 1.655 + if (sig == SIGSEGV && uc->uc_mcontext.gregs[TRAPNO] == T_GPFLT) { 1.656 + const unsigned char *p = 1.657 + (unsigned const char *) uc->uc_mcontext.gregs[EIP]; 1.658 + 1.659 + // Expected instruction? 1.660 + 1.661 + if(p[0] == movlfs[0] && p[1] == movlfs[1]) { 1.662 + 1.663 + Atomic::inc(&ldtr_refresh); 1.664 + 1.665 + // Infinite loop? 1.666 + 1.667 + if(ldtr_refresh < ((2 << 16) / PAGESIZE)) { 1.668 + 1.669 + // No, force scheduling to get a fresh view of the LDTR 1.670 + 1.671 + if(poll(NULL, 0, 10) == 0) { 1.672 + 1.673 + // Retry the move 1.674 + 1.675 + return false; 1.676 + } 1.677 + } 1.678 + } 1.679 + } 1.680 + } 1.681 +#endif // !AMD64 1.682 + 1.683 + if (!abort_if_unrecognized) { 1.684 + // caller wants another chance, so give it to him 1.685 + return false; 1.686 + } 1.687 + 1.688 + if (!os::Solaris::libjsig_is_loaded) { 1.689 + struct sigaction oldAct; 1.690 + sigaction(sig, (struct sigaction *)0, &oldAct); 1.691 + if (oldAct.sa_sigaction != signalHandler) { 1.692 + void* sighand = oldAct.sa_sigaction ? CAST_FROM_FN_PTR(void*, oldAct.sa_sigaction) 1.693 + : CAST_FROM_FN_PTR(void*, oldAct.sa_handler); 1.694 + warning("Unexpected Signal %d occured under user-defined signal handler %#lx", sig, (long)sighand); 1.695 + } 1.696 + } 1.697 + 1.698 + if (pc == NULL && uc != NULL) { 1.699 + pc = (address) uc->uc_mcontext.gregs[REG_PC]; 1.700 + } 1.701 + 1.702 + // unmask current signal 1.703 + sigset_t newset; 1.704 + sigemptyset(&newset); 1.705 + sigaddset(&newset, sig); 1.706 + sigprocmask(SIG_UNBLOCK, &newset, NULL); 1.707 + 1.708 + VMError err(t, sig, pc, info, ucVoid); 1.709 + err.report_and_die(); 1.710 + 1.711 + ShouldNotReachHere(); 1.712 +} 1.713 + 1.714 +void os::print_context(outputStream *st, void *context) { 1.715 + if (context == NULL) return; 1.716 + 1.717 + ucontext_t *uc = (ucontext_t*)context; 1.718 + st->print_cr("Registers:"); 1.719 +#ifdef AMD64 1.720 + st->print( "RAX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RAX]); 1.721 + st->print(", RBX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RBX]); 1.722 + st->print(", RCX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RCX]); 1.723 + st->print(", RDX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RDX]); 1.724 + st->cr(); 1.725 + st->print( "RSP=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RSP]); 1.726 + st->print(", RBP=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RBP]); 1.727 + st->print(", RSI=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RSI]); 1.728 + st->print(", RDI=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RDI]); 1.729 + st->cr(); 1.730 + st->print(", R8=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R8]); 1.731 + st->print(", R9=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R9]); 1.732 + st->print(", R10=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R10]); 1.733 + st->print(", R11=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R11]); 1.734 + st->print(", R12=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R12]); 1.735 + st->print(", R13=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R13]); 1.736 + st->print(", R14=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R14]); 1.737 + st->print(", R15=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R15]); 1.738 + st->cr(); 1.739 + st->print( "RIP=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RIP]); 1.740 + st->print(", RFLAGS=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RFL]); 1.741 +#else 1.742 + st->print( "EAX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[EAX]); 1.743 + st->print(", EBX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[EBX]); 1.744 + st->print(", ECX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[ECX]); 1.745 + st->print(", EDX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[EDX]); 1.746 + st->cr(); 1.747 + st->print( "ESP=" INTPTR_FORMAT, uc->uc_mcontext.gregs[UESP]); 1.748 + st->print(", EBP=" INTPTR_FORMAT, uc->uc_mcontext.gregs[EBP]); 1.749 + st->print(", ESI=" INTPTR_FORMAT, uc->uc_mcontext.gregs[ESI]); 1.750 + st->print(", EDI=" INTPTR_FORMAT, uc->uc_mcontext.gregs[EDI]); 1.751 + st->cr(); 1.752 + st->print( "EIP=" INTPTR_FORMAT, uc->uc_mcontext.gregs[EIP]); 1.753 + st->print(", EFLAGS=" INTPTR_FORMAT, uc->uc_mcontext.gregs[EFL]); 1.754 +#endif // AMD64 1.755 + st->cr(); 1.756 + st->cr(); 1.757 + 1.758 + intptr_t *sp = (intptr_t *)os::Solaris::ucontext_get_sp(uc); 1.759 + st->print_cr("Top of Stack: (sp=" PTR_FORMAT ")", sp); 1.760 + print_hex_dump(st, (address)sp, (address)(sp + 8*sizeof(intptr_t)), sizeof(intptr_t)); 1.761 + st->cr(); 1.762 + 1.763 + // Note: it may be unsafe to inspect memory near pc. For example, pc may 1.764 + // point to garbage if entry point in an nmethod is corrupted. Leave 1.765 + // this at the end, and hope for the best. 1.766 + ExtendedPC epc = os::Solaris::ucontext_get_ExtendedPC(uc); 1.767 + address pc = epc.pc(); 1.768 + st->print_cr("Instructions: (pc=" PTR_FORMAT ")", pc); 1.769 + print_hex_dump(st, pc - 16, pc + 16, sizeof(char)); 1.770 +} 1.771 + 1.772 +#ifdef AMD64 1.773 +void os::Solaris::init_thread_fpu_state(void) { 1.774 + // Nothing to do 1.775 +} 1.776 +#else 1.777 +// From solaris_i486.s 1.778 +extern "C" void fixcw(); 1.779 + 1.780 +void os::Solaris::init_thread_fpu_state(void) { 1.781 + // Set fpu to 53 bit precision. This happens too early to use a stub. 1.782 + fixcw(); 1.783 +} 1.784 + 1.785 +// These routines are the initial value of atomic_xchg_entry(), 1.786 +// atomic_cmpxchg_entry(), atomic_inc_entry() and fence_entry() 1.787 +// until initialization is complete. 1.788 +// TODO - replace with .il implementation when compiler supports it. 1.789 + 1.790 +typedef jint xchg_func_t (jint, volatile jint*); 1.791 +typedef jint cmpxchg_func_t (jint, volatile jint*, jint); 1.792 +typedef jlong cmpxchg_long_func_t(jlong, volatile jlong*, jlong); 1.793 +typedef jint add_func_t (jint, volatile jint*); 1.794 +typedef void fence_func_t (); 1.795 + 1.796 +jint os::atomic_xchg_bootstrap(jint exchange_value, volatile jint* dest) { 1.797 + // try to use the stub: 1.798 + xchg_func_t* func = CAST_TO_FN_PTR(xchg_func_t*, StubRoutines::atomic_xchg_entry()); 1.799 + 1.800 + if (func != NULL) { 1.801 + os::atomic_xchg_func = func; 1.802 + return (*func)(exchange_value, dest); 1.803 + } 1.804 + assert(Threads::number_of_threads() == 0, "for bootstrap only"); 1.805 + 1.806 + jint old_value = *dest; 1.807 + *dest = exchange_value; 1.808 + return old_value; 1.809 +} 1.810 + 1.811 +jint os::atomic_cmpxchg_bootstrap(jint exchange_value, volatile jint* dest, jint compare_value) { 1.812 + // try to use the stub: 1.813 + cmpxchg_func_t* func = CAST_TO_FN_PTR(cmpxchg_func_t*, StubRoutines::atomic_cmpxchg_entry()); 1.814 + 1.815 + if (func != NULL) { 1.816 + os::atomic_cmpxchg_func = func; 1.817 + return (*func)(exchange_value, dest, compare_value); 1.818 + } 1.819 + assert(Threads::number_of_threads() == 0, "for bootstrap only"); 1.820 + 1.821 + jint old_value = *dest; 1.822 + if (old_value == compare_value) 1.823 + *dest = exchange_value; 1.824 + return old_value; 1.825 +} 1.826 + 1.827 +jlong os::atomic_cmpxchg_long_bootstrap(jlong exchange_value, volatile jlong* dest, jlong compare_value) { 1.828 + // try to use the stub: 1.829 + cmpxchg_long_func_t* func = CAST_TO_FN_PTR(cmpxchg_long_func_t*, StubRoutines::atomic_cmpxchg_long_entry()); 1.830 + 1.831 + if (func != NULL) { 1.832 + os::atomic_cmpxchg_long_func = func; 1.833 + return (*func)(exchange_value, dest, compare_value); 1.834 + } 1.835 + assert(Threads::number_of_threads() == 0, "for bootstrap only"); 1.836 + 1.837 + jlong old_value = *dest; 1.838 + if (old_value == compare_value) 1.839 + *dest = exchange_value; 1.840 + return old_value; 1.841 +} 1.842 + 1.843 +jint os::atomic_add_bootstrap(jint add_value, volatile jint* dest) { 1.844 + // try to use the stub: 1.845 + add_func_t* func = CAST_TO_FN_PTR(add_func_t*, StubRoutines::atomic_add_entry()); 1.846 + 1.847 + if (func != NULL) { 1.848 + os::atomic_add_func = func; 1.849 + return (*func)(add_value, dest); 1.850 + } 1.851 + assert(Threads::number_of_threads() == 0, "for bootstrap only"); 1.852 + 1.853 + return (*dest) += add_value; 1.854 +} 1.855 + 1.856 +void os::fence_bootstrap() { 1.857 + // try to use the stub: 1.858 + fence_func_t* func = CAST_TO_FN_PTR(fence_func_t*, StubRoutines::fence_entry()); 1.859 + 1.860 + if (func != NULL) { 1.861 + os::fence_func = func; 1.862 + (*func)(); 1.863 + return; 1.864 + } 1.865 + assert(Threads::number_of_threads() == 0, "for bootstrap only"); 1.866 + 1.867 + // don't have to do anything for a single thread 1.868 +} 1.869 + 1.870 +xchg_func_t* os::atomic_xchg_func = os::atomic_xchg_bootstrap; 1.871 +cmpxchg_func_t* os::atomic_cmpxchg_func = os::atomic_cmpxchg_bootstrap; 1.872 +cmpxchg_long_func_t* os::atomic_cmpxchg_long_func = os::atomic_cmpxchg_long_bootstrap; 1.873 +add_func_t* os::atomic_add_func = os::atomic_add_bootstrap; 1.874 +fence_func_t* os::fence_func = os::fence_bootstrap; 1.875 + 1.876 +extern "C" _solaris_raw_setup_fpu(address ptr); 1.877 +void os::setup_fpu() { 1.878 + address fpu_cntrl = StubRoutines::addr_fpu_cntrl_wrd_std(); 1.879 + _solaris_raw_setup_fpu(fpu_cntrl); 1.880 +} 1.881 +#endif // AMD64