< prev index next >

src/os_cpu/linux_ppc/vm/os_linux_ppc.cpp

Print this page
rev 7905 : 8074552:  SafeFetch32 and SafeFetchN do not work in error handling
Summary: handle SafeFetch faults in secondary signal handlers
Contributed-by: Thomas Stuefe

*** 111,120 **** --- 111,128 ---- // Hopefully it was zero'd out beforehand. guarantee(uc->uc_mcontext.regs != NULL, "only use ucontext_get_pc in sigaction context"); return (address)uc->uc_mcontext.regs->nip; } + // modify PC in ucontext. + // Note: Only use this for an ucontext handed down to a signal handler. See comment + // in ucontext_get_pc. + void os::Linux::ucontext_set_pc(ucontext_t * uc, address pc) { + guarantee(uc->uc_mcontext.regs != NULL, "only use ucontext_set_pc in sigaction context"); + uc->uc_mcontext.regs->nip = (unsigned long)pc; + } + intptr_t* os::Linux::ucontext_get_sp(ucontext_t * uc) { return (intptr_t*)uc->uc_mcontext.regs->gpr[1/*REG_SP*/]; } intptr_t* os::Linux::ucontext_get_fp(ucontext_t * uc) {
*** 211,221 **** // Moved SafeFetch32 handling outside thread!=NULL conditional block to make // it work if no associated JavaThread object exists. if (uc) { address const pc = os::Linux::ucontext_get_pc(uc); if (pc && StubRoutines::is_safefetch_fault(pc)) { ! uc->uc_mcontext.regs->nip = (unsigned long)StubRoutines::continuation_for_safefetch_fault(pc); return true; } } // decide if this trap can be handled by a stub --- 219,229 ---- // Moved SafeFetch32 handling outside thread!=NULL conditional block to make // it work if no associated JavaThread object exists. if (uc) { address const pc = os::Linux::ucontext_get_pc(uc); if (pc && StubRoutines::is_safefetch_fault(pc)) { ! os::Linux::ucontext_set_pc(uc, StubRoutines::continuation_for_safefetch_fault(pc)); return true; } } // decide if this trap can be handled by a stub
*** 358,368 **** if (nm != NULL && nm->has_unsafe_access()) { // We don't really need a stub here! Just set the pending exeption and // continue at the next instruction after the faulting read. Returning // garbage from this read is ok. thread->set_pending_unsafe_access_error(); ! uc->uc_mcontext.regs->nip = ((unsigned long)pc) + 4; return true; } } } --- 366,376 ---- if (nm != NULL && nm->has_unsafe_access()) { // We don't really need a stub here! Just set the pending exeption and // continue at the next instruction after the faulting read. Returning // garbage from this read is ok. thread->set_pending_unsafe_access_error(); ! os::Linux::ucontext_set_pc(uc, pc + 4); return true; } } }
*** 377,387 **** sig == SIGBUS && thread->doing_unsafe_access()) { // We don't really need a stub here! Just set the pending exeption and // continue at the next instruction after the faulting read. Returning // garbage from this read is ok. thread->set_pending_unsafe_access_error(); ! uc->uc_mcontext.regs->nip = ((unsigned long)pc) + 4; return true; } } // Check to see if we caught the safepoint code in the --- 385,395 ---- sig == SIGBUS && thread->doing_unsafe_access()) { // We don't really need a stub here! Just set the pending exeption and // continue at the next instruction after the faulting read. Returning // garbage from this read is ok. thread->set_pending_unsafe_access_error(); ! os::Linux::ucontext_set_pc(uc, pc + 4); return true; } } // Check to see if we caught the safepoint code in the
*** 400,410 **** } if (stub != NULL) { // Save all thread context in case we need to restore it. if (thread != NULL) thread->set_saved_exception_pc(pc); ! uc->uc_mcontext.regs->nip = (unsigned long)stub; return true; } // signal-chaining if (os::Linux::chained_handler(sig, info, ucVoid)) { --- 408,418 ---- } if (stub != NULL) { // Save all thread context in case we need to restore it. if (thread != NULL) thread->set_saved_exception_pc(pc); ! os::Linux::ucontext_set_pc(uc, stub); return true; } // signal-chaining if (os::Linux::chained_handler(sig, info, ucVoid)) {
< prev index next >