2300 //-----------------------------------------------------------------------------
2301 LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) {
2302 if (InterceptOSException) return EXCEPTION_CONTINUE_SEARCH;
2303 DWORD exception_code = exceptionInfo->ExceptionRecord->ExceptionCode;
2304 #ifdef _M_IA64
2305 // On Itanium, we need the "precise pc", which has the slot number coded
2306 // into the least 4 bits: 0000=slot0, 0100=slot1, 1000=slot2 (Windows format).
2307 address pc = (address) exceptionInfo->ExceptionRecord->ExceptionAddress;
2308 // Convert the pc to "Unix format", which has the slot number coded
2309 // into the least 2 bits: 0000=slot0, 0001=slot1, 0010=slot2
2310 // This is needed for IA64 because "relocation" / "implicit null check" / "poll instruction"
2311 // information is saved in the Unix format.
2312 address pc_unix_format = (address) ((((uint64_t)pc) & 0xFFFFFFFFFFFFFFF0) | ((((uint64_t)pc) & 0xF) >> 2));
2313 #elif _M_AMD64
2314 address pc = (address) exceptionInfo->ContextRecord->Rip;
2315 #else
2316 address pc = (address) exceptionInfo->ContextRecord->Eip;
2317 #endif
2318 Thread* t = ThreadLocalStorage::get_thread_slow(); // slow & steady
2319
2320 #ifndef _WIN64
2321 // Execution protection violation - win32 running on AMD64 only
2322 // Handled first to avoid misdiagnosis as a "normal" access violation;
2323 // This is safe to do because we have a new/unique ExceptionInformation
2324 // code for this condition.
2325 if (exception_code == EXCEPTION_ACCESS_VIOLATION) {
2326 PEXCEPTION_RECORD exceptionRecord = exceptionInfo->ExceptionRecord;
2327 int exception_subcode = (int) exceptionRecord->ExceptionInformation[0];
2328 address addr = (address) exceptionRecord->ExceptionInformation[1];
2329
2330 if (exception_subcode == EXCEPTION_INFO_EXEC_VIOLATION) {
2331 int page_size = os::vm_page_size();
2332
2333 // Make sure the pc and the faulting address are sane.
2334 //
2335 // If an instruction spans a page boundary, and the page containing
2336 // the beginning of the instruction is executable but the following
2337 // page is not, the pc and the faulting address might be slightly
2338 // different - we still want to unguard the 2nd page in this case.
2339 //
|
2300 //-----------------------------------------------------------------------------
2301 LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) {
2302 if (InterceptOSException) return EXCEPTION_CONTINUE_SEARCH;
2303 DWORD exception_code = exceptionInfo->ExceptionRecord->ExceptionCode;
2304 #ifdef _M_IA64
2305 // On Itanium, we need the "precise pc", which has the slot number coded
2306 // into the least 4 bits: 0000=slot0, 0100=slot1, 1000=slot2 (Windows format).
2307 address pc = (address) exceptionInfo->ExceptionRecord->ExceptionAddress;
2308 // Convert the pc to "Unix format", which has the slot number coded
2309 // into the least 2 bits: 0000=slot0, 0001=slot1, 0010=slot2
2310 // This is needed for IA64 because "relocation" / "implicit null check" / "poll instruction"
2311 // information is saved in the Unix format.
2312 address pc_unix_format = (address) ((((uint64_t)pc) & 0xFFFFFFFFFFFFFFF0) | ((((uint64_t)pc) & 0xF) >> 2));
2313 #elif _M_AMD64
2314 address pc = (address) exceptionInfo->ContextRecord->Rip;
2315 #else
2316 address pc = (address) exceptionInfo->ContextRecord->Eip;
2317 #endif
2318 Thread* t = ThreadLocalStorage::get_thread_slow(); // slow & steady
2319
2320 // Handle SafeFetch32 and SafeFetchN exceptions.
2321 if (StubRoutines::is_safefetch_fault(pc)) {
2322 return Handle_Exception(exceptionInfo, StubRoutines::continuation_for_safefetch_fault(pc));
2323 }
2324
2325 #ifndef _WIN64
2326 // Execution protection violation - win32 running on AMD64 only
2327 // Handled first to avoid misdiagnosis as a "normal" access violation;
2328 // This is safe to do because we have a new/unique ExceptionInformation
2329 // code for this condition.
2330 if (exception_code == EXCEPTION_ACCESS_VIOLATION) {
2331 PEXCEPTION_RECORD exceptionRecord = exceptionInfo->ExceptionRecord;
2332 int exception_subcode = (int) exceptionRecord->ExceptionInformation[0];
2333 address addr = (address) exceptionRecord->ExceptionInformation[1];
2334
2335 if (exception_subcode == EXCEPTION_INFO_EXEC_VIOLATION) {
2336 int page_size = os::vm_page_size();
2337
2338 // Make sure the pc and the faulting address are sane.
2339 //
2340 // If an instruction spans a page boundary, and the page containing
2341 // the beginning of the instruction is executable but the following
2342 // page is not, the pc and the faulting address might be slightly
2343 // different - we still want to unguard the 2nd page in this case.
2344 //
|