< prev index next >

src/os_cpu/linux_ppc/vm/os_linux_ppc.cpp

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

@@ -111,10 +111,18 @@
   //   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,11 +219,11 @@
   // 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);
+      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,11 +366,11 @@
         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;
+          os::Linux::ucontext_set_pc(uc, pc + 4);
           return true;
         }
       }
     }
 

@@ -377,11 +385,11 @@
                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;
+        os::Linux::ucontext_set_pc(uc, pc + 4);
         return true;
       }
     }
 
     // Check to see if we caught the safepoint code in the

@@ -400,11 +408,11 @@
   }
 
   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;
+    os::Linux::ucontext_set_pc(uc, stub);
     return true;
   }
 
   // signal-chaining
   if (os::Linux::chained_handler(sig, info, ucVoid)) {
< prev index next >