< prev index next >

hotspot/src/os/windows/vm/os_windows.cpp

Print this page
rev 7342 : 8077674: BSD build failures due to undefined macros
Reviewed-by: dsamersoff, kbarrett, hseigel


  93 #include <vdmdbg.h>
  94 
  95 // for timer info max values which include all bits
  96 #define ALL_64_BITS CONST64(0xFFFFFFFFFFFFFFFF)
  97 
  98 // For DLL loading/load error detection
  99 // Values of PE COFF
 100 #define IMAGE_FILE_PTR_TO_SIGNATURE 0x3c
 101 #define IMAGE_FILE_SIGNATURE_LENGTH 4
 102 
 103 static HANDLE main_process;
 104 static HANDLE main_thread;
 105 static int    main_thread_id;
 106 
 107 static FILETIME process_creation_time;
 108 static FILETIME process_exit_time;
 109 static FILETIME process_user_time;
 110 static FILETIME process_kernel_time;
 111 
 112 #ifdef _M_IA64
 113 #define __CPU__ ia64
 114 #elif _M_AMD64
 115 #define __CPU__ amd64
 116 #else
 117 #define __CPU__ i486




 118 #endif
 119 
 120 // save DLL module handle, used by GetModuleFileName
 121 
 122 HINSTANCE vm_lib_handle;
 123 
 124 BOOL WINAPI DllMain(HINSTANCE hinst, DWORD reason, LPVOID reserved) {
 125   switch (reason) {
 126     case DLL_PROCESS_ATTACH:
 127       vm_lib_handle = hinst;
 128       if(ForceTimeHighResolution)
 129         timeBeginPeriod(1L);
 130       break;
 131     case DLL_PROCESS_DETACH:
 132       if(ForceTimeHighResolution)
 133         timeEndPeriod(1L);
 134 
 135       break;
 136     default:
 137       break;


2121 // Implicit OS exception handling
2122 
2123 LONG Handle_Exception(struct _EXCEPTION_POINTERS* exceptionInfo, address handler) {
2124   JavaThread* thread = JavaThread::current();
2125   // Save pc in thread
2126 #ifdef _M_IA64
2127   // Do not blow up if no thread info available.
2128   if (thread) {
2129     // Saving PRECISE pc (with slot information) in thread.
2130     uint64_t precise_pc = (uint64_t) exceptionInfo->ExceptionRecord->ExceptionAddress;
2131     // Convert precise PC into "Unix" format
2132     precise_pc = (precise_pc & 0xFFFFFFFFFFFFFFF0) | ((precise_pc & 0xF) >> 2);
2133     thread->set_saved_exception_pc((address)precise_pc);
2134   }
2135   // Set pc to handler
2136   exceptionInfo->ContextRecord->StIIP = (DWORD64)handler;
2137   // Clear out psr.ri (= Restart Instruction) in order to continue
2138   // at the beginning of the target bundle.
2139   exceptionInfo->ContextRecord->StIPSR &= 0xFFFFF9FFFFFFFFFF;
2140   assert(((DWORD64)handler & 0xF) == 0, "Target address must point to the beginning of a bundle!");
2141 #elif _M_AMD64

2142   // Do not blow up if no thread info available.
2143   if (thread) {
2144     thread->set_saved_exception_pc((address)(DWORD_PTR)exceptionInfo->ContextRecord->Rip);
2145   }
2146   // Set pc to handler
2147   exceptionInfo->ContextRecord->Rip = (DWORD64)handler;
2148 #else
2149   // Do not blow up if no thread info available.
2150   if (thread) {
2151     thread->set_saved_exception_pc((address)(DWORD_PTR)exceptionInfo->ContextRecord->Eip);
2152   }
2153   // Set pc to handler
2154   exceptionInfo->ContextRecord->Eip = (DWORD)(DWORD_PTR)handler;

2155 #endif
2156 
2157   // Continue the execution
2158   return EXCEPTION_CONTINUE_EXECUTION;
2159 }
2160 
2161 
2162 // Used for PostMortemDump
2163 extern "C" void safepoints();
2164 extern "C" void find(int x);
2165 extern "C" void events();
2166 
2167 // According to Windows API documentation, an illegal instruction sequence should generate
2168 // the 0xC000001C exception code. However, real world experience shows that occasionnaly
2169 // the execution of an illegal instruction can generate the exception code 0xC000001E. This
2170 // seems to be an undocumented feature of Win NT 4.0 (and probably other Windows systems).
2171 
2172 #define EXCEPTION_ILLEGAL_INSTRUCTION_2 0xC000001E
2173 
2174 // From "Execution Protection in the Windows Operating System" draft 0.35


2233     NULL, 0
2234 };
2235 
2236 const char* os::exception_name(int exception_code, char *buf, size_t size) {
2237   for (int i = 0; exceptlabels[i].name != NULL; i++) {
2238     if (exceptlabels[i].number == exception_code) {
2239        jio_snprintf(buf, size, "%s", exceptlabels[i].name);
2240        return buf;
2241     }
2242   }
2243 
2244   return NULL;
2245 }
2246 
2247 //-----------------------------------------------------------------------------
2248 LONG Handle_IDiv_Exception(struct _EXCEPTION_POINTERS* exceptionInfo) {
2249   // handle exception caused by idiv; should only happen for -MinInt/-1
2250   // (division by zero is handled explicitly)
2251 #ifdef _M_IA64
2252   assert(0, "Fix Handle_IDiv_Exception");
2253 #elif _M_AMD64

2254   PCONTEXT ctx = exceptionInfo->ContextRecord;
2255   address pc = (address)ctx->Rip;
2256   assert(pc[0] == 0xF7, "not an idiv opcode");
2257   assert((pc[1] & ~0x7) == 0xF8, "cannot handle non-register operands");
2258   assert(ctx->Rax == min_jint, "unexpected idiv exception");
2259   // set correct result values and continue after idiv instruction
2260   ctx->Rip = (DWORD)pc + 2;        // idiv reg, reg  is 2 bytes
2261   ctx->Rax = (DWORD)min_jint;      // result
2262   ctx->Rdx = (DWORD)0;             // remainder
2263   // Continue the execution
2264 #else
2265   PCONTEXT ctx = exceptionInfo->ContextRecord;
2266   address pc = (address)ctx->Eip;
2267   assert(pc[0] == 0xF7, "not an idiv opcode");
2268   assert((pc[1] & ~0x7) == 0xF8, "cannot handle non-register operands");
2269   assert(ctx->Eax == min_jint, "unexpected idiv exception");
2270   // set correct result values and continue after idiv instruction
2271   ctx->Eip = (DWORD)pc + 2;        // idiv reg, reg  is 2 bytes
2272   ctx->Eax = (DWORD)min_jint;      // result
2273   ctx->Edx = (DWORD)0;             // remainder
2274   // Continue the execution

2275 #endif
2276   return EXCEPTION_CONTINUE_EXECUTION;
2277 }
2278 
2279 #ifndef  _WIN64
2280 //-----------------------------------------------------------------------------
2281 LONG WINAPI Handle_FLT_Exception(struct _EXCEPTION_POINTERS* exceptionInfo) {
2282   // handle exception caused by native method modifying control word
2283   PCONTEXT ctx = exceptionInfo->ContextRecord;
2284   DWORD exception_code = exceptionInfo->ExceptionRecord->ExceptionCode;
2285 
2286   switch (exception_code) {
2287     case EXCEPTION_FLT_DENORMAL_OPERAND:
2288     case EXCEPTION_FLT_DIVIDE_BY_ZERO:
2289     case EXCEPTION_FLT_INEXACT_RESULT:
2290     case EXCEPTION_FLT_INVALID_OPERATION:
2291     case EXCEPTION_FLT_OVERFLOW:
2292     case EXCEPTION_FLT_STACK_CHECK:
2293     case EXCEPTION_FLT_UNDERFLOW:
2294       jint fp_control_word = (* (jint*) StubRoutines::addr_fpu_cntrl_wrd_std());


2334   VMError err(t, exception_code, addr, siginfo, context);
2335   err.report_and_die();
2336 
2337   // If UseOsErrorReporting, this will return here and save the error file
2338   // somewhere where we can find it in the minidump.
2339 }
2340 
2341 //-----------------------------------------------------------------------------
2342 LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) {
2343   if (InterceptOSException) return EXCEPTION_CONTINUE_SEARCH;
2344   DWORD exception_code = exceptionInfo->ExceptionRecord->ExceptionCode;
2345 #ifdef _M_IA64
2346   // On Itanium, we need the "precise pc", which has the slot number coded
2347   // into the least 4 bits: 0000=slot0, 0100=slot1, 1000=slot2 (Windows format).
2348   address pc = (address) exceptionInfo->ExceptionRecord->ExceptionAddress;
2349   // Convert the pc to "Unix format", which has the slot number coded
2350   // into the least 2 bits: 0000=slot0, 0001=slot1, 0010=slot2
2351   // This is needed for IA64 because "relocation" / "implicit null check" / "poll instruction"
2352   // information is saved in the Unix format.
2353   address pc_unix_format = (address) ((((uint64_t)pc) & 0xFFFFFFFFFFFFFFF0) | ((((uint64_t)pc) & 0xF) >> 2));
2354 #elif _M_AMD64
2355   address pc = (address) exceptionInfo->ContextRecord->Rip;
2356 #else



2357   address pc = (address) exceptionInfo->ContextRecord->Eip;

2358 #endif
2359   Thread* t = ThreadLocalStorage::get_thread_slow();          // slow & steady
2360 
2361   // Handle SafeFetch32 and SafeFetchN exceptions.
2362   if (StubRoutines::is_safefetch_fault(pc)) {
2363     return Handle_Exception(exceptionInfo, StubRoutines::continuation_for_safefetch_fault(pc));
2364   }
2365 
2366 #ifndef _WIN64
2367   // Execution protection violation - win32 running on AMD64 only
2368   // Handled first to avoid misdiagnosis as a "normal" access violation;
2369   // This is safe to do because we have a new/unique ExceptionInformation
2370   // code for this condition.
2371   if (exception_code == EXCEPTION_ACCESS_VIOLATION) {
2372     PEXCEPTION_RECORD exceptionRecord = exceptionInfo->ExceptionRecord;
2373     int exception_subcode = (int) exceptionRecord->ExceptionInformation[0];
2374     address addr = (address) exceptionRecord->ExceptionInformation[1];
2375 
2376     if (exception_subcode == EXCEPTION_INFO_EXEC_VIOLATION) {
2377       int page_size = os::vm_page_size();




  93 #include <vdmdbg.h>
  94 
  95 // for timer info max values which include all bits
  96 #define ALL_64_BITS CONST64(0xFFFFFFFFFFFFFFFF)
  97 
  98 // For DLL loading/load error detection
  99 // Values of PE COFF
 100 #define IMAGE_FILE_PTR_TO_SIGNATURE 0x3c
 101 #define IMAGE_FILE_SIGNATURE_LENGTH 4
 102 
 103 static HANDLE main_process;
 104 static HANDLE main_thread;
 105 static int    main_thread_id;
 106 
 107 static FILETIME process_creation_time;
 108 static FILETIME process_exit_time;
 109 static FILETIME process_user_time;
 110 static FILETIME process_kernel_time;
 111 
 112 #ifdef _M_IA64
 113   #define __CPU__ ia64


 114 #else
 115   #ifdef _M_AMD64
 116     #define __CPU__ amd64
 117   #else
 118     #define __CPU__ i486
 119   #endif
 120 #endif
 121 
 122 // save DLL module handle, used by GetModuleFileName
 123 
 124 HINSTANCE vm_lib_handle;
 125 
 126 BOOL WINAPI DllMain(HINSTANCE hinst, DWORD reason, LPVOID reserved) {
 127   switch (reason) {
 128     case DLL_PROCESS_ATTACH:
 129       vm_lib_handle = hinst;
 130       if(ForceTimeHighResolution)
 131         timeBeginPeriod(1L);
 132       break;
 133     case DLL_PROCESS_DETACH:
 134       if(ForceTimeHighResolution)
 135         timeEndPeriod(1L);
 136 
 137       break;
 138     default:
 139       break;


2123 // Implicit OS exception handling
2124 
2125 LONG Handle_Exception(struct _EXCEPTION_POINTERS* exceptionInfo, address handler) {
2126   JavaThread* thread = JavaThread::current();
2127   // Save pc in thread
2128 #ifdef _M_IA64
2129   // Do not blow up if no thread info available.
2130   if (thread) {
2131     // Saving PRECISE pc (with slot information) in thread.
2132     uint64_t precise_pc = (uint64_t) exceptionInfo->ExceptionRecord->ExceptionAddress;
2133     // Convert precise PC into "Unix" format
2134     precise_pc = (precise_pc & 0xFFFFFFFFFFFFFFF0) | ((precise_pc & 0xF) >> 2);
2135     thread->set_saved_exception_pc((address)precise_pc);
2136   }
2137   // Set pc to handler
2138   exceptionInfo->ContextRecord->StIIP = (DWORD64)handler;
2139   // Clear out psr.ri (= Restart Instruction) in order to continue
2140   // at the beginning of the target bundle.
2141   exceptionInfo->ContextRecord->StIPSR &= 0xFFFFF9FFFFFFFFFF;
2142   assert(((DWORD64)handler & 0xF) == 0, "Target address must point to the beginning of a bundle!");
2143 #else
2144   #ifdef _M_AMD64
2145   // Do not blow up if no thread info available.
2146   if (thread) {
2147     thread->set_saved_exception_pc((address)(DWORD_PTR)exceptionInfo->ContextRecord->Rip);
2148   }
2149   // Set pc to handler
2150   exceptionInfo->ContextRecord->Rip = (DWORD64)handler;
2151   #else
2152   // Do not blow up if no thread info available.
2153   if (thread) {
2154     thread->set_saved_exception_pc((address)(DWORD_PTR)exceptionInfo->ContextRecord->Eip);
2155   }
2156   // Set pc to handler
2157   exceptionInfo->ContextRecord->Eip = (DWORD)(DWORD_PTR)handler;
2158   #endif
2159 #endif
2160 
2161   // Continue the execution
2162   return EXCEPTION_CONTINUE_EXECUTION;
2163 }
2164 
2165 
2166 // Used for PostMortemDump
2167 extern "C" void safepoints();
2168 extern "C" void find(int x);
2169 extern "C" void events();
2170 
2171 // According to Windows API documentation, an illegal instruction sequence should generate
2172 // the 0xC000001C exception code. However, real world experience shows that occasionnaly
2173 // the execution of an illegal instruction can generate the exception code 0xC000001E. This
2174 // seems to be an undocumented feature of Win NT 4.0 (and probably other Windows systems).
2175 
2176 #define EXCEPTION_ILLEGAL_INSTRUCTION_2 0xC000001E
2177 
2178 // From "Execution Protection in the Windows Operating System" draft 0.35


2237     NULL, 0
2238 };
2239 
2240 const char* os::exception_name(int exception_code, char *buf, size_t size) {
2241   for (int i = 0; exceptlabels[i].name != NULL; i++) {
2242     if (exceptlabels[i].number == exception_code) {
2243        jio_snprintf(buf, size, "%s", exceptlabels[i].name);
2244        return buf;
2245     }
2246   }
2247 
2248   return NULL;
2249 }
2250 
2251 //-----------------------------------------------------------------------------
2252 LONG Handle_IDiv_Exception(struct _EXCEPTION_POINTERS* exceptionInfo) {
2253   // handle exception caused by idiv; should only happen for -MinInt/-1
2254   // (division by zero is handled explicitly)
2255 #ifdef _M_IA64
2256   assert(0, "Fix Handle_IDiv_Exception");
2257 #else
2258   #ifdef  _M_AMD64
2259   PCONTEXT ctx = exceptionInfo->ContextRecord;
2260   address pc = (address)ctx->Rip;
2261   assert(pc[0] == 0xF7, "not an idiv opcode");
2262   assert((pc[1] & ~0x7) == 0xF8, "cannot handle non-register operands");
2263   assert(ctx->Rax == min_jint, "unexpected idiv exception");
2264   // set correct result values and continue after idiv instruction
2265   ctx->Rip = (DWORD)pc + 2;        // idiv reg, reg  is 2 bytes
2266   ctx->Rax = (DWORD)min_jint;      // result
2267   ctx->Rdx = (DWORD)0;             // remainder
2268   // Continue the execution
2269   #else
2270   PCONTEXT ctx = exceptionInfo->ContextRecord;
2271   address pc = (address)ctx->Eip;
2272   assert(pc[0] == 0xF7, "not an idiv opcode");
2273   assert((pc[1] & ~0x7) == 0xF8, "cannot handle non-register operands");
2274   assert(ctx->Eax == min_jint, "unexpected idiv exception");
2275   // set correct result values and continue after idiv instruction
2276   ctx->Eip = (DWORD)pc + 2;        // idiv reg, reg  is 2 bytes
2277   ctx->Eax = (DWORD)min_jint;      // result
2278   ctx->Edx = (DWORD)0;             // remainder
2279   // Continue the execution
2280   #endif
2281 #endif
2282   return EXCEPTION_CONTINUE_EXECUTION;
2283 }
2284 
2285 #ifndef  _WIN64
2286 //-----------------------------------------------------------------------------
2287 LONG WINAPI Handle_FLT_Exception(struct _EXCEPTION_POINTERS* exceptionInfo) {
2288   // handle exception caused by native method modifying control word
2289   PCONTEXT ctx = exceptionInfo->ContextRecord;
2290   DWORD exception_code = exceptionInfo->ExceptionRecord->ExceptionCode;
2291 
2292   switch (exception_code) {
2293     case EXCEPTION_FLT_DENORMAL_OPERAND:
2294     case EXCEPTION_FLT_DIVIDE_BY_ZERO:
2295     case EXCEPTION_FLT_INEXACT_RESULT:
2296     case EXCEPTION_FLT_INVALID_OPERATION:
2297     case EXCEPTION_FLT_OVERFLOW:
2298     case EXCEPTION_FLT_STACK_CHECK:
2299     case EXCEPTION_FLT_UNDERFLOW:
2300       jint fp_control_word = (* (jint*) StubRoutines::addr_fpu_cntrl_wrd_std());


2340   VMError err(t, exception_code, addr, siginfo, context);
2341   err.report_and_die();
2342 
2343   // If UseOsErrorReporting, this will return here and save the error file
2344   // somewhere where we can find it in the minidump.
2345 }
2346 
2347 //-----------------------------------------------------------------------------
2348 LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) {
2349   if (InterceptOSException) return EXCEPTION_CONTINUE_SEARCH;
2350   DWORD exception_code = exceptionInfo->ExceptionRecord->ExceptionCode;
2351 #ifdef _M_IA64
2352   // On Itanium, we need the "precise pc", which has the slot number coded
2353   // into the least 4 bits: 0000=slot0, 0100=slot1, 1000=slot2 (Windows format).
2354   address pc = (address) exceptionInfo->ExceptionRecord->ExceptionAddress;
2355   // Convert the pc to "Unix format", which has the slot number coded
2356   // into the least 2 bits: 0000=slot0, 0001=slot1, 0010=slot2
2357   // This is needed for IA64 because "relocation" / "implicit null check" / "poll instruction"
2358   // information is saved in the Unix format.
2359   address pc_unix_format = (address) ((((uint64_t)pc) & 0xFFFFFFFFFFFFFFF0) | ((((uint64_t)pc) & 0xF) >> 2));


2360 #else
2361   #ifdef _M_AMD64
2362   address pc = (address) exceptionInfo->ContextRecord->Rip;
2363   #else
2364   address pc = (address) exceptionInfo->ContextRecord->Eip;
2365   #endif
2366 #endif
2367   Thread* t = ThreadLocalStorage::get_thread_slow();          // slow & steady
2368 
2369   // Handle SafeFetch32 and SafeFetchN exceptions.
2370   if (StubRoutines::is_safefetch_fault(pc)) {
2371     return Handle_Exception(exceptionInfo, StubRoutines::continuation_for_safefetch_fault(pc));
2372   }
2373 
2374 #ifndef _WIN64
2375   // Execution protection violation - win32 running on AMD64 only
2376   // Handled first to avoid misdiagnosis as a "normal" access violation;
2377   // This is safe to do because we have a new/unique ExceptionInformation
2378   // code for this condition.
2379   if (exception_code == EXCEPTION_ACCESS_VIOLATION) {
2380     PEXCEPTION_RECORD exceptionRecord = exceptionInfo->ExceptionRecord;
2381     int exception_subcode = (int) exceptionRecord->ExceptionInformation[0];
2382     address addr = (address) exceptionRecord->ExceptionInformation[1];
2383 
2384     if (exception_subcode == EXCEPTION_INFO_EXEC_VIOLATION) {
2385       int page_size = os::vm_page_size();


< prev index next >