147 ExtendedPC os::fetch_frame_from_context(void* ucVoid, 148 intptr_t** ret_sp, intptr_t** ret_fp) { 149 150 ExtendedPC epc; 151 ucontext_t* uc = (ucontext_t*)ucVoid; 152 153 if (uc != NULL) { 154 epc = ExtendedPC(os::Linux::ucontext_get_pc(uc)); 155 if (ret_sp) *ret_sp = os::Linux::ucontext_get_sp(uc); 156 if (ret_fp) *ret_fp = os::Linux::ucontext_get_fp(uc); 157 } else { 158 // construct empty ExtendedPC for return value checking 159 epc = ExtendedPC(NULL); 160 if (ret_sp) *ret_sp = (intptr_t *)NULL; 161 if (ret_fp) *ret_fp = (intptr_t *)NULL; 162 } 163 164 return epc; 165 } 166 167 frame os::fetch_frame_from_context(void* ucVoid) { 168 intptr_t* sp; 169 intptr_t* fp; 170 ExtendedPC epc = fetch_frame_from_context(ucVoid, &sp, &fp); 171 return frame(sp, fp, epc.pc()); 172 } 173 174 // By default, gcc always save frame pointer (%ebp/%rbp) on stack. It may get 175 // turned off by -fomit-frame-pointer, 176 frame os::get_sender_for_C_frame(frame* fr) { 177 return frame(fr->sender_sp(), fr->link(), fr->sender_pc()); 178 } 179 180 intptr_t* _get_previous_fp() { 181 #ifdef SPARC_WORKS 182 register intptr_t **ebp; 183 __asm__("mov %%"SPELL_REG_FP", %0":"=r"(ebp)); 184 #elif defined(__clang__) 185 intptr_t **ebp; 186 __asm__ __volatile__ ("mov %%"SPELL_REG_FP", %0":"=r"(ebp):); 187 #else 188 register intptr_t **ebp __asm__ (SPELL_REG_FP); 189 #endif 190 return (intptr_t*) *ebp; // we want what it points to. 191 } 192 193 194 frame os::current_frame() { 195 intptr_t* fp = _get_previous_fp(); 196 frame myframe((intptr_t*)os::current_stack_pointer(), 197 (intptr_t*)fp, 198 CAST_FROM_FN_PTR(address, os::current_frame)); 199 if (os::is_first_C_frame(&myframe)) { 200 // stack is not walkable 201 return frame(); 202 } else { 203 return os::get_sender_for_C_frame(&myframe); 204 } 205 } 206 207 // Utility functions 208 209 // From IA32 System Programming Guide 210 enum { 211 trap_page_fault = 0xE 212 }; 213 214 extern "C" JNIEXPORT int 215 JVM_handle_linux_signal(int sig, 216 siginfo_t* info, 217 void* ucVoid, 218 int abort_if_unrecognized) { 219 ucontext_t* uc = (ucontext_t*) ucVoid; 220 221 Thread* t = ThreadLocalStorage::get_thread_slow(); 222 223 // Must do this before SignalHandlerMark, if crash protection installed we will longjmp away | 147 ExtendedPC os::fetch_frame_from_context(void* ucVoid, 148 intptr_t** ret_sp, intptr_t** ret_fp) { 149 150 ExtendedPC epc; 151 ucontext_t* uc = (ucontext_t*)ucVoid; 152 153 if (uc != NULL) { 154 epc = ExtendedPC(os::Linux::ucontext_get_pc(uc)); 155 if (ret_sp) *ret_sp = os::Linux::ucontext_get_sp(uc); 156 if (ret_fp) *ret_fp = os::Linux::ucontext_get_fp(uc); 157 } else { 158 // construct empty ExtendedPC for return value checking 159 epc = ExtendedPC(NULL); 160 if (ret_sp) *ret_sp = (intptr_t *)NULL; 161 if (ret_fp) *ret_fp = (intptr_t *)NULL; 162 } 163 164 return epc; 165 } 166 167 frame os::fetch_frame_from_context(Thread* thread, void* ucVoid) { 168 intptr_t* sp; 169 intptr_t* fp; 170 ExtendedPC epc = fetch_frame_from_context(ucVoid, &sp, &fp); 171 return frame(thread, sp, fp, epc.pc()); 172 } 173 174 // By default, gcc always save frame pointer (%ebp/%rbp) on stack. It may get 175 // turned off by -fomit-frame-pointer, 176 frame os::get_sender_for_C_frame(Thread* thread, frame* fr) { 177 return frame(thread, fr->sender_sp(), fr->link(), fr->sender_pc()); 178 } 179 180 intptr_t* _get_previous_fp() { 181 #ifdef SPARC_WORKS 182 register intptr_t **ebp; 183 __asm__("mov %%"SPELL_REG_FP", %0":"=r"(ebp)); 184 #elif defined(__clang__) 185 intptr_t **ebp; 186 __asm__ __volatile__ ("mov %%"SPELL_REG_FP", %0":"=r"(ebp):); 187 #else 188 register intptr_t **ebp __asm__ (SPELL_REG_FP); 189 #endif 190 return (intptr_t*) *ebp; // we want what it points to. 191 } 192 193 194 frame os::current_frame() { 195 Thread* thread = Thread::current(); 196 intptr_t* fp = _get_previous_fp(); 197 frame myframe(thread, 198 (intptr_t*)os::current_stack_pointer(), 199 (intptr_t*)fp, 200 CAST_FROM_FN_PTR(address, os::current_frame)); 201 if (os::is_first_C_frame(&myframe)) { 202 // stack is not walkable 203 return frame(); 204 } else { 205 return os::get_sender_for_C_frame(thread, &myframe); 206 } 207 } 208 209 // Utility functions 210 211 // From IA32 System Programming Guide 212 enum { 213 trap_page_fault = 0xE 214 }; 215 216 extern "C" JNIEXPORT int 217 JVM_handle_linux_signal(int sig, 218 siginfo_t* info, 219 void* ucVoid, 220 int abort_if_unrecognized) { 221 ucontext_t* uc = (ucontext_t*) ucVoid; 222 223 Thread* t = ThreadLocalStorage::get_thread_slow(); 224 225 // Must do this before SignalHandlerMark, if crash protection installed we will longjmp away |