263 #ifndef AARCH64
264 extern "C" address check_vfp_fault_instr;
265 extern "C" address check_vfp3_32_fault_instr;
266
267 address check_vfp_fault_instr = NULL;
268 address check_vfp3_32_fault_instr = NULL;
269 #endif // !AARCH64
270 extern "C" address check_simd_fault_instr;
271 address check_simd_fault_instr = NULL;
272
273 // Utility functions
274
275 extern "C" int JVM_handle_linux_signal(int sig, siginfo_t* info,
276 void* ucVoid, int abort_if_unrecognized) {
277 ucontext_t* uc = (ucontext_t*) ucVoid;
278
279 Thread* t = Thread::current_or_null_safe();
280
281 // Must do this before SignalHandlerMark, if crash protection installed we will longjmp away
282 // (no destructors can be run)
283 os::WatcherThreadCrashProtection::check_crash_protection(sig, t);
284
285 SignalHandlerMark shm(t);
286
287 if (sig == SIGILL &&
288 ((info->si_addr == (caddr_t)check_simd_fault_instr)
289 NOT_AARCH64(|| info->si_addr == (caddr_t)check_vfp_fault_instr)
290 NOT_AARCH64(|| info->si_addr == (caddr_t)check_vfp3_32_fault_instr))) {
291 // skip faulty instruction + instruction that sets return value to
292 // success and set return value to failure.
293 os::Linux::ucontext_set_pc(uc, (address)info->si_addr + 8);
294 uc->uc_mcontext.arm_r0 = 0;
295 return true;
296 }
297
298 // Note: it's not uncommon that JNI code uses signal/sigset to install
299 // then restore certain signal handler (e.g. to temporarily block SIGPIPE,
300 // or have a SIGILL handler when detecting CPU type). When that happens,
301 // JVM_handle_linux_signal() might be invoked with junk info/ucVoid. To
302 // avoid unnecessary crash when libjsig is not preloaded, try handle signals
303 // that do not require siginfo/ucontext first.
|
263 #ifndef AARCH64
264 extern "C" address check_vfp_fault_instr;
265 extern "C" address check_vfp3_32_fault_instr;
266
267 address check_vfp_fault_instr = NULL;
268 address check_vfp3_32_fault_instr = NULL;
269 #endif // !AARCH64
270 extern "C" address check_simd_fault_instr;
271 address check_simd_fault_instr = NULL;
272
273 // Utility functions
274
275 extern "C" int JVM_handle_linux_signal(int sig, siginfo_t* info,
276 void* ucVoid, int abort_if_unrecognized) {
277 ucontext_t* uc = (ucontext_t*) ucVoid;
278
279 Thread* t = Thread::current_or_null_safe();
280
281 // Must do this before SignalHandlerMark, if crash protection installed we will longjmp away
282 // (no destructors can be run)
283 os::ThreadCrashProtection::check_crash_protection(sig, t);
284
285 SignalHandlerMark shm(t);
286
287 if (sig == SIGILL &&
288 ((info->si_addr == (caddr_t)check_simd_fault_instr)
289 NOT_AARCH64(|| info->si_addr == (caddr_t)check_vfp_fault_instr)
290 NOT_AARCH64(|| info->si_addr == (caddr_t)check_vfp3_32_fault_instr))) {
291 // skip faulty instruction + instruction that sets return value to
292 // success and set return value to failure.
293 os::Linux::ucontext_set_pc(uc, (address)info->si_addr + 8);
294 uc->uc_mcontext.arm_r0 = 0;
295 return true;
296 }
297
298 // Note: it's not uncommon that JNI code uses signal/sigset to install
299 // then restore certain signal handler (e.g. to temporarily block SIGPIPE,
300 // or have a SIGILL handler when detecting CPU type). When that happens,
301 // JVM_handle_linux_signal() might be invoked with junk info/ucVoid. To
302 // avoid unnecessary crash when libjsig is not preloaded, try handle signals
303 // that do not require siginfo/ucontext first.
|