68 // those are to reference registers in sigcontext
69 enum {
70 CON_G0 = 0,
71 CON_G1,
72 CON_G2,
73 CON_G3,
74 CON_G4,
75 CON_G5,
76 CON_G6,
77 CON_G7,
78 CON_O0,
79 CON_O1,
80 CON_O2,
81 CON_O3,
82 CON_O4,
83 CON_O5,
84 CON_O6,
85 CON_O7,
86 };
87
88 static inline void set_cont_address(sigcontext* ctx, address addr) {
89 SIG_PC(ctx) = (intptr_t)addr;
90 SIG_NPC(ctx) = (intptr_t)(addr+4);
91 }
92
93 // For Forte Analyzer AsyncGetCallTrace profiling support - thread is
94 // currently interrupted by SIGPROF.
95 // os::Solaris::fetch_frame_from_ucontext() tries to skip nested
96 // signal frames. Currently we don't do that on Linux, so it's the
97 // same as os::fetch_frame_from_context().
98 ExtendedPC os::Linux::fetch_frame_from_ucontext(Thread* thread,
99 ucontext_t* uc,
100 intptr_t** ret_sp,
101 intptr_t** ret_fp) {
102 assert(thread != NULL, "just checking");
103 assert(ret_sp != NULL, "just checking");
104 assert(ret_fp != NULL, "just checking");
105
106 return os::fetch_frame_from_context(uc, ret_sp, ret_fp);
107 }
108
109 ExtendedPC os::fetch_frame_from_context(void* ucVoid,
110 intptr_t** ret_sp,
111 intptr_t** ret_fp) {
112 ucontext_t* uc = (ucontext_t*) ucVoid;
334 st->print("L6="); print_location(st, sp[L6->sp_offset_in_saved_window()]);
335 st->print("L7="); print_location(st, sp[L7->sp_offset_in_saved_window()]);
336 st->cr();
337
338 st->print("I0="); print_location(st, sp[I0->sp_offset_in_saved_window()]);
339 st->print("I1="); print_location(st, sp[I1->sp_offset_in_saved_window()]);
340 st->print("I2="); print_location(st, sp[I2->sp_offset_in_saved_window()]);
341 st->print("I3="); print_location(st, sp[I3->sp_offset_in_saved_window()]);
342 st->print("I4="); print_location(st, sp[I4->sp_offset_in_saved_window()]);
343 st->print("I5="); print_location(st, sp[I5->sp_offset_in_saved_window()]);
344 st->print("I6="); print_location(st, sp[I6->sp_offset_in_saved_window()]);
345 st->print("I7="); print_location(st, sp[I7->sp_offset_in_saved_window()]);
346 st->cr();
347 }
348
349
350 address os::Linux::ucontext_get_pc(ucontext_t* uc) {
351 return (address) SIG_PC((sigcontext*)uc);
352 }
353
354 intptr_t* os::Linux::ucontext_get_sp(ucontext_t *uc) {
355 return (intptr_t*)
356 ((intptr_t)SIG_REGS((sigcontext*)uc).u_regs[CON_O6] + STACK_BIAS);
357 }
358
359 // not used on Sparc
360 intptr_t* os::Linux::ucontext_get_fp(ucontext_t *uc) {
361 ShouldNotReachHere();
362 return NULL;
363 }
364
365 // Utility functions
366
367 inline static bool checkPrefetch(sigcontext* uc, address pc) {
368 if (StubRoutines::is_safefetch_fault(pc)) {
369 set_cont_address(uc, address(StubRoutines::continuation_for_safefetch_fault(pc)));
370 return true;
371 }
372 return false;
373 }
374
375 inline static bool checkOverflow(sigcontext* uc,
376 address pc,
377 address addr,
378 JavaThread* thread,
379 address* stub) {
380 // check if fault address is within thread stack
381 if (addr < thread->stack_base() &&
382 addr >= thread->stack_base() - thread->stack_size()) {
383 // stack overflow
384 if (thread->in_stack_yellow_zone(addr)) {
385 thread->disable_stack_yellow_zone();
386 if (thread->thread_state() == _thread_in_Java) {
387 // Throw a stack overflow exception. Guard pages will be reenabled
388 // while unwinding the stack.
389 *stub =
649 break;
650 }
651
652 if ((sig == SIGSEGV) &&
653 checkNullPointer(pc, (intptr_t)info->si_addr, thread, &stub)) {
654 break;
655 }
656 } while (0);
657
658 // jni_fast_Get<Primitive>Field can trap at certain pc's if a GC kicks in
659 // and the heap gets shrunk before the field access.
660 if ((sig == SIGSEGV) || (sig == SIGBUS)) {
661 checkFastJNIAccess(pc, &stub);
662 }
663 }
664
665 if (stub != NULL) {
666 // save all thread context in case we need to restore it
667 thread->set_saved_exception_pc(pc);
668 thread->set_saved_exception_npc(npc);
669 set_cont_address(uc, stub);
670 return true;
671 }
672 }
673
674 // signal-chaining
675 if (os::Linux::chained_handler(sig, info, ucVoid)) {
676 return true;
677 }
678
679 if (!abort_if_unrecognized) {
680 // caller wants another chance, so give it to him
681 return false;
682 }
683
684 if (pc == NULL && uc != NULL) {
685 pc = os::Linux::ucontext_get_pc((ucontext_t*)uc);
686 }
687
688 // unmask current signal
689 sigset_t newset;
|
68 // those are to reference registers in sigcontext
69 enum {
70 CON_G0 = 0,
71 CON_G1,
72 CON_G2,
73 CON_G3,
74 CON_G4,
75 CON_G5,
76 CON_G6,
77 CON_G7,
78 CON_O0,
79 CON_O1,
80 CON_O2,
81 CON_O3,
82 CON_O4,
83 CON_O5,
84 CON_O6,
85 CON_O7,
86 };
87
88 // For Forte Analyzer AsyncGetCallTrace profiling support - thread is
89 // currently interrupted by SIGPROF.
90 // os::Solaris::fetch_frame_from_ucontext() tries to skip nested
91 // signal frames. Currently we don't do that on Linux, so it's the
92 // same as os::fetch_frame_from_context().
93 ExtendedPC os::Linux::fetch_frame_from_ucontext(Thread* thread,
94 ucontext_t* uc,
95 intptr_t** ret_sp,
96 intptr_t** ret_fp) {
97 assert(thread != NULL, "just checking");
98 assert(ret_sp != NULL, "just checking");
99 assert(ret_fp != NULL, "just checking");
100
101 return os::fetch_frame_from_context(uc, ret_sp, ret_fp);
102 }
103
104 ExtendedPC os::fetch_frame_from_context(void* ucVoid,
105 intptr_t** ret_sp,
106 intptr_t** ret_fp) {
107 ucontext_t* uc = (ucontext_t*) ucVoid;
329 st->print("L6="); print_location(st, sp[L6->sp_offset_in_saved_window()]);
330 st->print("L7="); print_location(st, sp[L7->sp_offset_in_saved_window()]);
331 st->cr();
332
333 st->print("I0="); print_location(st, sp[I0->sp_offset_in_saved_window()]);
334 st->print("I1="); print_location(st, sp[I1->sp_offset_in_saved_window()]);
335 st->print("I2="); print_location(st, sp[I2->sp_offset_in_saved_window()]);
336 st->print("I3="); print_location(st, sp[I3->sp_offset_in_saved_window()]);
337 st->print("I4="); print_location(st, sp[I4->sp_offset_in_saved_window()]);
338 st->print("I5="); print_location(st, sp[I5->sp_offset_in_saved_window()]);
339 st->print("I6="); print_location(st, sp[I6->sp_offset_in_saved_window()]);
340 st->print("I7="); print_location(st, sp[I7->sp_offset_in_saved_window()]);
341 st->cr();
342 }
343
344
345 address os::Linux::ucontext_get_pc(ucontext_t* uc) {
346 return (address) SIG_PC((sigcontext*)uc);
347 }
348
349 void os::Linux::ucontext_set_pc(ucontext_t* uc, address pc) {
350 sigcontext_t* ctx = (sigcontext_t*) uc;
351 SIG_PC(ctx) = (intptr_t)addr;
352 SIG_NPC(ctx) = (intptr_t)(addr+4);
353 }
354
355 intptr_t* os::Linux::ucontext_get_sp(ucontext_t *uc) {
356 return (intptr_t*)
357 ((intptr_t)SIG_REGS((sigcontext*)uc).u_regs[CON_O6] + STACK_BIAS);
358 }
359
360 // not used on Sparc
361 intptr_t* os::Linux::ucontext_get_fp(ucontext_t *uc) {
362 ShouldNotReachHere();
363 return NULL;
364 }
365
366 // Utility functions
367
368 inline static bool checkPrefetch(sigcontext* uc, address pc) {
369 if (StubRoutines::is_safefetch_fault(pc)) {
370 os::Linux::ucontext_set_pc((ucontext_t*)uc, StubRoutines::continuation_for_safefetch_fault(pc));
371 return true;
372 }
373 return false;
374 }
375
376 inline static bool checkOverflow(sigcontext* uc,
377 address pc,
378 address addr,
379 JavaThread* thread,
380 address* stub) {
381 // check if fault address is within thread stack
382 if (addr < thread->stack_base() &&
383 addr >= thread->stack_base() - thread->stack_size()) {
384 // stack overflow
385 if (thread->in_stack_yellow_zone(addr)) {
386 thread->disable_stack_yellow_zone();
387 if (thread->thread_state() == _thread_in_Java) {
388 // Throw a stack overflow exception. Guard pages will be reenabled
389 // while unwinding the stack.
390 *stub =
650 break;
651 }
652
653 if ((sig == SIGSEGV) &&
654 checkNullPointer(pc, (intptr_t)info->si_addr, thread, &stub)) {
655 break;
656 }
657 } while (0);
658
659 // jni_fast_Get<Primitive>Field can trap at certain pc's if a GC kicks in
660 // and the heap gets shrunk before the field access.
661 if ((sig == SIGSEGV) || (sig == SIGBUS)) {
662 checkFastJNIAccess(pc, &stub);
663 }
664 }
665
666 if (stub != NULL) {
667 // save all thread context in case we need to restore it
668 thread->set_saved_exception_pc(pc);
669 thread->set_saved_exception_npc(npc);
670 os::Linux::ucontext_set_pc((ucontext_t*)uc, stub);
671 return true;
672 }
673 }
674
675 // signal-chaining
676 if (os::Linux::chained_handler(sig, info, ucVoid)) {
677 return true;
678 }
679
680 if (!abort_if_unrecognized) {
681 // caller wants another chance, so give it to him
682 return false;
683 }
684
685 if (pc == NULL && uc != NULL) {
686 pc = os::Linux::ucontext_get_pc((ucontext_t*)uc);
687 }
688
689 // unmask current signal
690 sigset_t newset;
|