os_solaris_sparc.cpp revision 4558:746b070f5022
178189Sbrian/* 278189Sbrian * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. 378189Sbrian * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 478189Sbrian * 578189Sbrian * This code is free software; you can redistribute it and/or modify it 66059Samurai * under the terms of the GNU General Public License version 2 only, as 778189Sbrian * published by the Free Software Foundation. 878189Sbrian * 978189Sbrian * This code is distributed in the hope that it will be useful, but WITHOUT 1078189Sbrian * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1178189Sbrian * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1278189Sbrian * version 2 for more details (a copy is included in the LICENSE file that 1378189Sbrian * accompanied this code). 1478189Sbrian * 156059Samurai * You should have received a copy of the GNU General Public License version 1678189Sbrian * 2 along with this work; if not, write to the Free Software Foundation, 1778189Sbrian * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1878189Sbrian * 1978189Sbrian * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2078189Sbrian * or visit www.oracle.com if you need additional information or have any 2178189Sbrian * questions. 2278189Sbrian * 2378189Sbrian */ 2478189Sbrian 2578189Sbrian// no precompiled headers 2678189Sbrian#include "asm/macroAssembler.hpp" 276059Samurai#include "classfile/classLoader.hpp" 2850479Speter#include "classfile/systemDictionary.hpp" 296059Samurai#include "classfile/vmSymbols.hpp" 3078189Sbrian#include "code/icBuffer.hpp" 3143313Sbrian#include "code/vtableStubs.hpp" 3230715Sbrian#include "interpreter/interpreter.hpp" 3326031Sbrian#include "jvm_solaris.h" 3430715Sbrian#include "memory/allocation.inline.hpp" 3526031Sbrian#include "mutex_solaris.inline.hpp" 3630715Sbrian#include "nativeInst_sparc.hpp" 3726031Sbrian#include "os_share_solaris.hpp" 3830715Sbrian#include "prims/jniFastGetField.hpp" 3936285Sbrian#include "prims/jvm.h" 4030715Sbrian#include "prims/jvm_misc.hpp" 4138628Sbrian#include "runtime/arguments.hpp" 4230715Sbrian#include "runtime/extendedPC.hpp" 4326516Sbrian#include "runtime/frame.inline.hpp" 4430715Sbrian#include "runtime/interfaceSupport.hpp" 45102500Sbrian#include "runtime/java.hpp" 4630715Sbrian#include "runtime/javaCalls.hpp" 4730715Sbrian#include "runtime/mutexLocker.hpp" 4830715Sbrian#include "runtime/osThread.hpp" 4930715Sbrian#include "runtime/sharedRuntime.hpp" 5030715Sbrian#include "runtime/stubRoutines.hpp" 5130715Sbrian#include "runtime/thread.inline.hpp" 5230715Sbrian#include "runtime/timer.hpp" 5350059Sbrian#include "utilities/events.hpp" 5458037Sbrian#include "utilities/vmError.hpp" 5558037Sbrian 5658037Sbrian# include <signal.h> // needed first to avoid name collision for "std" with SC 5.0 5746086Sbrian 5839395Sbrian// put OS-includes here 5939395Sbrian# include <sys/types.h> 6058037Sbrian# include <sys/mman.h> 6146686Sbrian# include <pthread.h> 6237009Sbrian# include <errno.h> 6331343Sbrian# include <dlfcn.h> 6430715Sbrian# include <stdio.h> 6530715Sbrian# include <unistd.h> 6630715Sbrian# include <sys/resource.h> 676059Samurai# include <thread.h> 6831690Sbrian# include <sys/stat.h> 6936285Sbrian# include <sys/time.h> 7036285Sbrian# include <sys/filio.h> 7138557Sbrian# include <sys/utsname.h> 7238557Sbrian# include <sys/systeminfo.h> 7363484Sbrian# include <sys/socket.h> 7481634Sbrian# include <sys/lwp.h> 756059Samurai# include <pwd.h> 7650059Sbrian# include <poll.h> 7751075Sbrian# include <sys/lwp.h> 7831343Sbrian 7925630Sbrian# define _STRUCTURED_PROC 1 // this gets us the new structured proc interfaces of 5.6 & later 8036285Sbrian# include <sys/procfs.h> // see comment in <sys/procfs.h> 8136285Sbrian 8230715Sbrian#define MAX_PATH (2 * K) 8330715Sbrian 8430715Sbrian// Minimum stack size for the VM. It's easier to document a constant 8531080Sbrian// but it's different for x86 and sparc because the page sizes are different. 8636285Sbrian#ifdef _LP64 8736285Sbriansize_t os::Solaris::min_stack_allowed = 128*K; 8836285Sbrian#else 8936285Sbriansize_t os::Solaris::min_stack_allowed = 96*K; 9043313Sbrian#endif 9143313Sbrian 9243313Sbrianint os::Solaris::max_register_window_saves_before_flushing() { 9381634Sbrian // We should detect this at run time. For now, filling 9481634Sbrian // in with a constant. 9536285Sbrian return 8; 9636285Sbrian} 9736285Sbrian 9836285Sbrianstatic void handle_unflushed_register_windows(gwindows_t *win) { 9936285Sbrian int restore_count = win->wbcnt; 10038174Sbrian int i; 10136285Sbrian 10240561Sbrian for(i=0; i<restore_count; i++) { 10353298Sbrian address sp = ((address)win->spbuf[i]) + STACK_BIAS; 10481697Sbrian address reg_win = (address)&win->wbuf[i]; 1056059Samurai memcpy(sp,reg_win,sizeof(struct rwindow)); 10636285Sbrian } 10736285Sbrian} 10836285Sbrian 10936285Sbrianchar* os::non_memory_address_word() { 11036285Sbrian // Must never look like an address returned by reserve_memory, 11136285Sbrian // even in its subfields (as defined by the CPU immediate fields, 11236285Sbrian // if the CPU splits constants across multiple instructions). 11336285Sbrian // On SPARC, 0 != %hi(any real address), because there is no 11436285Sbrian // allocation in the first 1Kb of the virtual address space. 11536285Sbrian return (char*) 0; 11636285Sbrian} 11736285Sbrian 11836285Sbrian// Validate a ucontext retrieved from walking a uc_link of a ucontext. 11936285Sbrian// There are issues with libthread giving out uc_links for different threads 12036285Sbrian// on the same uc_link chain and bad or circular links. 12136285Sbrian// 12236285Sbrianbool os::Solaris::valid_ucontext(Thread* thread, ucontext_t* valid, ucontext_t* suspect) { 12336285Sbrian if (valid >= suspect || 12436285Sbrian valid->uc_stack.ss_flags != suspect->uc_stack.ss_flags || 12536285Sbrian valid->uc_stack.ss_sp != suspect->uc_stack.ss_sp || 12636285Sbrian valid->uc_stack.ss_size != suspect->uc_stack.ss_size) { 12736285Sbrian DEBUG_ONLY(tty->print_cr("valid_ucontext: failed test 1");) 12836285Sbrian return false; 12936285Sbrian } 13036285Sbrian 13138174Sbrian if (thread->is_Java_thread()) { 13238174Sbrian if (!valid_stack_address(thread, (address)suspect)) { 13338544Sbrian DEBUG_ONLY(tty->print_cr("valid_ucontext: uc_link not in thread stack");) 13440665Sbrian return false; 13540665Sbrian } 13643313Sbrian address _sp = (address)((intptr_t)suspect->uc_mcontext.gregs[REG_SP] + STACK_BIAS); 13744073Sbrian if (!valid_stack_address(thread, _sp) || 13846686Sbrian !frame::is_valid_stack_pointer(((JavaThread*)thread)->base_of_stack_pointer(), (intptr_t*)_sp)) { 13946686Sbrian DEBUG_ONLY(tty->print_cr("valid_ucontext: stackpointer not in thread stack");) 14050867Sbrian return false; 14152488Sbrian } 14261534Sbrian } 14378411Sbrian return true; 144102558Sbrian} 145132273Sbrian 146132818Sglebius// We will only follow one level of uc_link since there are libthread 147169986Snovel// issues with ucontext linking and it is better to be safe and just 1486059Samurai// let caller retry later. 14936285Sbrianucontext_t* os::Solaris::get_valid_uc_in_signal_handler(Thread *thread, 15036285Sbrian ucontext_t *uc) { 15136285Sbrian 15236285Sbrian ucontext_t *retuc = NULL; 15336285Sbrian 15436285Sbrian // Sometimes the topmost register windows are not properly flushed. 15544106Sbrian // i.e., if the kernel would have needed to take a page fault 15644106Sbrian if (uc != NULL && uc->uc_mcontext.gwins != NULL) { 15744106Sbrian ::handle_unflushed_register_windows(uc->uc_mcontext.gwins); 15844106Sbrian } 15947858Sbrian 160138799Sbrian if (uc != NULL) { 161138799Sbrian if (uc->uc_link == NULL) { 162138799Sbrian // cannot validate without uc_link so accept current ucontext 163138799Sbrian retuc = uc; 164138799Sbrian } else if (os::Solaris::valid_ucontext(thread, uc, uc->uc_link)) { 165138799Sbrian // first ucontext is valid so try the next one 166138799Sbrian uc = uc->uc_link; 167138799Sbrian if (uc->uc_link == NULL) { 168138799Sbrian // cannot validate without uc_link so accept current ucontext 169138799Sbrian retuc = uc; 170138799Sbrian } else if (os::Solaris::valid_ucontext(thread, uc, uc->uc_link)) { 17136285Sbrian // the ucontext one level down is also valid so return it 172138799Sbrian retuc = uc; 17336285Sbrian } 17436285Sbrian } 17536285Sbrian } 17636285Sbrian return retuc; 17736285Sbrian} 17836285Sbrian 17936285Sbrian// Assumes ucontext is valid 18036285SbrianExtendedPC os::Solaris::ucontext_get_ExtendedPC(ucontext_t *uc) { 18136285Sbrian address pc = (address)uc->uc_mcontext.gregs[REG_PC]; 18236285Sbrian // set npc to zero to avoid using it for safepoint, good for profiling only 18336285Sbrian return ExtendedPC(pc); 18436285Sbrian} 18536934Sbrian 18640561Sbrian// Assumes ucontext is valid 187218397Sbrianintptr_t* os::Solaris::ucontext_get_sp(ucontext_t *uc) { 18840561Sbrian return (intptr_t*)((intptr_t)uc->uc_mcontext.gregs[REG_SP] + STACK_BIAS); 18940561Sbrian} 19040561Sbrian 19140679Sbrian// Solaris X86 only 19250059Sbrianintptr_t* os::Solaris::ucontext_get_fp(ucontext_t *uc) { 19358867Sbrian ShouldNotReachHere(); 19458867Sbrian return NULL; 19531343Sbrian} 1966059Samurai 197177100Spiso// For Forte Analyzer AsyncGetCallTrace profiling support - thread 198177100Spiso// is currently interrupted by SIGPROF. 19936285Sbrian// 20036285Sbrian// ret_fp parameter is only used by Solaris X86. 20136285Sbrian// 20236285Sbrian// The difference between this and os::fetch_frame_from_context() is that 20336285Sbrian// here we try to skip nested signal frames. 20436285SbrianExtendedPC os::Solaris::fetch_frame_from_ucontext(Thread* thread, 20536285Sbrian ucontext_t* uc, intptr_t** ret_sp, intptr_t** ret_fp) { 20636285Sbrian 20736285Sbrian assert(thread != NULL, "just checking"); 20836285Sbrian assert(ret_sp != NULL, "just checking"); 20936285Sbrian assert(ret_fp == NULL, "just checking"); 2106059Samurai 21131343Sbrian ucontext_t *luc = os::Solaris::get_valid_uc_in_signal_handler(thread, uc); 2126059Samurai 21328679Sbrian return os::fetch_frame_from_context(luc, ret_sp, ret_fp); 21436285Sbrian} 21536285Sbrian 2166059Samurai 21736285Sbrian// ret_fp parameter is only used by Solaris X86. 21836285SbrianExtendedPC os::fetch_frame_from_context(void* ucVoid, 21926516Sbrian intptr_t** ret_sp, intptr_t** ret_fp) { 22036285Sbrian 22126516Sbrian ExtendedPC epc; 22236285Sbrian ucontext_t *uc = (ucontext_t*)ucVoid; 22336285Sbrian 22436285Sbrian if (uc != NULL) { 22536285Sbrian epc = os::Solaris::ucontext_get_ExtendedPC(uc); 22636285Sbrian if (ret_sp) *ret_sp = os::Solaris::ucontext_get_sp(uc); 22736285Sbrian } else { 22828679Sbrian // construct empty ExtendedPC for return value checking 2296059Samurai epc = ExtendedPC(NULL); 23026516Sbrian if (ret_sp) *ret_sp = (intptr_t *)NULL; 2316059Samurai } 23236285Sbrian 23331372Sbrian return epc; 23436285Sbrian} 23536285Sbrian 23636285Sbrianframe os::fetch_frame_from_context(void* ucVoid) { 23731372Sbrian intptr_t* sp; 23831372Sbrian intptr_t* fp; 23931372Sbrian ExtendedPC epc = fetch_frame_from_context(ucVoid, &sp, &fp); 24031372Sbrian return frame(sp, frame::unpatchable, epc.pc()); 24131372Sbrian} 24231372Sbrian 2436059Samuraiframe os::get_sender_for_C_frame(frame* fr) { 24436285Sbrian return frame(fr->sender_sp(), frame::unpatchable, fr->sender_pc()); 24536285Sbrian} 24636285Sbrian 24736285Sbrian// Returns an estimate of the current stack pointer. Result must be guaranteed to 24836285Sbrian// point into the calling threads stack, and be no lower than the current stack 24936285Sbrian// pointer. 25040482Sbrianaddress os::current_stack_pointer() { 25140482Sbrian volatile int dummy; 25240482Sbrian address sp = (address)&dummy + 8; // %%%% need to confirm if this is right 25336285Sbrian return sp; 25431372Sbrian} 25536285Sbrian 2566059Samuraiframe os::current_frame() { 25731372Sbrian intptr_t* sp = StubRoutines::Sparc::flush_callers_register_windows_func()(); 25836285Sbrian frame myframe(sp, frame::unpatchable, 25926516Sbrian CAST_FROM_FN_PTR(address, os::current_frame)); 26026516Sbrian if (os::is_first_C_frame(&myframe)) { 2616059Samurai // stack is not walkable 2626059Samurai return frame(NULL, NULL, NULL); 26336285Sbrian } else { 26463484Sbrian return os::get_sender_for_C_frame(&myframe); 26563484Sbrian } 26685991Sbrian} 26785991Sbrian 26885991Sbrian 26963484Sbrianvoid GetThreadPC_Callback::execute(OSThread::InterruptArguments *args) { 27063484Sbrian Thread* thread = args->thread(); 27163484Sbrian ucontext_t* uc = args->ucontext(); 27263484Sbrian intptr_t* sp; 27363484Sbrian 27463484Sbrian assert(ProfileVM && thread->is_VM_thread(), "just checking"); 27563484Sbrian 27663484Sbrian // Skip the mcontext corruption verification. If if occasionally 27763484Sbrian // things get corrupt, it is ok for profiling - we will just get an unresolved 27863484Sbrian // function name 27963484Sbrian ExtendedPC new_addr((address)uc->uc_mcontext.gregs[REG_PC]); 28063484Sbrian _addr = new_addr; 28163484Sbrian} 28263484Sbrian 28336285Sbrian 2846059Samuraistatic int threadgetstate(thread_t tid, int *flags, lwpid_t *lwp, stack_t *ss, gregset_t rs, lwpstatus_t *lwpstatus) { 28536285Sbrian char lwpstatusfile[PROCFILE_LENGTH]; 28636285Sbrian int lwpfd, err; 28736285Sbrian 2886059Samurai if (err = os::Solaris::thr_getstate(tid, flags, lwp, ss, rs)) 28936285Sbrian return (err); 29036285Sbrian if (*flags == TRS_LWPID) { 29136285Sbrian sprintf(lwpstatusfile, "/proc/%d/lwp/%d/lwpstatus", getpid(), 29236285Sbrian *lwp); 29336285Sbrian if ((lwpfd = ::open(lwpstatusfile, O_RDONLY)) < 0) { 29436285Sbrian perror("thr_mutator_status: open lwpstatus"); 29536285Sbrian return (EINVAL); 29636285Sbrian } 2976059Samurai if (pread(lwpfd, lwpstatus, sizeof (lwpstatus_t), (off_t)0) != 29836285Sbrian sizeof (lwpstatus_t)) { 29936285Sbrian perror("thr_mutator_status: read lwpstatus"); 3006059Samurai (void) ::close(lwpfd); 3016059Samurai return (EINVAL); 3026059Samurai } 30336285Sbrian (void) ::close(lwpfd); 3046059Samurai } 30536285Sbrian return (0); 30636285Sbrian} 30711336Samurai 30836285Sbrian 30936285Sbrianbool os::is_allocatable(size_t bytes) { 31036285Sbrian#ifdef _LP64 3116059Samurai return true; 31226516Sbrian#else 31336285Sbrian return (bytes <= (size_t)3835*M); 31436285Sbrian#endif 31536285Sbrian} 31632711Sbrian 31736285Sbrianextern "C" void Fetch32PFI () ; 31836285Sbrianextern "C" void Fetch32Resume () ; 31936285Sbrianextern "C" void FetchNPFI () ; 32036285Sbrianextern "C" void FetchNResume () ; 32136285Sbrian 32231121Sbrianextern "C" JNIEXPORT int 32336285SbrianJVM_handle_solaris_signal(int sig, siginfo_t* info, void* ucVoid, 32436285Sbrian int abort_if_unrecognized) { 32536285Sbrian ucontext_t* uc = (ucontext_t*) ucVoid; 32698243Sbrian 32736285Sbrian Thread* t = ThreadLocalStorage::get_thread_slow(); 32836285Sbrian 32936285Sbrian SignalHandlerMark shm(t); 33036285Sbrian 33185991Sbrian if(sig == SIGPIPE || sig == SIGXFSZ) { 33236285Sbrian if (os::Solaris::chained_handler(sig, info, ucVoid)) { 33336285Sbrian return true; 33440797Sbrian } else { 33540797Sbrian if (PrintMiscellaneous && (WizardMode || Verbose)) { 33636285Sbrian char buf[64]; 33740797Sbrian warning("Ignoring %s - see 4229104 or 6499219", 33836285Sbrian os::exception_name(sig, buf, sizeof(buf))); 33940797Sbrian 34040797Sbrian } 34140797Sbrian return true; 34240797Sbrian } 34340797Sbrian } 34440797Sbrian 34540797Sbrian JavaThread* thread = NULL; 34640797Sbrian VMThread* vmthread = NULL; 34740797Sbrian if (os::Solaris::signal_handlers_are_installed) { 34840797Sbrian if (t != NULL ){ 34940797Sbrian if(t->is_Java_thread()) { 35040797Sbrian thread = (JavaThread*)t; 35140797Sbrian } 35240797Sbrian else if(t->is_VM_thread()){ 35336285Sbrian vmthread = (VMThread *)t; 35436285Sbrian } 35540797Sbrian } 35640797Sbrian } 35740797Sbrian 35836285Sbrian guarantee(sig != os::Solaris::SIGinterrupt(), "Can not chain VM interrupt signal, try -XX:+UseAltSigs"); 35940797Sbrian 36026516Sbrian if (sig == os::Solaris::SIGasync()) { 3616059Samurai if (thread) { 3626059Samurai OSThread::InterruptArguments args(thread, uc); 36385991Sbrian thread->osthread()->do_interrupt_callbacks_at_interrupt(&args); 36485991Sbrian return true; 36585991Sbrian } else if (vmthread) { 36685991Sbrian OSThread::InterruptArguments args(vmthread, uc); 36785991Sbrian vmthread->osthread()->do_interrupt_callbacks_at_interrupt(&args); 36885991Sbrian return true; 36985991Sbrian } else if (os::Solaris::chained_handler(sig, info, ucVoid)) { 37085991Sbrian return true; 37185991Sbrian } else { 372134789Sbrian // If os::Solaris::SIGasync not chained, and this is a non-vm and 37385991Sbrian // non-java thread 37485991Sbrian return true; 37585991Sbrian } 37686760Sbrian } 37785991Sbrian 37885991Sbrian if (info == NULL || info->si_code <= 0 || info->si_code == SI_NOINFO) { 37985991Sbrian // can't decode this kind of signal 38085991Sbrian info = NULL; 38185991Sbrian } else { 38285991Sbrian assert(sig == info->si_signo, "bad siginfo"); 38385991Sbrian } 38485991Sbrian 38585991Sbrian // decide if this trap can be handled by a stub 38685991Sbrian address stub = NULL; 387134789Sbrian 38836285Sbrian address pc = NULL; 38985991Sbrian address npc = NULL; 39036285Sbrian 39136285Sbrian //%note os_trap_1 39236285Sbrian if (info != NULL && uc != NULL && thread != NULL) { 39310528Samurai // factor me: getPCfromContext 39436285Sbrian pc = (address) uc->uc_mcontext.gregs[REG_PC]; 39528536Sbrian npc = (address) uc->uc_mcontext.gregs[REG_nPC]; 39636285Sbrian 39736285Sbrian // SafeFetch() support 39836465Sbrian // Implemented with either a fixed set of addresses such 39936465Sbrian // as Fetch32*, or with Thread._OnTrap. 40036928Sbrian if (uc->uc_mcontext.gregs[REG_PC] == intptr_t(Fetch32PFI)) { 40136285Sbrian uc->uc_mcontext.gregs [REG_PC] = intptr_t(Fetch32Resume) ; 40236285Sbrian uc->uc_mcontext.gregs [REG_nPC] = intptr_t(Fetch32Resume) + 4 ; 40336285Sbrian return true ; 40434536Sbrian } 40536285Sbrian if (uc->uc_mcontext.gregs[REG_PC] == intptr_t(FetchNPFI)) { 40636285Sbrian uc->uc_mcontext.gregs [REG_PC] = intptr_t(FetchNResume) ; 40736285Sbrian uc->uc_mcontext.gregs [REG_nPC] = intptr_t(FetchNResume) + 4 ; 40836285Sbrian return true ; 40937993Sbrian } 41036285Sbrian 41136285Sbrian // Handle ALL stack overflow variations here 41228536Sbrian if (sig == SIGSEGV && info->si_code == SEGV_ACCERR) { 41328536Sbrian address addr = (address) info->si_addr; 41438628Sbrian if (thread->in_stack_yellow_zone(addr)) { 41538628Sbrian thread->disable_stack_yellow_zone(); 41638628Sbrian // Sometimes the register windows are not properly flushed. 41738628Sbrian if(uc->uc_mcontext.gwins != NULL) { 41838628Sbrian ::handle_unflushed_register_windows(uc->uc_mcontext.gwins); 419249582Sgabor } 42038628Sbrian if (thread->thread_state() == _thread_in_Java) { 42138628Sbrian // Throw a stack overflow exception. Guard pages will be reenabled 42238628Sbrian // while unwinding the stack. 42338628Sbrian stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::STACK_OVERFLOW); 42438628Sbrian } else { 42538628Sbrian // Thread was in the vm or native code. Return and try to finish. 42638628Sbrian return true; 42747865Sbrian } 42847865Sbrian } else if (thread->in_stack_red_zone(addr)) { 42947865Sbrian // Fatal red zone violation. Disable the guard pages and fall through 43047865Sbrian // to handle_unexpected_exception way down below. 43147865Sbrian thread->disable_stack_red_zone(); 43238628Sbrian tty->print_raw_cr("An irrecoverable stack overflow has occurred."); 43338628Sbrian // Sometimes the register windows are not properly flushed. 43438628Sbrian if(uc->uc_mcontext.gwins != NULL) { 43538628Sbrian ::handle_unflushed_register_windows(uc->uc_mcontext.gwins); 43638628Sbrian } 43738628Sbrian } 43838628Sbrian } 43938628Sbrian 44038628Sbrian 44138628Sbrian if (thread->thread_state() == _thread_in_vm) { 44238628Sbrian if (sig == SIGBUS && info->si_code == BUS_OBJERR && thread->doing_unsafe_access()) { 44338628Sbrian stub = StubRoutines::handler_for_unsafe_access(); 44438628Sbrian } 44538628Sbrian } 44638628Sbrian 44738628Sbrian else if (thread->thread_state() == _thread_in_Java) { 44838628Sbrian // Java thread running in Java code => find exception handler if any 44938628Sbrian // a fault inside compiled code, the interpreter, or a stub 45038628Sbrian 45138628Sbrian // Support Safepoint Polling 45238628Sbrian if ( sig == SIGSEGV && (address)info->si_addr == os::get_polling_page() ) { 45338628Sbrian stub = SharedRuntime::get_poll_stub(pc); 45438628Sbrian } 45538628Sbrian 45638628Sbrian // Not needed on x86 solaris because verify_oops doesn't generate 45738628Sbrian // SEGV/BUS like sparc does. 45838628Sbrian if ( (sig == SIGSEGV || sig == SIGBUS) 45938628Sbrian && pc >= MacroAssembler::_verify_oop_implicit_branch[0] 46038628Sbrian && pc < MacroAssembler::_verify_oop_implicit_branch[1] ) { 46138628Sbrian stub = MacroAssembler::_verify_oop_implicit_branch[2]; 462141504Sbrian warning("fixed up memory fault in +VerifyOops at address " INTPTR_FORMAT, info->si_addr); 46338628Sbrian } 46438628Sbrian 46538628Sbrian // This is not factored because on x86 solaris the patching for 46638628Sbrian // zombies does not generate a SEGV. 46738628Sbrian else if (sig == SIGSEGV && nativeInstruction_at(pc)->is_zombie()) { 46838628Sbrian // zombie method (ld [%g0],%o7 instruction) 46994934Sbrian stub = SharedRuntime::get_handle_wrong_method_stub(); 47094934Sbrian 47194934Sbrian // At the stub it needs to look like a call from the caller of this 47294934Sbrian // method (not a call from the segv site). 47394934Sbrian pc = (address)uc->uc_mcontext.gregs[REG_O7]; 47494934Sbrian } 47594934Sbrian else if (sig == SIGBUS && info->si_code == BUS_OBJERR) { 47697360Sbrian // BugId 4454115: A read from a MappedByteBuffer can fault 47794934Sbrian // here if the underlying file has been truncated. 47897360Sbrian // Do not crash the VM in such a case. 47994934Sbrian CodeBlob* cb = CodeCache::find_blob_unsafe(pc); 48097360Sbrian nmethod* nm = cb->is_nmethod() ? (nmethod*)cb : NULL; 48194934Sbrian if (nm != NULL && nm->has_unsafe_access()) { 48294934Sbrian stub = StubRoutines::handler_for_unsafe_access(); 48394934Sbrian } 48494934Sbrian } 48594934Sbrian 48694934Sbrian else if (sig == SIGFPE && info->si_code == FPE_INTDIV) { 48794934Sbrian // integer divide by zero 48894934Sbrian stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::IMPLICIT_DIVIDE_BY_ZERO); 48994934Sbrian } 49094934Sbrian else if (sig == SIGFPE && info->si_code == FPE_FLTDIV) { 49194934Sbrian // floating-point divide by zero 49294934Sbrian stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::IMPLICIT_DIVIDE_BY_ZERO); 49394934Sbrian } 49494934Sbrian#ifdef COMPILER2 49594934Sbrian else if (sig == SIGILL && nativeInstruction_at(pc)->is_ic_miss_trap()) { 49694934Sbrian#ifdef ASSERT 49794934Sbrian #ifdef TIERED 49894934Sbrian CodeBlob* cb = CodeCache::find_blob_unsafe(pc); 49994934Sbrian assert(cb->is_compiled_by_c2(), "Wrong compiler"); 50094934Sbrian #endif // TIERED 50194934Sbrian#endif // ASSERT 502116622Sume // Inline cache missed and user trap "Tne G0+ST_RESERVED_FOR_USER_0+2" taken. 503116622Sume stub = SharedRuntime::get_ic_miss_stub(); 504116622Sume // At the stub it needs to look like a call from the caller of this 505116622Sume // method (not a call from the segv site). 506116622Sume pc = (address)uc->uc_mcontext.gregs[REG_O7]; 507116622Sume } 508116622Sume#endif // COMPILER2 509116622Sume 510116622Sume else if (sig == SIGSEGV && info->si_code > 0 && !MacroAssembler::needs_explicit_null_check((intptr_t)info->si_addr)) { 511116622Sume // Determination of interpreter/vtable stub/compiled code null exception 512116622Sume stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::IMPLICIT_NULL); 513116622Sume } 514116622Sume } 515116622Sume 516116622Sume // jni_fast_Get<Primitive>Field can trap at certain pc's if a GC kicks in 51794934Sbrian // and the heap gets shrunk before the field access. 518116622Sume if ((sig == SIGSEGV) || (sig == SIGBUS)) { 51994934Sbrian address addr = JNI_FastGetField::find_slowcase_pc(pc); 52043888Sbrian if (addr != (address)-1) { 52143888Sbrian stub = addr; 52247849Sbrian } 52338628Sbrian } 52485991Sbrian 52594934Sbrian // Check to see if we caught the safepoint code in the 52694934Sbrian // process of write protecting the memory serialization page. 52738628Sbrian // It write enables the page immediately after protecting it 52841755Sbrian // so just return. 52941755Sbrian if ((sig == SIGSEGV) && 53041755Sbrian os::is_memory_serialize_page(thread, (address)info->si_addr)) { 53141755Sbrian // Block current thread until the memory serialize page permission restored. 53241755Sbrian os::block_on_serialize_page_trap(); 53341755Sbrian return true; 53494934Sbrian } 53594934Sbrian } 53694934Sbrian 53794934Sbrian if (stub != NULL) { 53894934Sbrian // save all thread context in case we need to restore it 53994934Sbrian 54094934Sbrian thread->set_saved_exception_pc(pc); 54194934Sbrian thread->set_saved_exception_npc(npc); 54294934Sbrian 54394934Sbrian // simulate a branch to the stub (a "call" in the safepoint stub case) 54494934Sbrian // factor me: setPC 54594934Sbrian uc->uc_mcontext.gregs[REG_PC ] = (greg_t)stub; 54694934Sbrian uc->uc_mcontext.gregs[REG_nPC] = (greg_t)(stub + 4); 54794934Sbrian 54894934Sbrian#ifndef PRODUCT 54941755Sbrian if (TraceJumps) thread->record_jump(stub, NULL, __FILE__, __LINE__); 55038629Sbrian#endif /* PRODUCT */ 55194934Sbrian 55294934Sbrian return true; 55394934Sbrian } 55498243Sbrian 55594934Sbrian // signal-chaining 55694934Sbrian if (os::Solaris::chained_handler(sig, info, ucVoid)) { 55794934Sbrian return true; 55894934Sbrian } 55981634Sbrian 56094934Sbrian if (!abort_if_unrecognized) { 56181634Sbrian // caller wants another chance, so give it to him 56240561Sbrian return false; 56394934Sbrian } 56494934Sbrian 56598243Sbrian if (!os::Solaris::libjsig_is_loaded) { 56694934Sbrian struct sigaction oldAct; 56798243Sbrian sigaction(sig, (struct sigaction *)0, &oldAct); 56894934Sbrian if (oldAct.sa_sigaction != signalHandler) { 56998243Sbrian void* sighand = oldAct.sa_sigaction ? CAST_FROM_FN_PTR(void*, oldAct.sa_sigaction) 57094934Sbrian : CAST_FROM_FN_PTR(void*, oldAct.sa_handler); 57181634Sbrian warning("Unexpected Signal %d occurred under user-defined signal handler " INTPTR_FORMAT, sig, (intptr_t)sighand); 57298243Sbrian } 57394934Sbrian } 57498243Sbrian 57594934Sbrian if (pc == NULL && uc != NULL) { 57698243Sbrian pc = (address) uc->uc_mcontext.gregs[REG_PC]; 57794934Sbrian } 57898243Sbrian 57994934Sbrian // Sometimes the register windows are not properly flushed. 58081634Sbrian if(uc->uc_mcontext.gwins != NULL) { 58194934Sbrian ::handle_unflushed_register_windows(uc->uc_mcontext.gwins); 58294934Sbrian } 58394934Sbrian 58494934Sbrian // unmask current signal 585116622Sume sigset_t newset; 586116622Sume sigemptyset(&newset); 587116622Sume sigaddset(&newset, sig); 58894934Sbrian sigprocmask(SIG_UNBLOCK, &newset, NULL); 589116622Sume 59094934Sbrian // Determine which sort of error to throw. Out of swap may signal 59194934Sbrian // on the thread stack, which could get a mapping error when touched. 59294934Sbrian address addr = (address) info->si_addr; 59394934Sbrian if (sig == SIGBUS && info->si_code == BUS_OBJERR && info->si_errno == ENOMEM) { 59438629Sbrian vm_exit_out_of_memory(0, OOM_MMAP_ERROR, "Out of swap space to map in thread stack."); 59538629Sbrian } 59638629Sbrian 59738629Sbrian VMError err(t, sig, pc, info, ucVoid); 59897360Sbrian err.report_and_die(); 59994934Sbrian 60097360Sbrian ShouldNotReachHere(); 60194934Sbrian} 60294934Sbrian 60394934Sbrianvoid os::print_context(outputStream *st, void *context) { 60494934Sbrian if (context == NULL) return; 60563484Sbrian 60638628Sbrian ucontext_t *uc = (ucontext_t*)context; 60738628Sbrian st->print_cr("Registers:"); 60838628Sbrian 60938628Sbrian st->print_cr(" G1=" INTPTR_FORMAT " G2=" INTPTR_FORMAT 61085991Sbrian " G3=" INTPTR_FORMAT " G4=" INTPTR_FORMAT, 61185991Sbrian uc->uc_mcontext.gregs[REG_G1], 61285991Sbrian uc->uc_mcontext.gregs[REG_G2], 61385991Sbrian uc->uc_mcontext.gregs[REG_G3], 61485991Sbrian uc->uc_mcontext.gregs[REG_G4]); 61585991Sbrian st->print_cr(" G5=" INTPTR_FORMAT " G6=" INTPTR_FORMAT 61685991Sbrian " G7=" INTPTR_FORMAT " Y=" INTPTR_FORMAT, 61785991Sbrian uc->uc_mcontext.gregs[REG_G5], 61885991Sbrian uc->uc_mcontext.gregs[REG_G6], 61985991Sbrian uc->uc_mcontext.gregs[REG_G7], 62028536Sbrian uc->uc_mcontext.gregs[REG_Y]); 62131343Sbrian st->print_cr(" O0=" INTPTR_FORMAT " O1=" INTPTR_FORMAT 62210528Samurai " O2=" INTPTR_FORMAT " O3=" INTPTR_FORMAT, 62310528Samurai uc->uc_mcontext.gregs[REG_O0], 62447849Sbrian uc->uc_mcontext.gregs[REG_O1], 62520813Sjkh uc->uc_mcontext.gregs[REG_O2], 62618856Ssos uc->uc_mcontext.gregs[REG_O3]); 62726911Sbrian st->print_cr(" O4=" INTPTR_FORMAT " O5=" INTPTR_FORMAT 62836285Sbrian " O6=" INTPTR_FORMAT " O7=" INTPTR_FORMAT, 62936285Sbrian uc->uc_mcontext.gregs[REG_O4], 63026516Sbrian uc->uc_mcontext.gregs[REG_O5], 63110528Samurai uc->uc_mcontext.gregs[REG_O6], 63226911Sbrian uc->uc_mcontext.gregs[REG_O7]); 63328679Sbrian 63436285Sbrian 63536285Sbrian intptr_t *sp = (intptr_t *)os::Solaris::ucontext_get_sp(uc); 63636285Sbrian st->print_cr(" L0=" INTPTR_FORMAT " L1=" INTPTR_FORMAT 63736285Sbrian " L2=" INTPTR_FORMAT " L3=" INTPTR_FORMAT, 63828381Sbrian sp[L0->sp_offset_in_saved_window()], 63936285Sbrian sp[L1->sp_offset_in_saved_window()], 64036285Sbrian sp[L2->sp_offset_in_saved_window()], 64136285Sbrian sp[L3->sp_offset_in_saved_window()]); 64236285Sbrian st->print_cr(" L4=" INTPTR_FORMAT " L5=" INTPTR_FORMAT 64328381Sbrian " L6=" INTPTR_FORMAT " L7=" INTPTR_FORMAT, 64436285Sbrian sp[L4->sp_offset_in_saved_window()], 64528679Sbrian sp[L5->sp_offset_in_saved_window()], 64628381Sbrian sp[L6->sp_offset_in_saved_window()], 64728381Sbrian sp[L7->sp_offset_in_saved_window()]); 64834536Sbrian st->print_cr(" I0=" INTPTR_FORMAT " I1=" INTPTR_FORMAT 64934536Sbrian " I2=" INTPTR_FORMAT " I3=" INTPTR_FORMAT, 65047849Sbrian sp[I0->sp_offset_in_saved_window()], 65128679Sbrian sp[I1->sp_offset_in_saved_window()], 65236285Sbrian sp[I2->sp_offset_in_saved_window()], 65318531Sbde sp[I3->sp_offset_in_saved_window()]); 65436285Sbrian st->print_cr(" I4=" INTPTR_FORMAT " I5=" INTPTR_FORMAT 65536285Sbrian " I6=" INTPTR_FORMAT " I7=" INTPTR_FORMAT, 65632017Sbrian sp[I4->sp_offset_in_saved_window()], 65736285Sbrian sp[I5->sp_offset_in_saved_window()], 65836285Sbrian sp[I6->sp_offset_in_saved_window()], 65936285Sbrian sp[I7->sp_offset_in_saved_window()]); 66036285Sbrian 66136285Sbrian st->print_cr(" PC=" INTPTR_FORMAT " nPC=" INTPTR_FORMAT, 66236285Sbrian uc->uc_mcontext.gregs[REG_PC], 66336285Sbrian uc->uc_mcontext.gregs[REG_nPC]); 66428679Sbrian st->cr(); 66528679Sbrian st->cr(); 66649976Sbrian 66749976Sbrian st->print_cr("Top of Stack: (sp=" PTR_FORMAT ")", sp); 66849976Sbrian print_hex_dump(st, (address)sp, (address)(sp + 32), sizeof(intptr_t)); 66949976Sbrian st->cr(); 67049976Sbrian 67126516Sbrian // Note: it may be unsafe to inspect memory near pc. For example, pc may 67264802Sbrian // point to garbage if entry point in an nmethod is corrupted. Leave 67355252Sbrian // this at the end, and hope for the best. 67464802Sbrian ExtendedPC epc = os::Solaris::ucontext_get_ExtendedPC(uc); 67536285Sbrian address pc = epc.pc(); 67628679Sbrian st->print_cr("Instructions: (pc=" PTR_FORMAT ")", pc); 67738628Sbrian print_hex_dump(st, pc - 32, pc + 32, sizeof(char)); 67838628Sbrian} 67938628Sbrian 680134789Sbrianvoid os::print_register_info(outputStream *st, void *context) { 68138628Sbrian if (context == NULL) return; 68238628Sbrian 68331343Sbrian ucontext_t *uc = (ucontext_t*)context; 68447849Sbrian intptr_t *sp = (intptr_t *)os::Solaris::ucontext_get_sp(uc); 68528679Sbrian 68628679Sbrian st->print_cr("Register to memory mapping:"); 68710528Samurai st->cr(); 68828679Sbrian 68928679Sbrian // this is only for the "general purpose" registers 69097360Sbrian st->print("G1="); print_location(st, uc->uc_mcontext.gregs[REG_G1]); 69128679Sbrian st->print("G2="); print_location(st, uc->uc_mcontext.gregs[REG_G2]); 69228679Sbrian st->print("G3="); print_location(st, uc->uc_mcontext.gregs[REG_G3]); 69336285Sbrian st->print("G4="); print_location(st, uc->uc_mcontext.gregs[REG_G4]); 69436285Sbrian st->print("G5="); print_location(st, uc->uc_mcontext.gregs[REG_G5]); 69531343Sbrian st->print("G6="); print_location(st, uc->uc_mcontext.gregs[REG_G6]); 69630316Sbrian st->print("G7="); print_location(st, uc->uc_mcontext.gregs[REG_G7]); 69736285Sbrian st->cr(); 69832017Sbrian 69936285Sbrian st->print("O0="); print_location(st, uc->uc_mcontext.gregs[REG_O0]); 70079450Sbrian st->print("O1="); print_location(st, uc->uc_mcontext.gregs[REG_O1]); 70130316Sbrian st->print("O2="); print_location(st, uc->uc_mcontext.gregs[REG_O2]); 70220813Sjkh st->print("O3="); print_location(st, uc->uc_mcontext.gregs[REG_O3]); 70340665Sbrian st->print("O4="); print_location(st, uc->uc_mcontext.gregs[REG_O4]); 70440665Sbrian st->print("O5="); print_location(st, uc->uc_mcontext.gregs[REG_O5]); 70540665Sbrian st->print("O6="); print_location(st, uc->uc_mcontext.gregs[REG_O6]); 70649976Sbrian st->print("O7="); print_location(st, uc->uc_mcontext.gregs[REG_O7]); 70710528Samurai st->cr(); 70836285Sbrian 70997360Sbrian st->print("L0="); print_location(st, sp[L0->sp_offset_in_saved_window()]); 71036285Sbrian st->print("L1="); print_location(st, sp[L1->sp_offset_in_saved_window()]); 71136285Sbrian st->print("L2="); print_location(st, sp[L2->sp_offset_in_saved_window()]); 71210528Samurai st->print("L3="); print_location(st, sp[L3->sp_offset_in_saved_window()]); 71331343Sbrian st->print("L4="); print_location(st, sp[L4->sp_offset_in_saved_window()]); 71410528Samurai st->print("L5="); print_location(st, sp[L5->sp_offset_in_saved_window()]); 71520813Sjkh st->print("L6="); print_location(st, sp[L6->sp_offset_in_saved_window()]); 71636285Sbrian st->print("L7="); print_location(st, sp[L7->sp_offset_in_saved_window()]); 71736285Sbrian st->cr(); 71820813Sjkh 71936285Sbrian st->print("I0="); print_location(st, sp[I0->sp_offset_in_saved_window()]); 72010528Samurai st->print("I1="); print_location(st, sp[I1->sp_offset_in_saved_window()]); 72110528Samurai st->print("I2="); print_location(st, sp[I2->sp_offset_in_saved_window()]); 72231343Sbrian st->print("I3="); print_location(st, sp[I3->sp_offset_in_saved_window()]); 72331343Sbrian st->print("I4="); print_location(st, sp[I4->sp_offset_in_saved_window()]); 72431343Sbrian st->print("I5="); print_location(st, sp[I5->sp_offset_in_saved_window()]); 72536285Sbrian st->print("I6="); print_location(st, sp[I6->sp_offset_in_saved_window()]); 72631343Sbrian st->print("I7="); print_location(st, sp[I7->sp_offset_in_saved_window()]); 72731343Sbrian st->cr(); 72831343Sbrian} 72931343Sbrian 73031343Sbrianvoid os::Solaris::init_thread_fpu_state(void) { 73131343Sbrian // Nothing needed on Sparc. 73231343Sbrian} 73331343Sbrian 73431343Sbrian#if !defined(COMPILER2) && !defined(_LP64) 73531343Sbrian 73658044Sbrian// These routines are the initial value of atomic_xchg_entry(), 73758044Sbrian// atomic_cmpxchg_entry(), atomic_add_entry() and fence_entry() 73858044Sbrian// until initialization is complete. 73958044Sbrian// TODO - remove when the VM drops support for V8. 74058044Sbrian 74158044Sbriantypedef jint xchg_func_t (jint, volatile jint*); 74258044Sbriantypedef jint cmpxchg_func_t (jint, volatile jint*, jint); 74358044Sbriantypedef jlong cmpxchg_long_func_t(jlong, volatile jlong*, jlong); 74458044Sbriantypedef jint add_func_t (jint, volatile jint*); 74558044Sbrian 74658044Sbrianjint os::atomic_xchg_bootstrap(jint exchange_value, volatile jint* dest) { 74758044Sbrian // try to use the stub: 74858044Sbrian xchg_func_t* func = CAST_TO_FN_PTR(xchg_func_t*, StubRoutines::atomic_xchg_entry()); 74958044Sbrian 75058044Sbrian if (func != NULL) { 75158044Sbrian os::atomic_xchg_func = func; 75258044Sbrian return (*func)(exchange_value, dest); 75358044Sbrian } 75458044Sbrian assert(Threads::number_of_threads() == 0, "for bootstrap only"); 75558044Sbrian 75658044Sbrian jint old_value = *dest; 75758044Sbrian *dest = exchange_value; 75858044Sbrian return old_value; 75950059Sbrian} 76058867Sbrian 76140561Sbrianjint os::atomic_cmpxchg_bootstrap(jint exchange_value, volatile jint* dest, jint compare_value) { 76250059Sbrian // try to use the stub: 763134789Sbrian cmpxchg_func_t* func = CAST_TO_FN_PTR(cmpxchg_func_t*, StubRoutines::atomic_cmpxchg_entry()); 76458867Sbrian 76550059Sbrian if (func != NULL) { 76640561Sbrian os::atomic_cmpxchg_func = func; 76758867Sbrian return (*func)(exchange_value, dest, compare_value); 768134789Sbrian } 76958867Sbrian assert(Threads::number_of_threads() == 0, "for bootstrap only"); 77050059Sbrian 77140561Sbrian jint old_value = *dest; 77250059Sbrian if (old_value == compare_value) 773134789Sbrian *dest = exchange_value; 77479433Sbrian return old_value; 775134789Sbrian} 77650059Sbrian 777134789Sbrianjlong os::atomic_cmpxchg_long_bootstrap(jlong exchange_value, volatile jlong* dest, jlong compare_value) { 77881033Sbrian // try to use the stub: 77981033Sbrian cmpxchg_long_func_t* func = CAST_TO_FN_PTR(cmpxchg_long_func_t*, StubRoutines::atomic_cmpxchg_long_entry()); 780134789Sbrian 78181033Sbrian if (func != NULL) { 782120372Smarcus os::atomic_cmpxchg_long_func = func; 783134789Sbrian return (*func)(exchange_value, dest, compare_value); 78458867Sbrian } 78550059Sbrian assert(Threads::number_of_threads() == 0, "for bootstrap only"); 78640561Sbrian 78758867Sbrian jlong old_value = *dest; 788134789Sbrian if (old_value == compare_value) 78958867Sbrian *dest = exchange_value; 79050059Sbrian return old_value; 79150059Sbrian} 79240561Sbrian 79358867Sbrianjint os::atomic_add_bootstrap(jint add_value, volatile jint* dest) { 79450059Sbrian // try to use the stub: 79540561Sbrian add_func_t* func = CAST_TO_FN_PTR(add_func_t*, StubRoutines::atomic_add_entry()); 79640561Sbrian 79758867Sbrian if (func != NULL) { 798134789Sbrian os::atomic_add_func = func; 79940561Sbrian return (*func)(add_value, dest); 80040561Sbrian } 80140561Sbrian assert(Threads::number_of_threads() == 0, "for bootstrap only"); 80240561Sbrian 80340561Sbrian return (*dest) += add_value; 804134789Sbrian} 80540561Sbrian 806134789Sbrianxchg_func_t* os::atomic_xchg_func = os::atomic_xchg_bootstrap; 80740561Sbriancmpxchg_func_t* os::atomic_cmpxchg_func = os::atomic_cmpxchg_bootstrap; 80840561Sbriancmpxchg_long_func_t* os::atomic_cmpxchg_long_func = os::atomic_cmpxchg_long_bootstrap; 809134789Sbrianadd_func_t* os::atomic_add_func = os::atomic_add_bootstrap; 81040561Sbrian 81140561Sbrian#endif // !_LP64 && !COMPILER2 81240561Sbrian 81340561Sbrian#if defined(__sparc) && defined(COMPILER2) && defined(_GNU_SOURCE) 81440561Sbrian // See file build/solaris/makefiles/$compiler.make 81540561Sbrian // For compiler1 the architecture is v8 and frps isn't present in v8 81640561Sbrian extern "C" void _mark_fpu_nosave() { 81740561Sbrian __asm__ __volatile__ ("wr %%g0, 0, %%fprs \n\t" : : :); 81840561Sbrian } 81940561Sbrian#endif //defined(__sparc) && defined(COMPILER2) 820134789Sbrian 82140561Sbrian#ifndef PRODUCT 82240561Sbrianvoid os::verify_stack_alignment() { 82340561Sbrian} 82440561Sbrian#endif 82540561Sbrian