equal
deleted
inserted
replaced
111 // Hopefully it was zero'd out beforehand. |
111 // Hopefully it was zero'd out beforehand. |
112 guarantee(uc->uc_mcontext.regs != NULL, "only use ucontext_get_pc in sigaction context"); |
112 guarantee(uc->uc_mcontext.regs != NULL, "only use ucontext_get_pc in sigaction context"); |
113 return (address)uc->uc_mcontext.regs->nip; |
113 return (address)uc->uc_mcontext.regs->nip; |
114 } |
114 } |
115 |
115 |
|
116 // modify PC in ucontext. |
|
117 // Note: Only use this for an ucontext handed down to a signal handler. See comment |
|
118 // in ucontext_get_pc. |
|
119 void os::Linux::ucontext_set_pc(ucontext_t * uc, address pc) { |
|
120 guarantee(uc->uc_mcontext.regs != NULL, "only use ucontext_set_pc in sigaction context"); |
|
121 uc->uc_mcontext.regs->nip = (unsigned long)pc; |
|
122 } |
|
123 |
116 intptr_t* os::Linux::ucontext_get_sp(ucontext_t * uc) { |
124 intptr_t* os::Linux::ucontext_get_sp(ucontext_t * uc) { |
117 return (intptr_t*)uc->uc_mcontext.regs->gpr[1/*REG_SP*/]; |
125 return (intptr_t*)uc->uc_mcontext.regs->gpr[1/*REG_SP*/]; |
118 } |
126 } |
119 |
127 |
120 intptr_t* os::Linux::ucontext_get_fp(ucontext_t * uc) { |
128 intptr_t* os::Linux::ucontext_get_fp(ucontext_t * uc) { |
211 // Moved SafeFetch32 handling outside thread!=NULL conditional block to make |
219 // Moved SafeFetch32 handling outside thread!=NULL conditional block to make |
212 // it work if no associated JavaThread object exists. |
220 // it work if no associated JavaThread object exists. |
213 if (uc) { |
221 if (uc) { |
214 address const pc = os::Linux::ucontext_get_pc(uc); |
222 address const pc = os::Linux::ucontext_get_pc(uc); |
215 if (pc && StubRoutines::is_safefetch_fault(pc)) { |
223 if (pc && StubRoutines::is_safefetch_fault(pc)) { |
216 uc->uc_mcontext.regs->nip = (unsigned long)StubRoutines::continuation_for_safefetch_fault(pc); |
224 os::Linux::ucontext_set_pc(uc, StubRoutines::continuation_for_safefetch_fault(pc)); |
217 return true; |
225 return true; |
218 } |
226 } |
219 } |
227 } |
220 |
228 |
221 // decide if this trap can be handled by a stub |
229 // decide if this trap can be handled by a stub |
358 if (nm != NULL && nm->has_unsafe_access()) { |
366 if (nm != NULL && nm->has_unsafe_access()) { |
359 // We don't really need a stub here! Just set the pending exeption and |
367 // We don't really need a stub here! Just set the pending exeption and |
360 // continue at the next instruction after the faulting read. Returning |
368 // continue at the next instruction after the faulting read. Returning |
361 // garbage from this read is ok. |
369 // garbage from this read is ok. |
362 thread->set_pending_unsafe_access_error(); |
370 thread->set_pending_unsafe_access_error(); |
363 uc->uc_mcontext.regs->nip = ((unsigned long)pc) + 4; |
371 os::Linux::ucontext_set_pc(uc, pc + 4); |
364 return true; |
372 return true; |
365 } |
373 } |
366 } |
374 } |
367 } |
375 } |
368 |
376 |
377 sig == SIGBUS && thread->doing_unsafe_access()) { |
385 sig == SIGBUS && thread->doing_unsafe_access()) { |
378 // We don't really need a stub here! Just set the pending exeption and |
386 // We don't really need a stub here! Just set the pending exeption and |
379 // continue at the next instruction after the faulting read. Returning |
387 // continue at the next instruction after the faulting read. Returning |
380 // garbage from this read is ok. |
388 // garbage from this read is ok. |
381 thread->set_pending_unsafe_access_error(); |
389 thread->set_pending_unsafe_access_error(); |
382 uc->uc_mcontext.regs->nip = ((unsigned long)pc) + 4; |
390 os::Linux::ucontext_set_pc(uc, pc + 4); |
383 return true; |
391 return true; |
384 } |
392 } |
385 } |
393 } |
386 |
394 |
387 // Check to see if we caught the safepoint code in the |
395 // Check to see if we caught the safepoint code in the |
400 } |
408 } |
401 |
409 |
402 if (stub != NULL) { |
410 if (stub != NULL) { |
403 // Save all thread context in case we need to restore it. |
411 // Save all thread context in case we need to restore it. |
404 if (thread != NULL) thread->set_saved_exception_pc(pc); |
412 if (thread != NULL) thread->set_saved_exception_pc(pc); |
405 uc->uc_mcontext.regs->nip = (unsigned long)stub; |
413 os::Linux::ucontext_set_pc(uc, stub); |
406 return true; |
414 return true; |
407 } |
415 } |
408 |
416 |
409 // signal-chaining |
417 // signal-chaining |
410 if (os::Linux::chained_handler(sig, info, ucVoid)) { |
418 if (os::Linux::chained_handler(sig, info, ucVoid)) { |