123 #else |
123 #else |
124 uc->uc_mcontext.pc = (intptr_t)pc; |
124 uc->uc_mcontext.pc = (intptr_t)pc; |
125 #endif |
125 #endif |
126 } |
126 } |
127 |
127 |
128 intptr_t* os::Linux::ucontext_get_sp(ucontext_t * uc) { |
128 intptr_t* os::Linux::ucontext_get_sp(const ucontext_t * uc) { |
129 #ifdef BUILTIN_SIM |
129 #ifdef BUILTIN_SIM |
130 return (intptr_t*)uc->uc_mcontext.gregs[REG_SP]; |
130 return (intptr_t*)uc->uc_mcontext.gregs[REG_SP]; |
131 #else |
131 #else |
132 return (intptr_t*)uc->uc_mcontext.sp; |
132 return (intptr_t*)uc->uc_mcontext.sp; |
133 #endif |
133 #endif |
134 } |
134 } |
135 |
135 |
136 intptr_t* os::Linux::ucontext_get_fp(ucontext_t * uc) { |
136 intptr_t* os::Linux::ucontext_get_fp(const ucontext_t * uc) { |
137 #ifdef BUILTIN_SIM |
137 #ifdef BUILTIN_SIM |
138 return (intptr_t*)uc->uc_mcontext.gregs[REG_FP]; |
138 return (intptr_t*)uc->uc_mcontext.gregs[REG_FP]; |
139 #else |
139 #else |
140 return (intptr_t*)uc->uc_mcontext.regs[REG_FP]; |
140 return (intptr_t*)uc->uc_mcontext.regs[REG_FP]; |
141 #endif |
141 #endif |
145 // is currently interrupted by SIGPROF. |
145 // is currently interrupted by SIGPROF. |
146 // os::Solaris::fetch_frame_from_ucontext() tries to skip nested signal |
146 // os::Solaris::fetch_frame_from_ucontext() tries to skip nested signal |
147 // frames. Currently we don't do that on Linux, so it's the same as |
147 // frames. Currently we don't do that on Linux, so it's the same as |
148 // os::fetch_frame_from_context(). |
148 // os::fetch_frame_from_context(). |
149 ExtendedPC os::Linux::fetch_frame_from_ucontext(Thread* thread, |
149 ExtendedPC os::Linux::fetch_frame_from_ucontext(Thread* thread, |
150 ucontext_t* uc, intptr_t** ret_sp, intptr_t** ret_fp) { |
150 const ucontext_t* uc, intptr_t** ret_sp, intptr_t** ret_fp) { |
151 |
151 |
152 assert(thread != NULL, "just checking"); |
152 assert(thread != NULL, "just checking"); |
153 assert(ret_sp != NULL, "just checking"); |
153 assert(ret_sp != NULL, "just checking"); |
154 assert(ret_fp != NULL, "just checking"); |
154 assert(ret_fp != NULL, "just checking"); |
155 |
155 |
156 return os::fetch_frame_from_context(uc, ret_sp, ret_fp); |
156 return os::fetch_frame_from_context(uc, ret_sp, ret_fp); |
157 } |
157 } |
158 |
158 |
159 ExtendedPC os::fetch_frame_from_context(void* ucVoid, |
159 ExtendedPC os::fetch_frame_from_context(const void* ucVoid, |
160 intptr_t** ret_sp, intptr_t** ret_fp) { |
160 intptr_t** ret_sp, intptr_t** ret_fp) { |
161 |
161 |
162 ExtendedPC epc; |
162 ExtendedPC epc; |
163 ucontext_t* uc = (ucontext_t*)ucVoid; |
163 const ucontext_t* uc = (const ucontext_t*)ucVoid; |
164 |
164 |
165 if (uc != NULL) { |
165 if (uc != NULL) { |
166 epc = ExtendedPC(os::Linux::ucontext_get_pc(uc)); |
166 epc = ExtendedPC(os::Linux::ucontext_get_pc(uc)); |
167 if (ret_sp) *ret_sp = os::Linux::ucontext_get_sp(uc); |
167 if (ret_sp) *ret_sp = os::Linux::ucontext_get_sp(uc); |
168 if (ret_fp) *ret_fp = os::Linux::ucontext_get_fp(uc); |
168 if (ret_fp) *ret_fp = os::Linux::ucontext_get_fp(uc); |
589 } |
589 } |
590 |
590 |
591 ///////////////////////////////////////////////////////////////////////////// |
591 ///////////////////////////////////////////////////////////////////////////// |
592 // helper functions for fatal error handler |
592 // helper functions for fatal error handler |
593 |
593 |
594 void os::print_context(outputStream *st, void *context) { |
594 void os::print_context(outputStream *st, const void *context) { |
595 if (context == NULL) return; |
595 if (context == NULL) return; |
596 |
596 |
597 ucontext_t *uc = (ucontext_t*)context; |
597 const ucontext_t *uc = (const ucontext_t*)context; |
598 st->print_cr("Registers:"); |
598 st->print_cr("Registers:"); |
599 #ifdef BUILTIN_SIM |
599 #ifdef BUILTIN_SIM |
600 st->print( "RAX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RAX]); |
600 st->print( "RAX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RAX]); |
601 st->print(", RBX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RBX]); |
601 st->print(", RBX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RBX]); |
602 st->print(", RCX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RCX]); |
602 st->print(", RCX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RCX]); |
641 address pc = os::Linux::ucontext_get_pc(uc); |
641 address pc = os::Linux::ucontext_get_pc(uc); |
642 st->print_cr("Instructions: (pc=" PTR_FORMAT ")", p2i(pc)); |
642 st->print_cr("Instructions: (pc=" PTR_FORMAT ")", p2i(pc)); |
643 print_hex_dump(st, pc - 32, pc + 32, sizeof(char)); |
643 print_hex_dump(st, pc - 32, pc + 32, sizeof(char)); |
644 } |
644 } |
645 |
645 |
646 void os::print_register_info(outputStream *st, void *context) { |
646 void os::print_register_info(outputStream *st, const void *context) { |
647 if (context == NULL) return; |
647 if (context == NULL) return; |
648 |
648 |
649 ucontext_t *uc = (ucontext_t*)context; |
649 const ucontext_t *uc = (const ucontext_t*)context; |
650 |
650 |
651 st->print_cr("Register to memory mapping:"); |
651 st->print_cr("Register to memory mapping:"); |
652 st->cr(); |
652 st->cr(); |
653 |
653 |
654 // this is horrendously verbose but the layout of the registers in the |
654 // this is horrendously verbose but the layout of the registers in the |